~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_select.cc

  • Committer: Monty Taylor
  • Date: 2010-11-08 18:26:08 UTC
  • mto: This revision was merged to the branch mainline in revision 1931.
  • Revision ID: mordred@inaugust.com-20101108182608-lci86acl7r53sbi3
Replaced auto_ptr with scoped_ptr.

Show diffs side-by-side

added added

removed removed

Lines of Context:
17
17
  @file
18
18
 
19
19
  @brief
20
 
  select_query and join optimization
 
20
  mysql_select and join optimization
21
21
 
22
22
  @defgroup Query_Optimizer  Query Optimizer
23
23
  @{
24
24
*/
25
 
#include <config.h>
 
25
#include "config.h"
26
26
 
27
27
#include <string>
28
28
#include <iostream>
29
29
#include <algorithm>
30
30
#include <vector>
31
31
 
32
 
#include <drizzled/sql_select.h> /* include join.h */
33
 
 
34
 
#include <drizzled/error.h>
35
 
#include <drizzled/gettext.h>
36
 
#include <drizzled/util/test.h>
37
 
#include <drizzled/name_resolution_context_state.h>
38
 
#include <drizzled/nested_join.h>
39
 
#include <drizzled/probes.h>
40
 
#include <drizzled/show.h>
41
 
#include <drizzled/item/cache.h>
42
 
#include <drizzled/item/cmpfunc.h>
43
 
#include <drizzled/item/copy_string.h>
44
 
#include <drizzled/item/uint.h>
45
 
#include <drizzled/cached_item.h>
46
 
#include <drizzled/sql_base.h>
47
 
#include <drizzled/field/blob.h>
48
 
#include <drizzled/check_stack_overrun.h>
49
 
#include <drizzled/lock.h>
50
 
#include <drizzled/item/outer_ref.h>
51
 
#include <drizzled/index_hint.h>
52
 
#include <drizzled/records.h>
53
 
#include <drizzled/internal/iocache.h>
54
 
#include <drizzled/drizzled.h>
55
 
#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,
122
117
{
123
118
  bool res;
124
119
  register Select_Lex *select_lex= &lex->select_lex;
125
 
  DRIZZLE_SELECT_START(session->getQueryString()->c_str());
 
120
  DRIZZLE_SELECT_START(session->query.c_str());
126
121
 
127
122
  if (select_lex->master_unit()->is_union() ||
128
123
      select_lex->master_unit()->fake_select_lex)
136
131
    unit->set_limit(unit->global_parameters);
137
132
    session->session_marker= 0;
138
133
    /*
139
 
      'options' of select_query will be set in JOIN, as far as JOIN for
 
134
      'options' of mysql_select will be set in JOIN, as far as JOIN for
140
135
      every PS/SP execution new, we will not need reset this flag if
141
136
      setup_tables_done_option changed for next rexecution
142
137
    */
143
 
    res= select_query(session,
144
 
                      &select_lex->ref_pointer_array,
 
138
    res= mysql_select(session, &select_lex->ref_pointer_array,
145
139
                      (TableList*) select_lex->table_list.first,
146
 
                      select_lex->with_wild,
147
 
                      select_lex->item_list,
 
140
                      select_lex->with_wild, select_lex->item_list,
148
141
                      select_lex->where,
149
142
                      select_lex->order_list.elements +
150
143
                      select_lex->group_list.elements,
212
205
  bool res= false;
213
206
  bool direct_ref= false;
214
207
 
215
 
  List<Item_outer_ref>::iterator ref_it(select->inner_refs_list.begin());
 
208
  List_iterator<Item_outer_ref> ref_it(select->inner_refs_list);
216
209
  while ((ref= ref_it++))
217
210
  {
218
211
    Item *item= ref->outer_ref;
219
212
    Item **item_ref= ref->ref;
220
213
    Item_ref *new_ref;
221
214
    /*
222
 
      @todo this field item already might be present in the select list.
 
215
      TODO: this field item already might be present in the select list.
223
216
      In this case instead of adding new field item we could use an
224
217
      existing one. The change will lead to less operations for copying fields,
225
218
      smaller temporary tables and less data passed through filesort.
275
268
 
276
269
/*****************************************************************************
277
270
  Check fields, find best join, do the select and output fields.
278
 
  select_query assumes that all tables are already opened
 
271
  mysql_select assumes that all tables are already opened
279
272
*****************************************************************************/
280
273
 
281
274
/*
355
348
  @retval
356
349
    true   an error
357
350
*/
358
 
bool select_query(Session *session,
 
351
bool mysql_select(Session *session,
359
352
                  Item ***rref_pointer_array,
360
353
                  TableList *tables, 
361
354
                  uint32_t wild_num, 
425
418
    goto err; // 1
426
419
  }
427
420
 
428
 
  if (session->getLex()->describe & DESCRIBE_EXTENDED)
 
421
  if (session->lex->describe & DESCRIBE_EXTENDED)
429
422
  {
430
423
    join->conds_history= join->conds;
431
424
    join->having_history= (join->having?join->having:join->tmp_having);
436
429
 
437
430
  join->exec();
438
431
 
439
 
  if (session->getLex()->describe & DESCRIBE_EXTENDED)
 
432
  if (session->lex->describe & DESCRIBE_EXTENDED)
440
433
  {
441
434
    select_lex->where= join->conds_history;
442
435
    select_lex->having= join->having_history;
575
568
    substitutions.
576
569
  */
577
570
  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)))
 
571
      (((session->lex->current_select->cond_count+1)*2 +
 
572
        session->lex->current_select->between_count)*m+1);
 
573
  if (! (key_fields= (optimizer::KeyField*) session->alloc(sz)))
581
574
    return true;
582
575
  and_level= 0;
583
576
  field= end= key_fields;
618
611
 
619
612
  /* Process ON conditions for the nested joins */
620
613
  {
621
 
    List<TableList>::iterator li(join_tab->join->join_list->begin());
 
614
    List_iterator<TableList> li(*join_tab->join->join_list);
622
615
    TableList *table;
623
616
    while ((table= li++))
624
617
    {
752
745
void add_group_and_distinct_keys(Join *join, JoinTable *join_tab)
753
746
{
754
747
  List<Item_field> indexed_fields;
755
 
  List<Item_field>::iterator indexed_fields_it(indexed_fields.begin());
 
748
  List_iterator<Item_field> indexed_fields_it(indexed_fields);
756
749
  Order      *cur_group;
757
750
  Item_field *cur_item;
758
751
  key_map possible_keys(0);
766
759
  else if (join->select_distinct)
767
760
  { /* Collect all query fields referenced in the SELECT clause. */
768
761
    List<Item> &select_items= join->fields_list;
769
 
    List<Item>::iterator select_items_it(select_items.begin());
 
762
    List_iterator<Item> select_items_it(select_items);
770
763
    Item *item;
771
764
    while ((item= select_items_it++))
772
765
      item->walk(&Item::collect_item_field_processor, 0,
936
929
 
937
930
  /*
938
931
    we should restore old value of count_cuted_fields because
939
 
    store_val_in_field can be called from insert_query
 
932
    store_val_in_field can be called from mysql_insert
940
933
    with select_insert, which make count_cuted_fields= 1
941
934
   */
942
935
  enum_check_fields old_count_cuted_fields= session->count_cuted_fields;
1009
1002
  j->ref.key_length=length;
1010
1003
  j->ref.key=(int) key;
1011
1004
  if (!(j->ref.key_buff= (unsigned char*) session->calloc(ALIGN_SIZE(length)*2)) ||
1012
 
      !(j->ref.key_copy= (StoredKey**) session->getMemRoot()->allocate((sizeof(StoredKey*) *
 
1005
      !(j->ref.key_copy= (StoredKey**) session->alloc((sizeof(StoredKey*) *
1013
1006
               (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)))
 
1007
      !(j->ref.items=    (Item**) session->alloc(sizeof(Item*)*keyparts)) ||
 
1008
      !(j->ref.cond_guards= (bool**) session->alloc(sizeof(uint*)*keyparts)))
1016
1009
  {
1017
1010
    return(true);
1018
1011
  }
1221
1214
*/
1222
1215
void JoinTable::cleanup()
1223
1216
{
1224
 
  safe_delete(select);
1225
 
  safe_delete(quick);
1226
 
 
 
1217
  delete select;
 
1218
  select= 0;
 
1219
  delete quick;
 
1220
  quick= 0;
1227
1221
  if (cache.buff)
1228
1222
  {
1229
1223
    size_t size= cache.end - cache.buff;
1352
1346
  bool in_upper_level= false;
1353
1347
  while (cond_equal)
1354
1348
  {
1355
 
    List<Item_equal>::iterator li(cond_equal->current_level.begin());
 
1349
    List_iterator_fast<Item_equal> li(cond_equal->current_level);
1356
1350
    while ((item= li++))
1357
1351
    {
1358
1352
      if (item->contains(field))
1517
1511
        /* Merge two multiple equalities forming a new one */
1518
1512
        left_item_equal->merge(right_item_equal);
1519
1513
        /* Remove the merged multiple equality from the list */
1520
 
        List<Item_equal>::iterator li(cond_equal->current_level.begin());
 
1514
        List_iterator<Item_equal> li(cond_equal->current_level);
1521
1515
        while ((li++) != right_item_equal) {};
1522
1516
        li.remove();
1523
1517
      }
1657
1651
                                       (Item_row *) right_item,
1658
1652
                                       cond_equal, eq_list);
1659
1653
      if (!is_converted)
1660
 
        session->getLex()->current_select->cond_count++;
 
1654
        session->lex->current_select->cond_count++;
1661
1655
    }
1662
1656
    else
1663
1657
    {
1664
1658
      is_converted= check_simple_equality(left_item, right_item, 0, cond_equal);
1665
 
      session->getLex()->current_select->cond_count++;
 
1659
      session->lex->current_select->cond_count++;
1666
1660
    }
1667
1661
 
1668
1662
    if (!is_converted)
1718
1712
    if (left_item->type() == Item::ROW_ITEM &&
1719
1713
        right_item->type() == Item::ROW_ITEM)
1720
1714
    {
1721
 
      session->getLex()->current_select->cond_count--;
 
1715
      session->lex->current_select->cond_count--;
1722
1716
      return check_row_equality(session,
1723
1717
                                (Item_row *) left_item,
1724
1718
                                (Item_row *) right_item,
1749
1743
    just an argument of a comparison predicate.
1750
1744
    The function also determines the maximum number of members in
1751
1745
    equality lists of each Item_cond_and object assigning it to
1752
 
    session->getLex()->current_select->max_equal_elems.
 
1746
    session->lex->current_select->max_equal_elems.
1753
1747
 
1754
1748
  @note
1755
1749
    Multiple equality predicate =(f1,..fn) is equivalent to the conjuction of
1806
1800
      Item_func::COND_AND_FUNC;
1807
1801
    List<Item> *args= ((Item_cond*) cond)->argument_list();
1808
1802
 
1809
 
    List<Item>::iterator li(args->begin());
 
1803
    List_iterator<Item> li(*args);
1810
1804
    Item *item;
1811
1805
 
1812
1806
    if (and_level)
1828
1822
          li.remove();
1829
1823
      }
1830
1824
 
1831
 
      List<Item_equal>::iterator it(cond_equal.current_level.begin());
 
1825
      List_iterator_fast<Item_equal> it(cond_equal.current_level);
1832
1826
      while ((item_equal= it++))
1833
1827
      {
1834
1828
        item_equal->fix_length_and_dec();
1835
1829
        item_equal->update_used_tables();
1836
 
        set_if_bigger(session->getLex()->current_select->max_equal_elems,
 
1830
        set_if_bigger(session->lex->current_select->max_equal_elems,
1837
1831
                      item_equal->members());
1838
1832
      }
1839
1833
 
1844
1838
       Make replacement of equality predicates for lower levels
1845
1839
       of the condition expression.
1846
1840
    */
1847
 
    li= args->begin();
 
1841
    li.rewind();
1848
1842
    while ((item= li++))
1849
1843
    {
1850
1844
      Item *new_item;
1892
1886
        }
1893
1887
        else
1894
1888
          item_equal= (Item_equal *) eq_list.pop();
1895
 
        set_if_bigger(session->getLex()->current_select->max_equal_elems,
 
1889
        set_if_bigger(session->lex->current_select->max_equal_elems,
1896
1890
                      item_equal->members());
1897
1891
        return item_equal;
1898
1892
      }
1905
1899
        Item_cond_and *and_cond= new Item_cond_and(eq_list);
1906
1900
        and_cond->quick_fix_field();
1907
1901
        List<Item> *args= and_cond->argument_list();
1908
 
        List<Item_equal>::iterator it(cond_equal.current_level.begin());
 
1902
        List_iterator_fast<Item_equal> it(cond_equal.current_level);
1909
1903
        while ((item_equal= it++))
1910
1904
        {
1911
1905
          item_equal->fix_length_and_dec();
1912
1906
          item_equal->update_used_tables();
1913
 
          set_if_bigger(session->getLex()->current_select->max_equal_elems,
 
1907
          set_if_bigger(session->lex->current_select->max_equal_elems,
1914
1908
                        item_equal->members());
1915
1909
        }
1916
1910
        and_cond->cond_equal= cond_equal;
2031
2025
  if (join_list)
2032
2026
  {
2033
2027
    TableList *table;
2034
 
    List<TableList>::iterator li(join_list->begin());
 
2028
    List_iterator<TableList> li(*join_list);
2035
2029
 
2036
2030
    while ((table= li++))
2037
2031
    {
2246
2240
      cond_equal= &((Item_cond_and *) cond)->cond_equal;
2247
2241
      cond_list->disjoin((List<Item> *) &cond_equal->current_level);
2248
2242
 
2249
 
      List<Item_equal>::iterator it(cond_equal->current_level.begin());
 
2243
      List_iterator_fast<Item_equal> it(cond_equal->current_level);
2250
2244
      while ((item_equal= it++))
2251
2245
      {
2252
2246
        item_equal->sort(&compare_fields_by_table_order, table_join_idx);
2253
2247
      }
2254
2248
    }
2255
2249
 
2256
 
    List<Item>::iterator li(cond_list->begin());
 
2250
    List_iterator<Item> li(*cond_list);
2257
2251
    Item *item;
2258
2252
    while ((item= li++))
2259
2253
    {
2269
2263
 
2270
2264
    if (and_level)
2271
2265
    {
2272
 
      List<Item_equal>::iterator it(cond_equal->current_level.begin());
 
2266
      List_iterator_fast<Item_equal> it(cond_equal->current_level);
2273
2267
      while ((item_equal= it++))
2274
2268
      {
2275
2269
        cond= eliminate_item_equal(cond, cond_equal->upper_levels, item_equal);
2311
2305
  @param cond       condition whose multiple equalities are to be checked
2312
2306
  @param table      constant table that has been read
2313
2307
*/
2314
 
void update_const_equal_items(COND *cond, JoinTable *tab)
 
2308
static void update_const_equal_items(COND *cond, JoinTable *tab)
2315
2309
{
2316
2310
  if (!(cond->used_tables() & tab->table->map))
2317
2311
    return;
2319
2313
  if (cond->type() == Item::COND_ITEM)
2320
2314
  {
2321
2315
    List<Item> *cond_list= ((Item_cond*) cond)->argument_list();
2322
 
    List<Item>::iterator li(cond_list->begin());
 
2316
    List_iterator_fast<Item> li(*cond_list);
2323
2317
    Item *item;
2324
2318
    while ((item= li++))
2325
2319
      update_const_equal_items(item, tab);
2368
2362
  and_level
2369
2363
*/
2370
2364
static void change_cond_ref_to_const(Session *session,
2371
 
                                     list<COND_CMP>& save_list,
 
2365
                                     vector<COND_CMP>& save_list,
2372
2366
                                     Item *and_father,
2373
2367
                                     Item *cond,
2374
2368
                                     Item *field,
2377
2371
  if (cond->type() == Item::COND_ITEM)
2378
2372
  {
2379
2373
    bool and_level= ((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC;
2380
 
    List<Item>::iterator li(((Item_cond*) cond)->argument_list()->begin());
 
2374
    List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
2381
2375
    Item *item;
2382
2376
    while ((item=li++))
2383
2377
      change_cond_ref_to_const(session, save_list, and_level ? cond : item, item, field, value);
2384
 
 
2385
2378
    return;
2386
2379
  }
2387
2380
  if (cond->eq_cmp_result() == Item::COND_OK)
2457
2450
  if (conds->type() == Item::COND_ITEM)
2458
2451
  {
2459
2452
    Item_cond *cnd= (Item_cond*) conds;
2460
 
    List<Item>::iterator li(cnd->argument_list()->begin());
 
2453
    List_iterator<Item> li(*(cnd->argument_list()));
2461
2454
    Item *item;
2462
2455
    while ((item= li++))
2463
2456
    {
2474
2467
}
2475
2468
 
2476
2469
static void propagate_cond_constants(Session *session, 
2477
 
                                     list<COND_CMP>& save_list, 
 
2470
                                     vector<COND_CMP>& save_list, 
2478
2471
                                     COND *and_father, 
2479
2472
                                     COND *cond)
2480
2473
{
2481
2474
  if (cond->type() == Item::COND_ITEM)
2482
2475
  {
2483
2476
    bool and_level= ((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC;
2484
 
    List<Item>::iterator li(((Item_cond*) cond)->argument_list()->begin());
 
2477
    List_iterator_fast<Item> li(*((Item_cond*) cond)->argument_list());
2485
2478
    Item *item;
2486
 
    list<COND_CMP> save;
 
2479
    vector<COND_CMP> save;
2487
2480
    while ((item=li++))
2488
2481
    {
2489
2482
      propagate_cond_constants(session, save, and_level ? cond : item, item);
2491
2484
    if (and_level)
2492
2485
    {
2493
2486
      // Handle other found items
2494
 
      for (list<COND_CMP>::iterator iter= save.begin(); iter != save.end(); ++iter)
 
2487
      for (vector<COND_CMP>::iterator iter= save.begin(); iter != save.end(); ++iter)
2495
2488
      {
2496
 
        Item **args= iter->second->arguments();
2497
 
        if (not args[0]->const_item())
 
2489
        Item **args= iter->cmp_func->arguments();
 
2490
        if (!args[0]->const_item())
2498
2491
        {
2499
 
          change_cond_ref_to_const(session, save, iter->first,
2500
 
                                   iter->first, args[0], args[1] );
 
2492
          change_cond_ref_to_const( session, save, iter->and_level,
 
2493
                                    iter->and_level, args[0], args[1] );
2501
2494
        }
2502
2495
      }
2503
2496
    }
2610
2603
         position:
2611
2604
          1. join->cur_embedding_map - bitmap of pairs of brackets (aka nested
2612
2605
             joins) we've opened but didn't close.
2613
 
          2. {each NestedJoin class not simplified away}->counter - number
 
2606
          2. {each nested_join_st structure not simplified away}->counter - number
2614
2607
             of this nested join's children that have already been added to to
2615
2608
             the partial join order.
2616
2609
  @endverbatim
2688
2681
                             &join->cond_equal);
2689
2682
 
2690
2683
    /* change field = field to field = const for each found field = const */
2691
 
    list<COND_CMP> temp;
 
2684
    vector<COND_CMP> temp;
2692
2685
    propagate_cond_constants(session, temp, conds, conds);
2693
2686
    /*
2694
2687
      Remove all instances of item == item
2715
2708
  {
2716
2709
    bool and_level= (((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC);
2717
2710
 
2718
 
    List<Item>::iterator li(((Item_cond*) cond)->argument_list()->begin());
 
2711
    List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
2719
2712
    Item::cond_result tmp_cond_value;
2720
2713
    bool should_fix_fields= false;
2721
2714
 
2769
2762
    {                                           
2770
2763
      /* Argument list contains only one element, so reduce it so a single item, then remove list */
2771
2764
      item= ((Item_cond*) cond)->argument_list()->head();
2772
 
      ((Item_cond*) cond)->argument_list()->clear();
 
2765
      ((Item_cond*) cond)->argument_list()->empty();
2773
2766
      return item;
2774
2767
    }
2775
2768
  }
2847
2840
  }
2848
2841
  else if (cond->const_item() && !cond->is_expensive())
2849
2842
  /*
2850
 
    @todo
 
2843
    TODO:
2851
2844
    Excluding all expensive functions is too restritive we should exclude only
2852
2845
    materialized IN subquery predicates because they can't yet be evaluated
2853
2846
    here (they need additional initialization that is done later on).
2919
2912
  {
2920
2913
    bool and_level= (((Item_cond*) cond)->functype()
2921
2914
                     == Item_func::COND_AND_FUNC);
2922
 
    List<Item>::iterator li(((Item_cond*) cond)->argument_list()->begin());
 
2915
    List_iterator_fast<Item> li(*((Item_cond*) cond)->argument_list());
2923
2916
    Item *item;
2924
2917
    while ((item=li++))
2925
2918
    {
3057
3050
    table->emptyRecord();
3058
3051
    if (table->group && join->tmp_table_param.sum_func_count &&
3059
3052
        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
 
    }
 
3053
      table->cursor->startIndexScan(0, 0);
3069
3054
  }
3070
3055
  /* Set up select_end */
3071
3056
  Next_select_func end_select= setup_end_select_func(join);
3371
3356
  return 0;
3372
3357
}
3373
3358
 
 
3359
int join_read_const_table(JoinTable *tab, optimizer::Position *pos)
 
3360
{
 
3361
  int error;
 
3362
  Table *table=tab->table;
 
3363
  table->const_table=1;
 
3364
  table->null_row=0;
 
3365
  table->status=STATUS_NO_RECORD;
 
3366
 
 
3367
  if (tab->type == AM_SYSTEM)
 
3368
  {
 
3369
    if ((error=join_read_system(tab)))
 
3370
    {                                           // Info for DESCRIBE
 
3371
      tab->info="const row not found";
 
3372
      /* Mark for EXPLAIN that the row was not found */
 
3373
      pos->setFanout(0.0);
 
3374
      pos->clearRefDependMap();
 
3375
      if (! table->maybe_null || error > 0)
 
3376
        return(error);
 
3377
    }
 
3378
  }
 
3379
  else
 
3380
  {
 
3381
    if (! table->key_read && 
 
3382
        table->covering_keys.test(tab->ref.key) && 
 
3383
        ! table->no_keyread &&
 
3384
        (int) table->reginfo.lock_type <= (int) TL_READ_WITH_SHARED_LOCKS)
 
3385
    {
 
3386
      table->key_read=1;
 
3387
      table->cursor->extra(HA_EXTRA_KEYREAD);
 
3388
      tab->index= tab->ref.key;
 
3389
    }
 
3390
    error=join_read_const(tab);
 
3391
    if (table->key_read)
 
3392
    {
 
3393
      table->key_read=0;
 
3394
      table->cursor->extra(HA_EXTRA_NO_KEYREAD);
 
3395
    }
 
3396
    if (error)
 
3397
    {
 
3398
      tab->info="unique row not found";
 
3399
      /* Mark for EXPLAIN that the row was not found */
 
3400
      pos->setFanout(0.0);
 
3401
      pos->clearRefDependMap();
 
3402
      if (!table->maybe_null || error > 0)
 
3403
        return(error);
 
3404
    }
 
3405
  }
 
3406
  if (*tab->on_expr_ref && !table->null_row)
 
3407
  {
 
3408
    if ((table->null_row= test((*tab->on_expr_ref)->val_int() == 0)))
 
3409
      table->mark_as_null_row();
 
3410
  }
 
3411
  if (!table->null_row)
 
3412
    table->maybe_null=0;
 
3413
 
 
3414
  /* Check appearance of new constant items in Item_equal objects */
 
3415
  Join *join= tab->join;
 
3416
  if (join->conds)
 
3417
    update_const_equal_items(join->conds, tab);
 
3418
  TableList *tbl;
 
3419
  for (tbl= join->select_lex->leaf_tables; tbl; tbl= tbl->next_leaf)
 
3420
  {
 
3421
    TableList *embedded;
 
3422
    TableList *embedding= tbl;
 
3423
    do
 
3424
    {
 
3425
      embedded= embedding;
 
3426
      if (embedded->on_expr)
 
3427
         update_const_equal_items(embedded->on_expr, tab);
 
3428
      embedding= embedded->getEmbedding();
 
3429
    }
 
3430
    while (embedding &&
 
3431
           embedding->getNestedJoin()->join_list.head() == embedded);
 
3432
  }
 
3433
 
 
3434
  return(0);
 
3435
}
 
3436
 
 
3437
int join_read_system(JoinTable *tab)
 
3438
{
 
3439
  Table *table= tab->table;
 
3440
  int error;
 
3441
  if (table->status & STATUS_GARBAGE)           // If first read
 
3442
  {
 
3443
    if ((error=table->cursor->read_first_row(table->getInsertRecord(),
 
3444
                                           table->getShare()->getPrimaryKey())))
 
3445
    {
 
3446
      if (error != HA_ERR_END_OF_FILE)
 
3447
        return table->report_error(error);
 
3448
      tab->table->mark_as_null_row();
 
3449
      table->emptyRecord();                     // Make empty record
 
3450
      return -1;
 
3451
    }
 
3452
    table->storeRecord();
 
3453
  }
 
3454
  else if (!table->status)                      // Only happens with left join
 
3455
    table->restoreRecord();                     // restore old record
 
3456
  table->null_row=0;
 
3457
  return table->status ? -1 : 0;
 
3458
}
 
3459
 
3374
3460
/**
3375
3461
  Read a (constant) table when there is at most one matching row.
3376
3462
 
3442
3528
 
3443
3529
  if (!table->cursor->inited)
3444
3530
  {
3445
 
    error= table->cursor->startIndexScan(tab->ref.key, tab->sorted);
3446
 
    if (error != 0)
3447
 
    {
3448
 
      table->print_error(error, MYF(0));
3449
 
    }
 
3531
    table->cursor->startIndexScan(tab->ref.key, tab->sorted);
3450
3532
  }
3451
3533
 
3452
 
  /* @todo Why don't we do "Late NULLs Filtering" here? */
 
3534
  /* TODO: Why don't we do "Late NULLs Filtering" here? */
3453
3535
  if (cmp_buffer_with_ref(tab) ||
3454
3536
      (table->status & (STATUS_GARBAGE | STATUS_NO_PARENT | STATUS_NULL_ROW)))
3455
3537
  {
3494
3576
 
3495
3577
  /* Initialize the index first */
3496
3578
  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
 
  }
 
3579
    table->cursor->startIndexScan(tab->ref.key, tab->sorted);
3502
3580
 
3503
3581
  /* Perform "Late NULLs Filtering" (see internals manual for explanations) */
3504
3582
  for (uint32_t i= 0 ; i < tab->ref.key_parts ; i++)
3532
3610
  Table *table= tab->table;
3533
3611
 
3534
3612
  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
 
  }
 
3613
    table->cursor->startIndexScan(tab->ref.key, tab->sorted);
3540
3614
  if (cp_buffer_from_ref(tab->join->session, &tab->ref))
3541
3615
    return -1;
3542
3616
  if ((error=table->cursor->index_read_last_map(table->getInsertRecord(),
3640
3714
 
3641
3715
int test_if_quick_select(JoinTable *tab)
3642
3716
{
3643
 
  safe_delete(tab->select->quick);
3644
 
 
 
3717
  delete tab->select->quick;
 
3718
  tab->select->quick= 0;
3645
3719
  return tab->select->test_quick_select(tab->join->session, tab->keys,
3646
3720
                                        (table_map) 0, HA_POS_ERROR, 0, false);
3647
3721
}
3651
3725
  if (tab->select && tab->select->quick && tab->select->quick->reset())
3652
3726
    return 1;
3653
3727
 
3654
 
  if (tab->read_record.init_read_record(tab->join->session, tab->table, tab->select, 1, true))
3655
 
    return 1;
 
3728
  tab->read_record.init_read_record(tab->join->session, tab->table, tab->select, 1, true);
3656
3729
 
3657
3730
  return (*tab->read_record.read_record)(&tab->read_record);
3658
3731
}
3685
3758
  }
3686
3759
 
3687
3760
  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
 
  }
 
3761
    table->cursor->startIndexScan(tab->index, tab->sorted);
3696
3762
  if ((error=tab->table->cursor->index_first(tab->table->getInsertRecord())))
3697
3763
  {
3698
3764
    if (error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE)
3751
3817
  tab->read_record.index=tab->index;
3752
3818
  tab->read_record.record=table->getInsertRecord();
3753
3819
  if (!table->cursor->inited)
3754
 
  {
3755
 
    error= table->cursor->startIndexScan(tab->index, 1);
3756
 
    if (error != 0)
3757
 
      return table->report_error(error);
3758
 
  }
 
3820
    table->cursor->startIndexScan(tab->index, 1);
3759
3821
  if ((error= tab->table->cursor->index_last(tab->table->getInsertRecord())))
3760
3822
    return table->report_error(error);
3761
3823
 
3819
3881
        {
3820
3882
          if (!join->first_record)
3821
3883
          {
3822
 
                  List<Item>::iterator it(join->fields->begin());
 
3884
                  List_iterator_fast<Item> it(*join->fields);
3823
3885
                  Item *item;
3824
3886
            /* No matching rows for group function */
3825
3887
            join->clear();
3835
3897
              error=join->result->send_data(*join->fields) ? 1 : 0;
3836
3898
            join->send_records++;
3837
3899
          }
3838
 
          if (join->rollup.getState() != Rollup::STATE_NONE && error <= 0)
 
3900
          if (join->rollup.state != ROLLUP::STATE_NONE && error <= 0)
3839
3901
          {
3840
3902
            if (join->rollup_send_data((uint32_t) (idx+1)))
3841
3903
              error= 1;
3925
3987
            return NESTED_LOOP_ERROR;
3926
3988
          }
3927
3989
        }
3928
 
        if (join->rollup.getState() != Rollup::STATE_NONE)
 
3990
        if (join->rollup.state != ROLLUP::STATE_NONE)
3929
3991
        {
3930
3992
          if (join->rollup_write_data((uint32_t) (idx+1), table))
3931
3993
            return NESTED_LOOP_ERROR;
3944
4006
    if (idx < (int) join->send_group_parts)
3945
4007
    {
3946
4008
      copy_fields(&join->tmp_table_param);
3947
 
      if (copy_funcs(join->tmp_table_param.items_to_copy, join->session))
3948
 
        return NESTED_LOOP_ERROR;
 
4009
      copy_funcs(join->tmp_table_param.items_to_copy);
3949
4010
      if (init_sum_functions(join->sum_funcs, join->sum_funcs_end[idx+1]))
3950
4011
        return NESTED_LOOP_ERROR;
3951
4012
      return NESTED_LOOP_OK;
4058
4119
      Item_cond_and *new_cond=new Item_cond_and;
4059
4120
      if (!new_cond)
4060
4121
        return (COND*) 0;
4061
 
      List<Item>::iterator li(((Item_cond*) cond)->argument_list()->begin());
 
4122
      List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
4062
4123
      Item *item;
4063
4124
      while ((item=li++))
4064
4125
      {
4088
4149
      Item_cond_or *new_cond=new Item_cond_or;
4089
4150
      if (!new_cond)
4090
4151
        return (COND*) 0;
4091
 
      List<Item>::iterator li(((Item_cond*) cond)->argument_list()->begin());
 
4152
      List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
4092
4153
      Item *item;
4093
4154
      while ((item=li++))
4094
4155
      {
4440
4501
{
4441
4502
  List<Item> *fields= (List<Item> *) data;
4442
4503
  bool part_found= 0;
4443
 
  List<Item>::iterator li(fields->begin());
 
4504
  List_iterator<Item> li(*fields);
4444
4505
  Item *item;
4445
4506
 
4446
4507
  while ((item= li++))
4525
4586
    save_quick= select->quick;
4526
4587
    /*
4527
4588
      assume results are not ordered when index merge is used
4528
 
      @todo sergeyp: Results of all index merge selects actually are ordered
 
4589
      TODO: sergeyp: Results of all index merge selects actually are ordered
4529
4590
      by clustered PK values.
4530
4591
    */
4531
4592
 
4800
4861
          tab->type= AM_NEXT;           // Read with index_first(), index_next()
4801
4862
          if (select && select->quick)
4802
4863
          {
4803
 
            safe_delete(select->quick);
 
4864
            delete select->quick;
 
4865
            select->quick= 0;
4804
4866
          }
4805
4867
          if (table->covering_keys.test(best_key))
4806
4868
          {
4873
4935
          tab->limit= 0;
4874
4936
          return 0; // Reverse sort not supported
4875
4937
        }
4876
 
        select->quick= tmp;
 
4938
        select->quick=tmp;
4877
4939
      }
4878
4940
    }
4879
4941
    else if (tab->type != AM_NEXT &&
5033
5095
  org_record=(char*) (record=table->getInsertRecord())+offset;
5034
5096
  new_record=(char*) table->getUpdateRecord()+offset;
5035
5097
 
5036
 
  if ((error= cursor->startTableScan(1)))
5037
 
    goto err;
5038
 
 
 
5098
  cursor->startTableScan(1);
5039
5099
  error=cursor->rnd_next(record);
5040
5100
  for (;;)
5041
5101
  {
5152
5212
    return(1);
5153
5213
  }
5154
5214
 
5155
 
  if ((error= cursor->startTableScan(1)))
5156
 
    goto err;
5157
 
 
 
5215
  cursor->startTableScan(1);
5158
5216
  key_pos= &key_buffer[0];
5159
5217
  for (;;)
5160
5218
  {
5366
5424
    if (!count || count > fields.elements)
5367
5425
    {
5368
5426
      my_error(ER_BAD_FIELD_ERROR, MYF(0),
5369
 
               order_item->full_name(), session->where());
 
5427
               order_item->full_name(), session->where);
5370
5428
      return true;
5371
5429
    }
5372
5430
    order->item= ref_pointer_array + count - 1;
5443
5501
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_NON_UNIQ_ERROR,
5444
5502
                          ER(ER_NON_UNIQ_ERROR),
5445
5503
                          ((Item_ident*) order_item)->field_name,
5446
 
                          session->where());
 
5504
                          session->where);
5447
5505
    }
5448
5506
  }
5449
5507
 
5485
5543
                List<Item> &all_fields,
5486
5544
                Order *order)
5487
5545
{
5488
 
  session->setWhere("order clause");
 
5546
  session->where="order clause";
5489
5547
  for (; order; order=order->next)
5490
5548
  {
5491
5549
    if (find_order_in_list(session, ref_pointer_array, tables, order, fields,
5536
5594
 
5537
5595
  uint32_t org_fields=all_fields.elements;
5538
5596
 
5539
 
  session->setWhere("group statement");
 
5597
  session->where="group statement";
5540
5598
  for (ord= order; ord; ord= ord->next)
5541
5599
  {
5542
5600
    if (find_order_in_list(session, ref_pointer_array, tables, ord, fields,
5569
5627
    Item *item;
5570
5628
    Item_field *field;
5571
5629
    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());
 
5630
    List_iterator<Item> li(fields);
 
5631
    List_iterator<Item_field> naf_it(session->lex->current_select->non_agg_fields);
5574
5632
 
5575
5633
    field= naf_it++;
5576
5634
    while (field && (item=li++))
5596
5654
            if ((*ord->item)->eq((Item*)field, 0))
5597
5655
              goto next_field;
5598
5656
          /*
5599
 
            @todo change ER_WRONG_FIELD_WITH_GROUP to more detailed ER_NON_GROUPING_FIELD_USED
 
5657
            TODO: change ER_WRONG_FIELD_WITH_GROUP to more detailed
 
5658
            ER_NON_GROUPING_FIELD_USED
5600
5659
          */
5601
5660
          my_error(ER_WRONG_FIELD_WITH_GROUP, MYF(0), field->full_name());
5602
5661
          return 1;
5625
5684
                                List<Item> &,
5626
5685
                                bool *all_order_by_fields_used)
5627
5686
{
5628
 
  List<Item>::iterator li(fields.begin());
 
5687
  List_iterator<Item> li(fields);
5629
5688
  Item *item;
5630
5689
  Order *order,*group,**prev;
5631
5690
 
5638
5697
  {
5639
5698
    if (order->in_field_list)
5640
5699
    {
5641
 
      Order *ord=(Order*) session->getMemRoot()->duplicate((char*) order,sizeof(Order));
 
5700
      Order *ord=(Order*) session->memdup((char*) order,sizeof(Order));
5642
5701
      if (!ord)
5643
5702
        return 0;
5644
5703
      *prev=ord;
5649
5708
      *all_order_by_fields_used= 0;
5650
5709
  }
5651
5710
 
5652
 
  li= fields.begin();
 
5711
  li.rewind();
5653
5712
  while ((item=li++))
5654
5713
  {
5655
5714
    if (!item->const_item() && !item->with_sum_func && !item->marker)
5689
5748
*/
5690
5749
void count_field_types(Select_Lex *select_lex, Tmp_Table_Param *param, List<Item> &fields, bool reset_with_sum_func)
5691
5750
{
5692
 
  List<Item>::iterator li(fields.begin());
 
5751
  List_iterator<Item> li(fields);
5693
5752
  Item *field;
5694
5753
 
5695
5754
  param->field_count=param->sum_func_count=param->func_count=
5746
5805
*/
5747
5806
int test_if_item_cache_changed(List<Cached_item> &list)
5748
5807
{
5749
 
  List<Cached_item>::iterator li(list.begin());
 
5808
  List_iterator<Cached_item> li(list);
5750
5809
  int idx= -1,i;
5751
5810
  Cached_item *buff;
5752
5811
 
5795
5854
                       List<Item> &all_fields)
5796
5855
{
5797
5856
  Item *pos;
5798
 
  List<Item>::iterator li(all_fields.begin());
 
5857
  List_iterator_fast<Item> li(all_fields);
5799
5858
  CopyField *copy= NULL;
5800
 
  res_selected_fields.clear();
5801
 
  res_all_fields.clear();
5802
 
  List<Item>::iterator itr(res_all_fields.begin());
 
5859
  res_selected_fields.empty();
 
5860
  res_all_fields.empty();
 
5861
  List_iterator_fast<Item> itr(res_all_fields);
5803
5862
  List<Item> extra_funcs;
5804
5863
  uint32_t i, border= all_fields.elements - elements;
5805
5864
 
5807
5866
      !(copy=param->copy_field= new CopyField[param->field_count]))
5808
5867
    goto err2;
5809
5868
 
5810
 
  param->copy_funcs.clear();
 
5869
  param->copy_funcs.empty();
5811
5870
  for (i= 0; (pos= li++); i++)
5812
5871
  {
5813
5872
    Field *field;
5876
5935
             !real_pos->with_sum_func)
5877
5936
    {                                           // Save for send fields
5878
5937
      pos= real_pos;
5879
 
      /* 
5880
 
        @todo In most cases this result will be sent to the user.
 
5938
      /* TODO:
 
5939
        In most cases this result will be sent to the user.
5881
5940
        This should be changed to use copy_int or copy_real depending
5882
5941
        on how the value is to be used: In some cases this may be an
5883
5942
        argument in a group function, like: IF(ISNULL(col),0,COUNT(*))
5931
5990
  for (; ptr != end; ptr++)
5932
5991
    (*ptr->do_copy)(ptr);
5933
5992
 
5934
 
  List<Item>::iterator it(param->copy_funcs.begin());
 
5993
  List_iterator_fast<Item> it(param->copy_funcs);
5935
5994
  Item_copy_string *item;
5936
5995
  while ((item = (Item_copy_string*) it++))
5937
5996
    item->copy();
5960
6019
                                                uint32_t elements,
5961
6020
                              List<Item> &all_fields)
5962
6021
{
5963
 
  List<Item>::iterator it(all_fields.begin());
 
6022
  List_iterator_fast<Item> it(all_fields);
5964
6023
  Item *item_field,*item;
5965
6024
 
5966
 
  res_selected_fields.clear();
5967
 
  res_all_fields.clear();
 
6025
  res_selected_fields.empty();
 
6026
  res_all_fields.empty();
5968
6027
 
5969
6028
  uint32_t i, border= all_fields.elements - elements;
5970
6029
  for (i= 0; (item= it++); i++)
6009
6068
      item_field;
6010
6069
  }
6011
6070
 
6012
 
  List<Item>::iterator itr(res_all_fields.begin());
 
6071
  List_iterator_fast<Item> itr(res_all_fields);
6013
6072
  for (i= 0; i < border; i++)
6014
6073
    itr++;
6015
6074
  itr.sublist(res_selected_fields, elements);
6039
6098
                               uint32_t elements,
6040
6099
                                                 List<Item> &all_fields)
6041
6100
{
6042
 
  List<Item>::iterator it(all_fields.begin());
 
6101
  List_iterator_fast<Item> it(all_fields);
6043
6102
  Item *item, *new_item;
6044
 
  res_selected_fields.clear();
6045
 
  res_all_fields.clear();
 
6103
  res_selected_fields.empty();
 
6104
  res_all_fields.empty();
6046
6105
 
6047
6106
  uint32_t i, border= all_fields.elements - elements;
6048
6107
  for (i= 0; (item= it++); i++)
6052
6111
      new_item;
6053
6112
  }
6054
6113
 
6055
 
  List<Item>::iterator itr(res_all_fields.begin());
 
6114
  List_iterator_fast<Item> itr(res_all_fields);
6056
6115
  for (i= 0; i < border; i++)
6057
6116
    itr++;
6058
6117
  itr.sublist(res_selected_fields, elements);
6135
6194
}
6136
6195
 
6137
6196
/** Copy result of functions to record in tmp_table. */
6138
 
bool copy_funcs(Item **func_ptr, const Session *session)
 
6197
void copy_funcs(Item **func_ptr)
6139
6198
{
6140
6199
  Item *func;
6141
6200
  for (; (func = *func_ptr) ; func_ptr++)
6142
 
  {
6143
6201
    func->save_in_result_field(1);
6144
 
    /*
6145
 
      Need to check the THD error state because Item::val_xxx() don't
6146
 
      return error code, but can generate errors
6147
 
      @todo change it for a real status check when Item::val_xxx()
6148
 
      are extended to return status code.
6149
 
    */
6150
 
    if (session->is_error())
6151
 
      return true;
6152
 
  }
6153
 
  return false;
6154
6202
}
6155
6203
 
6156
6204
/**
6202
6250
  @param changed        out:  returns 1 if item contains a replaced field item
6203
6251
 
6204
6252
  @todo
6205
 
    - @todo Some functions are not null-preserving. For those functions
 
6253
    - TODO: Some functions are not null-preserving. For those functions
6206
6254
    updating of the maybe_null attribute is an overkill.
6207
6255
 
6208
6256
  @retval
6214
6262
{
6215
6263
  if (expr->arg_count)
6216
6264
  {
6217
 
    Name_resolution_context *context= &session->getLex()->current_select->context;
 
6265
    Name_resolution_context *context= &session->lex->current_select->context;
6218
6266
    Item **arg,**arg_end;
6219
6267
    bool arg_changed= false;
6220
6268
    for (arg= expr->arguments(),
6292
6340
                List<TableList> *tables, enum_query_type)
6293
6341
{
6294
6342
  /* 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*) *
 
6343
  List_iterator_fast<TableList> ti(*tables);
 
6344
  TableList **table= (TableList **)session->alloc(sizeof(TableList*) *
6297
6345
                                                tables->elements);
6298
6346
  if (table == 0)
6299
6347
    return;  // out of memory
6329
6377
 
6330
6378
  //Item List
6331
6379
  bool first= 1;
6332
 
  List<Item>::iterator it(item_list.begin());
 
6380
  List_iterator_fast<Item> it(item_list);
6333
6381
  Item *item;
6334
6382
  while ((item= it++))
6335
6383
  {
6342
6390
 
6343
6391
  /*
6344
6392
    from clause
6345
 
    @todo support USING/FORCE/IGNORE index
 
6393
    TODO: support USING/FORCE/IGNORE index
6346
6394
  */
6347
6395
  if (table_list.elements)
6348
6396
  {