~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:
17
17
  @file
18
18
 
19
19
  @brief
20
 
  mysql_select and join optimization
 
20
  select_query 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
 
 
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
 
78
83
static Item* part_of_refkey(Table *form,Field *field);
79
84
static bool cmp_buffer_with_ref(JoinTable *tab);
80
85
static void change_cond_ref_to_const(Session *session,
81
 
                                     vector<COND_CMP>& save_list,
 
86
                                     list<COND_CMP>& save_list,
82
87
                                     Item *and_father,
83
88
                                     Item *cond,
84
89
                                     Item *field,
131
136
    unit->set_limit(unit->global_parameters);
132
137
    session->session_marker= 0;
133
138
    /*
134
 
      'options' of mysql_select will be set in JOIN, as far as JOIN for
 
139
      'options' of select_query will be set in JOIN, as far as JOIN for
135
140
      every PS/SP execution new, we will not need reset this flag if
136
141
      setup_tables_done_option changed for next rexecution
137
142
    */
138
 
    res= mysql_select(session,
 
143
    res= select_query(session,
139
144
                      &select_lex->ref_pointer_array,
140
145
                      (TableList*) select_lex->table_list.first,
141
146
                      select_lex->with_wild,
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.
270
275
 
271
276
/*****************************************************************************
272
277
  Check fields, find best join, do the select and output fields.
273
 
  mysql_select assumes that all tables are already opened
 
278
  select_query assumes that all tables are already opened
274
279
*****************************************************************************/
275
280
 
276
281
/*
350
355
  @retval
351
356
    true   an error
352
357
*/
353
 
bool mysql_select(Session *session,
 
358
bool select_query(Session *session,
354
359
                  Item ***rref_pointer_array,
355
360
                  TableList *tables, 
356
361
                  uint32_t wild_num, 
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,
931
936
 
932
937
  /*
933
938
    we should restore old value of count_cuted_fields because
934
 
    store_val_in_field can be called from mysql_insert
 
939
    store_val_in_field can be called from insert_query
935
940
    with select_insert, which make count_cuted_fields= 1
936
941
   */
937
942
  enum_check_fields old_count_cuted_fields= session->count_cuted_fields;
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);
2364
2368
  and_level
2365
2369
*/
2366
2370
static void change_cond_ref_to_const(Session *session,
2367
 
                                     vector<COND_CMP>& save_list,
 
2371
                                     list<COND_CMP>& save_list,
2368
2372
                                     Item *and_father,
2369
2373
                                     Item *cond,
2370
2374
                                     Item *field,
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
    {
2470
2474
}
2471
2475
 
2472
2476
static void propagate_cond_constants(Session *session, 
2473
 
                                     vector<COND_CMP>& save_list, 
 
2477
                                     list<COND_CMP>& save_list, 
2474
2478
                                     COND *and_father, 
2475
2479
                                     COND *cond)
2476
2480
{
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
 
    vector<COND_CMP> save;
 
2486
    list<COND_CMP> save;
2483
2487
    while ((item=li++))
2484
2488
    {
2485
2489
      propagate_cond_constants(session, save, and_level ? cond : item, item);
2487
2491
    if (and_level)
2488
2492
    {
2489
2493
      // Handle other found items
2490
 
      for (vector<COND_CMP>::iterator iter= save.begin(); iter != save.end(); ++iter)
 
2494
      for (list<COND_CMP>::iterator iter= save.begin(); iter != save.end(); ++iter)
2491
2495
      {
2492
 
        Item **args= iter->cmp_func->arguments();
2493
 
        if (!args[0]->const_item())
 
2496
        Item **args= iter->second->arguments();
 
2497
        if (not args[0]->const_item())
2494
2498
        {
2495
 
          change_cond_ref_to_const( session, save, iter->and_level,
2496
 
                                    iter->and_level, args[0], args[1] );
 
2499
          change_cond_ref_to_const(session, save, iter->first,
 
2500
                                   iter->first, args[0], args[1] );
2497
2501
        }
2498
2502
      }
2499
2503
    }
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
2684
2688
                             &join->cond_equal);
2685
2689
 
2686
2690
    /* change field = field to field = const for each found field = const */
2687
 
    vector<COND_CMP> temp;
 
2691
    list<COND_CMP> temp;
2688
2692
    propagate_cond_constants(session, temp, conds, conds);
2689
2693
    /*
2690
2694
      Remove all instances of item == item
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
    {
3053
3057
    table->emptyRecord();
3054
3058
    if (table->group && join->tmp_table_param.sum_func_count &&
3055
3059
        table->getShare()->sizeKeys() && !table->cursor->inited)
3056
 
      table->cursor->startIndexScan(0, 0);
 
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
    }
3057
3069
  }
3058
3070
  /* Set up select_end */
3059
3071
  Next_select_func end_select= setup_end_select_func(join);
3359
3371
  return 0;
3360
3372
}
3361
3373
 
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
 
 
3463
3374
/**
3464
3375
  Read a (constant) table when there is at most one matching row.
3465
3376
 
3531
3442
 
3532
3443
  if (!table->cursor->inited)
3533
3444
  {
3534
 
    table->cursor->startIndexScan(tab->ref.key, tab->sorted);
 
3445
    error= table->cursor->startIndexScan(tab->ref.key, tab->sorted);
 
3446
    if (error != 0)
 
3447
    {
 
3448
      table->print_error(error, MYF(0));
 
3449
    }
3535
3450
  }
3536
3451
 
3537
 
  /* TODO: Why don't we do "Late NULLs Filtering" here? */
 
3452
  /* @todo Why don't we do "Late NULLs Filtering" here? */
3538
3453
  if (cmp_buffer_with_ref(tab) ||
3539
3454
      (table->status & (STATUS_GARBAGE | STATUS_NO_PARENT | STATUS_NULL_ROW)))
3540
3455
  {
3579
3494
 
3580
3495
  /* Initialize the index first */
3581
3496
  if (!table->cursor->inited)
3582
 
    table->cursor->startIndexScan(tab->ref.key, tab->sorted);
 
3497
  {
 
3498
    error= table->cursor->startIndexScan(tab->ref.key, tab->sorted);
 
3499
    if (error != 0)
 
3500
      return table->report_error(error);
 
3501
  }
3583
3502
 
3584
3503
  /* Perform "Late NULLs Filtering" (see internals manual for explanations) */
3585
3504
  for (uint32_t i= 0 ; i < tab->ref.key_parts ; i++)
3613
3532
  Table *table= tab->table;
3614
3533
 
3615
3534
  if (!table->cursor->inited)
3616
 
    table->cursor->startIndexScan(tab->ref.key, tab->sorted);
 
3535
  {
 
3536
    error= table->cursor->startIndexScan(tab->ref.key, tab->sorted);
 
3537
    if (error != 0)
 
3538
      return table->report_error(error);
 
3539
  }
3617
3540
  if (cp_buffer_from_ref(tab->join->session, &tab->ref))
3618
3541
    return -1;
3619
3542
  if ((error=table->cursor->index_read_last_map(table->getInsertRecord(),
3717
3640
 
3718
3641
int test_if_quick_select(JoinTable *tab)
3719
3642
{
3720
 
  delete tab->select->quick;
3721
 
  tab->select->quick= 0;
 
3643
  safe_delete(tab->select->quick);
 
3644
 
3722
3645
  return tab->select->test_quick_select(tab->join->session, tab->keys,
3723
3646
                                        (table_map) 0, HA_POS_ERROR, 0, false);
3724
3647
}
3728
3651
  if (tab->select && tab->select->quick && tab->select->quick->reset())
3729
3652
    return 1;
3730
3653
 
3731
 
  tab->read_record.init_read_record(tab->join->session, tab->table, tab->select, 1, true);
 
3654
  if (tab->read_record.init_read_record(tab->join->session, tab->table, tab->select, 1, true))
 
3655
    return 1;
3732
3656
 
3733
3657
  return (*tab->read_record.read_record)(&tab->read_record);
3734
3658
}
3761
3685
  }
3762
3686
 
3763
3687
  if (!table->cursor->inited)
3764
 
    table->cursor->startIndexScan(tab->index, tab->sorted);
 
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
  }
3765
3696
  if ((error=tab->table->cursor->index_first(tab->table->getInsertRecord())))
3766
3697
  {
3767
3698
    if (error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE)
3820
3751
  tab->read_record.index=tab->index;
3821
3752
  tab->read_record.record=table->getInsertRecord();
3822
3753
  if (!table->cursor->inited)
3823
 
    table->cursor->startIndexScan(tab->index, 1);
 
3754
  {
 
3755
    error= table->cursor->startIndexScan(tab->index, 1);
 
3756
    if (error != 0)
 
3757
      return table->report_error(error);
 
3758
  }
3824
3759
  if ((error= tab->table->cursor->index_last(tab->table->getInsertRecord())))
3825
3760
    return table->report_error(error);
3826
3761
 
3884
3819
        {
3885
3820
          if (!join->first_record)
3886
3821
          {
3887
 
                  List_iterator_fast<Item> it(*join->fields);
 
3822
                  List<Item>::iterator it(join->fields->begin());
3888
3823
                  Item *item;
3889
3824
            /* No matching rows for group function */
3890
3825
            join->clear();
3900
3835
              error=join->result->send_data(*join->fields) ? 1 : 0;
3901
3836
            join->send_records++;
3902
3837
          }
3903
 
          if (join->rollup.state != ROLLUP::STATE_NONE && error <= 0)
 
3838
          if (join->rollup.getState() != Rollup::STATE_NONE && error <= 0)
3904
3839
          {
3905
3840
            if (join->rollup_send_data((uint32_t) (idx+1)))
3906
3841
              error= 1;
3990
3925
            return NESTED_LOOP_ERROR;
3991
3926
          }
3992
3927
        }
3993
 
        if (join->rollup.state != ROLLUP::STATE_NONE)
 
3928
        if (join->rollup.getState() != Rollup::STATE_NONE)
3994
3929
        {
3995
3930
          if (join->rollup_write_data((uint32_t) (idx+1), table))
3996
3931
            return NESTED_LOOP_ERROR;
4123
4058
      Item_cond_and *new_cond=new Item_cond_and;
4124
4059
      if (!new_cond)
4125
4060
        return (COND*) 0;
4126
 
      List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
 
4061
      List<Item>::iterator li(((Item_cond*) cond)->argument_list()->begin());
4127
4062
      Item *item;
4128
4063
      while ((item=li++))
4129
4064
      {
4153
4088
      Item_cond_or *new_cond=new Item_cond_or;
4154
4089
      if (!new_cond)
4155
4090
        return (COND*) 0;
4156
 
      List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
 
4091
      List<Item>::iterator li(((Item_cond*) cond)->argument_list()->begin());
4157
4092
      Item *item;
4158
4093
      while ((item=li++))
4159
4094
      {
4505
4440
{
4506
4441
  List<Item> *fields= (List<Item> *) data;
4507
4442
  bool part_found= 0;
4508
 
  List_iterator<Item> li(*fields);
 
4443
  List<Item>::iterator li(fields->begin());
4509
4444
  Item *item;
4510
4445
 
4511
4446
  while ((item= li++))
4590
4525
    save_quick= select->quick;
4591
4526
    /*
4592
4527
      assume results are not ordered when index merge is used
4593
 
      TODO: sergeyp: Results of all index merge selects actually are ordered
 
4528
      @todo sergeyp: Results of all index merge selects actually are ordered
4594
4529
      by clustered PK values.
4595
4530
    */
4596
4531
 
4865
4800
          tab->type= AM_NEXT;           // Read with index_first(), index_next()
4866
4801
          if (select && select->quick)
4867
4802
          {
4868
 
            delete select->quick;
4869
 
            select->quick= 0;
 
4803
            safe_delete(select->quick);
4870
4804
          }
4871
4805
          if (table->covering_keys.test(best_key))
4872
4806
          {
4939
4873
          tab->limit= 0;
4940
4874
          return 0; // Reverse sort not supported
4941
4875
        }
4942
 
        select->quick=tmp;
 
4876
        select->quick= tmp;
4943
4877
      }
4944
4878
    }
4945
4879
    else if (tab->type != AM_NEXT &&
5099
5033
  org_record=(char*) (record=table->getInsertRecord())+offset;
5100
5034
  new_record=(char*) table->getUpdateRecord()+offset;
5101
5035
 
5102
 
  cursor->startTableScan(1);
 
5036
  if ((error= cursor->startTableScan(1)))
 
5037
    goto err;
 
5038
 
5103
5039
  error=cursor->rnd_next(record);
5104
5040
  for (;;)
5105
5041
  {
5216
5152
    return(1);
5217
5153
  }
5218
5154
 
5219
 
  cursor->startTableScan(1);
 
5155
  if ((error= cursor->startTableScan(1)))
 
5156
    goto err;
 
5157
 
5220
5158
  key_pos= &key_buffer[0];
5221
5159
  for (;;)
5222
5160
  {
5428
5366
    if (!count || count > fields.elements)
5429
5367
    {
5430
5368
      my_error(ER_BAD_FIELD_ERROR, MYF(0),
5431
 
               order_item->full_name(), session->where);
 
5369
               order_item->full_name(), session->where());
5432
5370
      return true;
5433
5371
    }
5434
5372
    order->item= ref_pointer_array + count - 1;
5505
5443
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_NON_UNIQ_ERROR,
5506
5444
                          ER(ER_NON_UNIQ_ERROR),
5507
5445
                          ((Item_ident*) order_item)->field_name,
5508
 
                          session->where);
 
5446
                          session->where());
5509
5447
    }
5510
5448
  }
5511
5449
 
5547
5485
                List<Item> &all_fields,
5548
5486
                Order *order)
5549
5487
{
5550
 
  session->where="order clause";
 
5488
  session->setWhere("order clause");
5551
5489
  for (; order; order=order->next)
5552
5490
  {
5553
5491
    if (find_order_in_list(session, ref_pointer_array, tables, order, fields,
5598
5536
 
5599
5537
  uint32_t org_fields=all_fields.elements;
5600
5538
 
5601
 
  session->where="group statement";
 
5539
  session->setWhere("group statement");
5602
5540
  for (ord= order; ord; ord= ord->next)
5603
5541
  {
5604
5542
    if (find_order_in_list(session, ref_pointer_array, tables, ord, fields,
5631
5569
    Item *item;
5632
5570
    Item_field *field;
5633
5571
    int cur_pos_in_select_list= 0;
5634
 
    List_iterator<Item> li(fields);
5635
 
    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());
5636
5574
 
5637
5575
    field= naf_it++;
5638
5576
    while (field && (item=li++))
5658
5596
            if ((*ord->item)->eq((Item*)field, 0))
5659
5597
              goto next_field;
5660
5598
          /*
5661
 
            TODO: change ER_WRONG_FIELD_WITH_GROUP to more detailed
5662
 
            ER_NON_GROUPING_FIELD_USED
 
5599
            @todo change ER_WRONG_FIELD_WITH_GROUP to more detailed ER_NON_GROUPING_FIELD_USED
5663
5600
          */
5664
5601
          my_error(ER_WRONG_FIELD_WITH_GROUP, MYF(0), field->full_name());
5665
5602
          return 1;
5688
5625
                                List<Item> &,
5689
5626
                                bool *all_order_by_fields_used)
5690
5627
{
5691
 
  List_iterator<Item> li(fields);
 
5628
  List<Item>::iterator li(fields.begin());
5692
5629
  Item *item;
5693
5630
  Order *order,*group,**prev;
5694
5631
 
5701
5638
  {
5702
5639
    if (order->in_field_list)
5703
5640
    {
5704
 
      Order *ord=(Order*) session->memdup((char*) order,sizeof(Order));
 
5641
      Order *ord=(Order*) session->getMemRoot()->duplicate((char*) order,sizeof(Order));
5705
5642
      if (!ord)
5706
5643
        return 0;
5707
5644
      *prev=ord;
5712
5649
      *all_order_by_fields_used= 0;
5713
5650
  }
5714
5651
 
5715
 
  li.rewind();
 
5652
  li= fields.begin();
5716
5653
  while ((item=li++))
5717
5654
  {
5718
5655
    if (!item->const_item() && !item->with_sum_func && !item->marker)
5752
5689
*/
5753
5690
void count_field_types(Select_Lex *select_lex, Tmp_Table_Param *param, List<Item> &fields, bool reset_with_sum_func)
5754
5691
{
5755
 
  List_iterator<Item> li(fields);
 
5692
  List<Item>::iterator li(fields.begin());
5756
5693
  Item *field;
5757
5694
 
5758
5695
  param->field_count=param->sum_func_count=param->func_count=
5809
5746
*/
5810
5747
int test_if_item_cache_changed(List<Cached_item> &list)
5811
5748
{
5812
 
  List_iterator<Cached_item> li(list);
 
5749
  List<Cached_item>::iterator li(list.begin());
5813
5750
  int idx= -1,i;
5814
5751
  Cached_item *buff;
5815
5752
 
5858
5795
                       List<Item> &all_fields)
5859
5796
{
5860
5797
  Item *pos;
5861
 
  List_iterator_fast<Item> li(all_fields);
 
5798
  List<Item>::iterator li(all_fields.begin());
5862
5799
  CopyField *copy= NULL;
5863
 
  res_selected_fields.empty();
5864
 
  res_all_fields.empty();
5865
 
  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());
5866
5803
  List<Item> extra_funcs;
5867
5804
  uint32_t i, border= all_fields.elements - elements;
5868
5805
 
5870
5807
      !(copy=param->copy_field= new CopyField[param->field_count]))
5871
5808
    goto err2;
5872
5809
 
5873
 
  param->copy_funcs.empty();
 
5810
  param->copy_funcs.clear();
5874
5811
  for (i= 0; (pos= li++); i++)
5875
5812
  {
5876
5813
    Field *field;
5939
5876
             !real_pos->with_sum_func)
5940
5877
    {                                           // Save for send fields
5941
5878
      pos= real_pos;
5942
 
      /* TODO:
5943
 
        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.
5944
5881
        This should be changed to use copy_int or copy_real depending
5945
5882
        on how the value is to be used: In some cases this may be an
5946
5883
        argument in a group function, like: IF(ISNULL(col),0,COUNT(*))
5994
5931
  for (; ptr != end; ptr++)
5995
5932
    (*ptr->do_copy)(ptr);
5996
5933
 
5997
 
  List_iterator_fast<Item> it(param->copy_funcs);
 
5934
  List<Item>::iterator it(param->copy_funcs.begin());
5998
5935
  Item_copy_string *item;
5999
5936
  while ((item = (Item_copy_string*) it++))
6000
5937
    item->copy();
6023
5960
                                                uint32_t elements,
6024
5961
                              List<Item> &all_fields)
6025
5962
{
6026
 
  List_iterator_fast<Item> it(all_fields);
 
5963
  List<Item>::iterator it(all_fields.begin());
6027
5964
  Item *item_field,*item;
6028
5965
 
6029
 
  res_selected_fields.empty();
6030
 
  res_all_fields.empty();
 
5966
  res_selected_fields.clear();
 
5967
  res_all_fields.clear();
6031
5968
 
6032
5969
  uint32_t i, border= all_fields.elements - elements;
6033
5970
  for (i= 0; (item= it++); i++)
6072
6009
      item_field;
6073
6010
  }
6074
6011
 
6075
 
  List_iterator_fast<Item> itr(res_all_fields);
 
6012
  List<Item>::iterator itr(res_all_fields.begin());
6076
6013
  for (i= 0; i < border; i++)
6077
6014
    itr++;
6078
6015
  itr.sublist(res_selected_fields, elements);
6102
6039
                               uint32_t elements,
6103
6040
                                                 List<Item> &all_fields)
6104
6041
{
6105
 
  List_iterator_fast<Item> it(all_fields);
 
6042
  List<Item>::iterator it(all_fields.begin());
6106
6043
  Item *item, *new_item;
6107
 
  res_selected_fields.empty();
6108
 
  res_all_fields.empty();
 
6044
  res_selected_fields.clear();
 
6045
  res_all_fields.clear();
6109
6046
 
6110
6047
  uint32_t i, border= all_fields.elements - elements;
6111
6048
  for (i= 0; (item= it++); i++)
6115
6052
      new_item;
6116
6053
  }
6117
6054
 
6118
 
  List_iterator_fast<Item> itr(res_all_fields);
 
6055
  List<Item>::iterator itr(res_all_fields.begin());
6119
6056
  for (i= 0; i < border; i++)
6120
6057
    itr++;
6121
6058
  itr.sublist(res_selected_fields, elements);
6207
6144
    /*
6208
6145
      Need to check the THD error state because Item::val_xxx() don't
6209
6146
      return error code, but can generate errors
6210
 
      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()
6211
6148
      are extended to return status code.
6212
6149
    */
6213
6150
    if (session->is_error())
6265
6202
  @param changed        out:  returns 1 if item contains a replaced field item
6266
6203
 
6267
6204
  @todo
6268
 
    - TODO: Some functions are not null-preserving. For those functions
 
6205
    - @todo Some functions are not null-preserving. For those functions
6269
6206
    updating of the maybe_null attribute is an overkill.
6270
6207
 
6271
6208
  @retval
6277
6214
{
6278
6215
  if (expr->arg_count)
6279
6216
  {
6280
 
    Name_resolution_context *context= &session->lex->current_select->context;
 
6217
    Name_resolution_context *context= &session->getLex()->current_select->context;
6281
6218
    Item **arg,**arg_end;
6282
6219
    bool arg_changed= false;
6283
6220
    for (arg= expr->arguments(),
6355
6292
                List<TableList> *tables, enum_query_type)
6356
6293
{
6357
6294
  /* List is reversed => we should reverse it before using */
6358
 
  List_iterator_fast<TableList> ti(*tables);
6359
 
  TableList **table= (TableList **)session->alloc(sizeof(TableList*) *
 
6295
  List<TableList>::iterator ti(tables->begin());
 
6296
  TableList **table= (TableList **)session->getMemRoot()->allocate(sizeof(TableList*) *
6360
6297
                                                tables->elements);
6361
6298
  if (table == 0)
6362
6299
    return;  // out of memory
6392
6329
 
6393
6330
  //Item List
6394
6331
  bool first= 1;
6395
 
  List_iterator_fast<Item> it(item_list);
 
6332
  List<Item>::iterator it(item_list.begin());
6396
6333
  Item *item;
6397
6334
  while ((item= it++))
6398
6335
  {
6405
6342
 
6406
6343
  /*
6407
6344
    from clause
6408
 
    TODO: support USING/FORCE/IGNORE index
 
6345
    @todo support USING/FORCE/IGNORE index
6409
6346
  */
6410
6347
  if (table_list.elements)
6411
6348
  {