~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_select.cc

mergeĀ lp:~linuxjedi/drizzle/trunk-remove-drizzleadmin

Show diffs side-by-side

added added

removed removed

Lines of Context:
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"
 
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>
67
71
 
68
72
using namespace std;
69
73
 
70
 
namespace drizzled
71
 
{
 
74
namespace drizzled {
72
75
 
73
76
static int sort_keyuse(optimizer::KeyUse *a, optimizer::KeyUse *b);
74
77
static COND *build_equal_items(Session *session, COND *cond,
84
87
                                     Item *cond,
85
88
                                     Item *field,
86
89
                                     Item *value);
87
 
static bool copy_blobs(Field **ptr);
 
90
static void copy_blobs(Field **ptr);
88
91
 
89
92
static bool eval_const_cond(COND *cond)
90
93
{
99
102
const char *subq_sj_cond_name=
100
103
  "0123456789ABCDEF0123456789abcdef0123456789ABCDEF0123456789abcdef-sj-cond";
101
104
 
102
 
static bool copy_blobs(Field **ptr)
 
105
static void copy_blobs(Field **ptr)
103
106
{
104
107
  for (; *ptr ; ptr++)
105
108
  {
106
109
    if ((*ptr)->flags & BLOB_FLAG)
107
 
      if (((Field_blob *) (*ptr))->copy())
108
 
        return 1;                               // Error
 
110
      ((Field_blob *) (*ptr))->copy();
109
111
  }
110
 
  return 0;
111
112
}
112
113
 
113
114
/**
117
118
                   uint64_t setup_tables_done_option)
118
119
{
119
120
  bool res;
120
 
  register Select_Lex *select_lex= &lex->select_lex;
 
121
  Select_Lex *select_lex= &lex->select_lex;
121
122
  DRIZZLE_SELECT_START(session->getQueryString()->c_str());
122
123
 
123
124
  if (select_lex->master_unit()->is_union() ||
142
143
                      select_lex->with_wild,
143
144
                      select_lex->item_list,
144
145
                      select_lex->where,
145
 
                      select_lex->order_list.elements +
146
 
                      select_lex->group_list.elements,
 
146
                      select_lex->order_list.size() +
 
147
                      select_lex->group_list.size(),
147
148
                      (Order*) select_lex->order_list.first,
148
149
                      (Order*) select_lex->group_list.first,
149
150
                      select_lex->having,
199
200
    true  an error occured
200
201
    false ok
201
202
*/
202
 
bool fix_inner_refs(Session *session, 
203
 
                    List<Item> &all_fields, 
204
 
                    Select_Lex *select, 
 
203
bool fix_inner_refs(Session *session,
 
204
                    List<Item> &all_fields,
 
205
                    Select_Lex *select,
205
206
                    Item **ref_pointer_array)
206
207
{
207
208
  Item_outer_ref *ref;
208
209
  bool res= false;
209
210
  bool direct_ref= false;
210
211
 
211
 
  List_iterator<Item_outer_ref> ref_it(select->inner_refs_list);
 
212
  List<Item_outer_ref>::iterator ref_it(select->inner_refs_list.begin());
212
213
  while ((ref= ref_it++))
213
214
  {
214
215
    Item *item= ref->outer_ref;
215
216
    Item **item_ref= ref->ref;
216
217
    Item_ref *new_ref;
217
218
    /*
218
 
      TODO: this field item already might be present in the select list.
 
219
      @todo this field item already might be present in the select list.
219
220
      In this case instead of adding new field item we could use an
220
221
      existing one. The change will lead to less operations for copying fields,
221
222
      smaller temporary tables and less data passed through filesort.
222
223
    */
223
224
    if (ref_pointer_array && !ref->found_in_select_list)
224
225
    {
225
 
      int el= all_fields.elements;
 
226
      int el= all_fields.size();
226
227
      ref_pointer_array[el]= item;
227
228
      /* Add the field item to the select list of the current select. */
228
229
      all_fields.push_front(item);
353
354
*/
354
355
bool select_query(Session *session,
355
356
                  Item ***rref_pointer_array,
356
 
                  TableList *tables, 
357
 
                  uint32_t wild_num, 
 
357
                  TableList *tables,
 
358
                  uint32_t wild_num,
358
359
                  List<Item> &fields,
359
 
                  COND *conds, 
360
 
                  uint32_t og_num,  
 
360
                  COND *conds,
 
361
                  uint32_t og_num,
361
362
                  Order *order,
362
363
                  Order *group,
363
 
                  Item *having, 
 
364
                  Item *having,
364
365
                  uint64_t select_options,
365
 
                  select_result *result, 
 
366
                  select_result *result,
366
367
                  Select_Lex_Unit *unit,
367
368
                  Select_Lex *select_lex)
368
369
{
421
422
    goto err; // 1
422
423
  }
423
424
 
424
 
  if (session->lex->describe & DESCRIBE_EXTENDED)
 
425
  if (session->lex().describe & DESCRIBE_EXTENDED)
425
426
  {
426
427
    join->conds_history= join->conds;
427
428
    join->having_history= (join->having?join->having:join->tmp_having);
432
433
 
433
434
  join->exec();
434
435
 
435
 
  if (session->lex->describe & DESCRIBE_EXTENDED)
 
436
  if (session->lex().describe & DESCRIBE_EXTENDED)
436
437
  {
437
438
    select_lex->where= join->conds_history;
438
439
    select_lex->having= join->having_history;
542
543
                         DYNAMIC_ARRAY *keyuse,
543
544
                         JoinTable *join_tab,
544
545
                         uint32_t tables,
545
 
                         COND *cond, 
 
546
                         COND *cond,
546
547
                         COND_EQUAL *,
547
548
                         table_map normal_tables,
548
549
                         Select_Lex *select_lex,
559
560
    except BETWEEN predicates that have 3 arguments and
560
561
    IN predicates.
561
562
    This any predicate if it's not BETWEEN/IN can be used
562
 
    directly to fill at most 2 array elements, either of KeyField 
 
563
    directly to fill at most 2 array elements, either of KeyField
563
564
    or SargableParam type. For a BETWEEN predicate 3 elements
564
565
    can be filled as this predicate is considered as
565
566
    saragable with respect to each of its argument.
571
572
    substitutions.
572
573
  */
573
574
  sz= sizeof(optimizer::KeyField) *
574
 
      (((session->lex->current_select->cond_count+1)*2 +
575
 
        session->lex->current_select->between_count)*m+1);
 
575
      (((session->lex().current_select->cond_count+1)*2 +
 
576
        session->lex().current_select->between_count)*m+1);
576
577
  if (! (key_fields= (optimizer::KeyField*) session->getMemRoot()->allocate(sz)))
577
578
    return true;
578
579
  and_level= 0;
614
615
 
615
616
  /* Process ON conditions for the nested joins */
616
617
  {
617
 
    List_iterator<TableList> li(*join_tab->join->join_list);
 
618
    List<TableList>::iterator li(join_tab->join->join_list->begin());
618
619
    TableList *table;
619
620
    while ((table= li++))
620
621
    {
637
638
      (e.g. if there is a key(a,b,c) but only b < 5 (or a=2 and c < 3) is
638
639
      used in the query, we drop the partial key parts from consideration).
639
640
  */
640
 
  if (keyuse->elements)
 
641
  if (keyuse->size())
641
642
  {
642
643
    optimizer::KeyUse key_end,*prev,*save_pos,*use;
643
644
 
644
 
    internal::my_qsort(keyuse->buffer,keyuse->elements,sizeof(optimizer::KeyUse),
 
645
    internal::my_qsort(keyuse->buffer,keyuse->size(),sizeof(optimizer::KeyUse),
645
646
                       (qsort_cmp) sort_keyuse);
646
647
 
647
648
    memset(&key_end, 0, sizeof(key_end)); /* Add for easy testing */
648
 
    insert_dynamic(keyuse,(unsigned char*) &key_end);
 
649
    keyuse->push_back(&key_end);
649
650
 
650
 
    use= save_pos= dynamic_element(keyuse, 0, optimizer::KeyUse*);
 
651
    use= save_pos= (optimizer::KeyUse*)keyuse->buffer;
651
652
    prev= &key_end;
652
653
    found_eq_constant= 0;
653
654
    {
654
655
      uint32_t i;
655
656
 
656
 
      for (i= 0; i < keyuse->elements-1; i++, use++)
 
657
      for (i= 0; i < keyuse->size()-1; i++, use++)
657
658
      {
658
659
        if (! use->getUsedTables() && use->getOptimizeFlags() != KEY_OPTIMIZE_REF_OR_NULL)
659
660
          use->getTable()->const_key_parts[use->getKey()]|= use->getKeypartMap();
660
661
        if (use->getKey() == prev->getKey() && use->getTable() == prev->getTable())
661
662
        {
662
 
          if (prev->getKeypart() + 1 < use->getKeypart() || 
 
663
          if (prev->getKeypart() + 1 < use->getKeypart() ||
663
664
              ((prev->getKeypart() == use->getKeypart()) && found_eq_constant))
664
665
            continue;                           /* remove */
665
666
        }
680
681
        save_pos++;
681
682
      }
682
683
      i= (uint32_t) (save_pos - (optimizer::KeyUse*) keyuse->buffer);
683
 
      set_dynamic(keyuse, (unsigned char*) &key_end, i);
684
 
      keyuse->elements= i;
 
684
      reinterpret_cast<optimizer::KeyUse*>(keyuse->buffer)[i] = key_end;
 
685
      keyuse->set_size(i);
685
686
    }
686
687
  }
687
688
  return false;
692
693
*/
693
694
void optimize_keyuse(Join *join, DYNAMIC_ARRAY *keyuse_array)
694
695
{
695
 
  optimizer::KeyUse *end,*keyuse= dynamic_element(keyuse_array, 
696
 
                                                  0, 
697
 
                                                  optimizer::KeyUse*);
698
 
 
699
 
  for (end= keyuse+ keyuse_array->elements ; keyuse < end ; keyuse++)
 
696
  optimizer::KeyUse* keyuse= (optimizer::KeyUse*)keyuse_array->buffer;
 
697
  for (optimizer::KeyUse* end= keyuse+ keyuse_array->size() ; keyuse < end ; keyuse++)
700
698
  {
701
699
    table_map map;
702
700
    /*
748
746
void add_group_and_distinct_keys(Join *join, JoinTable *join_tab)
749
747
{
750
748
  List<Item_field> indexed_fields;
751
 
  List_iterator<Item_field> indexed_fields_it(indexed_fields);
 
749
  List<Item_field>::iterator indexed_fields_it(indexed_fields.begin());
752
750
  Order      *cur_group;
753
751
  Item_field *cur_item;
754
752
  key_map possible_keys(0);
762
760
  else if (join->select_distinct)
763
761
  { /* Collect all query fields referenced in the SELECT clause. */
764
762
    List<Item> &select_items= join->fields_list;
765
 
    List_iterator<Item> select_items_it(select_items);
 
763
    List<Item>::iterator select_items_it(select_items.begin());
766
764
    Item *item;
767
765
    while ((item= select_items_it++))
768
766
      item->walk(&Item::collect_item_field_processor, 0,
771
769
  else
772
770
    return;
773
771
 
774
 
  if (indexed_fields.elements == 0)
 
772
  if (indexed_fields.size() == 0)
775
773
    return;
776
774
 
777
775
  /* Intersect the keys of all group fields. */
957
955
    *e1= e2;
958
956
}
959
957
 
960
 
bool create_ref_for_key(Join *join, 
961
 
                        JoinTable *j, 
 
958
bool create_ref_for_key(Join *join,
 
959
                        JoinTable *j,
962
960
                        optimizer::KeyUse *org_keyuse,
963
961
                        table_map used_tables)
964
962
{
1209
1207
  return tmp;
1210
1208
}
1211
1209
 
1212
 
#define ICP_COND_USES_INDEX_ONLY 10
1213
 
 
1214
 
 
1215
1210
/**
1216
1211
  cleanup JoinTable.
1217
1212
*/
1218
1213
void JoinTable::cleanup()
1219
1214
{
1220
 
  delete select;
1221
 
  select= 0;
1222
 
  delete quick;
1223
 
  quick= 0;
 
1215
  safe_delete(select);
 
1216
  safe_delete(quick);
 
1217
 
1224
1218
  if (cache.buff)
1225
1219
  {
1226
1220
    size_t size= cache.end - cache.buff;
1349
1343
  bool in_upper_level= false;
1350
1344
  while (cond_equal)
1351
1345
  {
1352
 
    List_iterator_fast<Item_equal> li(cond_equal->current_level);
 
1346
    List<Item_equal>::iterator li(cond_equal->current_level.begin());
1353
1347
    while ((item= li++))
1354
1348
    {
1355
1349
      if (item->contains(field))
1514
1508
        /* Merge two multiple equalities forming a new one */
1515
1509
        left_item_equal->merge(right_item_equal);
1516
1510
        /* Remove the merged multiple equality from the list */
1517
 
        List_iterator<Item_equal> li(cond_equal->current_level);
 
1511
        List<Item_equal>::iterator li(cond_equal->current_level.begin());
1518
1512
        while ((li++) != right_item_equal) {};
1519
1513
        li.remove();
1520
1514
      }
1567
1561
 
1568
1562
      if (field_item->result_type() == STRING_RESULT)
1569
1563
      {
1570
 
        const CHARSET_INFO * const cs= ((Field_str*) field_item->field)->charset();
 
1564
        const charset_info_st * const cs= ((Field_str*) field_item->field)->charset();
1571
1565
        if (!item)
1572
1566
        {
1573
1567
          Item_func_eq *eq_item;
1635
1629
    false   otherwise
1636
1630
*/
1637
1631
static bool check_row_equality(Session *session,
1638
 
                               Item *left_row, 
 
1632
                               Item *left_row,
1639
1633
                               Item_row *right_row,
1640
1634
                               COND_EQUAL *cond_equal,
1641
1635
                               List<Item>* eq_list)
1654
1648
                                       (Item_row *) right_item,
1655
1649
                                       cond_equal, eq_list);
1656
1650
      if (!is_converted)
1657
 
        session->lex->current_select->cond_count++;
 
1651
        session->lex().current_select->cond_count++;
1658
1652
    }
1659
1653
    else
1660
1654
    {
1661
1655
      is_converted= check_simple_equality(left_item, right_item, 0, cond_equal);
1662
 
      session->lex->current_select->cond_count++;
 
1656
      session->lex().current_select->cond_count++;
1663
1657
    }
1664
1658
 
1665
1659
    if (!is_converted)
1715
1709
    if (left_item->type() == Item::ROW_ITEM &&
1716
1710
        right_item->type() == Item::ROW_ITEM)
1717
1711
    {
1718
 
      session->lex->current_select->cond_count--;
 
1712
      session->lex().current_select->cond_count--;
1719
1713
      return check_row_equality(session,
1720
1714
                                (Item_row *) left_item,
1721
1715
                                (Item_row *) right_item,
1746
1740
    just an argument of a comparison predicate.
1747
1741
    The function also determines the maximum number of members in
1748
1742
    equality lists of each Item_cond_and object assigning it to
1749
 
    session->lex->current_select->max_equal_elems.
 
1743
    session->lex().current_select->max_equal_elems.
1750
1744
 
1751
1745
  @note
1752
1746
    Multiple equality predicate =(f1,..fn) is equivalent to the conjuction of
1803
1797
      Item_func::COND_AND_FUNC;
1804
1798
    List<Item> *args= ((Item_cond*) cond)->argument_list();
1805
1799
 
1806
 
    List_iterator<Item> li(*args);
 
1800
    List<Item>::iterator li(args->begin());
1807
1801
    Item *item;
1808
1802
 
1809
1803
    if (and_level)
1825
1819
          li.remove();
1826
1820
      }
1827
1821
 
1828
 
      List_iterator_fast<Item_equal> it(cond_equal.current_level);
 
1822
      List<Item_equal>::iterator it(cond_equal.current_level.begin());
1829
1823
      while ((item_equal= it++))
1830
1824
      {
1831
1825
        item_equal->fix_length_and_dec();
1832
1826
        item_equal->update_used_tables();
1833
 
        set_if_bigger(session->lex->current_select->max_equal_elems,
 
1827
        set_if_bigger(session->lex().current_select->max_equal_elems,
1834
1828
                      item_equal->members());
1835
1829
      }
1836
1830
 
1841
1835
       Make replacement of equality predicates for lower levels
1842
1836
       of the condition expression.
1843
1837
    */
1844
 
    li.rewind();
 
1838
    li= args->begin();
1845
1839
    while ((item= li++))
1846
1840
    {
1847
1841
      Item *new_item;
1877
1871
     */
1878
1872
    if (check_equality(session, cond, &cond_equal, &eq_list))
1879
1873
    {
1880
 
      int n= cond_equal.current_level.elements + eq_list.elements;
 
1874
      int n= cond_equal.current_level.size() + eq_list.size();
1881
1875
      if (n == 0)
1882
1876
        return new Item_int((int64_t) 1,1);
1883
1877
      else if (n == 1)
1889
1883
        }
1890
1884
        else
1891
1885
          item_equal= (Item_equal *) eq_list.pop();
1892
 
        set_if_bigger(session->lex->current_select->max_equal_elems,
 
1886
        set_if_bigger(session->lex().current_select->max_equal_elems,
1893
1887
                      item_equal->members());
1894
1888
        return item_equal;
1895
1889
      }
1902
1896
        Item_cond_and *and_cond= new Item_cond_and(eq_list);
1903
1897
        and_cond->quick_fix_field();
1904
1898
        List<Item> *args= and_cond->argument_list();
1905
 
        List_iterator_fast<Item_equal> it(cond_equal.current_level);
 
1899
        List<Item_equal>::iterator it(cond_equal.current_level.begin());
1906
1900
        while ((item_equal= it++))
1907
1901
        {
1908
1902
          item_equal->fix_length_and_dec();
1909
1903
          item_equal->update_used_tables();
1910
 
          set_if_bigger(session->lex->current_select->max_equal_elems,
 
1904
          set_if_bigger(session->lex().current_select->max_equal_elems,
1911
1905
                        item_equal->members());
1912
1906
        }
1913
1907
        and_cond->cond_equal= cond_equal;
2028
2022
  if (join_list)
2029
2023
  {
2030
2024
    TableList *table;
2031
 
    List_iterator<TableList> li(*join_list);
 
2025
    List<TableList>::iterator li(join_list->begin());
2032
2026
 
2033
2027
    while ((table= li++))
2034
2028
    {
2138
2132
  if (((Item *) item_equal)->const_item() && !item_equal->val_int())
2139
2133
    return new Item_int((int64_t) 0,1);
2140
2134
  Item *item_const= item_equal->get_const();
2141
 
  Item_equal_iterator it(*item_equal);
 
2135
  Item_equal_iterator it(item_equal->begin());
2142
2136
  Item *head;
2143
2137
  if (item_const)
2144
2138
    head= item_const;
2158
2152
        item= 0;
2159
2153
      else
2160
2154
      {
2161
 
        Item_equal_iterator li(*item_equal);
 
2155
        Item_equal_iterator li(item_equal->begin());
2162
2156
        while ((item= li++) != item_field)
2163
2157
        {
2164
2158
          if (item->find_item_equal(upper_levels) == upper)
2178
2172
   }
2179
2173
  }
2180
2174
 
2181
 
  if (!cond && !eq_list.head())
 
2175
  if (!cond && !&eq_list.front())
2182
2176
  {
2183
2177
    if (!eq_item)
2184
2178
      return new Item_int((int64_t) 1,1);
2243
2237
      cond_equal= &((Item_cond_and *) cond)->cond_equal;
2244
2238
      cond_list->disjoin((List<Item> *) &cond_equal->current_level);
2245
2239
 
2246
 
      List_iterator_fast<Item_equal> it(cond_equal->current_level);
 
2240
      List<Item_equal>::iterator it(cond_equal->current_level.begin());
2247
2241
      while ((item_equal= it++))
2248
2242
      {
2249
2243
        item_equal->sort(&compare_fields_by_table_order, table_join_idx);
2250
2244
      }
2251
2245
    }
2252
2246
 
2253
 
    List_iterator<Item> li(*cond_list);
 
2247
    List<Item>::iterator li(cond_list->begin());
2254
2248
    Item *item;
2255
2249
    while ((item= li++))
2256
2250
    {
2266
2260
 
2267
2261
    if (and_level)
2268
2262
    {
2269
 
      List_iterator_fast<Item_equal> it(cond_equal->current_level);
 
2263
      List<Item_equal>::iterator it(cond_equal->current_level.begin());
2270
2264
      while ((item_equal= it++))
2271
2265
      {
2272
2266
        cond= eliminate_item_equal(cond, cond_equal->upper_levels, item_equal);
2278
2272
      }
2279
2273
    }
2280
2274
    if (cond->type() == Item::COND_ITEM &&
2281
 
        !((Item_cond*)cond)->argument_list()->elements)
 
2275
        !((Item_cond*)cond)->argument_list()->size())
2282
2276
      cond= new Item_int((int32_t)cond->val_bool());
2283
2277
 
2284
2278
  }
2287
2281
  {
2288
2282
    item_equal= (Item_equal *) cond;
2289
2283
    item_equal->sort(&compare_fields_by_table_order, table_join_idx);
2290
 
    if (cond_equal && cond_equal->current_level.head() == item_equal)
 
2284
    if (cond_equal && &cond_equal->current_level.front() == item_equal)
2291
2285
      cond_equal= 0;
2292
2286
    return eliminate_item_equal(0, cond_equal, item_equal);
2293
2287
  }
2316
2310
  if (cond->type() == Item::COND_ITEM)
2317
2311
  {
2318
2312
    List<Item> *cond_list= ((Item_cond*) cond)->argument_list();
2319
 
    List_iterator_fast<Item> li(*cond_list);
 
2313
    List<Item>::iterator li(cond_list->begin());
2320
2314
    Item *item;
2321
2315
    while ((item= li++))
2322
2316
      update_const_equal_items(item, tab);
2330
2324
    if (!contained_const && item_equal->get_const())
2331
2325
    {
2332
2326
      /* Update keys for range analysis */
2333
 
      Item_equal_iterator it(*item_equal);
 
2327
      Item_equal_iterator it(item_equal->begin());
2334
2328
      Item_field *item_field;
2335
2329
      while ((item_field= it++))
2336
2330
      {
2374
2368
  if (cond->type() == Item::COND_ITEM)
2375
2369
  {
2376
2370
    bool and_level= ((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC;
2377
 
    List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
 
2371
    List<Item>::iterator li(((Item_cond*) cond)->argument_list()->begin());
2378
2372
    Item *item;
2379
2373
    while ((item=li++))
2380
2374
      change_cond_ref_to_const(session, save_list, and_level ? cond : item, item, field, value);
2400
2394
    if (tmp)
2401
2395
    {
2402
2396
      tmp->collation.set(right_item->collation);
2403
 
      session->change_item_tree(args + 1, tmp);
 
2397
      args[1]= tmp;
2404
2398
      func->update_used_tables();
2405
2399
      if ((functype == Item_func::EQ_FUNC || functype == Item_func::EQUAL_FUNC) &&
2406
 
                and_father != cond && 
 
2400
                and_father != cond &&
2407
2401
          ! left_item->const_item())
2408
2402
      {
2409
2403
        cond->marker=1;
2422
2416
    if (tmp)
2423
2417
    {
2424
2418
      tmp->collation.set(left_item->collation);
2425
 
      session->change_item_tree(args, tmp);
 
2419
      *args= tmp;
2426
2420
      value= tmp;
2427
2421
      func->update_used_tables();
2428
2422
      if ((functype == Item_func::EQ_FUNC || functype == Item_func::EQUAL_FUNC) &&
2429
 
          and_father != cond && 
 
2423
          and_father != cond &&
2430
2424
          ! right_item->const_item())
2431
2425
      {
2432
2426
        args[0]= args[1];                       // For easy check
2433
 
        session->change_item_tree(args + 1, value);
 
2427
        args[1]= value;
2434
2428
        cond->marker=1;
2435
2429
        save_list.push_back( COND_CMP(and_father, func) );
2436
2430
      }
2454
2448
  if (conds->type() == Item::COND_ITEM)
2455
2449
  {
2456
2450
    Item_cond *cnd= (Item_cond*) conds;
2457
 
    List_iterator<Item> li(*(cnd->argument_list()));
 
2451
    List<Item>::iterator li(cnd->argument_list()->begin());
2458
2452
    Item *item;
2459
2453
    while ((item= li++))
2460
2454
    {
2461
2455
      if (item->name == in_additional_cond)
2462
2456
      {
2463
2457
        li.remove();
2464
 
        if (cnd->argument_list()->elements == 1)
2465
 
          return cnd->argument_list()->head();
 
2458
        if (cnd->argument_list()->size() == 1)
 
2459
          return &cnd->argument_list()->front();
2466
2460
        return conds;
2467
2461
      }
2468
2462
    }
2470
2464
  return conds;
2471
2465
}
2472
2466
 
2473
 
static void propagate_cond_constants(Session *session, 
2474
 
                                     list<COND_CMP>& save_list, 
2475
 
                                     COND *and_father, 
 
2467
static void propagate_cond_constants(Session *session,
 
2468
                                     list<COND_CMP>& save_list,
 
2469
                                     COND *and_father,
2476
2470
                                     COND *cond)
2477
2471
{
2478
2472
  if (cond->type() == Item::COND_ITEM)
2479
2473
  {
2480
2474
    bool and_level= ((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC;
2481
 
    List_iterator_fast<Item> li(*((Item_cond*) cond)->argument_list());
 
2475
    List<Item>::iterator li(((Item_cond*) cond)->argument_list()->begin());
2482
2476
    Item *item;
2483
2477
    list<COND_CMP> save;
2484
2478
    while ((item=li++))
2652
2646
      join->cur_embedding_map |= next_emb->getNestedJoin()->nj_map;
2653
2647
    }
2654
2648
 
2655
 
    if (next_emb->getNestedJoin()->join_list.elements !=
 
2649
    if (next_emb->getNestedJoin()->join_list.size() !=
2656
2650
        next_emb->getNestedJoin()->counter_)
2657
2651
      break;
2658
2652
 
2712
2706
  {
2713
2707
    bool and_level= (((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC);
2714
2708
 
2715
 
    List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
 
2709
    List<Item>::iterator li(((Item_cond*) cond)->argument_list()->begin());
2716
2710
    Item::cond_result tmp_cond_value;
2717
2711
    bool should_fix_fields= false;
2718
2712
 
2731
2725
      if (*cond_value == Item::COND_UNDEF)
2732
2726
              *cond_value= tmp_cond_value;
2733
2727
 
2734
 
      switch (tmp_cond_value) 
 
2728
      switch (tmp_cond_value)
2735
2729
      {
2736
2730
        case Item::COND_OK:                     /* Not true or false */
2737
2731
          if (and_level || (*cond_value == Item::COND_FALSE))
2759
2753
    if (should_fix_fields)
2760
2754
      cond->update_used_tables();
2761
2755
 
2762
 
    if (! ((Item_cond*) cond)->argument_list()->elements || *cond_value != Item::COND_OK)
 
2756
    if (! ((Item_cond*) cond)->argument_list()->size() || *cond_value != Item::COND_OK)
2763
2757
      return (COND*) NULL;
2764
2758
 
2765
 
    if (((Item_cond*) cond)->argument_list()->elements == 1)
2766
 
    {                                           
 
2759
    if (((Item_cond*) cond)->argument_list()->size() == 1)
 
2760
    {
2767
2761
      /* Argument list contains only one element, so reduce it so a single item, then remove list */
2768
 
      item= ((Item_cond*) cond)->argument_list()->head();
2769
 
      ((Item_cond*) cond)->argument_list()->empty();
 
2762
      item= &((Item_cond*) cond)->argument_list()->front();
 
2763
      ((Item_cond*) cond)->argument_list()->clear();
2770
2764
      return item;
2771
2765
    }
2772
2766
  }
2787
2781
    if (args[0]->type() == Item::FIELD_ITEM)
2788
2782
    {
2789
2783
      Field *field= ((Item_field*) args[0])->field;
2790
 
      if (field->flags & AUTO_INCREMENT_FLAG 
2791
 
          && ! field->getTable()->maybe_null 
 
2784
      if (field->flags & AUTO_INCREMENT_FLAG
 
2785
          && ! field->getTable()->maybe_null
2792
2786
          && session->options & OPTION_AUTO_IS_NULL
2793
2787
          && (
2794
 
            session->first_successful_insert_id_in_prev_stmt > 0 
 
2788
            session->first_successful_insert_id_in_prev_stmt > 0
2795
2789
            && session->substitute_null_with_insert_id
2796
2790
            )
2797
2791
          )
2818
2812
#ifdef NOTDEFINED
2819
2813
      /* fix to replace 'NULL' dates with '0' (shreeve@uci.edu) */
2820
2814
      else if (
2821
 
          ((field->type() == DRIZZLE_TYPE_DATE) || (field->type() == DRIZZLE_TYPE_DATETIME)) 
2822
 
          && (field->flags & NOT_NULL_FLAG) 
 
2815
          ((field->type() == DRIZZLE_TYPE_DATE) || (field->type() == DRIZZLE_TYPE_DATETIME))
 
2816
          && (field->flags & NOT_NULL_FLAG)
2823
2817
          && ! field->table->maybe_null)
2824
2818
      {
2825
2819
        COND *new_cond;
2844
2838
  }
2845
2839
  else if (cond->const_item() && !cond->is_expensive())
2846
2840
  /*
2847
 
    TODO:
 
2841
    @todo
2848
2842
    Excluding all expensive functions is too restritive we should exclude only
2849
2843
    materialized IN subquery predicates because they can't yet be evaluated
2850
2844
    here (they need additional initialization that is done later on).
2858
2852
    return (COND *) NULL;
2859
2853
  }
2860
2854
  else if ((*cond_value= cond->eq_cmp_result()) != Item::COND_OK)
2861
 
  {                                             
 
2855
  {
2862
2856
    /* boolan compare function */
2863
2857
    Item *left_item=    ((Item_func*) cond)->arguments()[0];
2864
2858
    Item *right_item= ((Item_func*) cond)->arguments()[1];
2916
2910
  {
2917
2911
    bool and_level= (((Item_cond*) cond)->functype()
2918
2912
                     == Item_func::COND_AND_FUNC);
2919
 
    List_iterator_fast<Item> li(*((Item_cond*) cond)->argument_list());
 
2913
    List<Item>::iterator li(((Item_cond*) cond)->argument_list()->begin());
2920
2914
    Item *item;
2921
2915
    while ((item=li++))
2922
2916
    {
3446
3440
    }
3447
3441
  }
3448
3442
 
3449
 
  /* TODO: Why don't we do "Late NULLs Filtering" here? */
 
3443
  /* @todo Why don't we do "Late NULLs Filtering" here? */
3450
3444
  if (cmp_buffer_with_ref(tab) ||
3451
3445
      (table->status & (STATUS_GARBAGE | STATUS_NO_PARENT | STATUS_NULL_ROW)))
3452
3446
  {
3637
3631
 
3638
3632
int test_if_quick_select(JoinTable *tab)
3639
3633
{
3640
 
  delete tab->select->quick;
3641
 
  tab->select->quick= 0;
 
3634
  safe_delete(tab->select->quick);
 
3635
 
3642
3636
  return tab->select->test_quick_select(tab->join->session, tab->keys,
3643
3637
                                        (table_map) 0, HA_POS_ERROR, 0, false);
3644
3638
}
3816
3810
        {
3817
3811
          if (!join->first_record)
3818
3812
          {
3819
 
                  List_iterator_fast<Item> it(*join->fields);
 
3813
                  List<Item>::iterator it(join->fields->begin());
3820
3814
                  Item *item;
3821
3815
            /* No matching rows for group function */
3822
3816
            join->clear();
4055
4049
      Item_cond_and *new_cond=new Item_cond_and;
4056
4050
      if (!new_cond)
4057
4051
        return (COND*) 0;
4058
 
      List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
 
4052
      List<Item>::iterator li(((Item_cond*) cond)->argument_list()->begin());
4059
4053
      Item *item;
4060
4054
      while ((item=li++))
4061
4055
      {
4064
4058
        if (fix)
4065
4059
          new_cond->argument_list()->push_back(fix);
4066
4060
      }
4067
 
      switch (new_cond->argument_list()->elements) 
 
4061
      switch (new_cond->argument_list()->size())
4068
4062
      {
4069
4063
        case 0:
4070
4064
          return (COND*) 0;                     // Always true
4071
4065
        case 1:
4072
 
          return new_cond->argument_list()->head();
 
4066
          return &new_cond->argument_list()->front();
4073
4067
        default:
4074
4068
          /*
4075
4069
            Item_cond_and do not need fix_fields for execution, its parameters
4085
4079
      Item_cond_or *new_cond=new Item_cond_or;
4086
4080
      if (!new_cond)
4087
4081
        return (COND*) 0;
4088
 
      List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
 
4082
      List<Item>::iterator li(((Item_cond*) cond)->argument_list()->begin());
4089
4083
      Item *item;
4090
4084
      while ((item=li++))
4091
4085
      {
4167
4161
      if (field->eq(key_part->field) &&
4168
4162
          !(key_part->key_part_flag & HA_PART_KEY_SEG) &&
4169
4163
          //If field can be NULL, we should not remove this predicate, as
4170
 
          //it may lead to non-rejection of NULL values. 
 
4164
          //it may lead to non-rejection of NULL values.
4171
4165
          !(field->real_maybe_null()))
4172
4166
      {
4173
4167
        return table->reginfo.join_tab->ref.items[part];
4437
4431
{
4438
4432
  List<Item> *fields= (List<Item> *) data;
4439
4433
  bool part_found= 0;
4440
 
  List_iterator<Item> li(*fields);
 
4434
  List<Item>::iterator li(fields->begin());
4441
4435
  Item *item;
4442
4436
 
4443
4437
  while ((item= li++))
4522
4516
    save_quick= select->quick;
4523
4517
    /*
4524
4518
      assume results are not ordered when index merge is used
4525
 
      TODO: sergeyp: Results of all index merge selects actually are ordered
 
4519
      @todo sergeyp: Results of all index merge selects actually are ordered
4526
4520
      by clustered PK values.
4527
4521
    */
4528
4522
 
4797
4791
          tab->type= AM_NEXT;           // Read with index_first(), index_next()
4798
4792
          if (select && select->quick)
4799
4793
          {
4800
 
            delete select->quick;
4801
 
            select->quick= 0;
 
4794
            safe_delete(select->quick);
4802
4795
          }
4803
4796
          if (table->covering_keys.test(best_key))
4804
4797
          {
4862
4855
 
4863
4856
        /* ORDER BY range_key DESC */
4864
4857
        tmp= new optimizer::QuickSelectDescending((optimizer::QuickRangeSelect*)(select->quick),
4865
 
                                                  used_key_parts, 
 
4858
                                                  used_key_parts,
4866
4859
                                                  &error);
4867
4860
        if (! tmp || error)
4868
4861
        {
4871
4864
          tab->limit= 0;
4872
4865
          return 0; // Reverse sort not supported
4873
4866
        }
4874
 
        select->quick=tmp;
 
4867
        select->quick= tmp;
4875
4868
      }
4876
4869
    }
4877
4870
    else if (tab->type != AM_NEXT &&
4954
4947
    return(-1);
4955
4948
  }
4956
4949
 
4957
 
  table->sort.io_cache= new internal::IO_CACHE;
 
4950
  table->sort.io_cache= new internal::io_cache_st;
4958
4951
  table->status=0;                              // May be wrong if quick_select
4959
4952
 
4960
4953
  // If table has a range, move it to select
4982
4975
        For impossible ranges (like when doing a lookup on NULL on a NOT NULL
4983
4976
        field, quick will contain an empty record set.
4984
4977
      */
4985
 
      if (! (select->quick= (optimizer::get_quick_select_for_ref(session, 
4986
 
                                                                 table, 
 
4978
      if (! (select->quick= (optimizer::get_quick_select_for_ref(session,
 
4979
                                                                 table,
4987
4980
                                                                 &tab->ref,
4988
4981
                                                                 tab->found_records))))
4989
4982
      {
5058
5051
      error=cursor->rnd_next(record);
5059
5052
      continue;
5060
5053
    }
5061
 
    if (copy_blobs(first_field))
5062
 
    {
5063
 
      my_message(ER_OUTOFMEMORY, ER(ER_OUTOFMEMORY), MYF(0));
5064
 
      error=0;
5065
 
      goto err;
5066
 
    }
 
5054
    copy_blobs(first_field);
5067
5055
    memcpy(new_record,org_record,reclength);
5068
5056
 
5069
5057
    /* Read through rest of cursor and mark duplicated rows deleted */
5110
5098
  @note
5111
5099
    Note that this will not work on tables with blobs!
5112
5100
*/
5113
 
int remove_dup_with_hash_index(Session *session, 
 
5101
int remove_dup_with_hash_index(Session *session,
5114
5102
                               Table *table,
5115
5103
                               uint32_t field_count,
5116
5104
                               Field **first_field,
5119
5107
{
5120
5108
  unsigned char *key_pos, *record=table->getInsertRecord();
5121
5109
  int error;
5122
 
  Cursor *cursor= table->cursor;
 
5110
  Cursor &cursor= *table->cursor;
5123
5111
  uint32_t extra_length= ALIGN_SIZE(key_length)-key_length;
5124
5112
  uint32_t *field_length;
5125
5113
  HASH hash;
5126
 
  std::vector<unsigned char> key_buffer;
5127
 
  std::vector<uint32_t> field_lengths;
5128
 
 
5129
 
  key_buffer.resize((key_length + extra_length) * (long) cursor->stats.records);
5130
 
  field_lengths.resize(field_count);
 
5114
  std::vector<unsigned char> key_buffer((key_length + extra_length) * (long) cursor.stats.records);
 
5115
  std::vector<uint32_t> field_lengths(field_count);
5131
5116
 
5132
5117
  {
5133
5118
    Field **ptr;
5144
5129
    extra_length= ALIGN_SIZE(key_length)-key_length;
5145
5130
  }
5146
5131
 
5147
 
  if (hash_init(&hash, &my_charset_bin, (uint32_t) cursor->stats.records, 0,
5148
 
                key_length, (hash_get_key) 0, 0, 0))
5149
 
  {
5150
 
    return(1);
5151
 
  }
 
5132
  if (hash_init(&hash, &my_charset_bin, (uint32_t) cursor.stats.records, 0, key_length, (hash_get_key) 0, 0, 0))
 
5133
    return 1;
5152
5134
 
5153
 
  if ((error= cursor->startTableScan(1)))
 
5135
  if ((error= cursor.startTableScan(1)))
5154
5136
    goto err;
5155
5137
 
5156
5138
  key_pos= &key_buffer[0];
5157
5139
  for (;;)
5158
5140
  {
5159
 
    unsigned char *org_key_pos;
5160
5141
    if (session->getKilled())
5161
5142
    {
5162
5143
      session->send_kill_message();
5163
5144
      error=0;
5164
5145
      goto err;
5165
5146
    }
5166
 
    if ((error=cursor->rnd_next(record)))
 
5147
    if ((error=cursor.rnd_next(record)))
5167
5148
    {
5168
5149
      if (error == HA_ERR_RECORD_DELETED)
5169
5150
        continue;
5173
5154
    }
5174
5155
    if (having && !having->val_int())
5175
5156
    {
5176
 
      if ((error=cursor->deleteRecord(record)))
 
5157
      if ((error=cursor.deleteRecord(record)))
5177
5158
        goto err;
5178
5159
      continue;
5179
5160
    }
5180
5161
 
5181
5162
    /* copy fields to key buffer */
5182
 
    org_key_pos= key_pos;
 
5163
    unsigned char* org_key_pos= key_pos;
5183
5164
    field_length= &field_lengths[0];
5184
5165
    for (Field **ptr= first_field ; *ptr ; ptr++)
5185
5166
    {
5190
5171
    if (hash_search(&hash, org_key_pos, key_length))
5191
5172
    {
5192
5173
      /* Duplicated found ; Remove the row */
5193
 
      if ((error=cursor->deleteRecord(record)))
 
5174
      if ((error=cursor.deleteRecord(record)))
5194
5175
        goto err;
5195
5176
    }
5196
5177
    else
5198
5179
    key_pos+=extra_length;
5199
5180
  }
5200
5181
  hash_free(&hash);
5201
 
  cursor->extra(HA_EXTRA_NO_CACHE);
5202
 
  (void) cursor->endTableScan();
5203
 
  return(0);
 
5182
  cursor.extra(HA_EXTRA_NO_CACHE);
 
5183
  (void) cursor.endTableScan();
 
5184
  return 0;
5204
5185
 
5205
5186
err:
5206
5187
  hash_free(&hash);
5207
 
  cursor->extra(HA_EXTRA_NO_CACHE);
5208
 
  (void) cursor->endTableScan();
 
5188
  cursor.extra(HA_EXTRA_NO_CACHE);
 
5189
  (void) cursor.endTableScan();
5209
5190
  if (error)
5210
5191
    table->print_error(error,MYF(0));
5211
 
  return(1);
 
5192
  return 1;
5212
5193
}
5213
5194
 
5214
5195
SortField *make_unireg_sortorder(Order *order, uint32_t *length, SortField *sortorder)
5339
5320
  @retval
5340
5321
    true  if error occurred
5341
5322
*/
5342
 
static bool find_order_in_list(Session *session, 
5343
 
                               Item **ref_pointer_array, 
 
5323
static bool find_order_in_list(Session *session,
 
5324
                               Item **ref_pointer_array,
5344
5325
                               TableList *tables,
5345
5326
                               Order *order,
5346
5327
                               List<Item> &fields,
5361
5342
  if (order_item->type() == Item::INT_ITEM && order_item->basic_const_item())
5362
5343
  {                                             /* Order by position */
5363
5344
    uint32_t count= (uint32_t) order_item->val_int();
5364
 
    if (!count || count > fields.elements)
 
5345
    if (!count || count > fields.size())
5365
5346
    {
5366
5347
      my_error(ER_BAD_FIELD_ERROR, MYF(0),
5367
5348
               order_item->full_name(), session->where());
5463
5444
       session->is_fatal_error))
5464
5445
    return true; /* Wrong field. */
5465
5446
 
5466
 
  uint32_t el= all_fields.elements;
 
5447
  uint32_t el= all_fields.size();
5467
5448
  all_fields.push_front(order_item); /* Add new field to field list. */
5468
5449
  ref_pointer_array[el]= order_item;
5469
5450
  order->item= ref_pointer_array + el;
5532
5513
  if (!order)
5533
5514
    return 0;                           /* Everything is ok */
5534
5515
 
5535
 
  uint32_t org_fields=all_fields.elements;
 
5516
  uint32_t org_fields=all_fields.size();
5536
5517
 
5537
5518
  session->setWhere("group statement");
5538
5519
  for (ord= order; ord; ord= ord->next)
5567
5548
    Item *item;
5568
5549
    Item_field *field;
5569
5550
    int cur_pos_in_select_list= 0;
5570
 
    List_iterator<Item> li(fields);
5571
 
    List_iterator<Item_field> naf_it(session->lex->current_select->non_agg_fields);
 
5551
    List<Item>::iterator li(fields.begin());
 
5552
    List<Item_field>::iterator naf_it(session->lex().current_select->non_agg_fields.begin());
5572
5553
 
5573
5554
    field= naf_it++;
5574
5555
    while (field && (item=li++))
5594
5575
            if ((*ord->item)->eq((Item*)field, 0))
5595
5576
              goto next_field;
5596
5577
          /*
5597
 
            TODO: change ER_WRONG_FIELD_WITH_GROUP to more detailed
5598
 
            ER_NON_GROUPING_FIELD_USED
 
5578
            @todo change ER_WRONG_FIELD_WITH_GROUP to more detailed ER_NON_GROUPING_FIELD_USED
5599
5579
          */
5600
5580
          my_error(ER_WRONG_FIELD_WITH_GROUP, MYF(0), field->full_name());
5601
5581
          return 1;
5606
5586
      cur_pos_in_select_list++;
5607
5587
    }
5608
5588
  }
5609
 
  if (org_fields != all_fields.elements)
 
5589
  if (org_fields != all_fields.size())
5610
5590
    *hidden_group_fields=1;                     // group fields is not used
5611
5591
  return 0;
5612
5592
}
5624
5604
                                List<Item> &,
5625
5605
                                bool *all_order_by_fields_used)
5626
5606
{
5627
 
  List_iterator<Item> li(fields);
 
5607
  List<Item>::iterator li(fields.begin());
5628
5608
  Item *item;
5629
5609
  Order *order,*group,**prev;
5630
5610
 
5648
5628
      *all_order_by_fields_used= 0;
5649
5629
  }
5650
5630
 
5651
 
  li.rewind();
 
5631
  li= fields.begin();
5652
5632
  while ((item=li++))
5653
5633
  {
5654
5634
    if (!item->const_item() && !item->with_sum_func && !item->marker)
5688
5668
*/
5689
5669
void count_field_types(Select_Lex *select_lex, Tmp_Table_Param *param, List<Item> &fields, bool reset_with_sum_func)
5690
5670
{
5691
 
  List_iterator<Item> li(fields);
 
5671
  List<Item>::iterator li(fields.begin());
5692
5672
  Item *field;
5693
5673
 
5694
5674
  param->field_count=param->sum_func_count=param->func_count=
5745
5725
*/
5746
5726
int test_if_item_cache_changed(List<Cached_item> &list)
5747
5727
{
5748
 
  List_iterator<Cached_item> li(list);
 
5728
  List<Cached_item>::iterator li(list.begin());
5749
5729
  int idx= -1,i;
5750
5730
  Cached_item *buff;
5751
5731
 
5752
 
  for (i=(int) list.elements-1 ; (buff=li++) ; i--)
 
5732
  for (i=(int) list.size()-1 ; (buff=li++) ; i--)
5753
5733
  {
5754
5734
    if (buff->cmp())
5755
5735
      idx=i;
5794
5774
                       List<Item> &all_fields)
5795
5775
{
5796
5776
  Item *pos;
5797
 
  List_iterator_fast<Item> li(all_fields);
 
5777
  List<Item>::iterator li(all_fields.begin());
5798
5778
  CopyField *copy= NULL;
5799
 
  res_selected_fields.empty();
5800
 
  res_all_fields.empty();
5801
 
  List_iterator_fast<Item> itr(res_all_fields);
 
5779
  res_selected_fields.clear();
 
5780
  res_all_fields.clear();
 
5781
  List<Item>::iterator itr(res_all_fields.begin());
5802
5782
  List<Item> extra_funcs;
5803
 
  uint32_t i, border= all_fields.elements - elements;
 
5783
  uint32_t i, border= all_fields.size() - elements;
5804
5784
 
5805
5785
  if (param->field_count &&
5806
 
      !(copy=param->copy_field= new CopyField[param->field_count]))
5807
 
    goto err2;
 
5786
      !(copy= param->copy_field= new CopyField[param->field_count]))
 
5787
    return true;
5808
5788
 
5809
 
  param->copy_funcs.empty();
 
5789
  param->copy_funcs.clear();
5810
5790
  for (i= 0; (pos= li++); i++)
5811
5791
  {
5812
5792
    Field *field;
5839
5819
              copy_funcs
5840
5820
              (to see full test case look at having.test, BUG #4358)
5841
5821
            */
5842
 
        if (param->copy_funcs.push_front(pos))
5843
 
          goto err;
 
5822
        param->copy_funcs.push_front(pos);
5844
5823
      }
5845
5824
      else
5846
5825
      {
5875
5854
             !real_pos->with_sum_func)
5876
5855
    {                                           // Save for send fields
5877
5856
      pos= real_pos;
5878
 
      /* TODO:
5879
 
        In most cases this result will be sent to the user.
 
5857
      /*
 
5858
        @todo In most cases this result will be sent to the user.
5880
5859
        This should be changed to use copy_int or copy_real depending
5881
5860
        on how the value is to be used: In some cases this may be an
5882
5861
        argument in a group function, like: IF(ISNULL(col),0,COUNT(*))
5883
5862
      */
5884
 
      if (!(pos=new Item_copy_string(pos)))
5885
 
        goto err;
 
5863
      pos=new Item_copy_string(pos);
5886
5864
      if (i < border)                           // HAVING, order_st and GROUP BY
5887
 
      {
5888
 
        if (extra_funcs.push_back(pos))
5889
 
          goto err;
5890
 
      }
5891
 
      else if (param->copy_funcs.push_back(pos))
5892
 
        goto err;
 
5865
        extra_funcs.push_back(pos);
 
5866
      else 
 
5867
                                param->copy_funcs.push_back(pos);
5893
5868
    }
5894
5869
    res_all_fields.push_back(pos);
5895
 
    ref_pointer_array[((i < border)? all_fields.elements-i-1 : i-border)]=
 
5870
    ref_pointer_array[((i < border)? all_fields.size()-i-1 : i-border)]=
5896
5871
      pos;
5897
5872
  }
5898
5873
  param->copy_field_end= copy;
5912
5887
  if (copy)
5913
5888
    delete [] param->copy_field;                        // This is never 0
5914
5889
  param->copy_field=0;
5915
 
err2:
5916
 
  return(true);
 
5890
  return true;
5917
5891
}
5918
5892
 
5919
5893
/**
5930
5904
  for (; ptr != end; ptr++)
5931
5905
    (*ptr->do_copy)(ptr);
5932
5906
 
5933
 
  List_iterator_fast<Item> it(param->copy_funcs);
 
5907
  List<Item>::iterator it(param->copy_funcs.begin());
5934
5908
  Item_copy_string *item;
5935
5909
  while ((item = (Item_copy_string*) it++))
5936
5910
    item->copy();
5959
5933
                                                uint32_t elements,
5960
5934
                              List<Item> &all_fields)
5961
5935
{
5962
 
  List_iterator_fast<Item> it(all_fields);
 
5936
  List<Item>::iterator it(all_fields.begin());
5963
5937
  Item *item_field,*item;
5964
5938
 
5965
 
  res_selected_fields.empty();
5966
 
  res_all_fields.empty();
 
5939
  res_selected_fields.clear();
 
5940
  res_all_fields.clear();
5967
5941
 
5968
 
  uint32_t i, border= all_fields.elements - elements;
 
5942
  uint32_t i, border= all_fields.size() - elements;
5969
5943
  for (i= 0; (item= it++); i++)
5970
5944
  {
5971
5945
    Field *field;
6004
5978
        item_field= item;
6005
5979
    }
6006
5980
    res_all_fields.push_back(item_field);
6007
 
    ref_pointer_array[((i < border)? all_fields.elements-i-1 : i-border)]=
 
5981
    ref_pointer_array[((i < border)? all_fields.size()-i-1 : i-border)]=
6008
5982
      item_field;
6009
5983
  }
6010
5984
 
6011
 
  List_iterator_fast<Item> itr(res_all_fields);
 
5985
  List<Item>::iterator itr(res_all_fields.begin());
6012
5986
  for (i= 0; i < border; i++)
6013
5987
    itr++;
6014
5988
  itr.sublist(res_selected_fields, elements);
6038
6012
                               uint32_t elements,
6039
6013
                                                 List<Item> &all_fields)
6040
6014
{
6041
 
  List_iterator_fast<Item> it(all_fields);
 
6015
  List<Item>::iterator it(all_fields.begin());
6042
6016
  Item *item, *new_item;
6043
 
  res_selected_fields.empty();
6044
 
  res_all_fields.empty();
 
6017
  res_selected_fields.clear();
 
6018
  res_all_fields.clear();
6045
6019
 
6046
 
  uint32_t i, border= all_fields.elements - elements;
 
6020
  uint32_t i, border= all_fields.size() - elements;
6047
6021
  for (i= 0; (item= it++); i++)
6048
6022
  {
6049
6023
    res_all_fields.push_back(new_item= item->get_tmp_table_item(session));
6050
 
    ref_pointer_array[((i < border)? all_fields.elements-i-1 : i-border)]=
 
6024
    ref_pointer_array[((i < border)? all_fields.size()-i-1 : i-border)]=
6051
6025
      new_item;
6052
6026
  }
6053
6027
 
6054
 
  List_iterator_fast<Item> itr(res_all_fields);
 
6028
  List<Item>::iterator itr(res_all_fields.begin());
6055
6029
  for (i= 0; i < border; i++)
6056
6030
    itr++;
6057
6031
  itr.sublist(res_selected_fields, elements);
6143
6117
    /*
6144
6118
      Need to check the THD error state because Item::val_xxx() don't
6145
6119
      return error code, but can generate errors
6146
 
      TODO: change it for a real status check when Item::val_xxx()
 
6120
      @todo change it for a real status check when Item::val_xxx()
6147
6121
      are extended to return status code.
6148
6122
    */
6149
6123
    if (session->is_error())
6201
6175
  @param changed        out:  returns 1 if item contains a replaced field item
6202
6176
 
6203
6177
  @todo
6204
 
    - TODO: Some functions are not null-preserving. For those functions
 
6178
    - @todo Some functions are not null-preserving. For those functions
6205
6179
    updating of the maybe_null attribute is an overkill.
6206
6180
 
6207
6181
  @retval
6213
6187
{
6214
6188
  if (expr->arg_count)
6215
6189
  {
6216
 
    Name_resolution_context *context= &session->lex->current_select->context;
 
6190
    Name_resolution_context *context= &session->lex().current_select->context;
6217
6191
    Item **arg,**arg_end;
6218
6192
    bool arg_changed= false;
6219
6193
    for (arg= expr->arguments(),
6232
6206
            if (!(new_item= new Item_ref(context, group_tmp->item, 0,
6233
6207
                                        item->name)))
6234
6208
              return 1;                                 // fatal_error is set
6235
 
            session->change_item_tree(arg, new_item);
 
6209
            *arg= new_item;
6236
6210
            arg_changed= true;
6237
6211
          }
6238
6212
        }
6256
6230
static void print_table_array(Session *session, String *str, TableList **table,
6257
6231
                              TableList **end)
6258
6232
{
6259
 
  (*table)->print(session, str, QT_ORDINARY);
 
6233
  (*table)->print(session, str);
6260
6234
 
6261
6235
  for (TableList **tbl= table + 1; tbl < end; tbl++)
6262
6236
  {
6270
6244
      str->append(STRING_WITH_LEN(" straight_join "));
6271
6245
    else
6272
6246
      str->append(STRING_WITH_LEN(" join "));
6273
 
    curr->print(session, str, QT_ORDINARY);
 
6247
    curr->print(session, str);
6274
6248
    if (curr->on_expr)
6275
6249
    {
6276
6250
      str->append(STRING_WITH_LEN(" on("));
6277
 
      curr->on_expr->print(str, QT_ORDINARY);
 
6251
      curr->on_expr->print(str);
6278
6252
      str->append(')');
6279
6253
    }
6280
6254
  }
6285
6259
  @param session     thread Cursor
6286
6260
  @param str     string where table should be printed
6287
6261
  @param tables  list of tables in join
6288
 
  @query_type    type of the query is being generated
6289
6262
*/
6290
6263
void print_join(Session *session, String *str,
6291
 
                List<TableList> *tables, enum_query_type)
 
6264
                List<TableList> *tables)
6292
6265
{
6293
6266
  /* List is reversed => we should reverse it before using */
6294
 
  List_iterator_fast<TableList> ti(*tables);
 
6267
  List<TableList>::iterator ti(tables->begin());
6295
6268
  TableList **table= (TableList **)session->getMemRoot()->allocate(sizeof(TableList*) *
6296
 
                                                tables->elements);
 
6269
                                                tables->size());
6297
6270
  if (table == 0)
6298
6271
    return;  // out of memory
6299
6272
 
6300
 
  for (TableList **t= table + (tables->elements - 1); t >= table; t--)
 
6273
  for (TableList **t= table + (tables->size() - 1); t >= table; t--)
6301
6274
    *t= ti++;
6302
 
  assert(tables->elements >= 1);
6303
 
  print_table_array(session, str, table, table + tables->elements);
 
6275
  assert(tables->size() >= 1);
 
6276
  print_table_array(session, str, table, table + tables->size());
6304
6277
}
6305
6278
 
6306
 
void Select_Lex::print(Session *session, String *str, enum_query_type query_type)
 
6279
void Select_Lex::print(Session *session, String *str)
6307
6280
{
6308
6281
  /* QQ: session may not be set for sub queries, but this should be fixed */
6309
6282
  if(not session)
6328
6301
 
6329
6302
  //Item List
6330
6303
  bool first= 1;
6331
 
  List_iterator_fast<Item> it(item_list);
 
6304
  List<Item>::iterator it(item_list.begin());
6332
6305
  Item *item;
6333
6306
  while ((item= it++))
6334
6307
  {
6336
6309
      first= 0;
6337
6310
    else
6338
6311
      str->append(',');
6339
 
    item->print_item_w_name(str, query_type);
 
6312
    item->print_item_w_name(str);
6340
6313
  }
6341
6314
 
6342
6315
  /*
6343
6316
    from clause
6344
 
    TODO: support USING/FORCE/IGNORE index
 
6317
    @todo support USING/FORCE/IGNORE index
6345
6318
  */
6346
 
  if (table_list.elements)
 
6319
  if (table_list.size())
6347
6320
  {
6348
6321
    str->append(STRING_WITH_LEN(" from "));
6349
6322
    /* go through join tree */
6350
 
    print_join(session, str, &top_join_list, query_type);
 
6323
    print_join(session, str, &top_join_list);
6351
6324
  }
6352
6325
  else if (where)
6353
6326
  {
6366
6339
  {
6367
6340
    str->append(STRING_WITH_LEN(" where "));
6368
6341
    if (cur_where)
6369
 
      cur_where->print(str, query_type);
 
6342
      cur_where->print(str);
6370
6343
    else
6371
6344
      str->append(cond_value != Item::COND_FALSE ? "1" : "0");
6372
6345
  }
6373
6346
 
6374
6347
  // group by & olap
6375
 
  if (group_list.elements)
 
6348
  if (group_list.size())
6376
6349
  {
6377
6350
    str->append(STRING_WITH_LEN(" group by "));
6378
 
    print_order(str, (Order *) group_list.first, query_type);
 
6351
    print_order(str, (Order *) group_list.first);
6379
6352
    switch (olap)
6380
6353
    {
6381
6354
      case CUBE_TYPE:
6398
6371
  {
6399
6372
    str->append(STRING_WITH_LEN(" having "));
6400
6373
    if (cur_having)
6401
 
      cur_having->print(str, query_type);
 
6374
      cur_having->print(str);
6402
6375
    else
6403
6376
      str->append(having_value != Item::COND_FALSE ? "1" : "0");
6404
6377
  }
6405
6378
 
6406
 
  if (order_list.elements)
 
6379
  if (order_list.size())
6407
6380
  {
6408
6381
    str->append(STRING_WITH_LEN(" order by "));
6409
 
    print_order(str, (Order *) order_list.first, query_type);
 
6382
    print_order(str, (Order *) order_list.first);
6410
6383
  }
6411
6384
 
6412
6385
  // limit
6413
 
  print_limit(session, str, query_type);
 
6386
  print_limit(session, str);
6414
6387
 
6415
6388
  // PROCEDURE unsupported here
6416
6389
}