~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_select.cc

  • Committer: Brian Aker
  • Date: 2011-02-22 06:12:02 UTC
  • mfrom: (2190.1.6 drizzle-build)
  • Revision ID: brian@tangent.org-20110222061202-k03czxykqy4x9hjs
List update, header fixes, multiple symbols, and David deletes some code.

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
 
 
56
 
#include "drizzled/sql_union.h"
57
 
#include "drizzled/optimizer/key_field.h"
58
 
#include "drizzled/optimizer/position.h"
59
 
#include "drizzled/optimizer/sargable_param.h"
60
 
#include "drizzled/optimizer/key_use.h"
61
 
#include "drizzled/optimizer/range.h"
62
 
#include "drizzled/optimizer/quick_range_select.h"
63
 
#include "drizzled/optimizer/quick_ror_intersect_select.h"
64
 
 
65
 
#include "drizzled/filesort.h"
 
32
#include <drizzled/sql_select.h> /* include join.h */
 
33
 
 
34
#include <drizzled/error.h>
 
35
#include <drizzled/gettext.h>
 
36
#include <drizzled/util/test.h>
 
37
#include <drizzled/name_resolution_context_state.h>
 
38
#include <drizzled/nested_join.h>
 
39
#include <drizzled/probes.h>
 
40
#include <drizzled/show.h>
 
41
#include <drizzled/item/cache.h>
 
42
#include <drizzled/item/cmpfunc.h>
 
43
#include <drizzled/item/copy_string.h>
 
44
#include <drizzled/item/uint.h>
 
45
#include <drizzled/cached_item.h>
 
46
#include <drizzled/sql_base.h>
 
47
#include <drizzled/field/blob.h>
 
48
#include <drizzled/check_stack_overrun.h>
 
49
#include <drizzled/lock.h>
 
50
#include <drizzled/item/outer_ref.h>
 
51
#include <drizzled/index_hint.h>
 
52
#include <drizzled/records.h>
 
53
#include <drizzled/internal/iocache.h>
 
54
#include <drizzled/drizzled.h>
 
55
#include <drizzled/plugin/storage_engine.h>
 
56
 
 
57
#include <drizzled/sql_union.h>
 
58
#include <drizzled/optimizer/key_field.h>
 
59
#include <drizzled/optimizer/position.h>
 
60
#include <drizzled/optimizer/sargable_param.h>
 
61
#include <drizzled/optimizer/key_use.h>
 
62
#include <drizzled/optimizer/range.h>
 
63
#include <drizzled/optimizer/quick_range_select.h>
 
64
#include <drizzled/optimizer/quick_ror_intersect_select.h>
 
65
 
 
66
#include <drizzled/filesort.h>
 
67
#include <drizzled/sql_lex.h>
 
68
#include <drizzled/session.h>
 
69
#include <drizzled/sort_field.h>
 
70
#include <drizzled/select_result.h>
66
71
 
67
72
using namespace std;
68
73
 
207
212
  bool res= false;
208
213
  bool direct_ref= false;
209
214
 
210
 
  List_iterator<Item_outer_ref> ref_it(select->inner_refs_list);
 
215
  List<Item_outer_ref>::iterator ref_it(select->inner_refs_list.begin());
211
216
  while ((ref= ref_it++))
