~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_select.cc

  • Committer: Brian Aker
  • Date: 2010-12-30 15:50:18 UTC
  • mto: This revision was merged to the branch mainline in revision 2041.
  • Revision ID: brian@tangent.org-20101230155018-bacjzhn8vfd57his
Update support since we support this syntax now.

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>
67
 
#include <drizzled/sql_lex.h>
68
 
#include <drizzled/session.h>
69
 
#include <drizzled/sort_field.h>
70
 
#include <drizzled/select_result.h>
 
32
#include "drizzled/sql_select.h" /* include join.h */
 
33
 
 
34
#include "drizzled/error.h"
 
35
#include "drizzled/gettext.h"
 
36
#include "drizzled/util/test.h"
 
37
#include "drizzled/name_resolution_context_state.h"
 
38
#include "drizzled/nested_join.h"
 
39
#include "drizzled/probes.h"
 
40
#include "drizzled/show.h"
 
41
#include "drizzled/item/cache.h"
 
42
#include "drizzled/item/cmpfunc.h"
 
43
#include "drizzled/item/copy_string.h"
 
44
#include "drizzled/item/uint.h"
 
45
#include "drizzled/cached_item.h"
 
46
#include "drizzled/sql_base.h"
 
47
#include "drizzled/field/blob.h"
 
48
#include "drizzled/check_stack_overrun.h"
 
49
#include "drizzled/lock.h"
 
50
#include "drizzled/item/outer_ref.h"
 
51
#include "drizzled/index_hint.h"
 
52
#include "drizzled/records.h"
 
53
#include "drizzled/internal/iocache.h"
 
54
#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"
71
66
 
72
67
using namespace std;
73
68
 
83
78
static Item* part_of_refkey(Table *form,Field *field);
84
79
static bool cmp_buffer_with_ref(JoinTable *tab);
85
80
static void change_cond_ref_to_const(Session *session,
86
 
                                     list<COND_CMP>& save_list,
 
81
                                     vector<COND_CMP>& save_list,
87
82
                                     Item *and_father,
88
83
                                     Item *cond,
89
84
                                     Item *field,
212
207
  bool res= false;
213
208
  bool direct_ref= false;
214
209
 
215
 
  List<Item_outer_ref>::iterator ref_it(select->inner_refs_list.begin());
 
210
  List_iterator<Item_outer_ref> ref_it(select->inner_refs_list);
216
211
  while ((ref= ref_it++))
217
212
  {
218
213
    Item *item= ref->outer_ref;
219
214
    Item **item_ref= ref->ref;
220
215
    Item_ref *new_ref;
221
216
    /*
222
 
      @todo this field item already might be present in the select list.
 
217
      TODO: this field item already might be present in the select list.
223
218
      In this case instead of adding new field item we could use an
224
219
      existing one. The change will lead to less operations for copying fields,
225
220
      smaller temporary tables and less data passed through filesort.
425
420
    goto err; // 1
426
421
  }
427
422
 
428
 
  if (session->getLex()->describe & DESCRIBE_EXTENDED)
 
423
  if (session->lex->describe & DESCRIBE_EXTENDED)
429
424
  {
430
425
    join->conds_history= join->conds;
431
426
    join->having_history= (join->having?join->having:join->tmp_having);
436
431
 
437
432
  join->exec();
438
433
 
439
 
  if (session->getLex()->describe & DESCRIBE_EXTENDED)
 
434
  if (session->lex->describe & DESCRIBE_EXTENDED)
440
435
  {
441
436
    select_lex->where= join->conds_history;
442
437
    select_lex->having= join->having_history;
575
570
    substitutions.
576
571
  */
577
572
  sz= sizeof(optimizer::KeyField) *
578
 
      (((session->getLex()->current_select->cond_count+1)*2 +
579
 
        session->getLex()->current_select->between_count)*m+1);
580
 
  if (! (key_fields= (optimizer::KeyField*) session->getMemRoot()->allocate(sz)))
 
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)))
581
576
    return true;
582
577
  and_level= 0;
583
578
  field= end= key_fields;
618
613
 
619
614
  /* Process ON conditions for the nested joins */
