~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_select.cc

  • Committer: pcrews
  • Date: 2011-05-24 17:36:24 UTC
  • mfrom: (1099.4.232 drizzle)
  • Revision ID: pcrews@lucid32-20110524173624-mwr1bvq6fa1r01ao
Updated translations + 2011.05.18 tarball tag

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