~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_select.cc

Refactor

Show diffs side-by-side

added added

removed removed

Lines of Context:
17
17
  @file
18
18
 
19
19
  @brief
20
 
  mysql_select and join optimization
 
20
  select_query and join optimization
21
21
 
22
22
  @defgroup Query_Optimizer  Query Optimizer
23
23
  @{
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
 
 
56
 
#include "drizzled/sql_union.h"
57
 
#include "drizzled/optimizer/key_field.h"
58
 
#include "drizzled/optimizer/position.h"
59
 
#include "drizzled/optimizer/sargable_param.h"
60
 
#include "drizzled/optimizer/key_use.h"
61
 
#include "drizzled/optimizer/range.h"
62
 
#include "drizzled/optimizer/quick_range_select.h"
63
 
#include "drizzled/optimizer/quick_ror_intersect_select.h"
64
 
 
65
 
#include "drizzled/filesort.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
#include <drizzled/drizzled.h>
 
55
#include <drizzled/plugin/storage_engine.h>
 
56
#include <drizzled/sql_union.h>
 
57
#include <drizzled/optimizer/key_field.h>
 
58
#include <drizzled/optimizer/position.h>
 
59
#include <drizzled/optimizer/sargable_param.h>
 
60
#include <drizzled/optimizer/key_use.h>
 
61
#include <drizzled/optimizer/range.h>
 
62
#include <drizzled/optimizer/quick_range_select.h>
 
63
#include <drizzled/optimizer/quick_ror_intersect_select.h>
 
64
#include <drizzled/filesort.h>
 
65
#include <drizzled/sql_lex.h>
 
66
#include <drizzled/session.h>
 
67
#include <drizzled/sort_field.h>
 
68
#include <drizzled/select_result.h>
 
69
#include <drizzled/key.h>
 
70
#include <drizzled/my_hash.h>
66
71
 
67
72
using namespace std;
68
73
 
69
 
namespace drizzled
70
 
{
 
74
namespace drizzled {
71
75
 
72
76
static int sort_keyuse(optimizer::KeyUse *a, optimizer::KeyUse *b);
73
77
static COND *build_equal_items(Session *session, COND *cond,
78
82
static Item* part_of_refkey(Table *form,Field *field);
79
83
static bool cmp_buffer_with_ref(JoinTable *tab);
80
84
static void change_cond_ref_to_const(Session *session,
81
 
                                     vector<COND_CMP>& save_list,
 
85
                                     list<COND_CMP>& save_list,
82
86
                                     Item *and_father,
83
87
                                     Item *cond,
84
88
                                     Item *field,
116
120
                   uint64_t setup_tables_done_option)
117
121
{
118
122
  bool res;
119
 
  register Select_Lex *select_lex= &lex->select_lex;
 
123
  Select_Lex *select_lex= &lex->select_lex;
120
124
  DRIZZLE_SELECT_START(session->getQueryString()->c_str());
121
125
 
122
126
  if (select_lex->master_unit()->is_union() ||
131
135
    unit->set_limit(unit->global_parameters);
132
136
    session->session_marker= 0;
133
137
    /*
134
 
      'options' of mysql_select will be set in JOIN, as far as JOIN for
 
138
      'options' of select_query will be set in JOIN, as far as JOIN for
135
139
      every PS/SP execution new, we will not need reset this flag if
136
140
      setup_tables_done_option changed for next rexecution
137
141
    */
138
 
    res= mysql_select(session,
 
142
    res= select_query(session,
139
143
                      &select_lex->ref_pointer_array,
140
144
                      (TableList*) select_lex->table_list.first,
141
145
                      select_lex->with_wild,
142
146
                      select_lex->item_list,
143
147
                      select_lex->where,
144
 
                      select_lex->order_list.elements +
145
 
                      select_lex->group_list.elements,
 
148
                      select_lex->order_list.size() +
 
149
                      select_lex->group_list.size(),
146
150
                      (Order*) select_lex->order_list.first,
147
151
                      (Order*) select_lex->group_list.first,
148
152
                      select_lex->having,
198
202
    true  an error occured
199
203
    false ok
200
204
*/
201
 
bool fix_inner_refs(Session *session, 
202
 
                    List<Item> &all_fields, 
203
 
                    Select_Lex *select, 
 
205
bool fix_inner_refs(Session *session,
 
206
                    List<Item> &all_fields,
 
207
                    Select_Lex *select,
204
208
                    Item **ref_pointer_array)
205
209
{
206
210
  Item_outer_ref *ref;
207
211
  bool res= false;
208
212
  bool direct_ref= false;
209
213
 
210
 
  List_iterator<Item_outer_ref> ref_it(select->inner_refs_list);
 
214
  List<Item_outer_ref>::iterator ref_it(select->inner_refs_list.begin());
211
215
  while ((ref= ref_it++))
212
216
  {
213
217
    Item *item= ref->outer_ref;
214
218
    Item **item_ref= ref->ref;
215
219
    Item_ref *new_ref;
216
220
    /*
217
 
      TODO: this field item already might be present in the select list.
 
221
      @todo this field item already might be present in the select list.
218
222
      In this case instead of adding new field item we could use an
219
223
      existing one. The change will lead to less operations for copying fields,
220
224
      smaller temporary tables and less data passed through filesort.
221
225
    */
222
226
    if (ref_pointer_array && !ref->found_in_select_list)
223
227
    {
224
 
      int el= all_fields.elements;
 
228
      int el= all_fields.size();
225
229
      ref_pointer_array[el]= item;
226
230
      /* Add the field item to the select list of the current select. */
227
231
      all_fields.push_front(item);
270
274
 
271
275
/*****************************************************************************
272
276
  Check fields, find best join, do the select and output fields.
273
 
  mysql_select assumes that all tables are already opened
 
277
  select_query assumes that all tables are already opened
274
278
*****************************************************************************/
275
279
 
276
280
/*
350
354
  @retval
351
355
    true   an error
352
356
*/
353
 
bool mysql_select(Session *session,
 
357
bool select_query(Session *session,
354
358
                  Item ***rref_pointer_array,
355
 
                  TableList *tables, 
356
 
                  uint32_t wild_num, 
 
359
                  TableList *tables,
 
360
                  uint32_t wild_num,
357
361
                  List<Item> &fields,
358
 
                  COND *conds, 
359
 
                  uint32_t og_num,  
 
362
                  COND *conds,
 
363
                  uint32_t og_num,
360
364
                  Order *order,
361
365
                  Order *group,
362
 
                  Item *having, 
 
366
                  Item *having,
363
367
                  uint64_t select_options,
364
 
                  select_result *result, 
 
368
                  select_result *result,
365
369
                  Select_Lex_Unit *unit,
366
370
                  Select_Lex *select_lex)
367
371
{
420
424
    goto err; // 1
421
425
  }
422
426
 
423
 
  if (session->lex->describe & DESCRIBE_EXTENDED)
 
427
  if (session->lex().describe & DESCRIBE_EXTENDED)
424
428
  {
425
429
    join->conds_history= join->conds;
426
430
    join->having_history= (join->having?join->having:join->tmp_having);
431
435
 
432
436
  join->exec();
433
437
 
434
 
  if (session->lex->describe & DESCRIBE_EXTENDED)
 
438
  if (session->lex().describe & DESCRIBE_EXTENDED)
435
439
  {
436
440
    select_lex->where= join->conds_history;
437
441
    select_lex->having= join->having_history;
541
545
                         DYNAMIC_ARRAY *keyuse,
542
546
                         JoinTable *join_tab,
543
547
                         uint32_t tables,
544
 
                         COND *cond, 
 
548
                         COND *cond,
545
549
                         COND_EQUAL *,
546
550
                         table_map normal_tables,
547
551
                         Select_Lex *select_lex,
558
562
    except BETWEEN predicates that have 3 arguments and
559
563
    IN predicates.
560
564
    This any predicate if it's not BETWEEN/IN can be used
561
 
    directly to fill at most 2 array elements, either of KeyField 
 
565
    directly to fill at most 2 array elements, either of KeyField
562
566
    or SargableParam type. For a BETWEEN predicate 3 elements
563
567
    can be filled as this predicate is considered as
564
568
    saragable with respect to each of its argument.
570
574
    substitutions.
571
575
  */
572
576
  sz= sizeof(optimizer::KeyField) *
573
 
      (((session->lex->current_select->cond_count+1)*2 +
574
 
        session->lex->current_select->between_count)*m+1);
575
 
  if (! (key_fields= (optimizer::KeyField*) session->alloc(sz)))
 
577
      (((session->lex().current_select->cond_count+1)*2 +
 
578
        session->lex().current_select->between_count)*m+1);
 
579
  if (! (key_fields= (optimizer::KeyField*) session->getMemRoot()->allocate(sz)))
576
580
    return true;
577
581
  and_level= 0;
578
582
  field= end= key_fields;
613
617
 
614
618
  /* Process ON conditions for the nested joins */
615
619
  {
616
 
    List_iterator<TableList> li(*join_tab->join->join_list);
 
620
    List<TableList>::iterator li(join_tab->join->join_list->begin());
617
621
    TableList *table;
618
622
    while ((table= li++))
619
623
    {
636
640
      (e.g. if there is a key(a,b,c) but only b < 5 (or a=2 and c < 3) is
637
641
      used in the query, we drop the partial key parts from consideration).
638
642
  */
639
 
  if (keyuse->elements)
 
643
  if (keyuse->size())
640
644
  {
641
645
    optimizer::KeyUse key_end,*prev,*save_pos,*use;
642
646
 
643
 
    internal::my_qsort(keyuse->buffer,keyuse->elements,sizeof(optimizer::KeyUse),
 
647
    internal::my_qsort(keyuse->buffer,keyuse->size(),sizeof(optimizer::KeyUse),
644
648
                       (qsort_cmp) sort_keyuse);
645
649
 
646
650
    memset(&key_end, 0, sizeof(key_end)); /* Add for easy testing */
647
 
    insert_dynamic(keyuse,(unsigned char*) &key_end);
 
651
    keyuse->push_back(&key_end);
648
652
 
649
 
    use= save_pos= dynamic_element(keyuse, 0, optimizer::KeyUse*);
 
653
    use= save_pos= (optimizer::KeyUse*)keyuse->buffer;
650
654
    prev= &key_end;
651
655
    found_eq_constant= 0;
652
656
    {
653
657
      uint32_t i;
654
658
 
655
 
      for (i= 0; i < keyuse->elements-1; i++, use++)
 
659
      for (i= 0; i < keyuse->size()-1; i++, use++)
656
660
      {
657
661
        if (! use->getUsedTables() && use->getOptimizeFlags() != KEY_OPTIMIZE_REF_OR_NULL)
658
662
          use->getTable()->const_key_parts[use->getKey()]|= use->getKeypartMap();
659
663
        if (use->getKey() == prev->getKey() && use->getTable() == prev->getTable())
660
664
        {
661
 
          if (prev->getKeypart() + 1 < use->getKeypart() || 
 
665
          if (prev->getKeypart() + 1 < use->getKeypart() ||
662
666
              ((prev->getKeypart() == use->getKeypart()) && found_eq_constant))
663
667
            continue;                           /* remove */
664
668
        }
679
683
        save_pos++;
680
684
      }
681
685
      i= (uint32_t) (save_pos - (optimizer::KeyUse*) keyuse->buffer);
682
 
      set_dynamic(keyuse, (unsigned char*) &key_end, i);
683
 
      keyuse->elements= i;
 
686
      reinterpret_cast<optimizer::KeyUse*>(keyuse->buffer)[i] = key_end;
 
687
      keyuse->set_size(i);
684
688
    }
685
689
  }
686
690
  return false;
691
695
*/
692
696
void optimize_keyuse(Join *join, DYNAMIC_ARRAY *keyuse_array)
693
697
{
694
 
  optimizer::KeyUse *end,*keyuse= dynamic_element(keyuse_array, 
695
 
                                                  0, 
696
 
                                                  optimizer::KeyUse*);
697
 
 
698
 
  for (end= keyuse+ keyuse_array->elements ; keyuse < end ; keyuse++)
 
698
  optimizer::KeyUse* keyuse= (optimizer::KeyUse*)keyuse_array->buffer;
 
699
  for (optimizer::KeyUse* end= keyuse+ keyuse_array->size() ; keyuse < end ; keyuse++)
699
700
  {
700
701
    table_map map;
701
702
    /*
747
748
void add_group_and_distinct_keys(Join *join, JoinTable *join_tab)
748
749
{
749
750
  List<Item_field> indexed_fields;
750
 
  List_iterator<Item_field> indexed_fields_it(indexed_fields);
 
751
  List<Item_field>::iterator indexed_fields_it(indexed_fields.begin());
751
752
  Order      *cur_group;
752
753
  Item_field *cur_item;
753
754
  key_map possible_keys(0);
761
762
  else if (join->select_distinct)
762
763
  { /* Collect all query fields referenced in the SELECT clause. */
763
764
    List<Item> &select_items= join->fields_list;
764
 
    List_iterator<Item> select_items_it(select_items);
 
765
    List<Item>::iterator select_items_it(select_items.begin());
765
766
    Item *item;
766
767
    while ((item= select_items_it++))
767
768
      item->walk(&Item::collect_item_field_processor, 0,
770
771
  else
771
772
    return;
772
773
 
773
 
  if (indexed_fields.elements == 0)
 
774
  if (indexed_fields.size() == 0)
774
775
    return;
775
776
 
776
777
  /* Intersect the keys of all group fields. */
931
932
 
932
933
  /*
933
934
    we should restore old value of count_cuted_fields because
934
 
    store_val_in_field can be called from mysql_insert
 
935
    store_val_in_field can be called from insert_query
935
936
    with select_insert, which make count_cuted_fields= 1
936
937
   */
937
938
  enum_check_fields old_count_cuted_fields= session->count_cuted_fields;
956
957
    *e1= e2;
957
958
}
958
959
 
959
 
bool create_ref_for_key(Join *join, 
960
 
                        JoinTable *j, 
 
960
bool create_ref_for_key(Join *join,
 
961
                        JoinTable *j,
961
962
                        optimizer::KeyUse *org_keyuse,
962
963
                        table_map used_tables)
963
964
{
1004
1005
  j->ref.key_length=length;
1005
1006
  j->ref.key=(int) key;
1006
1007
  if (!(j->ref.key_buff= (unsigned char*) session->calloc(ALIGN_SIZE(length)*2)) ||
1007
 
      !(j->ref.key_copy= (StoredKey**) session->alloc((sizeof(StoredKey*) *
 
1008
      !(j->ref.key_copy= (StoredKey**) session->getMemRoot()->allocate((sizeof(StoredKey*) *
1008
1009
               (keyparts+1)))) ||
1009
 
      !(j->ref.items=    (Item**) session->alloc(sizeof(Item*)*keyparts)) ||
1010
 
      !(j->ref.cond_guards= (bool**) session->alloc(sizeof(uint*)*keyparts)))
 
1010
      !(j->ref.items=    (Item**) session->getMemRoot()->allocate(sizeof(Item*)*keyparts)) ||
 
1011
      !(j->ref.cond_guards= (bool**) session->getMemRoot()->allocate(sizeof(uint*)*keyparts)))
1011
1012
  {
1012
1013
    return(true);
1013
1014
  }
1216
1217
*/
1217
1218
void JoinTable::cleanup()
1218
1219
{
1219
 
  delete select;
1220
 
  select= 0;
1221
 
  delete quick;
1222
 
  quick= 0;
 
1220
  safe_delete(select);
 
1221
  safe_delete(quick);
 
1222
 
1223
1223
  if (cache.buff)
1224
1224
  {
1225
1225
    size_t size= cache.end - cache.buff;
1348
1348
  bool in_upper_level= false;
1349
1349
  while (cond_equal)
1350
1350
  {
1351
 
    List_iterator_fast<Item_equal> li(cond_equal->current_level);
 
1351
    List<Item_equal>::iterator li(cond_equal->current_level.begin());
1352
1352
    while ((item= li++))
1353
1353
    {
1354
1354
      if (item->contains(field))
1513
1513
        /* Merge two multiple equalities forming a new one */
1514
1514
        left_item_equal->merge(right_item_equal);
1515
1515
        /* Remove the merged multiple equality from the list */
1516
 
        List_iterator<Item_equal> li(cond_equal->current_level);
 
1516
        List<Item_equal>::iterator li(cond_equal->current_level.begin());
1517
1517
        while ((li++) != right_item_equal) {};
1518
1518
        li.remove();
1519
1519
      }
1634
1634
    false   otherwise
1635
1635
*/
1636
1636
static bool check_row_equality(Session *session,
1637
 
                               Item *left_row, 
 
1637
                               Item *left_row,
1638
1638
                               Item_row *right_row,
1639
1639
                               COND_EQUAL *cond_equal,
1640
1640
                               List<Item>* eq_list)
1653
1653
                                       (Item_row *) right_item,
1654
1654
                                       cond_equal, eq_list);
1655
1655
      if (!is_converted)
1656
 
        session->lex->current_select->cond_count++;
 
1656
        session->lex().current_select->cond_count++;
1657
1657
    }
1658
1658
    else
1659
1659
    {
1660
1660
      is_converted= check_simple_equality(left_item, right_item, 0, cond_equal);
1661
 
      session->lex->current_select->cond_count++;
 
1661
      session->lex().current_select->cond_count++;
1662
1662
    }
1663
1663
 
1664
1664
    if (!is_converted)
1714
1714
    if (left_item->type() == Item::ROW_ITEM &&
1715
1715
        right_item->type() == Item::ROW_ITEM)
1716
1716
    {
1717
 
      session->lex->current_select->cond_count--;
 
1717
      session->lex().current_select->cond_count--;
1718
1718
      return check_row_equality(session,
1719
1719
                                (Item_row *) left_item,
1720
1720
                                (Item_row *) right_item,
1745
1745
    just an argument of a comparison predicate.
1746
1746
    The function also determines the maximum number of members in
1747
1747
    equality lists of each Item_cond_and object assigning it to
1748
 
    session->lex->current_select->max_equal_elems.
 
1748
    session->lex().current_select->max_equal_elems.
1749
1749
 
1750
1750
  @note
1751
1751
    Multiple equality predicate =(f1,..fn) is equivalent to the conjuction of
1802
1802
      Item_func::COND_AND_FUNC;
1803
1803
    List<Item> *args= ((Item_cond*) cond)->argument_list();
1804
1804
 
1805
 
    List_iterator<Item> li(*args);
 
1805
    List<Item>::iterator li(args->begin());
1806
1806
    Item *item;
1807
1807
 
1808
1808
    if (and_level)
1824
1824
          li.remove();
1825
1825
      }
1826
1826
 
1827
 
      List_iterator_fast<Item_equal> it(cond_equal.current_level);
 
1827
      List<Item_equal>::iterator it(cond_equal.current_level.begin());
1828
1828
      while ((item_equal= it++))
1829
1829
      {
1830
1830
        item_equal->fix_length_and_dec();
1831
1831
        item_equal->update_used_tables();
1832
 
        set_if_bigger(session->lex->current_select->max_equal_elems,
 
1832
        set_if_bigger(session->lex().current_select->max_equal_elems,
1833
1833
                      item_equal->members());
1834
1834
      }
1835
1835
 
1840
1840
       Make replacement of equality predicates for lower levels
1841
1841
       of the condition expression.
1842
1842
    */
1843
 
    li.rewind();
 
1843
    li= args->begin();
1844
1844
    while ((item= li++))
1845
1845
    {
1846
1846
      Item *new_item;
1876
1876
     */
1877
1877
    if (check_equality(session, cond, &cond_equal, &eq_list))
1878
1878
    {
1879
 
      int n= cond_equal.current_level.elements + eq_list.elements;
 
1879
      int n= cond_equal.current_level.size() + eq_list.size();
1880
1880
      if (n == 0)
1881
1881
        return new Item_int((int64_t) 1,1);
1882
1882
      else if (n == 1)
1888
1888
        }
1889
1889
        else
1890
1890
          item_equal= (Item_equal *) eq_list.pop();
1891
 
        set_if_bigger(session->lex->current_select->max_equal_elems,
 
1891
        set_if_bigger(session->lex().current_select->max_equal_elems,
1892
1892
                      item_equal->members());
1893
1893
        return item_equal;
1894
1894
      }
1901
1901
        Item_cond_and *and_cond= new Item_cond_and(eq_list);
1902
1902
        and_cond->quick_fix_field();
1903
1903
        List<Item> *args= and_cond->argument_list();
1904
 
        List_iterator_fast<Item_equal> it(cond_equal.current_level);
 
1904
        List<Item_equal>::iterator it(cond_equal.current_level.begin());
1905
1905
        while ((item_equal= it++))
1906
1906
        {
1907
1907
          item_equal->fix_length_and_dec();
1908
1908
          item_equal->update_used_tables();
1909
 
          set_if_bigger(session->lex->current_select->max_equal_elems,
 
1909
          set_if_bigger(session->lex().current_select->max_equal_elems,
1910
1910
                        item_equal->members());
1911
1911
        }
1912
1912
        and_cond->cond_equal= cond_equal;
2027
2027
  if (join_list)
2028
2028
  {
2029
2029
    TableList *table;
2030
 
    List_iterator<TableList> li(*join_list);
 
2030
    List<TableList>::iterator li(join_list->begin());
2031
2031
 
2032
2032
    while ((table= li++))
2033
2033
    {
2137
2137
  if (((Item *) item_equal)->const_item() && !item_equal->val_int())
2138
2138
    return new Item_int((int64_t) 0,1);
2139
2139
  Item *item_const= item_equal->get_const();
2140
 
  Item_equal_iterator it(*item_equal);
 
2140
  Item_equal_iterator it(item_equal->begin());
2141
2141
  Item *head;
2142
2142
  if (item_const)
2143
2143
    head= item_const;
2157
2157
        item= 0;
2158
2158
      else
2159
2159
      {
2160
 
        Item_equal_iterator li(*item_equal);
 
2160
        Item_equal_iterator li(item_equal->begin());
2161
2161
        while ((item= li++) != item_field)
2162
2162
        {
2163
2163
          if (item->find_item_equal(upper_levels) == upper)
2177
2177
   }
2178
2178
  }
2179
2179
 
2180
 
  if (!cond && !eq_list.head())
 
2180
  if (!cond && !&eq_list.front())
2181
2181
  {
2182
2182
    if (!eq_item)
2183
2183
      return new Item_int((int64_t) 1,1);
2242
2242
      cond_equal= &((Item_cond_and *) cond)->cond_equal;
2243
2243
      cond_list->disjoin((List<Item> *) &cond_equal->current_level);
2244
2244
 
2245
 
      List_iterator_fast<Item_equal> it(cond_equal->current_level);
 
2245
      List<Item_equal>::iterator it(cond_equal->current_level.begin());
2246
2246
      while ((item_equal= it++))
2247
2247
      {
2248
2248
        item_equal->sort(&compare_fields_by_table_order, table_join_idx);
2249
2249
      }
2250
2250
    }
2251
2251
 
2252
 
    List_iterator<Item> li(*cond_list);
 
2252
    List<Item>::iterator li(cond_list->begin());
2253
2253
    Item *item;
2254
2254
    while ((item= li++))
2255
2255
    {
2265
2265
 
2266
2266
    if (and_level)
2267
2267
    {
2268
 
      List_iterator_fast<Item_equal> it(cond_equal->current_level);
 
2268
      List<Item_equal>::iterator it(cond_equal->current_level.begin());
2269
2269
      while ((item_equal= it++))
2270
2270
      {
2271
2271
        cond= eliminate_item_equal(cond, cond_equal->upper_levels, item_equal);
2277
2277
      }
2278
2278
    }
2279
2279
    if (cond->type() == Item::COND_ITEM &&
2280
 
        !((Item_cond*)cond)->argument_list()->elements)
 
2280
        !((Item_cond*)cond)->argument_list()->size())
2281
2281
      cond= new Item_int((int32_t)cond->val_bool());
2282
2282
 
2283
2283
  }
2286
2286
  {
2287
2287
    item_equal= (Item_equal *) cond;
2288
2288
    item_equal->sort(&compare_fields_by_table_order, table_join_idx);
2289
 
    if (cond_equal && cond_equal->current_level.head() == item_equal)
 
2289
    if (cond_equal && &cond_equal->current_level.front() == item_equal)
2290
2290
      cond_equal= 0;
2291
2291
    return eliminate_item_equal(0, cond_equal, item_equal);
2292
2292
  }
2307
2307
  @param cond       condition whose multiple equalities are to be checked
2308
2308
  @param table      constant table that has been read
2309
2309
*/
2310
 
static void update_const_equal_items(COND *cond, JoinTable *tab)
 
2310
void update_const_equal_items(COND *cond, JoinTable *tab)
2311
2311
{
2312
2312
  if (!(cond->used_tables() & tab->table->map))
2313
2313
    return;
2315
2315
  if (cond->type() == Item::COND_ITEM)
2316
2316
  {
2317
2317
    List<Item> *cond_list= ((Item_cond*) cond)->argument_list();
2318
 
    List_iterator_fast<Item> li(*cond_list);
 
2318
    List<Item>::iterator li(cond_list->begin());
2319
2319
    Item *item;
2320
2320
    while ((item= li++))
2321
2321
      update_const_equal_items(item, tab);
2329
2329
    if (!contained_const && item_equal->get_const())
2330
2330
    {
2331
2331
      /* Update keys for range analysis */
2332
 
      Item_equal_iterator it(*item_equal);
 
2332
      Item_equal_iterator it(item_equal->begin());
2333
2333
      Item_field *item_field;
2334
2334
      while ((item_field= it++))
2335
2335
      {
2364
2364
  and_level
2365
2365
*/
2366
2366
static void change_cond_ref_to_const(Session *session,
2367
 
                                     vector<COND_CMP>& save_list,
 
2367
                                     list<COND_CMP>& save_list,
2368
2368
                                     Item *and_father,
2369
2369
                                     Item *cond,
2370
2370
                                     Item *field,
2373
2373
  if (cond->type() == Item::COND_ITEM)
2374
2374
  {
2375
2375
    bool and_level= ((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC;
2376
 
    List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
 
2376
    List<Item>::iterator li(((Item_cond*) cond)->argument_list()->begin());
2377
2377
    Item *item;
2378
2378
    while ((item=li++))
2379
2379
      change_cond_ref_to_const(session, save_list, and_level ? cond : item, item, field, value);
2399
2399
    if (tmp)
2400
2400
    {
2401
2401
      tmp->collation.set(right_item->collation);
2402
 
      session->change_item_tree(args + 1, tmp);
 
2402
      args[1]= tmp;
2403
2403
      func->update_used_tables();
2404
2404
      if ((functype == Item_func::EQ_FUNC || functype == Item_func::EQUAL_FUNC) &&
2405
 
                and_father != cond && 
 
2405
                and_father != cond &&
2406
2406
          ! left_item->const_item())
2407
2407
      {
2408
2408
        cond->marker=1;
2421
2421
    if (tmp)
2422
2422
    {
2423
2423
      tmp->collation.set(left_item->collation);
2424
 
      session->change_item_tree(args, tmp);
 
2424
      *args= tmp;
2425
2425
      value= tmp;
2426
2426
      func->update_used_tables();
2427
2427
      if ((functype == Item_func::EQ_FUNC || functype == Item_func::EQUAL_FUNC) &&
2428
 
          and_father != cond && 
 
2428
          and_father != cond &&
2429
2429
          ! right_item->const_item())
2430
2430
      {
2431
2431
        args[0]= args[1];                       // For easy check
2432
 
        session->change_item_tree(args + 1, value);
 
2432
        args[1]= value;
2433
2433
        cond->marker=1;
2434
2434
        save_list.push_back( COND_CMP(and_father, func) );
2435
2435
      }
2453
2453
  if (conds->type() == Item::COND_ITEM)
2454
2454
  {
2455
2455
    Item_cond *cnd= (Item_cond*) conds;
2456
 
    List_iterator<Item> li(*(cnd->argument_list()));
 
2456
    List<Item>::iterator li(cnd->argument_list()->begin());
2457
2457
    Item *item;
2458
2458
    while ((item= li++))
2459
2459
    {
2460
2460
      if (item->name == in_additional_cond)
2461
2461
      {
2462
2462
        li.remove();
2463
 
        if (cnd->argument_list()->elements == 1)
2464
 
          return cnd->argument_list()->head();
 
2463
        if (cnd->argument_list()->size() == 1)
 
2464
          return &cnd->argument_list()->front();
2465
2465
        return conds;
2466
2466
      }
2467
2467
    }
2469
2469
  return conds;
2470
2470
}
2471
2471
 
2472
 
static void propagate_cond_constants(Session *session, 
2473
 
                                     vector<COND_CMP>& save_list, 
2474
 
                                     COND *and_father, 
 
2472
static void propagate_cond_constants(Session *session,
 
2473
                                     list<COND_CMP>& save_list,
 
2474
                                     COND *and_father,
2475
2475
                                     COND *cond)
2476
2476
{
2477
2477
  if (cond->type() == Item::COND_ITEM)
2478
2478
  {
2479
2479
    bool and_level= ((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC;
2480
 
    List_iterator_fast<Item> li(*((Item_cond*) cond)->argument_list());
 
2480
    List<Item>::iterator li(((Item_cond*) cond)->argument_list()->begin());
2481
2481
    Item *item;
2482
 
    vector<COND_CMP> save;
 
2482
    list<COND_CMP> save;
2483
2483
    while ((item=li++))
2484
2484
    {
2485
2485
      propagate_cond_constants(session, save, and_level ? cond : item, item);
2487
2487
    if (and_level)
2488
2488
    {
2489
2489
      // Handle other found items
2490
 
      for (vector<COND_CMP>::iterator iter= save.begin(); iter != save.end(); ++iter)
 
2490
      for (list<COND_CMP>::iterator iter= save.begin(); iter != save.end(); ++iter)
2491
2491
      {
2492
 
        Item **args= iter->cmp_func->arguments();
 
2492
        Item **args= iter->second->arguments();
2493
2493
        if (not args[0]->const_item())
2494
2494
        {
2495
 
          change_cond_ref_to_const(session, save_list, iter->and_level,
2496
 
                                   iter->and_level, args[0], args[1] );
 
2495
          change_cond_ref_to_const(session, save, iter->first,
 
2496
                                   iter->first, args[0], args[1] );
2497
2497
        }
2498
2498
      }
2499
2499
    }
2606
2606
         position:
2607
2607
          1. join->cur_embedding_map - bitmap of pairs of brackets (aka nested
2608
2608
             joins) we've opened but didn't close.
2609
 
          2. {each nested_join_st structure not simplified away}->counter - number
 
2609
          2. {each NestedJoin class not simplified away}->counter - number
2610
2610
             of this nested join's children that have already been added to to
2611
2611
             the partial join order.
2612
2612
  @endverbatim
2651
2651
      join->cur_embedding_map |= next_emb->getNestedJoin()->nj_map;
2652
2652
    }
2653
2653
 
2654
 
    if (next_emb->getNestedJoin()->join_list.elements !=
 
2654
    if (next_emb->getNestedJoin()->join_list.size() !=
2655
2655
        next_emb->getNestedJoin()->counter_)
2656
2656
      break;
2657
2657
 
2684
2684
                             &join->cond_equal);
2685
2685
 
2686
2686
    /* change field = field to field = const for each found field = const */
2687
 
    vector<COND_CMP> temp;
 
2687
    list<COND_CMP> temp;
2688
2688
    propagate_cond_constants(session, temp, conds, conds);
2689
2689
    /*
2690
2690
      Remove all instances of item == item
2711
2711
  {
2712
2712
    bool and_level= (((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC);
2713
2713
 
2714
 
    List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
 
2714
    List<Item>::iterator li(((Item_cond*) cond)->argument_list()->begin());
2715
2715
    Item::cond_result tmp_cond_value;
2716
2716
    bool should_fix_fields= false;
2717
2717
 
2730
2730
      if (*cond_value == Item::COND_UNDEF)
2731
2731
              *cond_value= tmp_cond_value;
2732
2732
 
2733
 
      switch (tmp_cond_value) 
 
2733
      switch (tmp_cond_value)
2734
2734
      {
2735
2735
        case Item::COND_OK:                     /* Not true or false */
2736
2736
          if (and_level || (*cond_value == Item::COND_FALSE))
2758
2758
    if (should_fix_fields)
2759
2759
      cond->update_used_tables();
2760
2760
 
2761
 
    if (! ((Item_cond*) cond)->argument_list()->elements || *cond_value != Item::COND_OK)
 
2761
    if (! ((Item_cond*) cond)->argument_list()->size() || *cond_value != Item::COND_OK)
2762
2762
      return (COND*) NULL;
2763
2763
 
2764
 
    if (((Item_cond*) cond)->argument_list()->elements == 1)
2765
 
    {                                           
 
2764
    if (((Item_cond*) cond)->argument_list()->size() == 1)
 
2765
    {
2766
2766
      /* Argument list contains only one element, so reduce it so a single item, then remove list */
2767
 
      item= ((Item_cond*) cond)->argument_list()->head();
2768
 
      ((Item_cond*) cond)->argument_list()->empty();
 
2767
      item= &((Item_cond*) cond)->argument_list()->front();
 
2768
      ((Item_cond*) cond)->argument_list()->clear();
2769
2769
      return item;
2770
2770
    }
2771
2771
  }
2786
2786
    if (args[0]->type() == Item::FIELD_ITEM)
2787
2787
    {
2788
2788
      Field *field= ((Item_field*) args[0])->field;
2789
 
      if (field->flags & AUTO_INCREMENT_FLAG 
2790
 
          && ! field->getTable()->maybe_null 
 
2789
      if (field->flags & AUTO_INCREMENT_FLAG
 
2790
          && ! field->getTable()->maybe_null
2791
2791
          && session->options & OPTION_AUTO_IS_NULL
2792
2792
          && (
2793
 
            session->first_successful_insert_id_in_prev_stmt > 0 
 
2793
            session->first_successful_insert_id_in_prev_stmt > 0
2794
2794
            && session->substitute_null_with_insert_id
2795
2795
            )
2796
2796
          )
2817
2817
#ifdef NOTDEFINED
2818
2818
      /* fix to replace 'NULL' dates with '0' (shreeve@uci.edu) */
2819
2819
      else if (
2820
 
          ((field->type() == DRIZZLE_TYPE_DATE) || (field->type() == DRIZZLE_TYPE_DATETIME)) 
2821
 
          && (field->flags & NOT_NULL_FLAG) 
 
2820
          ((field->type() == DRIZZLE_TYPE_DATE) || (field->type() == DRIZZLE_TYPE_DATETIME))
 
2821
          && (field->flags & NOT_NULL_FLAG)
2822
2822
          && ! field->table->maybe_null)
2823
2823
      {
2824
2824
        COND *new_cond;
2843
2843
  }
2844
2844
  else if (cond->const_item() && !cond->is_expensive())
2845
2845
  /*
2846
 
    TODO:
 
2846
    @todo
2847
2847
    Excluding all expensive functions is too restritive we should exclude only
2848
2848
    materialized IN subquery predicates because they can't yet be evaluated
2849
2849
    here (they need additional initialization that is done later on).
2857
2857
    return (COND *) NULL;
2858
2858
  }
2859
2859
  else if ((*cond_value= cond->eq_cmp_result()) != Item::COND_OK)
2860
 
  {                                             
 
2860
  {
2861
2861
    /* boolan compare function */
2862
2862
    Item *left_item=    ((Item_func*) cond)->arguments()[0];
2863
2863
    Item *right_item= ((Item_func*) cond)->arguments()[1];
2915
2915
  {
2916
2916
    bool and_level= (((Item_cond*) cond)->functype()
2917
2917
                     == Item_func::COND_AND_FUNC);
2918
 
    List_iterator_fast<Item> li(*((Item_cond*) cond)->argument_list());
 
2918
    List<Item>::iterator li(((Item_cond*) cond)->argument_list()->begin());
2919
2919
    Item *item;
2920
2920
    while ((item=li++))
2921
2921
    {
3053
3053
    table->emptyRecord();
3054
3054
    if (table->group && join->tmp_table_param.sum_func_count &&
3055
3055
        table->getShare()->sizeKeys() && !table->cursor->inited)
3056
 
      table->cursor->startIndexScan(0, 0);
 
3056
    {
 
3057
      int tmp_error;
 
3058
      tmp_error= table->cursor->startIndexScan(0, 0);
 
3059
      if (tmp_error != 0)
 
3060
      {
 
3061
        table->print_error(tmp_error, MYF(0));
 
3062
        return -1;
 
3063
      }
 
3064
    }
3057
3065
  }
3058
3066
  /* Set up select_end */
3059
3067
  Next_select_func end_select= setup_end_select_func(join);
3359
3367
  return 0;
3360
3368
}
3361
3369
 
3362
 
int join_read_const_table(JoinTable *tab, optimizer::Position *pos)
3363
 
{
3364
 
  int error;
3365
 
  Table *table=tab->table;
3366
 
  table->const_table=1;
3367
 
  table->null_row=0;
3368
 
  table->status=STATUS_NO_RECORD;
3369
 
 
3370
 
  if (tab->type == AM_SYSTEM)
3371
 
  {
3372
 
    if ((error=join_read_system(tab)))
3373
 
    {                                           // Info for DESCRIBE
3374
 
      tab->info="const row not found";
3375
 
      /* Mark for EXPLAIN that the row was not found */
3376
 
      pos->setFanout(0.0);
3377
 
      pos->clearRefDependMap();
3378
 
      if (! table->maybe_null || error > 0)
3379
 
        return(error);
3380
 
    }
3381
 
  }
3382
 
  else
3383
 
  {
3384
 
    if (! table->key_read && 
3385
 
        table->covering_keys.test(tab->ref.key) && 
3386
 
        ! table->no_keyread &&
3387
 
        (int) table->reginfo.lock_type <= (int) TL_READ_WITH_SHARED_LOCKS)
3388
 
    {
3389
 
      table->key_read=1;
3390
 
      table->cursor->extra(HA_EXTRA_KEYREAD);
3391
 
      tab->index= tab->ref.key;
3392
 
    }
3393
 
    error=join_read_const(tab);
3394
 
    if (table->key_read)
3395
 
    {
3396
 
      table->key_read=0;
3397
 
      table->cursor->extra(HA_EXTRA_NO_KEYREAD);
3398
 
    }
3399
 
    if (error)
3400
 
    {
3401
 
      tab->info="unique row not found";
3402
 
      /* Mark for EXPLAIN that the row was not found */
3403
 
      pos->setFanout(0.0);
3404
 
      pos->clearRefDependMap();
3405
 
      if (!table->maybe_null || error > 0)
3406
 
        return(error);
3407
 
    }
3408
 
  }
3409
 
  if (*tab->on_expr_ref && !table->null_row)
3410
 
  {
3411
 
    if ((table->null_row= test((*tab->on_expr_ref)->val_int() == 0)))
3412
 
      table->mark_as_null_row();
3413
 
  }
3414
 
  if (!table->null_row)
3415
 
    table->maybe_null=0;
3416
 
 
3417
 
  /* Check appearance of new constant items in Item_equal objects */
3418
 
  Join *join= tab->join;
3419
 
  if (join->conds)
3420
 
    update_const_equal_items(join->conds, tab);
3421
 
  TableList *tbl;
3422
 
  for (tbl= join->select_lex->leaf_tables; tbl; tbl= tbl->next_leaf)
3423
 
  {
3424
 
    TableList *embedded;
3425
 
    TableList *embedding= tbl;
3426
 
    do
3427
 
    {
3428
 
      embedded= embedding;
3429
 
      if (embedded->on_expr)
3430
 
         update_const_equal_items(embedded->on_expr, tab);
3431
 
      embedding= embedded->getEmbedding();
3432
 
    }
3433
 
    while (embedding &&
3434
 
           embedding->getNestedJoin()->join_list.head() == embedded);
3435
 
  }
3436
 
 
3437
 
  return(0);
3438
 
}
3439
 
 
3440
 
int join_read_system(JoinTable *tab)
3441
 
{
3442
 
  Table *table= tab->table;
3443
 
  int error;
3444
 
  if (table->status & STATUS_GARBAGE)           // If first read
3445
 
  {
3446
 
    if ((error=table->cursor->read_first_row(table->getInsertRecord(),
3447
 
                                           table->getShare()->getPrimaryKey())))
3448
 
    {
3449
 
      if (error != HA_ERR_END_OF_FILE)
3450
 
        return table->report_error(error);
3451
 
      tab->table->mark_as_null_row();
3452
 
      table->emptyRecord();                     // Make empty record
3453
 
      return -1;
3454
 
    }
3455
 
    table->storeRecord();
3456
 
  }
3457
 
  else if (!table->status)                      // Only happens with left join
3458
 
    table->restoreRecord();                     // restore old record
3459
 
  table->null_row=0;
3460
 
  return table->status ? -1 : 0;
3461
 
}
3462
 
 
3463
3370
/**
3464
3371
  Read a (constant) table when there is at most one matching row.
3465
3372
 
3531
3438
 
3532
3439
  if (!table->cursor->inited)
3533
3440
  {
3534
 
    table->cursor->startIndexScan(tab->ref.key, tab->sorted);
 
3441
    error= table->cursor->startIndexScan(tab->ref.key, tab->sorted);
 
3442
    if (error != 0)
 
3443
    {
 
3444
      table->print_error(error, MYF(0));
 
3445
    }
3535
3446
  }
3536
3447
 
3537
 
  /* TODO: Why don't we do "Late NULLs Filtering" here? */
 
3448
  /* @todo Why don't we do "Late NULLs Filtering" here? */
3538
3449
  if (cmp_buffer_with_ref(tab) ||
3539
3450
      (table->status & (STATUS_GARBAGE | STATUS_NO_PARENT | STATUS_NULL_ROW)))
3540
3451
  {
3579
3490
 
3580
3491
  /* Initialize the index first */
3581
3492
  if (!table->cursor->inited)
3582
 
    table->cursor->startIndexScan(tab->ref.key, tab->sorted);
 
3493
  {
 
3494
    error= table->cursor->startIndexScan(tab->ref.key, tab->sorted);
 
3495
    if (error != 0)
 
3496
      return table->report_error(error);
 
3497
  }
3583
3498
 
3584
3499
  /* Perform "Late NULLs Filtering" (see internals manual for explanations) */
3585
3500
  for (uint32_t i= 0 ; i < tab->ref.key_parts ; i++)
3613
3528
  Table *table= tab->table;
3614
3529
 
3615
3530
  if (!table->cursor->inited)
3616
 
    table->cursor->startIndexScan(tab->ref.key, tab->sorted);
 
3531
  {
 
3532
    error= table->cursor->startIndexScan(tab->ref.key, tab->sorted);
 
3533
    if (error != 0)
 
3534
      return table->report_error(error);
 
3535
  }
3617
3536
  if (cp_buffer_from_ref(tab->join->session, &tab->ref))
3618
3537
    return -1;
3619
3538
  if ((error=table->cursor->index_read_last_map(table->getInsertRecord(),
3717
3636
 
3718
3637
int test_if_quick_select(JoinTable *tab)
3719
3638
{
3720
 
  delete tab->select->quick;
3721
 
  tab->select->quick= 0;
 
3639
  safe_delete(tab->select->quick);
 
3640
 
3722
3641
  return tab->select->test_quick_select(tab->join->session, tab->keys,
3723
3642
                                        (table_map) 0, HA_POS_ERROR, 0, false);
3724
3643
}
3728
3647
  if (tab->select && tab->select->quick && tab->select->quick->reset())
3729
3648
    return 1;
3730
3649
 
3731
 
  tab->read_record.init_read_record(tab->join->session, tab->table, tab->select, 1, true);
 
3650
  if (tab->read_record.init_read_record(tab->join->session, tab->table, tab->select, 1, true))
 
3651
    return 1;
3732
3652
 
3733
3653
  return (*tab->read_record.read_record)(&tab->read_record);
3734
3654
}
3761
3681
  }
3762
3682
 
3763
3683
  if (!table->cursor->inited)
3764
 
    table->cursor->startIndexScan(tab->index, tab->sorted);
 
3684
  {
 
3685
    error= table->cursor->startIndexScan(tab->index, tab->sorted);
 
3686
    if (error != 0)
 
3687
    {
 
3688
      table->report_error(error);
 
3689
      return -1;
 
3690
    }
 
3691
  }
3765
3692
  if ((error=tab->table->cursor->index_first(tab->table->getInsertRecord())))
3766
3693
  {
3767
3694
    if (error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE)
3820
3747
  tab->read_record.index=tab->index;
3821
3748
  tab->read_record.record=table->getInsertRecord();
3822
3749
  if (!table->cursor->inited)
3823
 
    table->cursor->startIndexScan(tab->index, 1);
 
3750
  {
 
3751
    error= table->cursor->startIndexScan(tab->index, 1);
 
3752
    if (error != 0)
 
3753
      return table->report_error(error);
 
3754
  }
3824
3755
  if ((error= tab->table->cursor->index_last(tab->table->getInsertRecord())))
3825
3756
    return table->report_error(error);
3826
3757
 
3884
3815
        {
3885
3816
          if (!join->first_record)
3886
3817
          {
3887
 
                  List_iterator_fast<Item> it(*join->fields);
 
3818
                  List<Item>::iterator it(join->fields->begin());
3888
3819
                  Item *item;
3889
3820
            /* No matching rows for group function */
3890
3821
            join->clear();
3900
3831
              error=join->result->send_data(*join->fields) ? 1 : 0;
3901
3832
            join->send_records++;
3902
3833
          }
3903
 
          if (join->rollup.state != ROLLUP::STATE_NONE && error <= 0)
 
3834
          if (join->rollup.getState() != Rollup::STATE_NONE && error <= 0)
3904
3835
          {
3905
3836
            if (join->rollup_send_data((uint32_t) (idx+1)))
3906
3837
              error= 1;
3990
3921
            return NESTED_LOOP_ERROR;
3991
3922
          }
3992
3923
        }
3993
 
        if (join->rollup.state != ROLLUP::STATE_NONE)
 
3924
        if (join->rollup.getState() != Rollup::STATE_NONE)
3994
3925
        {
3995
3926
          if (join->rollup_write_data((uint32_t) (idx+1), table))
3996
3927
            return NESTED_LOOP_ERROR;
4123
4054
      Item_cond_and *new_cond=new Item_cond_and;
4124
4055
      if (!new_cond)
4125
4056
        return (COND*) 0;
4126
 
      List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
 
4057
      List<Item>::iterator li(((Item_cond*) cond)->argument_list()->begin());
4127
4058
      Item *item;
4128
4059
      while ((item=li++))
4129
4060
      {
4132
4063
        if (fix)
4133
4064
          new_cond->argument_list()->push_back(fix);
4134
4065
      }
4135
 
      switch (new_cond->argument_list()->elements) 
 
4066
      switch (new_cond->argument_list()->size())
4136
4067
      {
4137
4068
        case 0:
4138
4069
          return (COND*) 0;                     // Always true
4139
4070
        case 1:
4140
 
          return new_cond->argument_list()->head();
 
4071
          return &new_cond->argument_list()->front();
4141
4072
        default:
4142
4073
          /*
4143
4074
            Item_cond_and do not need fix_fields for execution, its parameters
4153
4084
      Item_cond_or *new_cond=new Item_cond_or;
4154
4085
      if (!new_cond)
4155
4086
        return (COND*) 0;
4156
 
      List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
 
4087
      List<Item>::iterator li(((Item_cond*) cond)->argument_list()->begin());
4157
4088
      Item *item;
4158
4089
      while ((item=li++))
4159
4090
      {
4235
4166
      if (field->eq(key_part->field) &&
4236
4167
          !(key_part->key_part_flag & HA_PART_KEY_SEG) &&
4237
4168
          //If field can be NULL, we should not remove this predicate, as
4238
 
          //it may lead to non-rejection of NULL values. 
 
4169
          //it may lead to non-rejection of NULL values.
4239
4170
          !(field->real_maybe_null()))
4240
4171
      {
4241
4172
        return table->reginfo.join_tab->ref.items[part];
4505
4436
{
4506
4437
  List<Item> *fields= (List<Item> *) data;
4507
4438
  bool part_found= 0;
4508
 
  List_iterator<Item> li(*fields);
 
4439
  List<Item>::iterator li(fields->begin());
4509
4440
  Item *item;
4510
4441
 
4511
4442
  while ((item= li++))
4590
4521
    save_quick= select->quick;
4591
4522
    /*
4592
4523
      assume results are not ordered when index merge is used
4593
 
      TODO: sergeyp: Results of all index merge selects actually are ordered
 
4524
      @todo sergeyp: Results of all index merge selects actually are ordered
4594
4525
      by clustered PK values.
4595
4526
    */
4596
4527
 
4865
4796
          tab->type= AM_NEXT;           // Read with index_first(), index_next()
4866
4797
          if (select && select->quick)
4867
4798
          {
4868
 
            delete select->quick;
4869
 
            select->quick= 0;
 
4799
            safe_delete(select->quick);
4870
4800
          }
4871
4801
          if (table->covering_keys.test(best_key))
4872
4802
          {
4930
4860
 
4931
4861
        /* ORDER BY range_key DESC */
4932
4862
        tmp= new optimizer::QuickSelectDescending((optimizer::QuickRangeSelect*)(select->quick),
4933
 
                                                  used_key_parts, 
 
4863
                                                  used_key_parts,
4934
4864
                                                  &error);
4935
4865
        if (! tmp || error)
4936
4866
        {
4939
4869
          tab->limit= 0;
4940
4870
          return 0; // Reverse sort not supported
4941
4871
        }
4942
 
        select->quick=tmp;
 
4872
        select->quick= tmp;
4943
4873
      }
4944
4874
    }
4945
4875
    else if (tab->type != AM_NEXT &&
5050
4980
        For impossible ranges (like when doing a lookup on NULL on a NOT NULL
5051
4981
        field, quick will contain an empty record set.
5052
4982
      */
5053
 
      if (! (select->quick= (optimizer::get_quick_select_for_ref(session, 
5054
 
                                                                 table, 
 
4983
      if (! (select->quick= (optimizer::get_quick_select_for_ref(session,
 
4984
                                                                 table,
5055
4985
                                                                 &tab->ref,
5056
4986
                                                                 tab->found_records))))
5057
4987
      {
5099
5029
  org_record=(char*) (record=table->getInsertRecord())+offset;
5100
5030
  new_record=(char*) table->getUpdateRecord()+offset;
5101
5031
 
5102
 
  cursor->startTableScan(1);
 
5032
  if ((error= cursor->startTableScan(1)))
 
5033
    goto err;
 
5034
 
5103
5035
  error=cursor->rnd_next(record);
5104
5036
  for (;;)
5105
5037
  {
5176
5108
  @note
5177
5109
    Note that this will not work on tables with blobs!
5178
5110
*/
5179
 
int remove_dup_with_hash_index(Session *session, 
 
5111
int remove_dup_with_hash_index(Session *session,
5180
5112
                               Table *table,
5181
5113
                               uint32_t field_count,
5182
5114
                               Field **first_field,
5185
5117
{
5186
5118
  unsigned char *key_pos, *record=table->getInsertRecord();
5187
5119
  int error;
5188
 
  Cursor *cursor= table->cursor;
 
5120
  Cursor &cursor= *table->cursor;
5189
5121
  uint32_t extra_length= ALIGN_SIZE(key_length)-key_length;
5190
5122
  uint32_t *field_length;
5191
5123
  HASH hash;
5192
 
  std::vector<unsigned char> key_buffer;
5193
 
  std::vector<uint32_t> field_lengths;
5194
 
 
5195
 
  key_buffer.resize((key_length + extra_length) * (long) cursor->stats.records);
5196
 
  field_lengths.resize(field_count);
 
5124
  std::vector<unsigned char> key_buffer((key_length + extra_length) * (long) cursor.stats.records);
 
5125
  std::vector<uint32_t> field_lengths(field_count);
5197
5126
 
5198
5127
  {
5199
5128
    Field **ptr;
5210
5139
    extra_length= ALIGN_SIZE(key_length)-key_length;
5211
5140
  }
5212
5141
 
5213
 
  if (hash_init(&hash, &my_charset_bin, (uint32_t) cursor->stats.records, 0,
5214
 
                key_length, (hash_get_key) 0, 0, 0))
5215
 
  {
5216
 
    return(1);
5217
 
  }
5218
 
 
5219
 
  cursor->startTableScan(1);
 
5142
  if (hash_init(&hash, &my_charset_bin, (uint32_t) cursor.stats.records, 0, key_length, (hash_get_key) 0, 0, 0))
 
5143
    return 1;
 
5144
 
 
5145
  if ((error= cursor.startTableScan(1)))
 
5146
    goto err;
 
5147
 
5220
5148
  key_pos= &key_buffer[0];
5221
5149
  for (;;)
5222
5150
  {
5223
 
    unsigned char *org_key_pos;
5224
5151
    if (session->getKilled())
5225
5152
    {
5226
5153
      session->send_kill_message();
5227
5154
      error=0;
5228
5155
      goto err;
5229
5156
    }
5230
 
    if ((error=cursor->rnd_next(record)))
 
5157
    if ((error=cursor.rnd_next(record)))
5231
5158
    {
5232
5159
      if (error == HA_ERR_RECORD_DELETED)
5233
5160
        continue;
5237
5164
    }
5238
5165
    if (having && !having->val_int())
5239
5166
    {
5240
 
      if ((error=cursor->deleteRecord(record)))
 
5167
      if ((error=cursor.deleteRecord(record)))
5241
5168
        goto err;
5242
5169
      continue;
5243
5170
    }
5244
5171
 
5245
5172
    /* copy fields to key buffer */
5246
 
    org_key_pos= key_pos;
 
5173
    unsigned char* org_key_pos= key_pos;
5247
5174
    field_length= &field_lengths[0];
5248
5175
    for (Field **ptr= first_field ; *ptr ; ptr++)
5249
5176
    {
5254
5181
    if (hash_search(&hash, org_key_pos, key_length))
5255
5182
    {
5256
5183
      /* Duplicated found ; Remove the row */
5257
 
      if ((error=cursor->deleteRecord(record)))
 
5184
      if ((error=cursor.deleteRecord(record)))
5258
5185
        goto err;
5259
5186
    }
5260
5187
    else
5262
5189
    key_pos+=extra_length;
5263
5190
  }
5264
5191
  hash_free(&hash);
5265
 
  cursor->extra(HA_EXTRA_NO_CACHE);
5266
 
  (void) cursor->endTableScan();
5267
 
  return(0);
 
5192
  cursor.extra(HA_EXTRA_NO_CACHE);
 
5193
  (void) cursor.endTableScan();
 
5194
  return 0;
5268
5195
 
5269
5196
err:
5270
5197
  hash_free(&hash);
5271
 
  cursor->extra(HA_EXTRA_NO_CACHE);
5272
 
  (void) cursor->endTableScan();
 
5198
  cursor.extra(HA_EXTRA_NO_CACHE);
 
5199
  (void) cursor.endTableScan();
5273
5200
  if (error)
5274
5201
    table->print_error(error,MYF(0));
5275
 
  return(1);
 
5202
  return 1;
5276
5203
}
5277
5204
 
5278
5205
SortField *make_unireg_sortorder(Order *order, uint32_t *length, SortField *sortorder)
5403
5330
  @retval
5404
5331
    true  if error occurred
5405
5332
*/
5406
 
static bool find_order_in_list(Session *session, 
5407
 
                               Item **ref_pointer_array, 
 
5333
static bool find_order_in_list(Session *session,
 
5334
                               Item **ref_pointer_array,
5408
5335
                               TableList *tables,
5409
5336
                               Order *order,
5410
5337
                               List<Item> &fields,
5425
5352
  if (order_item->type() == Item::INT_ITEM && order_item->basic_const_item())
5426
5353
  {                                             /* Order by position */
5427
5354
    uint32_t count= (uint32_t) order_item->val_int();
5428
 
    if (!count || count > fields.elements)
 
5355
    if (!count || count > fields.size())
5429
5356
    {
5430
5357
      my_error(ER_BAD_FIELD_ERROR, MYF(0),
5431
 
               order_item->full_name(), session->where);
 
5358
               order_item->full_name(), session->where());
5432
5359
      return true;
5433
5360
    }
5434
5361
    order->item= ref_pointer_array + count - 1;
5505
5432
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_NON_UNIQ_ERROR,
5506
5433
                          ER(ER_NON_UNIQ_ERROR),
5507
5434
                          ((Item_ident*) order_item)->field_name,
5508
 
                          session->where);
 
5435
                          session->where());
5509
5436
    }
5510
5437
  }
5511
5438
 
5527
5454
       session->is_fatal_error))
5528
5455
    return true; /* Wrong field. */
5529
5456
 
5530
 
  uint32_t el= all_fields.elements;
 
5457
  uint32_t el= all_fields.size();
5531
5458
  all_fields.push_front(order_item); /* Add new field to field list. */
5532
5459
  ref_pointer_array[el]= order_item;
5533
5460
  order->item= ref_pointer_array + el;
5547
5474
                List<Item> &all_fields,
5548
5475
                Order *order)
5549
5476
{
5550
 
  session->where="order clause";
 
5477
  session->setWhere("order clause");
5551
5478
  for (; order; order=order->next)
5552
5479
  {
5553
5480
    if (find_order_in_list(session, ref_pointer_array, tables, order, fields,
5596
5523
  if (!order)
5597
5524
    return 0;                           /* Everything is ok */
5598
5525
 
5599
 
  uint32_t org_fields=all_fields.elements;
 
5526
  uint32_t org_fields=all_fields.size();
5600
5527
 
5601
 
  session->where="group statement";
 
5528
  session->setWhere("group statement");
5602
5529
  for (ord= order; ord; ord= ord->next)
5603
5530
  {
5604
5531
    if (find_order_in_list(session, ref_pointer_array, tables, ord, fields,
5631
5558
    Item *item;
5632
5559
    Item_field *field;
5633
5560
    int cur_pos_in_select_list= 0;
5634
 
    List_iterator<Item> li(fields);
5635
 
    List_iterator<Item_field> naf_it(session->lex->current_select->non_agg_fields);
 
5561
    List<Item>::iterator li(fields.begin());
 
5562
    List<Item_field>::iterator naf_it(session->lex().current_select->non_agg_fields.begin());
5636
5563
 
5637
5564
    field= naf_it++;
5638
5565
    while (field && (item=li++))
5658
5585
            if ((*ord->item)->eq((Item*)field, 0))
5659
5586
              goto next_field;
5660
5587
          /*
5661
 
            TODO: change ER_WRONG_FIELD_WITH_GROUP to more detailed
5662
 
            ER_NON_GROUPING_FIELD_USED
 
5588
            @todo change ER_WRONG_FIELD_WITH_GROUP to more detailed ER_NON_GROUPING_FIELD_USED
5663
5589
          */
5664
5590
          my_error(ER_WRONG_FIELD_WITH_GROUP, MYF(0), field->full_name());
5665
5591
          return 1;
5670
5596
      cur_pos_in_select_list++;
5671
5597
    }
5672
5598
  }
5673
 
  if (org_fields != all_fields.elements)
 
5599
  if (org_fields != all_fields.size())
5674
5600
    *hidden_group_fields=1;                     // group fields is not used
5675
5601
  return 0;
5676
5602
}
5688
5614
                                List<Item> &,
5689
5615
                                bool *all_order_by_fields_used)
5690
5616
{
5691
 
  List_iterator<Item> li(fields);
 
5617
  List<Item>::iterator li(fields.begin());
5692
5618
  Item *item;
5693
5619
  Order *order,*group,**prev;
5694
5620
 
5701
5627
  {
5702
5628
    if (order->in_field_list)
5703
5629
    {
5704
 
      Order *ord=(Order*) session->memdup((char*) order,sizeof(Order));
 
5630
      Order *ord=(Order*) session->getMemRoot()->duplicate((char*) order,sizeof(Order));
5705
5631
      if (!ord)
5706
5632
        return 0;
5707
5633
      *prev=ord;
5712
5638
      *all_order_by_fields_used= 0;
5713
5639
  }
5714
5640
 
5715
 
  li.rewind();
 
5641
  li= fields.begin();
5716
5642
  while ((item=li++))
5717
5643
  {
5718
5644
    if (!item->const_item() && !item->with_sum_func && !item->marker)
5752
5678
*/
5753
5679
void count_field_types(Select_Lex *select_lex, Tmp_Table_Param *param, List<Item> &fields, bool reset_with_sum_func)
5754
5680
{
5755
 
  List_iterator<Item> li(fields);
 
5681
  List<Item>::iterator li(fields.begin());
5756
5682
  Item *field;
5757
5683
 
5758
5684
  param->field_count=param->sum_func_count=param->func_count=
5809
5735
*/
5810
5736
int test_if_item_cache_changed(List<Cached_item> &list)
5811
5737
{
5812
 
  List_iterator<Cached_item> li(list);
 
5738
  List<Cached_item>::iterator li(list.begin());
5813
5739
  int idx= -1,i;
5814
5740
  Cached_item *buff;
5815
5741
 
5816
 
  for (i=(int) list.elements-1 ; (buff=li++) ; i--)
 
5742
  for (i=(int) list.size()-1 ; (buff=li++) ; i--)
5817
5743
  {
5818
5744
    if (buff->cmp())
5819
5745
      idx=i;
5858
5784
                       List<Item> &all_fields)
5859
5785
{
5860
5786
  Item *pos;
5861
 
  List_iterator_fast<Item> li(all_fields);
 
5787
  List<Item>::iterator li(all_fields.begin());
5862
5788
  CopyField *copy= NULL;
5863
 
  res_selected_fields.empty();
5864
 
  res_all_fields.empty();
5865
 
  List_iterator_fast<Item> itr(res_all_fields);
 
5789
  res_selected_fields.clear();
 
5790
  res_all_fields.clear();
 
5791
  List<Item>::iterator itr(res_all_fields.begin());
5866
5792
  List<Item> extra_funcs;
5867
 
  uint32_t i, border= all_fields.elements - elements;
 
5793
  uint32_t i, border= all_fields.size() - elements;
5868
5794
 
5869
5795
  if (param->field_count &&
5870
 
      !(copy=param->copy_field= new CopyField[param->field_count]))
5871
 
    goto err2;
 
5796
      !(copy= param->copy_field= new CopyField[param->field_count]))
 
5797
    return true;
5872
5798
 
5873
 
  param->copy_funcs.empty();
 
5799
  param->copy_funcs.clear();
5874
5800
  for (i= 0; (pos= li++); i++)
5875
5801
  {
5876
5802
    Field *field;
5903
5829
              copy_funcs
5904
5830
              (to see full test case look at having.test, BUG #4358)
5905
5831
            */
5906
 
        if (param->copy_funcs.push_front(pos))
5907
 
          goto err;
 
5832
        param->copy_funcs.push_front(pos);
5908
5833
      }
5909
5834
      else
5910
5835
      {
5939
5864
             !real_pos->with_sum_func)
5940
5865
    {                                           // Save for send fields
5941
5866
      pos= real_pos;
5942
 
      /* TODO:
5943
 
        In most cases this result will be sent to the user.
 
5867
      /*
 
5868
        @todo In most cases this result will be sent to the user.
5944
5869
        This should be changed to use copy_int or copy_real depending
5945
5870
        on how the value is to be used: In some cases this may be an
5946
5871
        argument in a group function, like: IF(ISNULL(col),0,COUNT(*))
5947
5872
      */
5948
 
      if (!(pos=new Item_copy_string(pos)))
5949
 
        goto err;
 
5873
      pos=new Item_copy_string(pos);
5950
5874
      if (i < border)                           // HAVING, order_st and GROUP BY
5951
 
      {
5952
 
        if (extra_funcs.push_back(pos))
5953
 
          goto err;
5954
 
      }
5955
 
      else if (param->copy_funcs.push_back(pos))
5956
 
        goto err;
 
5875
        extra_funcs.push_back(pos);
 
5876
      else 
 
5877
                                param->copy_funcs.push_back(pos);
5957
5878
    }
5958
5879
    res_all_fields.push_back(pos);
5959
 
    ref_pointer_array[((i < border)? all_fields.elements-i-1 : i-border)]=
 
5880
    ref_pointer_array[((i < border)? all_fields.size()-i-1 : i-border)]=
5960
5881
      pos;
5961
5882
  }
5962
5883
  param->copy_field_end= copy;
5976
5897
  if (copy)
5977
5898
    delete [] param->copy_field;                        // This is never 0
5978
5899
  param->copy_field=0;
5979
 
err2:
5980
 
  return(true);
 
5900
  return true;
5981
5901
}
5982
5902
 
5983
5903
/**
5994
5914
  for (; ptr != end; ptr++)
5995
5915
    (*ptr->do_copy)(ptr);
5996
5916
 
5997
 
  List_iterator_fast<Item> it(param->copy_funcs);
 
5917
  List<Item>::iterator it(param->copy_funcs.begin());
5998
5918
  Item_copy_string *item;
5999
5919
  while ((item = (Item_copy_string*) it++))
6000
5920
    item->copy();
6023
5943
                                                uint32_t elements,
6024
5944
                              List<Item> &all_fields)
6025
5945
{
6026
 
  List_iterator_fast<Item> it(all_fields);
 
5946
  List<Item>::iterator it(all_fields.begin());
6027
5947
  Item *item_field,*item;
6028
5948
 
6029
 
  res_selected_fields.empty();
6030
 
  res_all_fields.empty();
 
5949
  res_selected_fields.clear();
 
5950
  res_all_fields.clear();
6031
5951
 
6032
 
  uint32_t i, border= all_fields.elements - elements;
 
5952
  uint32_t i, border= all_fields.size() - elements;
6033
5953
  for (i= 0; (item= it++); i++)
6034
5954
  {
6035
5955
    Field *field;
6068
5988
        item_field= item;
6069
5989
    }
6070
5990
    res_all_fields.push_back(item_field);
6071
 
    ref_pointer_array[((i < border)? all_fields.elements-i-1 : i-border)]=
 
5991
    ref_pointer_array[((i < border)? all_fields.size()-i-1 : i-border)]=
6072
5992
      item_field;
6073
5993
  }
6074
5994
 
6075
 
  List_iterator_fast<Item> itr(res_all_fields);
 
5995
  List<Item>::iterator itr(res_all_fields.begin());
6076
5996
  for (i= 0; i < border; i++)
6077
5997
    itr++;
6078
5998
  itr.sublist(res_selected_fields, elements);
6102
6022
                               uint32_t elements,
6103
6023
                                                 List<Item> &all_fields)
6104
6024
{
6105
 
  List_iterator_fast<Item> it(all_fields);
 
6025
  List<Item>::iterator it(all_fields.begin());
6106
6026
  Item *item, *new_item;
6107
 
  res_selected_fields.empty();
6108
 
  res_all_fields.empty();
 
6027
  res_selected_fields.clear();
 
6028
  res_all_fields.clear();
6109
6029
 
6110
 
  uint32_t i, border= all_fields.elements - elements;
 
6030
  uint32_t i, border= all_fields.size() - elements;
6111
6031
  for (i= 0; (item= it++); i++)
6112
6032
  {
6113
6033
    res_all_fields.push_back(new_item= item->get_tmp_table_item(session));
6114
 
    ref_pointer_array[((i < border)? all_fields.elements-i-1 : i-border)]=
 
6034
    ref_pointer_array[((i < border)? all_fields.size()-i-1 : i-border)]=
6115
6035
      new_item;
6116
6036
  }
6117
6037
 
6118
 
  List_iterator_fast<Item> itr(res_all_fields);
 
6038
  List<Item>::iterator itr(res_all_fields.begin());
6119
6039
  for (i= 0; i < border; i++)
6120
6040
    itr++;
6121
6041
  itr.sublist(res_selected_fields, elements);
6207
6127
    /*
6208
6128
      Need to check the THD error state because Item::val_xxx() don't
6209
6129
      return error code, but can generate errors
6210
 
      TODO: change it for a real status check when Item::val_xxx()
 
6130
      @todo change it for a real status check when Item::val_xxx()
6211
6131
      are extended to return status code.
6212
6132
    */
6213
6133
    if (session->is_error())
6265
6185
  @param changed        out:  returns 1 if item contains a replaced field item
6266
6186
 
6267
6187
  @todo
6268
 
    - TODO: Some functions are not null-preserving. For those functions
 
6188
    - @todo Some functions are not null-preserving. For those functions
6269
6189
    updating of the maybe_null attribute is an overkill.
6270
6190
 
6271
6191
  @retval
6277
6197
{
6278
6198
  if (expr->arg_count)
6279
6199
  {
6280
 
    Name_resolution_context *context= &session->lex->current_select->context;
 
6200
    Name_resolution_context *context= &session->lex().current_select->context;
6281
6201
    Item **arg,**arg_end;
6282
6202
    bool arg_changed= false;
6283
6203
    for (arg= expr->arguments(),
6296
6216
            if (!(new_item= new Item_ref(context, group_tmp->item, 0,
6297
6217
                                        item->name)))
6298
6218
              return 1;                                 // fatal_error is set
6299
 
            session->change_item_tree(arg, new_item);
 
6219
            *arg= new_item;
6300
6220
            arg_changed= true;
6301
6221
          }
6302
6222
        }
6320
6240
static void print_table_array(Session *session, String *str, TableList **table,
6321
6241
                              TableList **end)
6322
6242
{
6323
 
  (*table)->print(session, str, QT_ORDINARY);
 
6243
  (*table)->print(session, str);
6324
6244
 
6325
6245
  for (TableList **tbl= table + 1; tbl < end; tbl++)
6326
6246
  {
6334
6254
      str->append(STRING_WITH_LEN(" straight_join "));
6335
6255
    else
6336
6256
      str->append(STRING_WITH_LEN(" join "));
6337
 
    curr->print(session, str, QT_ORDINARY);
 
6257
    curr->print(session, str);
6338
6258
    if (curr->on_expr)
6339
6259
    {
6340
6260
      str->append(STRING_WITH_LEN(" on("));
6341
 
      curr->on_expr->print(str, QT_ORDINARY);
 
6261
      curr->on_expr->print(str);
6342
6262
      str->append(')');
6343
6263
    }
6344
6264
  }
6349
6269
  @param session     thread Cursor
6350
6270
  @param str     string where table should be printed
6351
6271
  @param tables  list of tables in join
6352
 
  @query_type    type of the query is being generated
6353
6272
*/
6354
6273
void print_join(Session *session, String *str,
6355
 
                List<TableList> *tables, enum_query_type)
 
6274
                List<TableList> *tables)
6356
6275
{
6357
6276
  /* List is reversed => we should reverse it before using */
6358
 
  List_iterator_fast<TableList> ti(*tables);
6359
 
  TableList **table= (TableList **)session->alloc(sizeof(TableList*) *
6360
 
                                                tables->elements);
 
6277
  List<TableList>::iterator ti(tables->begin());
 
6278
  TableList **table= (TableList **)session->getMemRoot()->allocate(sizeof(TableList*) *
 
6279
                                                tables->size());
6361
6280
  if (table == 0)
6362
6281
    return;  // out of memory
6363
6282
 
6364
 
  for (TableList **t= table + (tables->elements - 1); t >= table; t--)
 
6283
  for (TableList **t= table + (tables->size() - 1); t >= table; t--)
6365
6284
    *t= ti++;
6366
 
  assert(tables->elements >= 1);
6367
 
  print_table_array(session, str, table, table + tables->elements);
 
6285
  assert(tables->size() >= 1);
 
6286
  print_table_array(session, str, table, table + tables->size());
6368
6287
}
6369
6288
 
6370
 
void Select_Lex::print(Session *session, String *str, enum_query_type query_type)
 
6289
void Select_Lex::print(Session *session, String *str)
6371
6290
{
6372
6291
  /* QQ: session may not be set for sub queries, but this should be fixed */
6373
6292
  if(not session)
6392
6311
 
6393
6312
  //Item List
6394
6313
  bool first= 1;
6395
 
  List_iterator_fast<Item> it(item_list);
 
6314
  List<Item>::iterator it(item_list.begin());
6396
6315
  Item *item;
6397
6316
  while ((item= it++))
6398
6317
  {
6400
6319
      first= 0;
6401
6320
    else
6402
6321
      str->append(',');
6403
 
    item->print_item_w_name(str, query_type);
 
6322
    item->print_item_w_name(str);
6404
6323
  }
6405
6324
 
6406
6325
  /*
6407
6326
    from clause
6408
 
    TODO: support USING/FORCE/IGNORE index
 
6327
    @todo support USING/FORCE/IGNORE index
6409
6328
  */
6410
 
  if (table_list.elements)
 
6329
  if (table_list.size())
6411
6330
  {
6412
6331
    str->append(STRING_WITH_LEN(" from "));
6413
6332
    /* go through join tree */
6414
 
    print_join(session, str, &top_join_list, query_type);
 
6333
    print_join(session, str, &top_join_list);
6415
6334
  }
6416
6335
  else if (where)
6417
6336
  {
6430
6349
  {
6431
6350
    str->append(STRING_WITH_LEN(" where "));
6432
6351
    if (cur_where)
6433
 
      cur_where->print(str, query_type);
 
6352
      cur_where->print(str);
6434
6353
    else
6435
6354
      str->append(cond_value != Item::COND_FALSE ? "1" : "0");
6436
6355
  }
6437
6356
 
6438
6357
  // group by & olap
6439
 
  if (group_list.elements)
 
6358
  if (group_list.size())
6440
6359
  {
6441
6360
    str->append(STRING_WITH_LEN(" group by "));
6442
 
    print_order(str, (Order *) group_list.first, query_type);
 
6361
    print_order(str, (Order *) group_list.first);
6443
6362
    switch (olap)
6444
6363
    {
6445
6364
      case CUBE_TYPE:
6462
6381
  {
6463
6382
    str->append(STRING_WITH_LEN(" having "));
6464
6383
    if (cur_having)
6465
 
      cur_having->print(str, query_type);
 
6384
      cur_having->print(str);
6466
6385
    else
6467
6386
      str->append(having_value != Item::COND_FALSE ? "1" : "0");
6468
6387
  }
6469
6388
 
6470
 
  if (order_list.elements)
 
6389
  if (order_list.size())
6471
6390
  {
6472
6391
    str->append(STRING_WITH_LEN(" order by "));
6473
 
    print_order(str, (Order *) order_list.first, query_type);
 
6392
    print_order(str, (Order *) order_list.first);
6474
6393
  }
6475
6394
 
6476
6395
  // limit
6477
 
  print_limit(session, str, query_type);
 
6396
  print_limit(session, str);
6478
6397
 
6479
6398
  // PROCEDURE unsupported here
6480
6399
}