620
615
  {
621
 
    List<TableList>::iterator li(join_tab->join->join_list->begin());
 
616
    List_iterator<TableList> li(*join_tab->join->join_list);
622
617
    TableList *table;
623
618
    while ((table= li++))
624
619
    {
752
747
void add_group_and_distinct_keys(Join *join, JoinTable *join_tab)
753
748
{
754
749
  List<Item_field> indexed_fields;
755
 
  List<Item_field>::iterator indexed_fields_it(indexed_fields.begin());
 
750
  List_iterator<Item_field> indexed_fields_it(indexed_fields);
756
751
  Order      *cur_group;
757
752
  Item_field *cur_item;
758
753
  key_map possible_keys(0);
766
761
  else if (join->select_distinct)
767
762
  { /* Collect all query fields referenced in the SELECT clause. */
768
763
    List<Item> &select_items= join->fields_list;
769
 
    List<Item>::iterator select_items_it(select_items.begin());
 
764
    List_iterator<Item> select_items_it(select_items);
770
765
    Item *item;
771
766
    while ((item= select_items_it++))
772
767
      item->walk(&Item::collect_item_field_processor, 0,
1009
1004
  j->ref.key_length=length;
1010
1005
  j->ref.key=(int) key;
1011
1006
  if (!(j->ref.key_buff= (unsigned char*) session->calloc(ALIGN_SIZE(length)*2)) ||
1012
 
      !(j->ref.key_copy= (StoredKey**) session->getMemRoot()->allocate((sizeof(StoredKey*) *
 
1007
      !(j->ref.key_copy= (StoredKey**) session->alloc((sizeof(StoredKey*) *
1013
1008
               (keyparts+1)))) ||
1014
 
      !(j->ref.items=    (Item**) session->getMemRoot()->allocate(sizeof(Item*)*keyparts)) ||
1015
 
      !(j->ref.cond_guards= (bool**) session->getMemRoot()->allocate(sizeof(uint*)*keyparts)))
 
1009
      !(j->ref.items=    (Item**) session->alloc(sizeof(Item*)*keyparts)) ||
 
1010
      !(j->ref.cond_guards= (bool**) session->alloc(sizeof(uint*)*keyparts)))
1016
1011
  {
1017
1012
    return(true);
1018
1013
  }
1221
1216
*/
1222
1217
void JoinTable::cleanup()
1223
1218
{
1224
 
  safe_delete(select);
1225
 
  safe_delete(quick);
1226
 
 
 
1219
  delete select;
 
1220
  select= 0;
 
1221
  delete quick;
 
1222
  quick= 0;
1227
1223
  if (cache.buff)
1228
1224
  {
1229
1225
    size_t size= cache.end - cache.buff;
1352
1348
  bool in_upper_level= false;
1353
1349
  while (cond_equal)
1354
1350
  {
1355
 
    List<Item_equal>::iterator li(cond_equal->current_level.begin());
 
1351
    List_iterator_fast<Item_equal> li(cond_equal->current_level);
1356
1352
    while ((item= li++))
1357
1353
    {
1358
1354
      if (item->contains(field))
1517
1513
        /* Merge two multiple equalities forming a new one */
1518
1514
        left_item_equal->merge(right_item_equal);
1519
1515
        /* Remove the merged multiple equality from the list */
1520
 
        List<Item_equal>::iterator li(cond_equal->current_level.begin());
 
1516
        List_iterator<Item_equal> li(cond_equal->current_level);
1521
1517
        while ((li++) != right_item_equal) {};
1522
1518
        li.remove();
1523
1519
      }
1657
1653
                                       (Item_row *) right_item,
1658
1654
                                       cond_equal, eq_list);
1659
1655
      if (!is_converted)
1660
 
        session->getLex()->current_select->cond_count++;
 
1656
        session->lex->current_select->cond_count++;
1661
1657
    }
1662
1658
    else
1663
1659
    {
1664
1660
      is_converted= check_simple_equality(left_item, right_item, 0, cond_equal);
1665
 
      session->getLex()->current_select->cond_count++;
 
1661
      session->lex->current_select->cond_count++;
1666
1662
    }
1667
1663
 
1668
1664
    if (!is_converted)
1718
1714
    if (left_item->type() == Item::ROW_ITEM &&
1719
1715
        right_item->type() == Item::ROW_ITEM)
1720
1716
    {
1721
 
      session->getLex()->current_select->cond_count--;
 
1717
      session->lex->current_select->cond_count--;
1722
1718
      return check_row_equality(session,
1723
1719
                                (Item_row *) left_item,
1724
1720
                                (Item_row *) right_item,
1749
1745
    just an argument of a comparison predicate.
1750
1746
    The function also determines the maximum number of members in
1751
1747
    equality lists of each Item_cond_and object assigning it to
1752
 
    session->getLex()->current_select->max_equal_elems.
 
1748
    session->lex->current_select->max_equal_elems.
1753
1749
 
1754
1750
  @note
1755
1751
    Multiple equality predicate =(f1,..fn) is equivalent to the conjuction of
1806
1802
      Item_func::COND_AND_FUNC;
1807
1803
    List<Item> *args= ((Item_cond*) cond)->argument_list();
1808
1804
 
1809
 
    List<Item>::iterator li(args->begin());
 
1805
    List_iterator<Item> li(*args);
1810
1806
    Item *item;
1811
1807
 
1812
1808
    if (and_level)
1828
1824
          li.remove();
1829
1825
      }
1830
1826
 
1831
 
      List<Item_equal>::iterator it(cond_equal.current_level.begin());
 
1827
      List_iterator_fast<Item_equal> it(cond_equal.current_level);
1832
1828
      while ((item_equal= it++))
1833
1829
      {
1834
1830
        item_equal->fix_length_and_dec();
1835
1831
        item_equal->update_used_tables();
1836
 
        set_if_bigger(session->getLex()->current_select->max_equal_elems,
 
1832
        set_if_bigger(session->lex->current_select->max_equal_elems,
1837
1833
                      item_equal->members());
1838
1834
      }
1839
1835
 
1844
1840
       Make replacement of equality predicates for lower levels
1845
1841
       of the condition expression.
1846
1842
    */
1847
 
    li= args->begin();
 
1843
    li.rewind();
1848
1844
    while ((item= li++))
1849
1845
    {
1850
1846
      Item *new_item;
1892
1888
        }
1893
1889
        else
1894
1890
          item_equal= (Item_equal *) eq_list.pop();
1895
 
        set_if_bigger(session->getLex()->current_select->max_equal_elems,
 
1891
        set_if_bigger(session->lex->current_select->max_equal_elems,
1896
1892
                      item_equal->members());
1897
1893
        return item_equal;
1898
1894
      }
1905
1901
        Item_cond_and *and_cond= new Item_cond_and(eq_list);
1906
1902
        and_cond->quick_fix_field();
1907
1903
        List<Item> *args= and_cond->argument_list();
1908
 
        List<Item_equal>::iterator it(cond_equal.current_level.begin());
 
1904
        List_iterator_fast<Item_equal> it(cond_equal.current_level);
1909
1905
        while ((item_equal= it++))
1910
1906
        {
1911
1907
          item_equal->fix_length_and_dec();
1912
1908
          item_equal->update_used_tables();
1913
 
          set_if_bigger(session->getLex()->current_select->max_equal_elems,
 
1909
          set_if_bigger(session->lex->current_select->max_equal_elems,
1914
1910
                        item_equal->members());
1915
1911
        }
1916
1912
        and_cond->cond_equal= cond_equal;
2031
2027
  if (join_list)
2032
2028
  {
2033
2029
    TableList *table;
2034
 
    List<TableList>::iterator li(join_list->begin());
 
2030
    List_iterator<TableList> li(*join_list);
2035
2031
 
2036
2032
    while ((table= li++))
2037
2033
    {
2246
2242
      cond_equal= &((Item_cond_and *) cond)->cond_equal;
2247
2243
      cond_list->disjoin((List<Item> *) &cond_equal->current_level);
2248
2244
 
2249
 
      List<Item_equal>::iterator it(cond_equal->current_level.begin());
 
2245
      List_iterator_fast<Item_equal> it(cond_equal->current_level);
2250
2246
      while ((item_equal= it++))
2251
2247
      {
2252
2248
        item_equal->sort(&compare_fields_by_table_order, table_join_idx);
2253
2249
      }
2254
2250
    }
2255
2251
 
2256
 
    List<Item>::iterator li(cond_list->begin());
 
2252
    List_iterator<Item> li(*cond_list);
2257
2253
    Item *item;
2258
2254
    while ((item= li++))
2259
2255
    {
2269
2265
 
2270
2266
    if (and_level)
2271
2267
    {
2272
 
      List<Item_equal>::iterator it(cond_equal->current_level.begin());
 
2268
      List_iterator_fast<Item_equal> it(cond_equal->current_level);
2273
2269
      while ((item_equal= it++))
2274
2270
      {
2275
2271
        cond= eliminate_item_equal(cond, cond_equal->upper_levels, item_equal);
2311
2307
  @param cond       condition whose multiple equalities are to be checked
2312
2308
  @param table      constant table that has been read
2313
2309
*/
2314
 
void update_const_equal_items(COND *cond, JoinTable *tab)
 
2310
static void update_const_equal_items(COND *cond, JoinTable *tab)
2315
2311
{
2316
2312
  if (!(cond->used_tables() & tab->table->map))
2317
2313
    return;
2319
2315
  if (cond->type() == Item::COND_ITEM)
2320
2316
  {
2321
2317
    List<Item> *cond_list= ((Item_cond*) cond)->argument_list();
2322
 
    List<Item>::iterator li(cond_list->begin());
 
2318
    List_iterator_fast<Item> li(*cond_list);
2323
2319
    Item *item;
2324
2320
    while ((item= li++))
2325
2321
      update_const_equal_items(item, tab);
2368
2364
  and_level
2369
2365
*/
2370
2366
static void change_cond_ref_to_const(Session *session,
2371
 
                                     list<COND_CMP>& save_list,
 
2367
                                     vector<COND_CMP>& save_list,
2372
2368
                                     Item *and_father,
2373
2369
                                     Item *cond,
2374
2370
                                     Item *field,
2377
2373
  if (cond->type() == Item::COND_ITEM)
2378
2374
  {
2379
2375
    bool and_level= ((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC;
2380
 
    List<Item>::iterator li(((Item_cond*) cond)->argument_list()->begin());
 
2376
    List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
2381
2377
    Item *item;
2382
2378
    while ((item=li++))
2383
2379
      change_cond_ref_to_const(session, save_list, and_level ? cond : item, item, field, value);
2457
2453
  if (conds->type() == Item::COND_ITEM)
2458
2454
  {
2459
2455
    Item_cond *cnd= (Item_cond*) conds;
2460
 
    List<Item>::iterator li(cnd->argument_list()->begin());
 
2456
    List_iterator<Item> li(*(cnd->argument_list()));
2461
2457
    Item *item;
2462
2458
    while ((item= li++))
2463
2459
    {
2474
2470
}
2475
2471
 
2476
2472
static void propagate_cond_constants(Session *session, 
2477
 
                                     list<COND_CMP>& save_list, 
 
2473
                                     vector<COND_CMP>& save_list, 
2478
2474
                                     COND *and_father, 
2479
2475
                                     COND *cond)
2480
2476
{
2481
2477
  if (cond->type() == Item::COND_ITEM)
2482
2478
  {
2483
2479
    bool and_level= ((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC;
2484
 
    List<Item>::iterator li(((Item_cond*) cond)->argument_list()->begin());
 
2480
    List_iterator_fast<Item> li(*((Item_cond*) cond)->argument_list());
2485
2481
    Item *item;
2486
 
    list<COND_CMP> save;
 
2482
    vector<COND_CMP> save;
2487
2483
    while ((item=li++))
2488
2484
    {
2489
2485
      propagate_cond_constants(session, save, and_level ? cond : item, item);
2491
2487
    if (and_level)
2492
2488
    {
2493
2489
      // Handle other found items
2494
 
      for (list<COND_CMP>::iterator iter= save.begin(); iter != save.end(); ++iter)
 
2490
      for (vector<COND_CMP>::iterator iter= save.begin(); iter != save.end(); ++iter)
2495
2491
      {
2496
 
        Item **args= iter->second->arguments();
 
2492
        Item **args= iter->cmp_func->arguments();
2497
2493
        if (not args[0]->const_item())
2498
2494
        {
2499
 
          change_cond_ref_to_const(session, save, iter->first,
2500
 
                                   iter->first, args[0], args[1] );
 
2495
          change_cond_ref_to_const(session, save_list, iter->and_level,
 
2496
                                   iter->and_level, args[0], args[1] );
2501
2497
        }
2502
2498
      }
2503
2499
    }
2610
2606
         position:
2611
2607
          1. join->cur_embedding_map - bitmap of pairs of brackets (aka nested
2612
2608
             joins) we've opened but didn't close.
2613
 
          2. {each NestedJoin class not simplified away}->counter - number
 
2609
          2. {each nested_join_st structure not simplified away}->counter - number
2614
2610
             of this nested join's children that have already been added to to
2615
2611
             the partial join order.
2616
2612
  @endverbatim
2688
2684
                             &join->cond_equal);
2689
2685
 
2690
2686
    /* change field = field to field = const for each found field = const */
2691
 
    list<COND_CMP> temp;
 
2687
    vector<COND_CMP> temp;
2692
2688
    propagate_cond_constants(session, temp, conds, conds);
2693
2689
    /*
2694
2690
      Remove all instances of item == item
2715
2711
  {
2716
2712
    bool and_level= (((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC);
2717
2713
 
2718
 
    List<Item>::iterator li(((Item_cond*) cond)->argument_list()->begin());
 
2714
    List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
2719
2715
    Item::cond_result tmp_cond_value;
2720
2716
    bool should_fix_fields= false;
2721
2717
 
2769
2765
    {                                           
2770
2766
      /* Argument list contains only one element, so reduce it so a single item, then remove list */
2771
2767
      item= ((Item_cond*) cond)->argument_list()->head();
2772
 
      ((Item_cond*) cond)->argument_list()->clear();
 
2768
      ((Item_cond*) cond)->argument_list()->empty();
2773
2769
      return item;
2774
2770
    }
2775
2771
  }
2847
2843
  }
2848
2844
  else if (cond->const_item() && !cond->is_expensive())
2849
2845
  /*
2850
 
    @todo
 
2846
    TODO:
2851
2847
    Excluding all expensive functions is too restritive we should exclude only
2852
2848
    materialized IN subquery predicates because they can't yet be evaluated
2853
2849
    here (they need additional initialization that is done later on).
2919
2915
  {
2920
2916
    bool and_level= (((Item_cond*) cond)->functype()
2921
2917
                     == Item_func::COND_AND_FUNC);
2922
 
    List<Item>::iterator li(((Item_cond*) cond)->argument_list()->begin());
 
2918
    List_iterator_fast<Item> li(*((Item_cond*) cond)->argument_list());
2923
2919
    Item *item;
2924
2920
    while ((item=li++))
2925
2921
    {
3057
3053
    table->emptyRecord();
3058
3054
    if (table->group && join->tmp_table_param.sum_func_count &&
3059
3055
        table->getShare()->sizeKeys() && !table->cursor->inited)
3060
 
    {
3061
 
      int tmp_error;
3062
 
      tmp_error= table->cursor->startIndexScan(0, 0);
3063
 
      if (tmp_error != 0)
3064
 
      {
3065
 
        table->print_error(tmp_error, MYF(0));
3066
 
        return -1;
3067
 
      }
3068
 
    }
 
3056
      table->cursor->startIndexScan(0, 0);
3069
3057
  }
3070
3058
  /* Set up select_end */
3071
3059
  Next_select_func end_select= setup_end_select_func(join);
3371
3359
  return 0;
3372
3360
}
3373
3361
 
 
3362
int join_read_const_table(JoinTable *tab, optimizer::Position *pos)
 
3363
{
 
3364
  int error;
 
3365
  Table *table=tab->table;
 
3366
  table->const_table=1;
 
3367
  table->null_row=0;
 
3368
  table->status=STATUS_NO_RECORD;
 
3369
 
 
3370
  if (tab->type == AM_SYSTEM)
 
3371
  {
 
3372
    if ((error=join_read_system(tab)))
 
3373
    {                                           // Info for DESCRIBE
 
3374
      tab->info="const row not found";
 
3375
      /* Mark for EXPLAIN that the row was not found */
 
3376
      pos->setFanout(0.0);
 
3377
      pos->clearRefDependMap();
 
3378
      if (! table->maybe_null || error > 0)
 
3379
        return(error);
 
3380
    }
 
3381
  }
 
3382
  else
 
3383
  {
 
3384
    if (! table->key_read && 
 
3385
        table->covering_keys.test(tab->ref.key) && 
 
3386
        ! table->no_keyread &&
 
3387
        (int) table->reginfo.lock_type <= (int) TL_READ_WITH_SHARED_LOCKS)
 
3388
    {
 
3389
      table->key_read=1;
 
3390
      table->cursor->extra(HA_EXTRA_KEYREAD);
 
3391
      tab->index= tab->ref.key;
 
3392
    }
 
3393
    error=join_read_const(tab);
 
3394
    if (table->key_read)
 
3395
    {
 
3396
      table->key_read=0;
 
3397
      table->cursor->extra(HA_EXTRA_NO_KEYREAD);
 
3398
    }
 
3399
    if (error)
 
3400
    {
 
3401
      tab->info="unique row not found";
 
3402
      /* Mark for EXPLAIN that the row was not found */
 
3403
      pos->setFanout(0.0);
 
3404
      pos->clearRefDependMap();
 
3405
      if (!table->maybe_null || error > 0)
 
3406
        return(error);
 
3407
    }
 
3408
  }
 
3409
  if (*tab->on_expr_ref && !table->null_row)
 
3410
  {
 
3411
    if ((table->null_row= test((*tab->on_expr_ref)->val_int() == 0)))
 
3412
      table->mark_as_null_row();
 
3413
  }
 
3414
  if (!table->null_row)
 
3415
    table->maybe_null=0;
 
3416
 
 
3417
  /* Check appearance of new constant items in Item_equal objects */
 
3418
  Join *join= tab->join;
 
3419
  if (join->conds)
 
3420
    update_const_equal_items(join->conds, tab);
 
3421
  TableList *tbl;
 
3422
  for (tbl= join->select_lex->leaf_tables; tbl; tbl= tbl->next_leaf)
 
3423
  {
 
3424
    TableList *embedded;
 
3425
    TableList *embedding= tbl;
 
3426
    do
 
3427
    {
 
3428
      embedded= embedding;
 
3429
      if (embedded->on_expr)
 
3430
         update_const_equal_items(embedded->on_expr, tab);
 
3431
      embedding= embedded->getEmbedding();
 
3432
    }
 
3433
    while (embedding &&
 
3434
           embedding->getNestedJoin()->join_list.head() == embedded);
 
3435
  }
 
3436
 
 
3437
  return(0);
 
3438
}
 
3439
 
 
3440
int join_read_system(JoinTable *tab)
 
3441
{
 
3442
  Table *table= tab->table;
 
3443
  int error;
 
3444
  if (table->status & STATUS_GARBAGE)           // If first read
 
3445
  {
 
3446
    if ((error=table->cursor->read_first_row(table->getInsertRecord(),
 
3447
                                           table->getShare()->getPrimaryKey())))
 
3448
    {
 
3449
      if (error != HA_ERR_END_OF_FILE)
 
3450
        return table->report_error(error);
 
3451
      tab->table->mark_as_null_row();
 
3452
      table->emptyRecord();                     // Make empty record
 
3453
      return -1;
 
3454
    }
 
3455
    table->storeRecord();
 
3456
  }
 
3457
  else if (!table->status)                      // Only happens with left join
 
3458
    table->restoreRecord();                     // restore old record
 
3459
  table->null_row=0;
 
3460
  return table->status ? -1 : 0;
 
3461
}
 
3462
 
3374
3463
/**
3375
3464
  Read a (constant) table when there is at most one matching row.
3376
3465
 
3442
3531
 
3443
3532
  if (!table->cursor->inited)
3444
3533
  {
3445
 
    error= table->cursor->startIndexScan(tab->ref.key, tab->sorted);
3446
 
    if (error != 0)
3447
 
    {
3448
 
      table->print_error(error, MYF(0));
3449
 
    }
 
3534
    table->cursor->startIndexScan(tab->ref.key, tab->sorted);
3450
3535
  }
3451
3536
 
3452
 
  /* @todo Why don't we do "Late NULLs Filtering" here? */
 
3537
  /* TODO: Why don't we do "Late NULLs Filtering" here? */
3453
3538
  if (cmp_buffer_with_ref(tab) ||
3454
3539
      (table->status & (STATUS_GARBAGE | STATUS_NO_PARENT | STATUS_NULL_ROW)))
3455
3540
  {
3494
3579
 
3495
3580
  /* Initialize the index first */
3496
3581
  if (!table->cursor->inited)
3497
 
  {
3498
 
    error= table->cursor->startIndexScan(tab->ref.key, tab->sorted);
3499
 
    if (error != 0)
3500
 
      return table->report_error(error);
3501
 
  }
 
3582
    table->cursor->startIndexScan(tab->ref.key, tab->sorted);
3502
3583
 
3503
3584
  /* Perform "Late NULLs Filtering" (see internals manual for explanations) */
3504
3585
  for (uint32_t i= 0 ; i < tab->ref.key_parts ; i++)
3532
3613
  Table *table= tab->table;
3533
3614
 
3534
3615
  if (!table->cursor->inited)
3535
 
  {
3536
 
    error= table->cursor->startIndexScan(tab->ref.key, tab->sorted);
3537
 
    if (error != 0)
3538
 
      return table->report_error(error);
3539
 
  }
 
3616
    table->cursor->startIndexScan(tab->ref.key, tab->sorted);
3540
3617
  if (cp_buffer_from_ref(tab->join->session, &tab->ref))
3541
3618
    return -1;
3542
3619
  if ((error=table->cursor->index_read_last_map(table->getInsertRecord(),
3640
3717
 
3641
3718
int test_if_quick_select(JoinTable *tab)
3642
3719
{
3643
 
  safe_delete(tab->select->quick);
3644
 
 
 
3720
  delete tab->select->quick;
 
3721
  tab->select->quick= 0;
3645
3722
  return tab->select->test_quick_select(tab->join->session, tab->keys,
3646
3723
                                        (table_map) 0, HA_POS_ERROR, 0, false);
3647
3724
}
3651
3728
  if (tab->select && tab->select->quick && tab->select->quick->reset())
3652
3729
    return 1;
3653
3730
 
3654
 
  if (tab->read_record.init_read_record(tab->join->session, tab->table, tab->select, 1, true))
3655
 
    return 1;
 
3731
  tab->read_record.init_read_record(tab->join->session, tab->table, tab->select, 1, true);
3656
3732
 
3657
3733
  return (*tab->read_record.read_record)(&tab->read_record);
3658
3734
}
3685
3761
  }
3686
3762
 
3687
3763
  if (!table->cursor->inited)
3688
 
  {
3689
 
    error= table->cursor->startIndexScan(tab->index, tab->sorted);
3690
 
    if (error != 0)
3691
 
    {
3692
 
      table->report_error(error);
3693
 
      return -1;
3694
 
    }
3695
 
  }
 
3764
    table->cursor->startIndexScan(tab->index, tab->sorted);
3696
3765
  if ((error=tab->table->cursor->index_first(tab->table->getInsertRecord())))
3697
3766
  {
3698
3767
    if (error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE)
3751
3820
  tab->read_record.index=tab->index;
3752
3821
  tab->read_record.record=table->getInsertRecord();
3753
3822
  if (!table->cursor->inited)
3754
 
  {
3755
 
    error= table->cursor->startIndexScan(tab->index, 1);
3756
 
    if (error != 0)
3757
 
      return table->report_error(error);
3758
 
  }
 
3823
    table->cursor->startIndexScan(tab->index, 1);
3759
3824
  if ((error= tab->table->cursor->index_last(tab->table->getInsertRecord())))
3760
3825
    return table->report_error(error);
3761
3826
 
3819
3884
        {
3820
3885
          if (!join->first_record)
3821
3886
          {
3822
 
                  List<Item>::iterator it(join->fields->begin());
 
3887
                  List_iterator_fast<Item> it(*join->fields);
3823
3888
                  Item *item;
3824
3889
            /* No matching rows for group function */
3825
3890
            join->clear();
3835
3900
              error=join->result->send_data(*join->fields) ? 1 : 0;
3836
3901
            join->send_records++;
3837
3902
          }
3838
 
          if (join->rollup.getState() != Rollup::STATE_NONE && error <= 0)
 
3903
          if (join->rollup.state != ROLLUP::STATE_NONE && error <= 0)
3839
3904
          {
3840
3905
            if (join->rollup_send_data((uint32_t) (idx+1)))
3841
3906
              error= 1;
3925
3990
            return NESTED_LOOP_ERROR;
3926
3991
          }
3927
3992
        }
3928
 
        if (join->rollup.getState() != Rollup::STATE_NONE)
 
3993
        if (join->rollup.state != ROLLUP::STATE_NONE)
3929
3994
        {
3930
3995
          if (join->rollup_write_data((uint32_t) (idx+1), table))
3931
3996
            return NESTED_LOOP_ERROR;
4058
4123
      Item_cond_and *new_cond=new Item_cond_and;
4059
4124
      if (!new_cond)
4060
4125
        return (COND*) 0;
4061
 
      List<Item>::iterator li(((Item_cond*) cond)->argument_list()->begin());
 
4126
      List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
4062
4127
      Item *item;
4063
4128
      while ((item=li++))
4064
4129
      {
4088
4153
      Item_cond_or *new_cond=new Item_cond_or;
4089
4154
      if (!new_cond)
4090
4155
        return (COND*) 0;
4091
 
      List<Item>::iterator li(((Item_cond*) cond)->argument_list()->begin());
 
4156
      List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
4092
4157
      Item *item;
4093
4158
      while ((item=li++))
4094
4159
      {
4440
4505
{
4441
4506
  List<Item> *fields= (List<Item> *) data;
4442
4507
  bool part_found= 0;
4443
 
  List<Item>::iterator li(fields->begin());
 
4508
  List_iterator<Item> li(*fields);
4444
4509
  Item *item;
4445
4510
 
4446
4511
  while ((item= li++))
4525
4590
    save_quick= select->quick;
4526
4591
    /*
4527
4592
      assume results are not ordered when index merge is used
4528
 
      @todo sergeyp: Results of all index merge selects actually are ordered
 
4593
      TODO: sergeyp: Results of all index merge selects actually are ordered
4529
4594
      by clustered PK values.
4530
4595
    */
4531
4596
 
4800
4865
          tab->type= AM_NEXT;           // Read with index_first(), index_next()
4801
4866
          if (select && select->quick)
4802
4867
          {
4803
 
            safe_delete(select->quick);
 
4868
            delete select->quick;
 
4869
            select->quick= 0;
4804
4870
          }
4805
4871
          if (table->covering_keys.test(best_key))
4806
4872
          {
4873
4939
          tab->limit= 0;
4874
4940
          return 0; // Reverse sort not supported
4875
4941
        }
4876
 
        select->quick= tmp;
 
4942
        select->quick=tmp;
4877
4943
      }
4878
4944
    }
4879
4945
    else if (tab->type != AM_NEXT &&
5033
5099
  org_record=(char*) (record=table->getInsertRecord())+offset;
5034
5100
  new_record=(char*) table->getUpdateRecord()+offset;
5035
5101
 
5036
 
  if ((error= cursor->startTableScan(1)))
5037
 
    goto err;
5038
 
 
 
5102
  cursor->startTableScan(1);
5039
5103
  error=cursor->rnd_next(record);
5040
5104
  for (;;)
5041
5105
  {
5152
5216
    return(1);
5153
5217
  }
5154
5218
 
5155
 
  if ((error= cursor->startTableScan(1)))
5156
 
    goto err;
5157
 
 
 
5219
  cursor->startTableScan(1);
5158
5220
  key_pos= &key_buffer[0];
5159
5221
  for (;;)
5160
5222
  {
5366
5428
    if (!count || count > fields.elements)
5367
5429
    {
5368
5430
      my_error(ER_BAD_FIELD_ERROR, MYF(0),
5369
 
               order_item->full_name(), session->where());
 
5431
               order_item->full_name(), session->where);
5370
5432
      return true;
5371
5433
    }
5372
5434
    order->item= ref_pointer_array + count - 1;
5443
5505
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_NON_UNIQ_ERROR,
5444
5506
                          ER(ER_NON_UNIQ_ERROR),
5445
5507
                          ((Item_ident*) order_item)->field_name,
5446
 
                          session->where());
 
5508
                          session->where);
5447
5509
    }
5448
5510
  }
5449
5511
 
5485
5547
                List<Item> &all_fields,
5486
5548
                Order *order)
5487
5549
{
5488
 
  session->setWhere("order clause");
 
5550
  session->where="order clause";
5489
5551
  for (; order; order=order->next)
5490
5552
  {
5491
5553
    if (find_order_in_list(session, ref_pointer_array, tables, order, fields,
5536
5598
 
5537
5599
  uint32_t org_fields=all_fields.elements;
5538
5600
 
5539
 
  session->setWhere("group statement");
 
5601
  session->where="group statement";
5540
5602
  for (ord= order; ord; ord= ord->next)
5541
5603
  {
5542
5604
    if (find_order_in_list(session, ref_pointer_array, tables, ord, fields,
5569
5631
    Item *item;
5570
5632
    Item_field *field;
5571
5633
    int cur_pos_in_select_list= 0;
5572
 
    List<Item>::iterator li(fields.begin());
5573
 
    List<Item_field>::iterator naf_it(session->getLex()->current_select->non_agg_fields.begin());
 
5634
    List_iterator<Item> li(fields);
 
5635
    List_iterator<Item_field> naf_it(session->lex->current_select->non_agg_fields);
5574
5636
 
5575
5637
    field= naf_it++;
5576
5638
    while (field && (item=li++))
5596
5658
            if ((*ord->item)->eq((Item*)field, 0))
5597
5659
              goto next_field;
5598
5660
          /*
5599
 
            @todo change ER_WRONG_FIELD_WITH_GROUP to more detailed ER_NON_GROUPING_FIELD_USED
 
5661
            TODO: change ER_WRONG_FIELD_WITH_GROUP to more detailed
 
5662
            ER_NON_GROUPING_FIELD_USED
5600
5663
          */
5601
5664
          my_error(ER_WRONG_FIELD_WITH_GROUP, MYF(0), field->full_name());
5602
5665
          return 1;
5625
5688
                                List<Item> &,
5626
5689
                                bool *all_order_by_fields_used)
5627
5690
{
5628
 
  List<Item>::iterator li(fields.begin());
 
5691
  List_iterator<Item> li(fields);
5629
5692
  Item *item;
5630
5693
  Order *order,*group,**prev;
5631
5694
 
5638
5701
  {
5639
5702
    if (order->in_field_list)
5640
5703
    {
5641
 
      Order *ord=(Order*) session->getMemRoot()->duplicate((char*) order,sizeof(Order));
 
5704
      Order *ord=(Order*) session->memdup((char*) order,sizeof(Order));
5642
5705
      if (!ord)
5643
5706
        return 0;
5644
5707
      *prev=ord;
5649
5712
      *all_order_by_fields_used= 0;
5650
5713
  }
5651
5714
 
5652
 
  li= fields.begin();
 
5715
  li.rewind();
5653
5716
  while ((item=li++))
5654
5717
  {
5655
5718
    if (!item->const_item() && !item->with_sum_func && !item->marker)
5689
5752
*/
5690
5753
void count_field_types(Select_Lex *select_lex, Tmp_Table_Param *param, List<Item> &fields, bool reset_with_sum_func)
5691
5754
{
5692
 
  List<Item>::iterator li(fields.begin());
 
5755
  List_iterator<Item> li(fields);
5693
5756
  Item *field;
5694
5757
 
5695
5758
  param->field_count=param->sum_func_count=param->func_count=
5746
5809
*/
5747
5810
int test_if_item_cache_changed(List<Cached_item> &list)
5748
5811
{
5749
 
  List<Cached_item>::iterator li(list.begin());
 
5812
  List_iterator<Cached_item> li(list);
5750
5813
  int idx= -1,i;
5751
5814
  Cached_item *buff;
5752
5815
 
5795
5858
                       List<Item> &all_fields)
5796
5859
{
5797
5860
  Item *pos;
5798
 
  List<Item>::iterator li(all_fields.begin());
 
5861
  List_iterator_fast<Item> li(all_fields);
5799
5862
  CopyField *copy= NULL;
5800
 
  res_selected_fields.clear();
5801
 
  res_all_fields.clear();
5802
 
  List<Item>::iterator itr(res_all_fields.begin());
 
5863
  res_selected_fields.empty();
 
5864
  res_all_fields.empty();
 
5865
  List_iterator_fast<Item> itr(res_all_fields);
5803
5866
  List<Item> extra_funcs;
5804
5867
  uint32_t i, border= all_fields.elements - elements;
5805
5868
 
5807
5870
      !(copy=param->copy_field= new CopyField[param->field_count]))
5808
5871
    goto err2;
5809
5872
 
5810
 
  param->copy_funcs.clear();
 
5873
  param->copy_funcs.empty();
5811
5874
  for (i= 0; (pos= li++); i++)
5812
5875
  {
5813
5876
    Field *field;
5876
5939
             !real_pos->with_sum_func)
5877
5940
    {                                           // Save for send fields
5878
5941
      pos= real_pos;
5879
 
      /* 
5880
 
        @todo In most cases this result will be sent to the user.
 
5942
      /* TODO:
 
5943
        In most cases this result will be sent to the user.
5881
5944
        This should be changed to use copy_int or copy_real depending
5882
5945
        on how the value is to be used: In some cases this may be an
5883
5946
        argument in a group function, like: IF(ISNULL(col),0,COUNT(*))
5931
5994
  for (; ptr != end; ptr++)
5932
5995
    (*ptr->do_copy)(ptr);
5933
5996
 
5934
 
  List<Item>::iterator it(param->copy_funcs.begin());
 
5997
  List_iterator_fast<Item> it(param->copy_funcs);
5935
5998
  Item_copy_string *item;
5936
5999
  while ((item = (Item_copy_string*) it++))
5937
6000
    item->copy();
5960
6023
                                                uint32_t elements,
5961
6024
                              List<Item> &all_fields)
5962
6025
{
5963
 
  List<Item>::iterator it(all_fields.begin());
 
6026
  List_iterator_fast<Item> it(all_fields);
5964
6027
  Item *item_field,*item;
5965
6028
 
5966
 
  res_selected_fields.clear();
5967
 
  res_all_fields.clear();
 
6029
  res_selected_fields.empty();
 
6030
  res_all_fields.empty();
5968
6031
 
5969
6032
  uint32_t i, border= all_fields.elements - elements;
5970
6033
  for (i= 0; (item= it++); i++)
6009
6072
      item_field;
6010
6073
  }
6011
6074
 
6012
 
  List<Item>::iterator itr(res_all_fields.begin());
 
6075
  List_iterator_fast<Item> itr(res_all_fields);
6013
6076
  for (i= 0; i < border; i++)
6014
6077
    itr++;
6015
6078
  itr.sublist(res_selected_fields, elements);
6039
6102
                               uint32_t elements,
6040
6103
                                                 List<Item> &all_fields)
6041
6104
{
6042
 
  List<Item>::iterator it(all_fields.begin());
 
6105
  List_iterator_fast<Item> it(all_fields);
6043
6106
  Item *item, *new_item;
6044
 
  res_selected_fields.clear();
6045
 
  res_all_fields.clear();
 
6107
  res_selected_fields.empty();
 
6108
  res_all_fields.empty();
6046
6109
 
6047
6110
  uint32_t i, border= all_fields.elements - elements;
6048
6111
  for (i= 0; (item= it++); i++)
6052
6115
      new_item;
6053
6116
  }
6054
6117
 
6055
 
  List<Item>::iterator itr(res_all_fields.begin());
 
6118
  List_iterator_fast<Item> itr(res_all_fields);
6056
6119
  for (i= 0; i < border; i++)
6057
6120
    itr++;
6058
6121
  itr.sublist(res_selected_fields, elements);
6144
6207
    /*
6145
6208
      Need to check the THD error state because Item::val_xxx() don't
6146
6209
      return error code, but can generate errors
6147
 
      @todo change it for a real status check when Item::val_xxx()
 
6210
      TODO: change it for a real status check when Item::val_xxx()
6148
6211
      are extended to return status code.
6149
6212
    */
6150
6213
    if (session->is_error())
6202
6265
  @param changed        out:  returns 1 if item contains a replaced field item
6203
6266
 
6204
6267
  @todo
6205
 
    - @todo Some functions are not null-preserving. For those functions
 
6268
    - TODO: Some functions are not null-preserving. For those functions
6206
6269
    updating of the maybe_null attribute is an overkill.
6207
6270
 
6208
6271
  @retval
6214
6277
{
6215
6278
  if (expr->arg_count)
6216
6279
  {
6217
 
    Name_resolution_context *context= &session->getLex()->current_select->context;
 
6280
    Name_resolution_context *context= &session->lex->current_select->context;
6218
6281
    Item **arg,**arg_end;
6219
6282
    bool arg_changed= false;
6220
6283
    for (arg= expr->arguments(),
6292
6355
                List<TableList> *tables, enum_query_type)
6293
6356
{
6294
6357
  /* List is reversed => we should reverse it before using */
6295
 
  List<TableList>::iterator ti(tables->begin());
6296
 
  TableList **table= (TableList **)session->getMemRoot()->allocate(sizeof(TableList*) *
 
6358
  List_iterator_fast<TableList> ti(*tables);
 
6359
  TableList **table= (TableList **)session->alloc(sizeof(TableList*) *
6297
6360
                                                tables->elements);
6298
6361
  if (table == 0)
6299
6362
    return;  // out of memory
6329
6392
 
6330
6393
  //Item List
6331
6394
  bool first= 1;
6332
 
  List<Item>::iterator it(item_list.begin());
 
6395
  List_iterator_fast<Item> it(item_list);
6333
6396
  Item *item;
6334
6397
  while ((item= it++))
6335
6398
  {
6342
6405
 
6343
6406
  /*
6344
6407
    from clause
6345
 
    @todo support USING/FORCE/IGNORE index
 
6408
    TODO: support USING/FORCE/IGNORE index
6346
6409
  */
6347
6410
  if (table_list.elements)
6348
6411
  {