212
217
  {
213
218
    Item *item= ref->outer_ref;
214
219
    Item **item_ref= ref->ref;
215
220
    Item_ref *new_ref;
216
221
    /*
217
 
      TODO: this field item already might be present in the select list.
 
222
      @todo this field item already might be present in the select list.
218
223
      In this case instead of adding new field item we could use an
219
224
      existing one. The change will lead to less operations for copying fields,
220
225
      smaller temporary tables and less data passed through filesort.
420
425
    goto err; // 1
421
426
  }
422
427
 
423
 
  if (session->lex->describe & DESCRIBE_EXTENDED)
 
428
  if (session->getLex()->describe & DESCRIBE_EXTENDED)
424
429
  {
425
430
    join->conds_history= join->conds;
426
431
    join->having_history= (join->having?join->having:join->tmp_having);
431
436
 
432
437
  join->exec();
433
438
 
434
 
  if (session->lex->describe & DESCRIBE_EXTENDED)
 
439
  if (session->getLex()->describe & DESCRIBE_EXTENDED)
435
440
  {
436
441
    select_lex->where= join->conds_history;
437
442
    select_lex->having= join->having_history;
570
575
    substitutions.
571
576
  */
572
577
  sz= sizeof(optimizer::KeyField) *
573
 
      (((session->lex->current_select->cond_count+1)*2 +
574
 
        session->lex->current_select->between_count)*m+1);
575
 
  if (! (key_fields= (optimizer::KeyField*) session->alloc(sz)))
 
578
      (((session->getLex()->current_select->cond_count+1)*2 +
 
579
        session->getLex()->current_select->between_count)*m+1);
 
580
  if (! (key_fields= (optimizer::KeyField*) session->getMemRoot()->allocate(sz)))
576
581
    return true;
577
582
  and_level= 0;
578
583
  field= end= key_fields;
613
618
 
614
619
  /* Process ON conditions for the nested joins */
615
620
  {
616
 
    List_iterator<TableList> li(*join_tab->join->join_list);
 
621
    List<TableList>::iterator li(join_tab->join->join_list->begin());
617
622
    TableList *table;
618
623
    while ((table= li++))
619
624
    {
747
752
void add_group_and_distinct_keys(Join *join, JoinTable *join_tab)
748
753
{
749
754
  List<Item_field> indexed_fields;
750
 
  List_iterator<Item_field> indexed_fields_it(indexed_fields);
 
755
  List<Item_field>::iterator indexed_fields_it(indexed_fields.begin());
751
756
  Order      *cur_group;
752
757
  Item_field *cur_item;
753
758
  key_map possible_keys(0);
761
766
  else if (join->select_distinct)
762
767
  { /* Collect all query fields referenced in the SELECT clause. */
763
768
    List<Item> &select_items= join->fields_list;
764
 
    List_iterator<Item> select_items_it(select_items);
 
769
    List<Item>::iterator select_items_it(select_items.begin());
765
770
    Item *item;
766
771
    while ((item= select_items_it++))
767
772
      item->walk(&Item::collect_item_field_processor, 0,
1004
1009
  j->ref.key_length=length;
1005
1010
  j->ref.key=(int) key;
1006
1011
  if (!(j->ref.key_buff= (unsigned char*) session->calloc(ALIGN_SIZE(length)*2)) ||
1007
 
      !(j->ref.key_copy= (StoredKey**) session->alloc((sizeof(StoredKey*) *
 
1012
      !(j->ref.key_copy= (StoredKey**) session->getMemRoot()->allocate((sizeof(StoredKey*) *
1008
1013
               (keyparts+1)))) ||
1009
 
      !(j->ref.items=    (Item**) session->alloc(sizeof(Item*)*keyparts)) ||
1010
 
      !(j->ref.cond_guards= (bool**) session->alloc(sizeof(uint*)*keyparts)))
 
1014
      !(j->ref.items=    (Item**) session->getMemRoot()->allocate(sizeof(Item*)*keyparts)) ||
 
1015
      !(j->ref.cond_guards= (bool**) session->getMemRoot()->allocate(sizeof(uint*)*keyparts)))
1011
1016
  {
1012
1017
    return(true);
1013
1018
  }
1216
1221
*/
1217
1222
void JoinTable::cleanup()
1218
1223
{
1219
 
  delete select;
1220
 
  select= 0;
1221
 
  delete quick;
1222
 
  quick= 0;
 
1224
  safe_delete(select);
 
1225
  safe_delete(quick);
 
1226
 
1223
1227
  if (cache.buff)
1224
1228
  {
1225
1229
    size_t size= cache.end - cache.buff;
1348
1352
  bool in_upper_level= false;
1349
1353
  while (cond_equal)
1350
1354
  {
1351
 
    List_iterator_fast<Item_equal> li(cond_equal->current_level);
 
1355
    List<Item_equal>::iterator li(cond_equal->current_level.begin());
1352
1356
    while ((item= li++))
1353
1357
    {
1354
1358
      if (item->contains(field))
1513
1517
        /* Merge two multiple equalities forming a new one */
1514
1518
        left_item_equal->merge(right_item_equal);
1515
1519
        /* Remove the merged multiple equality from the list */
1516
 
        List_iterator<Item_equal> li(cond_equal->current_level);
 
1520
        List<Item_equal>::iterator li(cond_equal->current_level.begin());
1517
1521
        while ((li++) != right_item_equal) {};
1518
1522
        li.remove();
1519
1523
      }
1653
1657
                                       (Item_row *) right_item,
1654
1658
                                       cond_equal, eq_list);
1655
1659
      if (!is_converted)
1656
 
        session->lex->current_select->cond_count++;
 
1660
        session->getLex()->current_select->cond_count++;
1657
1661
    }
1658
1662
    else
1659
1663
    {
1660
1664
      is_converted= check_simple_equality(left_item, right_item, 0, cond_equal);
1661
 
      session->lex->current_select->cond_count++;
 
1665
      session->getLex()->current_select->cond_count++;
1662
1666
    }
1663
1667
 
1664
1668
    if (!is_converted)
1714
1718
    if (left_item->type() == Item::ROW_ITEM &&
1715
1719
        right_item->type() == Item::ROW_ITEM)
1716
1720
    {
1717
 
      session->lex->current_select->cond_count--;
 
1721
      session->getLex()->current_select->cond_count--;
1718
1722
      return check_row_equality(session,
1719
1723
                                (Item_row *) left_item,
1720
1724
                                (Item_row *) right_item,
1745
1749
    just an argument of a comparison predicate.
1746
1750
    The function also determines the maximum number of members in
1747
1751
    equality lists of each Item_cond_and object assigning it to
1748
 
    session->lex->current_select->max_equal_elems.
 
1752
    session->getLex()->current_select->max_equal_elems.
1749
1753
 
1750
1754
  @note
1751
1755
    Multiple equality predicate =(f1,..fn) is equivalent to the conjuction of
1802
1806
      Item_func::COND_AND_FUNC;
1803
1807
    List<Item> *args= ((Item_cond*) cond)->argument_list();
1804
1808
 
1805
 
    List_iterator<Item> li(*args);
 
1809
    List<Item>::iterator li(args->begin());
1806
1810
    Item *item;
1807
1811
 
1808
1812
    if (and_level)
1824
1828
          li.remove();
1825
1829
      }
1826
1830
 
1827
 
      List_iterator_fast<Item_equal> it(cond_equal.current_level);
 
1831
      List<Item_equal>::iterator it(cond_equal.current_level.begin());
1828
1832
      while ((item_equal= it++))
1829
1833
      {
1830
1834
        item_equal->fix_length_and_dec();
1831
1835
        item_equal->update_used_tables();
1832
 
        set_if_bigger(session->lex->current_select->max_equal_elems,
 
1836
        set_if_bigger(session->getLex()->current_select->max_equal_elems,
1833
1837
                      item_equal->members());
1834
1838
      }
1835
1839
 
1840
1844
       Make replacement of equality predicates for lower levels
1841
1845
       of the condition expression.
1842
1846
    */
1843
 
    li.rewind();
 
1847
    li= args->begin();
1844
1848
    while ((item= li++))
1845
1849
    {
1846
1850
      Item *new_item;
1888
1892
        }
1889
1893
        else
1890
1894
          item_equal= (Item_equal *) eq_list.pop();
1891
 
        set_if_bigger(session->lex->current_select->max_equal_elems,
 
1895
        set_if_bigger(session->getLex()->current_select->max_equal_elems,
1892
1896
                      item_equal->members());
1893
1897
        return item_equal;
1894
1898
      }
1901
1905
        Item_cond_and *and_cond= new Item_cond_and(eq_list);
1902
1906
        and_cond->quick_fix_field();
1903
1907
        List<Item> *args= and_cond->argument_list();
1904
 
        List_iterator_fast<Item_equal> it(cond_equal.current_level);
 
1908
        List<Item_equal>::iterator it(cond_equal.current_level.begin());
1905
1909
        while ((item_equal= it++))
1906
1910
        {
1907
1911
          item_equal->fix_length_and_dec();
1908
1912
          item_equal->update_used_tables();
1909
 
          set_if_bigger(session->lex->current_select->max_equal_elems,
 
1913
          set_if_bigger(session->getLex()->current_select->max_equal_elems,
1910
1914
                        item_equal->members());
1911
1915
        }
1912
1916
        and_cond->cond_equal= cond_equal;
2027
2031
  if (join_list)
2028
2032
  {
2029
2033
    TableList *table;
2030
 
    List_iterator<TableList> li(*join_list);
 
2034
    List<TableList>::iterator li(join_list->begin());
2031
2035
 
2032
2036
    while ((table= li++))
2033
2037
    {
2242
2246
      cond_equal= &((Item_cond_and *) cond)->cond_equal;
2243
2247
      cond_list->disjoin((List<Item> *) &cond_equal->current_level);
2244
2248
 
2245
 
      List_iterator_fast<Item_equal> it(cond_equal->current_level);
 
2249
      List<Item_equal>::iterator it(cond_equal->current_level.begin());
2246
2250
      while ((item_equal= it++))
2247
2251
      {
2248
2252
        item_equal->sort(&compare_fields_by_table_order, table_join_idx);
2249
2253
      }
2250
2254
    }
2251
2255
 
2252
 
    List_iterator<Item> li(*cond_list);
 
2256
    List<Item>::iterator li(cond_list->begin());
2253
2257
    Item *item;
2254
2258
    while ((item= li++))
2255
2259
    {
2265
2269
 
2266
2270
    if (and_level)
2267
2271
    {
2268
 
      List_iterator_fast<Item_equal> it(cond_equal->current_level);
 
2272
      List<Item_equal>::iterator it(cond_equal->current_level.begin());
2269
2273
      while ((item_equal= it++))
2270
2274
      {
2271
2275
        cond= eliminate_item_equal(cond, cond_equal->upper_levels, item_equal);
2307
2311
  @param cond       condition whose multiple equalities are to be checked
2308
2312
  @param table      constant table that has been read
2309
2313
*/
2310
 
static void update_const_equal_items(COND *cond, JoinTable *tab)
 
2314
void update_const_equal_items(COND *cond, JoinTable *tab)
2311
2315
{
2312
2316
  if (!(cond->used_tables() & tab->table->map))
2313
2317
    return;
2315
2319
  if (cond->type() == Item::COND_ITEM)
2316
2320
  {
2317
2321
    List<Item> *cond_list= ((Item_cond*) cond)->argument_list();
2318
 
    List_iterator_fast<Item> li(*cond_list);
 
2322
    List<Item>::iterator li(cond_list->begin());
2319
2323
    Item *item;
2320
2324
    while ((item= li++))
2321
2325
      update_const_equal_items(item, tab);
2373
2377
  if (cond->type() == Item::COND_ITEM)
2374
2378
  {
2375
2379
    bool and_level= ((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC;
2376
 
    List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
 
2380
    List<Item>::iterator li(((Item_cond*) cond)->argument_list()->begin());
2377
2381
    Item *item;
2378
2382
    while ((item=li++))
2379
2383
      change_cond_ref_to_const(session, save_list, and_level ? cond : item, item, field, value);
2453
2457
  if (conds->type() == Item::COND_ITEM)
2454
2458
  {
2455
2459
    Item_cond *cnd= (Item_cond*) conds;
2456
 
    List_iterator<Item> li(*(cnd->argument_list()));
 
2460
    List<Item>::iterator li(cnd->argument_list()->begin());
2457
2461
    Item *item;
2458
2462
    while ((item= li++))
2459
2463
    {
2477
2481
  if (cond->type() == Item::COND_ITEM)
2478
2482
  {
2479
2483
    bool and_level= ((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC;
2480
 
    List_iterator_fast<Item> li(*((Item_cond*) cond)->argument_list());
 
2484
    List<Item>::iterator li(((Item_cond*) cond)->argument_list()->begin());
2481
2485
    Item *item;
2482
2486
    list<COND_CMP> save;
2483
2487
    while ((item=li++))
2606
2610
         position:
2607
2611
          1. join->cur_embedding_map - bitmap of pairs of brackets (aka nested
2608
2612
             joins) we've opened but didn't close.
2609
 
          2. {each nested_join_st structure not simplified away}->counter - number
 
2613
          2. {each NestedJoin class not simplified away}->counter - number
2610
2614
             of this nested join's children that have already been added to to
2611
2615
             the partial join order.
2612
2616
  @endverbatim
2711
2715
  {
2712
2716
    bool and_level= (((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC);
2713
2717
 
2714
 
    List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
 
2718
    List<Item>::iterator li(((Item_cond*) cond)->argument_list()->begin());
2715
2719
    Item::cond_result tmp_cond_value;
2716
2720
    bool should_fix_fields= false;
2717
2721
 
2765
2769
    {                                           
2766
2770
      /* Argument list contains only one element, so reduce it so a single item, then remove list */
2767
2771
      item= ((Item_cond*) cond)->argument_list()->head();
2768
 
      ((Item_cond*) cond)->argument_list()->empty();
 
2772
      ((Item_cond*) cond)->argument_list()->clear();
2769
2773
      return item;
2770
2774
    }
2771
2775
  }
2843
2847
  }
2844
2848
  else if (cond->const_item() && !cond->is_expensive())
2845
2849
  /*
2846
 
    TODO:
 
2850
    @todo
2847
2851
    Excluding all expensive functions is too restritive we should exclude only
2848
2852
    materialized IN subquery predicates because they can't yet be evaluated
2849
2853
    here (they need additional initialization that is done later on).
2915
2919
  {
2916
2920
    bool and_level= (((Item_cond*) cond)->functype()
2917
2921
                     == Item_func::COND_AND_FUNC);
2918
 
    List_iterator_fast<Item> li(*((Item_cond*) cond)->argument_list());
 
2922
    List<Item>::iterator li(((Item_cond*) cond)->argument_list()->begin());
2919
2923
    Item *item;
2920
2924
    while ((item=li++))
2921
2925
    {
3367
3371
  return 0;
3368
3372
}
3369
3373
 
3370
 
int join_read_const_table(JoinTable *tab, optimizer::Position *pos)
3371
 
{
3372
 
  int error;
3373
 
  Table *table=tab->table;
3374
 
  table->const_table=1;
3375
 
  table->null_row=0;
3376
 
  table->status=STATUS_NO_RECORD;
3377
 
 
3378
 
  if (tab->type == AM_SYSTEM)
3379
 
  {
3380
 
    if ((error=join_read_system(tab)))
3381
 
    {                                           // Info for DESCRIBE
3382
 
      tab->info="const row not found";
3383
 
      /* Mark for EXPLAIN that the row was not found */
3384
 
      pos->setFanout(0.0);
3385
 
      pos->clearRefDependMap();
3386
 
      if (! table->maybe_null || error > 0)
3387
 
        return(error);
3388
 
    }
3389
 
  }
3390
 
  else
3391
 
  {
3392
 
    if (! table->key_read && 
3393
 
        table->covering_keys.test(tab->ref.key) && 
3394
 
        ! table->no_keyread &&
3395
 
        (int) table->reginfo.lock_type <= (int) TL_READ_WITH_SHARED_LOCKS)
3396
 
    {
3397
 
      table->key_read=1;
3398
 
      table->cursor->extra(HA_EXTRA_KEYREAD);
3399
 
      tab->index= tab->ref.key;
3400
 
    }
3401
 
    error=join_read_const(tab);
3402
 
    if (table->key_read)
3403
 
    {
3404
 
      table->key_read=0;
3405
 
      table->cursor->extra(HA_EXTRA_NO_KEYREAD);
3406
 
    }
3407
 
    if (error)
3408
 
    {
3409
 
      tab->info="unique row not found";
3410
 
      /* Mark for EXPLAIN that the row was not found */
3411
 
      pos->setFanout(0.0);
3412
 
      pos->clearRefDependMap();
3413
 
      if (!table->maybe_null || error > 0)
3414
 
        return(error);
3415
 
    }
3416
 
  }
3417
 
  if (*tab->on_expr_ref && !table->null_row)
3418
 
  {
3419
 
    if ((table->null_row= test((*tab->on_expr_ref)->val_int() == 0)))
3420
 
      table->mark_as_null_row();
3421
 
  }
3422
 
  if (!table->null_row)
3423
 
    table->maybe_null=0;
3424
 
 
3425
 
  /* Check appearance of new constant items in Item_equal objects */
3426
 
  Join *join= tab->join;
3427
 
  if (join->conds)
3428
 
    update_const_equal_items(join->conds, tab);
3429
 
  TableList *tbl;
3430
 
  for (tbl= join->select_lex->leaf_tables; tbl; tbl= tbl->next_leaf)
3431
 
  {
3432
 
    TableList *embedded;
3433
 
    TableList *embedding= tbl;
3434
 
    do
3435
 
    {
3436
 
      embedded= embedding;
3437
 
      if (embedded->on_expr)
3438
 
         update_const_equal_items(embedded->on_expr, tab);
3439
 
      embedding= embedded->getEmbedding();
3440
 
    }
3441
 
    while (embedding &&
3442
 
           embedding->getNestedJoin()->join_list.head() == embedded);
3443
 
  }
3444
 
 
3445
 
  return(0);
3446
 
}
3447
 
 
3448
 
int join_read_system(JoinTable *tab)
3449
 
{
3450
 
  Table *table= tab->table;
3451
 
  int error;
3452
 
  if (table->status & STATUS_GARBAGE)           // If first read
3453
 
  {
3454
 
    if ((error=table->cursor->read_first_row(table->getInsertRecord(),
3455
 
                                           table->getShare()->getPrimaryKey())))
3456
 
    {
3457
 
      if (error != HA_ERR_END_OF_FILE)
3458
 
        return table->report_error(error);
3459
 
      tab->table->mark_as_null_row();
3460
 
      table->emptyRecord();                     // Make empty record
3461
 
      return -1;
3462
 
    }
3463
 
    table->storeRecord();
3464
 
  }
3465
 
  else if (!table->status)                      // Only happens with left join
3466
 
    table->restoreRecord();                     // restore old record
3467
 
  table->null_row=0;
3468
 
  return table->status ? -1 : 0;
3469
 
}
3470
 
 
3471
3374
/**
3472
3375
  Read a (constant) table when there is at most one matching row.
3473
3376
 
3546
3449
    }
3547
3450
  }
3548
3451
 
3549
 
  /* TODO: Why don't we do "Late NULLs Filtering" here? */
 
3452
  /* @todo Why don't we do "Late NULLs Filtering" here? */
3550
3453
  if (cmp_buffer_with_ref(tab) ||
3551
3454
      (table->status & (STATUS_GARBAGE | STATUS_NO_PARENT | STATUS_NULL_ROW)))
3552
3455
  {
3737
3640
 
3738
3641
int test_if_quick_select(JoinTable *tab)
3739
3642
{
3740
 
  delete tab->select->quick;
3741
 
  tab->select->quick= 0;
 
3643
  safe_delete(tab->select->quick);
 
3644
 
3742
3645
  return tab->select->test_quick_select(tab->join->session, tab->keys,
3743
3646
                                        (table_map) 0, HA_POS_ERROR, 0, false);
3744
3647
}
3916
3819
        {
3917
3820
          if (!join->first_record)
3918
3821
          {
3919
 
                  List_iterator_fast<Item> it(*join->fields);
 
3822
                  List<Item>::iterator it(join->fields->begin());
3920
3823
                  Item *item;
3921
3824
            /* No matching rows for group function */
3922
3825
            join->clear();
3932
3835
              error=join->result->send_data(*join->fields) ? 1 : 0;
3933
3836
            join->send_records++;
3934
3837
          }
3935
 
          if (join->rollup.state != ROLLUP::STATE_NONE && error <= 0)
 
3838
          if (join->rollup.getState() != Rollup::STATE_NONE && error <= 0)
3936
3839
          {
3937
3840
            if (join->rollup_send_data((uint32_t) (idx+1)))
3938
3841
              error= 1;
4022
3925
            return NESTED_LOOP_ERROR;
4023
3926
          }
4024
3927
        }
4025
 
        if (join->rollup.state != ROLLUP::STATE_NONE)
 
3928
        if (join->rollup.getState() != Rollup::STATE_NONE)
4026
3929
        {
4027
3930
          if (join->rollup_write_data((uint32_t) (idx+1), table))
4028
3931
            return NESTED_LOOP_ERROR;
4155
4058
      Item_cond_and *new_cond=new Item_cond_and;
4156
4059
      if (!new_cond)
4157
4060
        return (COND*) 0;
4158
 
      List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
 
4061
      List<Item>::iterator li(((Item_cond*) cond)->argument_list()->begin());
4159
4062
      Item *item;
4160
4063
      while ((item=li++))
4161
4064
      {
4185
4088
      Item_cond_or *new_cond=new Item_cond_or;
4186
4089
      if (!new_cond)
4187
4090
        return (COND*) 0;
4188
 
      List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
 
4091
      List<Item>::iterator li(((Item_cond*) cond)->argument_list()->begin());
4189
4092
      Item *item;
4190
4093
      while ((item=li++))
4191
4094
      {
4537
4440
{
4538
4441
  List<Item> *fields= (List<Item> *) data;
4539
4442
  bool part_found= 0;
4540
 
  List_iterator<Item> li(*fields);
 
4443
  List<Item>::iterator li(fields->begin());
4541
4444
  Item *item;
4542
4445
 
4543
4446
  while ((item= li++))
4622
4525
    save_quick= select->quick;
4623
4526
    /*
4624
4527
      assume results are not ordered when index merge is used
4625
 
      TODO: sergeyp: Results of all index merge selects actually are ordered
 
4528
      @todo sergeyp: Results of all index merge selects actually are ordered
4626
4529
      by clustered PK values.
4627
4530
    */
4628
4531
 
4897
4800
          tab->type= AM_NEXT;           // Read with index_first(), index_next()
4898
4801
          if (select && select->quick)
4899
4802
          {
4900
 
            delete select->quick;
4901
 
            select->quick= 0;
 
4803
            safe_delete(select->quick);
4902
4804
          }
4903
4805
          if (table->covering_keys.test(best_key))
4904
4806
          {
4971
4873
          tab->limit= 0;
4972
4874
          return 0; // Reverse sort not supported
4973
4875
        }
4974
 
        select->quick=tmp;
 
4876
        select->quick= tmp;
4975
4877
      }
4976
4878
    }
4977
4879
    else if (tab->type != AM_NEXT &&
5464
5366
    if (!count || count > fields.elements)
5465
5367
    {
5466
5368
      my_error(ER_BAD_FIELD_ERROR, MYF(0),
5467
 
               order_item->full_name(), session->where);
 
5369
               order_item->full_name(), session->where());
5468
5370
      return true;
5469
5371
    }
5470
5372
    order->item= ref_pointer_array + count - 1;
5541
5443
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_NON_UNIQ_ERROR,
5542
5444
                          ER(ER_NON_UNIQ_ERROR),
5543
5445
                          ((Item_ident*) order_item)->field_name,
5544
 
                          session->where);
 
5446
                          session->where());
5545
5447
    }
5546
5448
  }
5547
5449
 
5583
5485
                List<Item> &all_fields,
5584
5486
                Order *order)
5585
5487
{
5586
 
  session->where="order clause";
 
5488
  session->setWhere("order clause");
5587
5489
  for (; order; order=order->next)
5588
5490
  {
5589
5491
    if (find_order_in_list(session, ref_pointer_array, tables, order, fields,
5634
5536
 
5635
5537
  uint32_t org_fields=all_fields.elements;
5636
5538
 
5637
 
  session->where="group statement";
 
5539
  session->setWhere("group statement");
5638
5540
  for (ord= order; ord; ord= ord->next)
5639
5541
  {
5640
5542
    if (find_order_in_list(session, ref_pointer_array, tables, ord, fields,
5667
5569
    Item *item;
5668
5570
    Item_field *field;
5669
5571
    int cur_pos_in_select_list= 0;
5670
 
    List_iterator<Item> li(fields);
5671
 
    List_iterator<Item_field> naf_it(session->lex->current_select->non_agg_fields);
 
5572
    List<Item>::iterator li(fields.begin());
 
5573
    List<Item_field>::iterator naf_it(session->getLex()->current_select->non_agg_fields.begin());
5672
5574
 
5673
5575
    field= naf_it++;
5674
5576
    while (field && (item=li++))
5694
5596
            if ((*ord->item)->eq((Item*)field, 0))
5695
5597
              goto next_field;
5696
5598
          /*
5697
 
            TODO: change ER_WRONG_FIELD_WITH_GROUP to more detailed
5698
 
            ER_NON_GROUPING_FIELD_USED
 
5599
            @todo change ER_WRONG_FIELD_WITH_GROUP to more detailed ER_NON_GROUPING_FIELD_USED
5699
5600
          */
5700
5601
          my_error(ER_WRONG_FIELD_WITH_GROUP, MYF(0), field->full_name());
5701
5602
          return 1;
5724
5625
                                List<Item> &,
5725
5626
                                bool *all_order_by_fields_used)
5726
5627
{
5727
 
  List_iterator<Item> li(fields);
 
5628
  List<Item>::iterator li(fields.begin());
5728
5629
  Item *item;
5729
5630
  Order *order,*group,**prev;
5730
5631
 
5737
5638
  {
5738
5639
    if (order->in_field_list)
5739
5640
    {
5740
 
      Order *ord=(Order*) session->memdup((char*) order,sizeof(Order));
 
5641
      Order *ord=(Order*) session->getMemRoot()->duplicate((char*) order,sizeof(Order));
5741
5642
      if (!ord)
5742
5643
        return 0;
5743
5644
      *prev=ord;
5748
5649
      *all_order_by_fields_used= 0;
5749
5650
  }
5750
5651
 
5751
 
  li.rewind();
 
5652
  li= fields.begin();
5752
5653
  while ((item=li++))
5753
5654
  {
5754
5655
    if (!item->const_item() && !item->with_sum_func && !item->marker)
5788
5689
*/
5789
5690
void count_field_types(Select_Lex *select_lex, Tmp_Table_Param *param, List<Item> &fields, bool reset_with_sum_func)
5790
5691
{
5791
 
  List_iterator<Item> li(fields);
 
5692
  List<Item>::iterator li(fields.begin());
5792
5693
  Item *field;
5793
5694
 
5794
5695
  param->field_count=param->sum_func_count=param->func_count=
5845
5746
*/
5846
5747
int test_if_item_cache_changed(List<Cached_item> &list)
5847
5748
{
5848
 
  List_iterator<Cached_item> li(list);
 
5749
  List<Cached_item>::iterator li(list.begin());
5849
5750
  int idx= -1,i;
5850
5751
  Cached_item *buff;
5851
5752
 
5894
5795
                       List<Item> &all_fields)
5895
5796
{
5896
5797
  Item *pos;
5897
 
  List_iterator_fast<Item> li(all_fields);
 
5798
  List<Item>::iterator li(all_fields.begin());
5898
5799
  CopyField *copy= NULL;
5899
 
  res_selected_fields.empty();
5900
 
  res_all_fields.empty();
5901
 
  List_iterator_fast<Item> itr(res_all_fields);
 
5800
  res_selected_fields.clear();
 
5801
  res_all_fields.clear();
 
5802
  List<Item>::iterator itr(res_all_fields.begin());
5902
5803
  List<Item> extra_funcs;
5903
5804
  uint32_t i, border= all_fields.elements - elements;
5904
5805
 
5906
5807
      !(copy=param->copy_field= new CopyField[param->field_count]))
5907
5808
    goto err2;
5908
5809
 
5909
 
  param->copy_funcs.empty();
 
5810
  param->copy_funcs.clear();
5910
5811
  for (i= 0; (pos= li++); i++)
5911
5812
  {
5912
5813
    Field *field;
5975
5876
             !real_pos->with_sum_func)
5976
5877
    {                                           // Save for send fields
5977
5878
      pos= real_pos;
5978
 
      /* TODO:
5979
 
        In most cases this result will be sent to the user.
 
5879
      /* 
 
5880
        @todo In most cases this result will be sent to the user.
5980
5881
        This should be changed to use copy_int or copy_real depending
5981
5882
        on how the value is to be used: In some cases this may be an
5982
5883
        argument in a group function, like: IF(ISNULL(col),0,COUNT(*))
6030
5931
  for (; ptr != end; ptr++)
6031
5932
    (*ptr->do_copy)(ptr);
6032
5933
 
6033
 
  List_iterator_fast<Item> it(param->copy_funcs);
 
5934
  List<Item>::iterator it(param->copy_funcs.begin());
6034
5935
  Item_copy_string *item;
6035
5936
  while ((item = (Item_copy_string*) it++))
6036
5937
    item->copy();
6059
5960
                                                uint32_t elements,
6060
5961
                              List<Item> &all_fields)
6061
5962
{
6062
 
  List_iterator_fast<Item> it(all_fields);
 
5963
  List<Item>::iterator it(all_fields.begin());
6063
5964
  Item *item_field,*item;
6064
5965
 
6065
 
  res_selected_fields.empty();
6066
 
  res_all_fields.empty();
 
5966
  res_selected_fields.clear();
 
5967
  res_all_fields.clear();
6067
5968
 
6068
5969
  uint32_t i, border= all_fields.elements - elements;
6069
5970
  for (i= 0; (item= it++); i++)
6108
6009
      item_field;
6109
6010
  }
6110
6011
 
6111
 
  List_iterator_fast<Item> itr(res_all_fields);
 
6012
  List<Item>::iterator itr(res_all_fields.begin());
6112
6013
  for (i= 0; i < border; i++)
6113
6014
    itr++;
6114
6015
  itr.sublist(res_selected_fields, elements);
6138
6039
                               uint32_t elements,
6139
6040
                                                 List<Item> &all_fields)
6140
6041
{
6141
 
  List_iterator_fast<Item> it(all_fields);
 
6042
  List<Item>::iterator it(all_fields.begin());
6142
6043
  Item *item, *new_item;
6143
 
  res_selected_fields.empty();
6144
 
  res_all_fields.empty();
 
6044
  res_selected_fields.clear();
 
6045
  res_all_fields.clear();
6145
6046
 
6146
6047
  uint32_t i, border= all_fields.elements - elements;
6147
6048
  for (i= 0; (item= it++); i++)
6151
6052
      new_item;
6152
6053
  }
6153
6054
 
6154
 
  List_iterator_fast<Item> itr(res_all_fields);
 
6055
  List<Item>::iterator itr(res_all_fields.begin());
6155
6056
  for (i= 0; i < border; i++)
6156
6057
    itr++;
6157
6058
  itr.sublist(res_selected_fields, elements);
6243
6144
    /*
6244
6145
      Need to check the THD error state because Item::val_xxx() don't
6245
6146
      return error code, but can generate errors
6246
 
      TODO: change it for a real status check when Item::val_xxx()
 
6147
      @todo change it for a real status check when Item::val_xxx()
6247
6148
      are extended to return status code.
6248
6149
    */
6249
6150
    if (session->is_error())
6301
6202
  @param changed        out:  returns 1 if item contains a replaced field item
6302
6203
 
6303
6204
  @todo
6304
 
    - TODO: Some functions are not null-preserving. For those functions
 
6205
    - @todo Some functions are not null-preserving. For those functions
6305
6206
    updating of the maybe_null attribute is an overkill.
6306
6207
 
6307
6208
  @retval
6313
6214
{
6314
6215
  if (expr->arg_count)
6315
6216
  {
6316
 
    Name_resolution_context *context= &session->lex->current_select->context;
 
6217
    Name_resolution_context *context= &session->getLex()->current_select->context;
6317
6218
    Item **arg,**arg_end;
6318
6219
    bool arg_changed= false;
6319
6220
    for (arg= expr->arguments(),
6391
6292
                List<TableList> *tables, enum_query_type)
6392
6293
{
6393
6294
  /* List is reversed => we should reverse it before using */
6394
 
  List_iterator_fast<TableList> ti(*tables);
6395
 
  TableList **table= (TableList **)session->alloc(sizeof(TableList*) *
 
6295
  List<TableList>::iterator ti(tables->begin());
 
6296
  TableList **table= (TableList **)session->getMemRoot()->allocate(sizeof(TableList*) *
6396
6297
                                                tables->elements);
6397
6298
  if (table == 0)
6398
6299
    return;  // out of memory
6428
6329
 
6429
6330
  //Item List
6430
6331
  bool first= 1;
6431
 
  List_iterator_fast<Item> it(item_list);
 
6332
  List<Item>::iterator it(item_list.begin());
6432
6333
  Item *item;
6433
6334
  while ((item= it++))
6434
6335
  {
6441
6342
 
6442
6343
  /*
6443
6344
    from clause
6444
 
    TODO: support USING/FORCE/IGNORE index
 
6345
    @todo support USING/FORCE/IGNORE index
6445
6346
  */
6446
6347
  if (table_list.elements)
6447
6348
  {