~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/join.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:
1
1
/* - mode: c; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
2
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3
3
 *
4
 
 *  Copyright (C) 2008-2009 Sun Microsystems
 
4
 *  Copyright (C) 2008-2009 Sun Microsystems, Inc.
5
5
 *
6
6
 *  This program is free software; you can redistribute it and/or modify
7
7
 *  it under the terms of the GNU General Public License as published by
27
27
 * @{
28
28
 */
29
29
 
30
 
#include "config.h"
 
30
#include <config.h>
31
31
 
32
32
#include <float.h>
33
33
#include <math.h>
34
34
 
35
 
#include "drizzled/item/cache.h"
36
 
#include "drizzled/item/cmpfunc.h"
37
 
#include "drizzled/item/copy_string.h"
38
 
#include "drizzled/item/uint.h"
39
 
#include "drizzled/cached_item.h"
40
 
#include "drizzled/sql_base.h"
41
 
#include "drizzled/sql_select.h" /* include join.h */
42
 
#include "drizzled/lock.h"
43
 
#include "drizzled/nested_join.h"
44
 
#include "drizzled/join.h"
45
 
#include "drizzled/join_cache.h"
46
 
#include "drizzled/show.h"
47
 
#include "drizzled/field/blob.h"
48
 
#include "drizzled/optimizer/position.h"
49
 
#include "drizzled/optimizer/sargable_param.h"
50
 
#include "drizzled/optimizer/key_use.h"
51
 
#include "drizzled/optimizer/range.h"
52
 
#include "drizzled/optimizer/sum.h"
53
 
#include "drizzled/optimizer/explain_plan.h"
54
 
#include "drizzled/optimizer/access_method_factory.h"
55
 
#include "drizzled/optimizer/access_method.h"
56
 
#include "drizzled/records.h"
57
 
#include "drizzled/probes.h"
58
 
#include "drizzled/internal/my_bit.h"
59
 
#include "drizzled/internal/my_sys.h"
60
 
#include "drizzled/internal/iocache.h"
 
35
#include <drizzled/item/cache.h>
 
36
#include <drizzled/item/cmpfunc.h>
 
37
#include <drizzled/item/copy_string.h>
 
38
#include <drizzled/item/uint.h>
 
39
#include <drizzled/cached_item.h>
 
40
#include <drizzled/sql_base.h>
 
41
#include <drizzled/sql_select.h> /* include join.h */
 
42
#include <drizzled/lock.h>
 
43
#include <drizzled/nested_join.h>
 
44
#include <drizzled/join.h>
 
45
#include <drizzled/join_cache.h>
 
46
#include <drizzled/show.h>
 
47
#include <drizzled/field/blob.h>
 
48
#include <drizzled/optimizer/position.h>
 
49
#include <drizzled/optimizer/sargable_param.h>
 
50
#include <drizzled/optimizer/key_use.h>
 
51
#include <drizzled/optimizer/range.h>
 
52
#include <drizzled/optimizer/sum.h>
 
53
#include <drizzled/optimizer/explain_plan.h>
 
54
#include <drizzled/optimizer/access_method_factory.h>
 
55
#include <drizzled/optimizer/access_method.h>
 
56
#include <drizzled/records.h>
 
57
#include <drizzled/probes.h>
 
58
#include <drizzled/internal/my_bit.h>
 
59
#include <drizzled/internal/my_sys.h>
 
60
#include <drizzled/internal/iocache.h>
 
61
#include <drizzled/plugin/storage_engine.h>
 
62
#include <drizzled/session.h>
 
63
#include <drizzled/select_result.h>
 
64
 
 
65
#include <drizzled/debug.h>
61
66
 
62
67
#include <algorithm>
63
68
 
65
70
 
66
71
namespace drizzled
67
72
{
68
 
 
69
73
extern plugin::StorageEngine *heap_engine;
70
 
extern std::bitset<12> test_flags;
71
74
 
72
75
/** Declarations of static functions used in this source file. */
73
76
static bool make_group_fields(Join *main_join, Join *curr_join);
133
136
static bool add_ref_to_table_cond(Session *session, JoinTable *join_tab);
134
137
static void free_blobs(Field **ptr); /* Rename this method...conflicts with another in global namespace... */
135
138
 
 
139
Join::Join(Session *session_arg, 
 
140
           List<Item> &fields_arg, 
 
141
           uint64_t select_options_arg,
 
142
           select_result *result_arg) :
 
143
  join_tab(NULL),
 
144
  best_ref(NULL),
 
145
  map2table(NULL),
 
146
  join_tab_save(NULL),
 
147
  table(NULL),
 
148
  all_tables(NULL),
 
149
  sort_by_table(NULL),
 
150
  tables(0),
 
151
  outer_tables(0),
 
152
  const_tables(0),
 
153
  send_group_parts(0),
 
154
  sort_and_group(false),
 
155
  first_record(false),
 
156
  full_join(false),
 
157
  group(false),
 
158
  no_field_update(false),
 
159
  do_send_rows(true),
 
160
  resume_nested_loop(false),
 
161
  no_const_tables(false),
 
162
  select_distinct(false),
 
163
  group_optimized_away(false),
 
164
  simple_order(false),
 
165
  simple_group(false),
 
166
  no_order(false),
 
167
  skip_sort_order(false),
 
168
  union_part(false),
 
169
  optimized(false),
 
170
  need_tmp(false),
 
171
  hidden_group_fields(false),
 
172
  const_table_map(0),
 
173
  found_const_table_map(0),
 
174
  outer_join(0),
 
175
  send_records(0),
 
176
  found_records(0),
 
177
  examined_rows(0),
 
178
  row_limit(0),
 
179
  select_limit(0),
 
180
  fetch_limit(HA_POS_ERROR),
 
181
  session(session_arg),
 
182
  fields_list(fields_arg), 
 
183
  join_list(NULL),
 
184
  unit(NULL),
 
185
  select_lex(NULL),
 
186
  select(NULL),
 
187
  exec_tmp_table1(NULL),
 
188
  exec_tmp_table2(NULL),
 
189
  sum_funcs(NULL),
 
190
  sum_funcs2(NULL),
 
191
  having(NULL),
 
192
  tmp_having(NULL),
 
193
  having_history(NULL),
 
194
  select_options(select_options_arg),
 
195
  result(result_arg),
 
196
  lock(session_arg->lock),
 
197
  tmp_join(NULL),
 
198
  all_fields(fields_arg),
 
199
  error(0),
 
200
  cond_equal(NULL),
 
201
  return_tab(NULL),
 
202
  ref_pointer_array(NULL),
 
203
  items0(NULL),
 
204
  items1(NULL),
 
205
  items2(NULL),
 
206
  items3(NULL),
 
207
  ref_pointer_array_size(0),
 
208
  zero_result_cause(NULL),
 
209
  sortorder(NULL),
 
210
  table_reexec(NULL),
 
211
  join_tab_reexec(NULL)
 
212
{
 
213
  select_distinct= test(select_options & SELECT_DISTINCT);
 
214
  if (&fields_list != &fields_arg) /* only copy if not same*/
 
215
    fields_list= fields_arg;
 
216
  memset(&keyuse, 0, sizeof(keyuse));
 
217
  tmp_table_param.init();
 
218
  tmp_table_param.end_write_records= HA_POS_ERROR;
 
219
  rollup.setState(Rollup::STATE_NONE);
 
220
}
 
221
 
 
222
  /** 
 
223
   * This method is currently only used when a subselect EXPLAIN is performed.
 
224
   * I pulled out the init() method and have simply reset the values to what
 
225
   * was previously in the init() method.  See the note about the hack in 
 
226
   * sql_union.cc...
 
227
   */
 
228
void Join::reset(Session *session_arg, 
 
229
                 List<Item> &fields_arg, 
 
230
                 uint64_t select_options_arg,
 
231
                 select_result *result_arg)
 
232
{
 
233
  join_tab= NULL;
 
234
  best_ref= NULL;
 
235
  map2table= NULL;
 
236
  join_tab_save= NULL;
 
237
  table= NULL;
 
238
  all_tables= NULL;
 
239
  sort_by_table= NULL;
 
240
  tables= 0;
 
241
  outer_tables= 0;
 
242
  const_tables= 0;
 
243
  send_group_parts= 0;
 
244
  sort_and_group= false;
 
245
  first_record= false;
 
246
  full_join= false;
 
247
  group= false;
 
248
  no_field_update= false;
 
249
  do_send_rows= true;
 
250
  resume_nested_loop= false;
 
251
  no_const_tables= false;
 
252
  select_distinct= false;
 
253
  group_optimized_away= false;
 
254
  simple_order= false;
 
255
  simple_group= false;
 
256
  no_order= false;
 
257
  skip_sort_order= false;
 
258
  union_part= false;
 
259
  optimized= false;
 
260
  need_tmp= false;
 
261
  hidden_group_fields= false;
 
262
  const_table_map= 0;
 
263
  found_const_table_map= 0;
 
264
  outer_join= 0;
 
265
  send_records= 0;
 
266
  found_records= 0;
 
267
  examined_rows= 0;
 
268
  row_limit= 0;
 
269
  select_limit= 0;
 
270
  fetch_limit= HA_POS_ERROR;
 
271
  session= session_arg;
 
272
  fields_list= fields_arg; 
 
273
  join_list= NULL;
 
274
  unit= NULL;
 
275
  select_lex= NULL;
 
276
  select= NULL;
 
277
  exec_tmp_table1= NULL;
 
278
  exec_tmp_table2= NULL;
 
279
  sum_funcs= NULL;
 
280
  sum_funcs2= NULL;
 
281
  having= NULL;
 
282
  tmp_having= NULL;
 
283
  having_history= NULL;
 
284
  select_options= select_options_arg;
 
285
  result= result_arg;
 
286
  lock= session_arg->lock;
 
287
  tmp_join= NULL;
 
288
  all_fields= fields_arg;
 
289
  error= 0;
 
290
  cond_equal= NULL;
 
291
  return_tab= NULL;
 
292
  ref_pointer_array= NULL;
 
293
  items0= NULL;
 
294
  items1= NULL;
 
295
  items2= NULL;
 
296
  items3= NULL;
 
297
  ref_pointer_array_size= 0;
 
298
  zero_result_cause= NULL;
 
299
  sortorder= NULL;
 
300
  table_reexec= NULL;
 
301
  join_tab_reexec= NULL;
 
302
  select_distinct= test(select_options & SELECT_DISTINCT);
 
303
  if (&fields_list != &fields_arg) /* only copy if not same*/
 
304
    fields_list= fields_arg;
 
305
  memset(&keyuse, 0, sizeof(keyuse));
 
306
  tmp_table_param.init();
 
307
  tmp_table_param.end_write_records= HA_POS_ERROR;
 
308
  rollup.setState(Rollup::STATE_NONE);
 
309
}
 
310
 
 
311
bool Join::is_top_level_join() const
 
312
{
 
313
  return (unit == &session->getLex()->unit && (unit->fake_select_lex == 0 ||
 
314
                                          select_lex == unit->fake_select_lex));
 
315
}
 
316
 
136
317
/**
137
318
  Prepare of whole select (including sub queries in future).
138
319
 
170
351
  join_list= &select_lex->top_join_list;
171
352
  union_part= unit_arg->is_union();
172
353
 
173
 
  session->lex->current_select->is_item_list_lookup= 1;
 
354
  session->getLex()->current_select->is_item_list_lookup= 1;
174
355
  /*
175
356
    If we have already executed SELECT, then it have not sense to prevent
176
357
    its table from update (see unique_table())
211
392
 
212
393
  if (having)
213
394
  {
214
 
    nesting_map save_allow_sum_func= session->lex->allow_sum_func;
215
 
    session->where="having clause";
216
 
    session->lex->allow_sum_func|= 1 << select_lex_arg->nest_level;
 
395
    nesting_map save_allow_sum_func= session->getLex()->allow_sum_func;
 
396
    session->setWhere("having clause");
 
397
    session->getLex()->allow_sum_func|= 1 << select_lex_arg->nest_level;
217
398
    select_lex->having_fix_field= 1;
218
399
    bool having_fix_rc= (!having->fixed &&
219
400
       (having->fix_fields(session, &having) ||
221
402
    select_lex->having_fix_field= 0;
222
403
    if (having_fix_rc || session->is_error())
223
404
      return(-1);
224
 
    session->lex->allow_sum_func= save_allow_sum_func;
 
405
    session->getLex()->allow_sum_func= save_allow_sum_func;
225
406
  }
226
407
 
227
408
  {
271
452
            in_subs  &&                                                   // 1
272
453
            !select_lex->master_unit()->first_select()->next_select() &&  // 2
273
454
            select_lex->master_unit()->first_select()->leaf_tables &&     // 3
274
 
            session->lex->sql_command == SQLCOM_SELECT)                       // *
 
455
            session->getLex()->sql_command == SQLCOM_SELECT)                       // *
275
456
        {
276
457
          if (in_subs->is_top_level_item() &&                             // 4
277
458
              !in_subs->is_correlated &&                                  // 5
444
625
    select_limit= HA_POS_ERROR;
445
626
  do_send_rows = (unit->select_limit_cnt) ? 1 : 0;
446
627
  // Ignore errors of execution if option IGNORE present
447
 
  if (session->lex->ignore)
448
 
    session->lex->current_select->no_error= 1;
 
628
  if (session->getLex()->ignore)
 
629
    session->getLex()->current_select->no_error= 1;
449
630
 
450
631
#ifdef HAVE_REF_TO_FIELDS     // Not done yet
451
632
  /* Add HAVING to WHERE if possible */
545
726
        conjunctions.
546
727
        Preserve conditions for EXPLAIN.
547
728
      */
548
 
      if (conds && !(session->lex->describe & DESCRIBE_EXTENDED))
 
729
      if (conds && !(session->getLex()->describe & DESCRIBE_EXTENDED))
549
730
      {
550
731
        COND *table_independent_conds= make_cond_for_table(conds, PSEUDO_TABLE_BITS, 0, 0);
551
732
        conds= table_independent_conds;
580
761
      !(select_options & SELECT_DESCRIBE) &&
581
762
      (!conds ||
582
763
       !(conds->used_tables() & RAND_TABLE_BIT) ||
583
 
       select_lex->master_unit() == &session->lex->unit)) // upper level SELECT
 
764
       select_lex->master_unit() == &session->getLex()->unit)) // upper level SELECT
584
765
  {
585
766
    zero_result_cause= "no matching row in const table";
586
767
    goto setup_subq_exit;
640
821
 
641
822
  if (conds &&!outer_join && const_table_map != found_const_table_map &&
642
823
      (select_options & SELECT_DESCRIBE) &&
643
 
      select_lex->master_unit() == &session->lex->unit) // upper level SELECT
 
824
      select_lex->master_unit() == &session->getLex()->unit) // upper level SELECT
644
825
  {
645
826
    conds=new Item_int((int64_t) 0,1);  // Always false
646
827
  }
728
909
  }
729
910
  if (group_list || tmp_table_param.sum_func_count)
730
911
  {
731
 
    if (! hidden_group_fields && rollup.state == ROLLUP::STATE_NONE)
 
912
    if (! hidden_group_fields && rollup.getState() == Rollup::STATE_NONE)
732
913
      select_distinct=0;
733
914
  }
734
915
  else if (select_distinct && tables - const_tables == 1)
792
973
  {
793
974
    Order *old_group_list;
794
975
    group_list= remove_constants(this, (old_group_list= group_list), conds,
795
 
                                 rollup.state == ROLLUP::STATE_NONE,
 
976
                                 rollup.getState() == Rollup::STATE_NONE,
796
977
                                 &simple_group);
797
978
    if (session->is_error())
798
979
    {
984
1165
 
985
1166
    tmp_table_param.hidden_field_count= (all_fields.elements -
986
1167
           fields_list.elements);
987
 
    Order *tmp_group= ((!simple_group &&
988
 
                           ! (test_flags.test(TEST_NO_KEY_GROUP))) ? group_list :
989
 
                                                                     (Order*) 0);
 
1168
    Order *tmp_group= (((not simple_group) or not (getDebug().test(debug::NO_KEY_GROUP))) ? group_list : (Order*) 0);
 
1169
 
990
1170
    /*
991
1171
      Pushing LIMIT to the temporary table creation is not applicable
992
1172
      when there is ORDER BY or GROUP BY or there is no GROUP BY, but
995
1175
    */
996
1176
    ha_rows tmp_rows_limit= ((order == 0 || skip_sort_order) &&
997
1177
                             !tmp_group &&
998
 
                             !session->lex->current_select->with_sum_func) ?
 
1178
                             !session->getLex()->current_select->with_sum_func) ?
999
1179
                            select_limit : HA_POS_ERROR;
1000
1180
 
1001
1181
    if (!(exec_tmp_table1=
1172
1352
*/
1173
1353
bool Join::init_save_join_tab()
1174
1354
{
1175
 
  if (!(tmp_join= (Join*)session->alloc(sizeof(Join))))
 
1355
  if (!(tmp_join= (Join*)session->getMemRoot()->allocate(sizeof(Join))))
1176
1356
    return 1;
1177
1357
 
1178
1358
  error= 0;              // Ensure that tmp_join.error= 0
1185
1365
{
1186
1366
  if (! join_tab_save && select_lex->master_unit()->uncacheable.any())
1187
1367
  {
1188
 
    if (!(join_tab_save= (JoinTable*)session->memdup((unsigned char*) join_tab,
 
1368
    if (!(join_tab_save= (JoinTable*)session->getMemRoot()->duplicate((unsigned char*) join_tab,
1189
1369
            sizeof(JoinTable) * tables)))
1190
1370
      return 1;
1191
1371
  }
1587
1767
      if (sort_table_cond)
1588
1768
      {
1589
1769
        if (!curr_table->select)
1590
 
          if (!(curr_table->select= new optimizer::SqlSelect))
 
1770
          if (!(curr_table->select= new optimizer::SqlSelect()))
1591
1771
            return;
1592
1772
        if (!curr_table->select->cond)
1593
1773
          curr_table->select->cond= sort_table_cond;
1691
1871
    for a derived table which is always materialized.
1692
1872
    Otherwise we would not be able to print the query  correctly.
1693
1873
  */
1694
 
  if (items0 && (session->lex->describe & DESCRIBE_EXTENDED) && select_lex->linkage == DERIVED_TABLE_TYPE)
 
1874
  if (items0 && (session->getLex()->describe & DESCRIBE_EXTENDED) && select_lex->linkage == DERIVED_TABLE_TYPE)
1695
1875
    set_items_ref_array(items0);
1696
1876
 
1697
1877
  return;
1823
2003
    Optimization: if not EXPLAIN and we are done with the Join,
1824
2004
    free all tables.
1825
2005
  */
1826
 
  bool full= (select_lex->uncacheable.none() && ! session->lex->describe);
 
2006
  bool full= (select_lex->uncacheable.none() && ! session->getLex()->describe);
1827
2007
  bool can_unlock= full;
1828
2008
 
1829
2009
  cleanup(full);
1834
2014
    for (sl= tmp_unit->first_select(); sl; sl= sl->next_select())
1835
2015
    {
1836
2016
      Item_subselect *subselect= sl->master_unit()->item;
1837
 
      bool full_local= full && (!subselect || subselect->is_evaluated());
 
2017
      bool full_local= full && (!subselect || 
 
2018
                                (subselect->is_evaluated() &&
 
2019
                                !subselect->is_uncacheable()));
1838
2020
      /*
1839
2021
        If this join is evaluated, we can fully clean it up and clean up all
1840
2022
        its underlying joins even if they are correlated -- they will not be
1856
2038
  if (can_unlock && lock && session->lock &&
1857
2039
      !(select_options & SELECT_NO_UNLOCK) &&
1858
2040
      !select_lex->subquery_in_having &&
1859
 
      (select_lex == (session->lex->unit.fake_select_lex ?
1860
 
                      session->lex->unit.fake_select_lex : &session->lex->select_lex)))
 
2041
      (select_lex == (session->getLex()->unit.fake_select_lex ?
 
2042
                      session->getLex()->unit.fake_select_lex : &session->getLex()->select_lex)))
1861
2043
  {
1862
2044
    /*
1863
2045
      TODO: unlock tables even if the join isn't top level select in the
1886
2068
{
1887
2069
  if (table)
1888
2070
  {
1889
 
    JoinTable *tab,*end;
1890
2071
    /*
1891
2072
      Only a sorted table may be cached.  This sorted table is always the
1892
2073
      first non const table in join->table
1896
2077
      table[const_tables]->free_io_cache();
1897
2078
      table[const_tables]->filesort_free_buffers(full);
1898
2079
    }
 
2080
  }
 
2081
 
 
2082
  if (join_tab)
 
2083
  {
 
2084
    JoinTable *tab,*end;
1899
2085
 
1900
2086
    if (full)
1901
2087
    {
1912
2098
      }
1913
2099
    }
1914
2100
  }
 
2101
 
1915
2102
  /*
1916
2103
    We are not using tables anymore
1917
2104
    Unlock all tables. We may be in an INSERT .... SELECT statement.
1925
2112
      We can't call delete_elements() on copy_funcs as this will cause
1926
2113
      problems in free_elements() as some of the elements are then deleted.
1927
2114
    */
1928
 
    tmp_table_param.copy_funcs.empty();
 
2115
    tmp_table_param.copy_funcs.clear();
1929
2116
    /*
1930
2117
      If we have tmp_join and 'this' Join is not tmp_join and
1931
2118
      tmp_table_param.copy_field's  of them are equal then we have to remove
1955
2142
    are not re-calculated.
1956
2143
  */
1957
2144
  for (uint32_t i= join->const_tables; i < join->tables; i++)
 
2145
  {
1958
2146
    join->table[i]->mark_as_null_row();   // All fields are NULL
 
2147
  }
1959
2148
}
1960
2149
 
1961
2150
/**
1976
2165
    If we are using rollup, we need a copy of the summary functions for
1977
2166
    each level
1978
2167
  */
1979
 
  if (rollup.state != ROLLUP::STATE_NONE)
 
2168
  if (rollup.getState() != Rollup::STATE_NONE)
1980
2169
    func_count*= (send_group_parts+1);
1981
2170
 
1982
2171
  group_parts= send_group_parts;
2024
2213
                              bool before_group_by, 
2025
2214
                              bool recompute)
2026
2215
{
2027
 
  List_iterator_fast<Item> it(field_list);
 
2216
  List<Item>::iterator it(field_list.begin());
2028
2217
  Item_sum **func;
2029
2218
  Item *item;
2030
2219
 
2039
2228
         ((Item_sum *)item)->depended_from() == select_lex))
2040
2229
      *func++= (Item_sum*) item;
2041
2230
  }
2042
 
  if (before_group_by && rollup.state == ROLLUP::STATE_INITED)
 
2231
  if (before_group_by && rollup.getState() == Rollup::STATE_INITED)
2043
2232
  {
2044
 
    rollup.state= ROLLUP::STATE_READY;
 
2233
    rollup.setState(Rollup::STATE_READY);
2045
2234
    if (rollup_make_fields(field_list, send_fields, &func))
2046
 
      return(true);     // Should never happen
 
2235
      return true;     // Should never happen
2047
2236
  }
2048
 
  else if (rollup.state == ROLLUP::STATE_NONE)
 
2237
  else if (rollup.getState() == Rollup::STATE_NONE)
2049
2238
  {
2050
2239
    for (uint32_t i=0 ; i <= send_group_parts ;i++)
2051
2240
      sum_funcs_end[i]= func;
2052
2241
  }
2053
 
  else if (rollup.state == ROLLUP::STATE_READY)
 
2242
  else if (rollup.getState() == Rollup::STATE_READY)
2054
2243
    return(false);                         // Don't put end marker
2055
2244
  *func=0;          // End marker
2056
2245
  return(false);
2059
2248
/** Allocate memory needed for other rollup functions. */
2060
2249
bool Join::rollup_init()
2061
2250
{
2062
 
  uint32_t i,j;
2063
2251
  Item **ref_array;
2064
2252
 
2065
2253
  tmp_table_param.quick_group= 0; // Can't create groups in tmp table
2066
 
  rollup.state= ROLLUP::STATE_INITED;
 
2254
  rollup.setState(Rollup::STATE_INITED);
2067
2255
 
2068
2256
  /*
2069
2257
    Create pointers to the different sum function groups
2071
2259
  */
2072
2260
  tmp_table_param.group_parts= send_group_parts;
2073
2261
 
2074
 
  if (!(rollup.null_items= (Item_null_result**) session->alloc((sizeof(Item*) +
2075
 
                                                sizeof(Item**) +
2076
 
                                                sizeof(List<Item>) +
2077
 
                        ref_pointer_array_size)
2078
 
                        * send_group_parts )))
 
2262
  rollup.setNullItems((Item_null_result**) session->getMemRoot()->allocate((sizeof(Item*) +
 
2263
                                                                sizeof(Item**) +
 
2264
                                                                sizeof(List<Item>) +
 
2265
                                                                ref_pointer_array_size)
 
2266
                                                               * send_group_parts ));
 
2267
  if (! rollup.getNullItems())
 
2268
  {
2079
2269
    return 1;
 
2270
  }
2080
2271
 
2081
 
  rollup.fields= (List<Item>*) (rollup.null_items + send_group_parts);
2082
 
  rollup.ref_pointer_arrays= (Item***) (rollup.fields + send_group_parts);
2083
 
  ref_array= (Item**) (rollup.ref_pointer_arrays+send_group_parts);
 
2272
  rollup.setFields((List<Item>*) (rollup.getNullItems() + send_group_parts));
 
2273
  rollup.setRefPointerArrays((Item***) (rollup.getFields() + send_group_parts));
 
2274
  ref_array= (Item**) (rollup.getRefPointerArrays()+send_group_parts);
2084
2275
 
2085
2276
  /*
2086
2277
    Prepare space for field list for the different levels
2087
2278
    These will be filled up in rollup_make_fields()
2088
2279
  */
2089
 
  for (i= 0 ; i < send_group_parts ; i++)
 
2280
  for (uint32_t i= 0 ; i < send_group_parts ; i++)
2090
2281
  {
2091
 
    rollup.null_items[i]= new (session->mem_root) Item_null_result();
2092
 
    List<Item> *rollup_fields= &rollup.fields[i];
2093
 
    rollup_fields->empty();
2094
 
    rollup.ref_pointer_arrays[i]= ref_array;
 
2282
    rollup.getNullItems()[i]= new (session->mem_root) Item_null_result();
 
2283
    List<Item> *rollup_fields= &rollup.getFields()[i];
 
2284
    rollup_fields->clear();
 
2285
    rollup.getRefPointerArrays()[i]= ref_array;
2095
2286
    ref_array+= all_fields.elements;
2096
2287
  }
2097
 
  for (i= 0 ; i < send_group_parts; i++)
 
2288
 
 
2289
  for (uint32_t i= 0 ; i < send_group_parts; i++)
2098
2290
  {
2099
 
    for (j=0 ; j < fields_list.elements ; j++)
2100
 
      rollup.fields[i].push_back(rollup.null_items[i]);
 
2291
    for (uint32_t j= 0 ; j < fields_list.elements ; j++)
 
2292
    {
 
2293
      rollup.getFields()[i].push_back(rollup.getNullItems()[i]);
 
2294
    }
2101
2295
  }
2102
 
  List_iterator<Item> it(all_fields);
 
2296
 
 
2297
  List<Item>::iterator it(all_fields.begin());
2103
2298
  Item *item;
2104
2299
  while ((item= it++))
2105
2300
  {
2174
2369
*/
2175
2370
bool Join::rollup_make_fields(List<Item> &fields_arg, List<Item> &sel_fields, Item_sum ***func)
2176
2371
{
2177
 
  List_iterator_fast<Item> it(fields_arg);
 
2372
  List<Item>::iterator it(fields_arg.begin());
2178
2373
  Item *first_field= sel_fields.head();
2179
2374
  uint32_t level;
2180
2375
 
2205
2400
    uint32_t pos= send_group_parts - level -1;
2206
2401
    bool real_fields= 0;
2207
2402
    Item *item;
2208
 
    List_iterator<Item> new_it(rollup.fields[pos]);
2209
 
    Item **ref_array_start= rollup.ref_pointer_arrays[pos];
 
2403
    List<Item>::iterator new_it(rollup.getFields()[pos].begin());
 
2404
    Item **ref_array_start= rollup.getRefPointerArrays()[pos];
2210
2405
    Order *start_group;
2211
2406
 
2212
2407
    /* Point to first hidden field */
2219
2414
    for (i= 0, start_group= group_list ;i++ < pos ;start_group= start_group->next)
2220
2415
    {}
2221
2416
 
2222
 
    it.rewind();
 
2417
    it= fields_arg.begin();
2223
2418
    while ((item= it++))
2224
2419
    {
2225
2420
      if (item == first_field)
2304
2499
*/
2305
2500
int Join::rollup_send_data(uint32_t idx)
2306
2501
{
2307
 
  uint32_t i;
2308
 
  for (i= send_group_parts ; i-- > idx ; )
 
2502
  for (uint32_t i= send_group_parts ; i-- > idx ; )
2309
2503
  {
2310
2504
    /* Get reference pointers to sum functions in place */
2311
 
    memcpy(ref_pointer_array, rollup.ref_pointer_arrays[i],
2312
 
     ref_pointer_array_size);
 
2505
    memcpy(ref_pointer_array, rollup.getRefPointerArrays()[i], ref_pointer_array_size);
 
2506
 
2313
2507
    if ((!having || having->val_int()))
2314
2508
    {
2315
 
      if (send_records < unit->select_limit_cnt && do_send_rows &&
2316
 
    result->send_data(rollup.fields[i]))
2317
 
  return 1;
 
2509
      if (send_records < unit->select_limit_cnt && do_send_rows && result->send_data(rollup.getFields()[i]))
 
2510
      {
 
2511
        return 1;
 
2512
      }
2318
2513
      send_records++;
2319
2514
    }
2320
2515
  }
2321
2516
  /* Restore ref_pointer_array */
2322
2517
  set_items_ref_array(current_ref_pointer_array);
 
2518
 
2323
2519
  return 0;
2324
2520
}
2325
2521
 
2344
2540
*/
2345
2541
int Join::rollup_write_data(uint32_t idx, Table *table_arg)
2346
2542
{
2347
 
  uint32_t i;
2348
 
  for (i= send_group_parts ; i-- > idx ; )
 
2543
  for (uint32_t i= send_group_parts ; i-- > idx ; )
2349
2544
  {
2350
2545
    /* Get reference pointers to sum functions in place */
2351
 
    memcpy(ref_pointer_array, rollup.ref_pointer_arrays[i],
 
2546
    memcpy(ref_pointer_array, rollup.getRefPointerArrays()[i],
2352
2547
           ref_pointer_array_size);
2353
2548
    if ((!having || having->val_int()))
2354
2549
    {
2355
2550
      int write_error;
2356
2551
      Item *item;
2357
 
      List_iterator_fast<Item> it(rollup.fields[i]);
 
2552
      List<Item>::iterator it(rollup.getFields()[i].begin());
2358
2553
      while ((item= it++))
2359
2554
      {
2360
2555
        if (item->type() == Item::NULL_ITEM && item->is_result_field())
2370
2565
  }
2371
2566
  /* Restore ref_pointer_array */
2372
2567
  set_items_ref_array(current_ref_pointer_array);
 
2568
 
2373
2569
  return 0;
2374
2570
}
2375
2571
 
3016
3212
      case REAL_RESULT:
3017
3213
        key_length+= sizeof(double);
3018
3214
        break;
 
3215
 
3019
3216
      case INT_RESULT:
3020
3217
        key_length+= sizeof(int64_t);
3021
3218
        break;
 
3219
 
3022
3220
      case DECIMAL_RESULT:
3023
 
        key_length+= my_decimal_get_binary_size(group_item->max_length -
 
3221
        key_length+= class_decimal_get_binary_size(group_item->max_length -
3024
3222
                                                (group_item->decimals ? 1 : 0),
3025
3223
                                                group_item->decimals);
3026
3224
        break;
 
3225
 
3027
3226
      case STRING_RESULT:
3028
 
      {
3029
 
        enum enum_field_types type= group_item->field_type();
3030
 
        /*
3031
 
          As items represented as DATE/TIME fields in the group buffer
3032
 
          have STRING_RESULT result type, we increase the length
3033
 
          by 8 as maximum pack length of such fields.
3034
 
        */
3035
 
        if (type == DRIZZLE_TYPE_DATE ||
3036
 
            type == DRIZZLE_TYPE_DATETIME ||
3037
 
            type == DRIZZLE_TYPE_TIMESTAMP)
3038
 
        {
3039
 
          key_length+= 8;
3040
 
        }
3041
 
        else
3042
 
        {
 
3227
        {
 
3228
          enum enum_field_types type= group_item->field_type();
3043
3229
          /*
3044
 
            Group strings are taken as varstrings and require an length field.
3045
 
            A field is not yet created by create_tmp_field()
3046
 
            and the sizes should match up.
 
3230
            As items represented as DATE/TIME fields in the group buffer
 
3231
            have STRING_RESULT result type, we increase the length
 
3232
            by 8 as maximum pack length of such fields.
3047
3233
          */
3048
 
          key_length+= group_item->max_length + HA_KEY_BLOB_LENGTH;
 
3234
          if (field::isDateTime(type))
 
3235
          {
 
3236
            key_length+= 8;
 
3237
          }
 
3238
          else
 
3239
          {
 
3240
            /*
 
3241
              Group strings are taken as varstrings and require an length field.
 
3242
              A field is not yet created by create_tmp_field()
 
3243
              and the sizes should match up.
 
3244
            */
 
3245
            key_length+= group_item->max_length + HA_KEY_BLOB_LENGTH;
 
3246
          }
 
3247
 
 
3248
          break;
3049
3249
        }
3050
 
        break;
3051
 
      }
3052
 
      default:
 
3250
 
 
3251
      case ROW_RESULT:
3053
3252
        /* This case should never be choosen */
3054
3253
        assert(0);
3055
3254
        my_error(ER_OUT_OF_RESOURCES, MYF(ME_FATALERROR));
3056
3255
      }
3057
3256
    }
 
3257
 
3058
3258
    parts++;
 
3259
 
3059
3260
    if (group_item->maybe_null)
3060
3261
      null_parts++;
3061
3262
  }
 
3263
 
3062
3264
  join->tmp_table_param.group_length=key_length+null_parts;
3063
3265
  join->tmp_table_param.group_parts=parts;
3064
3266
  join->tmp_table_param.group_null_parts=null_parts;
3201
3403
 
3202
3404
  table_count=join->tables;
3203
3405
  if (!(join->join_tab=join_tab=
3204
 
  (JoinTable*) session->alloc(sizeof(JoinTable)*table_count)))
 
3406
  (JoinTable*) session->getMemRoot()->allocate(sizeof(JoinTable)*table_count)))
3205
3407
    return(true);
3206
3408
 
 
3409
  for (i= 0; i < table_count; i++)
 
3410
    new (join_tab+i) JoinTable();
 
3411
 
3207
3412
  join->full_join=0;
3208
3413
 
3209
3414
  used_tables= OUTER_REF_TABLE_BIT;   // Outer row is already read
3322
3527
    i.e. they have subqueries, unions or call stored procedures.
3323
3528
    TODO: calculate a correct cost for a query with subqueries and UNIONs.
3324
3529
  */
3325
 
  if (join->session->lex->is_single_level_stmt())
 
3530
  if (join->session->getLex()->is_single_level_stmt())
3326
3531
    join->session->status_var.last_query_cost= join->best_read;
3327
3532
  return(false);
3328
3533
}
3835
4040
        will ensure that this will be used
3836
4041
      */
3837
4042
      best= tmp;
3838
 
      records= rows2double(rnd_records);
 
4043
      records= rnd_records;
3839
4044
      best_key= 0;
3840
4045
      /* range/index_merge/ALL/index access method are "independent", so: */
3841
4046
      best_ref_depends_map= 0;
4356
4561
  */
4357
4562
  if (!join->table_reexec)
4358
4563
  {
4359
 
    if (!(join->table_reexec= (Table**) join->session->alloc(sizeof(Table*))))
 
4564
    if (!(join->table_reexec= (Table**) join->session->getMemRoot()->allocate(sizeof(Table*))))
4360
4565
      return(true);
4361
4566
    if (join->tmp_join)
4362
4567
      join->tmp_join->table_reexec= join->table_reexec;
4364
4569
  if (!join->join_tab_reexec)
4365
4570
  {
4366
4571
    if (!(join->join_tab_reexec=
4367
 
          (JoinTable*) join->session->alloc(sizeof(JoinTable))))
 
4572
          (JoinTable*) join->session->getMemRoot()->allocate(sizeof(JoinTable))))
4368
4573
      return(true);
 
4574
    new (join->join_tab_reexec) JoinTable();
4369
4575
    if (join->tmp_join)
4370
4576
      join->tmp_join->join_tab_reexec= join->join_tab_reexec;
4371
4577
  }
4386
4592
  join->row_limit=join->unit->select_limit_cnt;
4387
4593
  join->do_send_rows = (join->row_limit) ? 1 : 0;
4388
4594
 
4389
 
  join_tab->cache.buff=0;                       /* No caching */
4390
4595
  join_tab->table=tmp_table;
4391
4596
  join_tab->select=0;
4392
4597
  join_tab->select_cond=0;
4477
4682
      /* Ignore sj-nests: */
4478
4683
      if (!embedding->on_expr)
4479
4684
        continue;
4480
 
      nested_join_st *nested_join= embedding->getNestedJoin();
 
4685
      NestedJoin *nested_join= embedding->getNestedJoin();
4481
4686
      if (!nested_join->counter_)
4482
4687
      {
4483
4688
        /*
4516
4721
      if (join->tables > 1)
4517
4722
        cond->update_used_tables();             // Tablenr may have changed
4518
4723
      if (join->const_tables == join->tables &&
4519
 
          session->lex->current_select->master_unit() ==
4520
 
          &session->lex->unit)          // not upper level SELECT
 
4724
          session->getLex()->current_select->master_unit() ==
 
4725
          &session->getLex()->unit)             // not upper level SELECT
4521
4726
        join->const_table_map|=RAND_TABLE_BIT;
4522
4727
      {                                         // Check const tables
4523
4728
        COND *const_cond=
4586
4791
        tab->ref.key= -1;
4587
4792
        tab->ref.key_parts= 0;          // Don't use ref key.
4588
4793
        cur_pos= join->getPosFromOptimalPlan(i);
4589
 
        cur_pos.setFanout(rows2double(tab->quick->records));
 
4794
        cur_pos.setFanout(tab->quick->records);
4590
4795
        /*
4591
4796
           We will use join cache here : prevent sorting of the first
4592
4797
           table only and sort at the end.
4595
4800
          join->full_join= 1;
4596
4801
      }
4597
4802
 
 
4803
      if (join->full_join and not session->getLex()->current_select->is_cross and not cond)
 
4804
      {
 
4805
        my_error(ER_CARTESIAN_JOIN_ATTEMPTED, MYF(0));
 
4806
        return 1;
 
4807
      }
 
4808
 
4598
4809
      tmp= NULL;
4599
4810
      if (cond)
4600
4811
        tmp= make_cond_for_table(cond,used_tables,current_map, 0);
4625
4836
          tab->type == AM_EQ_REF)
4626
4837
      {
4627
4838
        optimizer::SqlSelect *sel= tab->select= ((optimizer::SqlSelect*)
4628
 
            session->memdup((unsigned char*) select,
 
4839
            session->getMemRoot()->duplicate((unsigned char*) select,
4629
4840
              sizeof(*select)));
4630
4841
        if (! sel)
4631
4842
          return 1;                     // End of memory
4763
4974
                                         current_map, 0)))
4764
4975
            {
4765
4976
              tab->cache.select= (optimizer::SqlSelect*)
4766
 
                session->memdup((unsigned char*) sel, sizeof(optimizer::SqlSelect));
 
4977
                session->getMemRoot()->duplicate((unsigned char*) sel, sizeof(optimizer::SqlSelect));
4767
4978
              tab->cache.select->cond= tmp;
4768
4979
              tab->cache.select->read_tables= join->const_table_map;
4769
4980
            }
4899
5110
 
4900
5111
    if (tab->insideout_match_tab)
4901
5112
    {
4902
 
      if (! (tab->insideout_buf= (unsigned char*) join->session->alloc(tab->table->key_info
 
5113
      if (! (tab->insideout_buf= (unsigned char*) join->session->getMemRoot()->allocate(tab->table->key_info
4903
5114
                                                                       [tab->index].
4904
5115
                                                                       key_length)))
4905
5116
        return true;
5081
5292
  {
5082
5293
    if (send_row)
5083
5294
    {
5084
 
      List_iterator_fast<Item> it(fields);
 
5295
      List<Item>::iterator it(fields.begin());
5085
5296
      Item *item;
5086
5297
      while ((item= it++))
5087
5298
        item->no_rows_in_result();
5217
5428
static COND *simplify_joins(Join *join, List<TableList> *join_list, COND *conds, bool top)
5218
5429
{
5219
5430
  TableList *table;
5220
 
  nested_join_st *nested_join;
 
5431
  NestedJoin *nested_join;
5221
5432
  TableList *prev_table= 0;
5222
 
  List_iterator<TableList> li(*join_list);
 
5433
  List<TableList>::iterator li(join_list->begin());
5223
5434
 
5224
5435
  /*
5225
5436
    Try to simplify join operations from join_list.
5355
5566
    Flatten nested joins that can be flattened.
5356
5567
    no ON expression and not a semi-join => can be flattened.
5357
5568
  */
5358
 
  li.rewind();
 
5569
  li= join_list->begin();
5359
5570
  while ((table= li++))
5360
5571
  {
5361
5572
    nested_join= table->getNestedJoin();
5362
5573
    if (nested_join && !table->on_expr)
5363
5574
    {
5364
5575
      TableList *tbl;
5365
 
      List_iterator<TableList> it(nested_join->join_list);
 
5576
      List<TableList>::iterator it(nested_join->join_list.begin());
5366
5577
      while ((tbl= it++))
5367
5578
      {
5368
5579
        tbl->setEmbedding(table->getEmbedding());
5385
5596
 
5386
5597
  /* Calculate how many saved fields there is in list */
5387
5598
  field_count=0;
5388
 
  List_iterator<Item> it(fields);
 
5599
  List<Item>::iterator it(fields.begin());
5389
5600
  Item *item;
5390
5601
  while ((item=it++))
5391
5602
  {
5439
5650
                               bool *hidden_group_fields)
5440
5651
{
5441
5652
  int res;
5442
 
  nesting_map save_allow_sum_func=session->lex->allow_sum_func ;
 
5653
  nesting_map save_allow_sum_func=session->getLex()->allow_sum_func ;
5443
5654
 
5444
 
  session->lex->allow_sum_func&= ~(1 << session->lex->current_select->nest_level);
 
5655
  session->getLex()->allow_sum_func&= ~(1 << session->getLex()->current_select->nest_level);
5445
5656
  res= session->setup_conds(tables, conds);
5446
5657
 
5447
 
  session->lex->allow_sum_func|= 1 << session->lex->current_select->nest_level;
 
5658
  session->getLex()->allow_sum_func|= 1 << session->getLex()->current_select->nest_level;
5448
5659
  res= res || setup_order(session, ref_pointer_array, tables, fields, all_fields,
5449
5660
                          order);
5450
 
  session->lex->allow_sum_func&= ~(1 << session->lex->current_select->nest_level);
 
5661
  session->getLex()->allow_sum_func&= ~(1 << session->getLex()->current_select->nest_level);
5451
5662
  res= res || setup_group(session, ref_pointer_array, tables, fields, all_fields,
5452
5663
                          group, hidden_group_fields);
5453
 
  session->lex->allow_sum_func= save_allow_sum_func;
 
5664
  session->getLex()->allow_sum_func= save_allow_sum_func;
5454
5665
  return(res);
5455
5666
}
5456
5667
 
5490
5701
 
5491
5702
  table_count= join->tables;
5492
5703
  stat= (JoinTable*) join->session->calloc(sizeof(JoinTable)*table_count);
5493
 
  stat_ref= (JoinTable**) join->session->alloc(sizeof(JoinTable*)*MAX_TABLES);
5494
 
  table_vector= (Table**) join->session->alloc(sizeof(Table*)*(table_count*2));
 
5704
  stat_ref= (JoinTable**) join->session->getMemRoot()->allocate(sizeof(JoinTable*)*MAX_TABLES);
 
5705
  table_vector= (Table**) join->session->getMemRoot()->allocate(sizeof(Table*)*(table_count*2));
5495
5706
  if (! stat || ! stat_ref || ! table_vector)
5496
5707
    return 1;
5497
5708
 
5555
5766
      s->embedding_map.reset();
5556
5767
      do
5557
5768
      {
5558
 
        nested_join_st *nested_join= embedding->getNestedJoin();
 
5769
        NestedJoin *nested_join= embedding->getNestedJoin();
5559
5770
        s->embedding_map|= nested_join->nj_map;
5560
5771
        s->dependent|= embedding->getDepTables();
5561
5772
        embedding= embedding->getEmbedding();
5584
5795
       As we use bitmaps to represent the relation the complexity
5585
5796
       of the algorithm is O((number of tables)^2).
5586
5797
    */
5587
 
    for (i= 0, s= stat ; i < table_count ; i++, s++)
 
5798
    for (i= 0; i < table_count; i++)
5588
5799
    {
5589
 
      for (uint32_t j= 0 ; j < table_count ; j++)
 
5800
      uint32_t j;
 
5801
      table= stat[i].table;
 
5802
 
 
5803
      if (!table->reginfo.join_tab->dependent)
 
5804
        continue;
 
5805
 
 
5806
      for (j= 0, s= stat; j < table_count; j++, s++)
5590
5807
      {
5591
 
        table= stat[j].table;
5592
5808
        if (s->dependent & table->map)
 
5809
        {
 
5810
          table_map was_dependent= s->dependent;
5593
5811
          s->dependent |= table->reginfo.join_tab->dependent;
 
5812
          if (i > j && s->dependent != was_dependent)
 
5813
          {
 
5814
            i= j= 1;
 
5815
            break;
 
5816
          }
 
5817
        }
5594
5818
      }
5595
 
      if (s->dependent)
5596
 
        s->table->maybe_null= 1;
5597
5819
    }
5598
5820
    /* Catch illegal cross references for outer joins */
5599
5821
    for (i= 0, s= stat ; i < table_count ; i++, s++)
5604
5826
        my_message(ER_WRONG_OUTER_JOIN, ER(ER_WRONG_OUTER_JOIN), MYF(0));
5605
5827
        return 1;
5606
5828
      }
 
5829
      if (outer_join & s->table->map)
 
5830
        s->table->maybe_null= 1;
 
5831
 
5607
5832
      s->key_dependent= s->dependent;
5608
5833
    }
5609
5834
  }
5625
5850
    s= p_pos->getJoinTable();
5626
5851
    s->type= AM_SYSTEM;
5627
5852
    join->const_table_map|=s->table->map;
5628
 
    if ((tmp= join_read_const_table(s, p_pos)))
 
5853
    if ((tmp= s->joinReadConstTable(p_pos)))
5629
5854
    {
5630
5855
      if (tmp > 0)
5631
5856
        return 1;                       // Fatal error
5699
5924
          join->const_table_map|=table->map;
5700
5925
          set_position(join, const_count++, s, (optimizer::KeyUse*) 0);
5701
5926
          partial_pos= join->getSpecificPosInPartialPlan(const_count - 1);
5702
 
          if ((tmp= join_read_const_table(s, partial_pos)))
 
5927
          if ((tmp= s->joinReadConstTable(partial_pos)))
5703
5928
          {
5704
5929
            if (tmp > 0)
5705
5930
              return 1;                 // Fatal error
5751
5976
                if (create_ref_for_key(join, s, start_keyuse, found_const_table_map))
5752
5977
                  return 1;
5753
5978
                partial_pos= join->getSpecificPosInPartialPlan(const_count - 1);
5754
 
                if ((tmp=join_read_const_table(s, partial_pos)))
 
5979
                if ((tmp=s->joinReadConstTable(partial_pos)))
5755
5980
                {
5756
5981
                  if (tmp > 0)
5757
5982
                    return 1;                   // Fatal error
5835
6060
      s->quick=select->quick;
5836
6061
      s->needed_reg=select->needed_reg;
5837
6062
      select->quick=0;
 
6063
 
5838
6064
      if (records == 0 && s->table->reginfo.impossible_range)
5839
6065
      {
5840
6066
        /*
5912
6138
*/
5913
6139
static uint32_t build_bitmap_for_nested_joins(List<TableList> *join_list, uint32_t first_unused)
5914
6140
{
5915
 
  List_iterator<TableList> li(*join_list);
 
6141
  List<TableList>::iterator li(join_list->begin());
5916
6142
  TableList *table;
5917
6143
  while ((table= li++))
5918
6144
  {
5919
 
    nested_join_st *nested_join;
 
6145
    NestedJoin *nested_join;
5920
6146
    if ((nested_join= table->getNestedJoin()))
5921
6147
    {
5922
6148
      /*
5973
6199
}
5974
6200
 
5975
6201
/**
5976
 
  Set nested_join_st::counter=0 in all nested joins in passed list.
 
6202
  Set NestedJoin::counter=0 in all nested joins in passed list.
5977
6203
 
5978
 
    Recursively set nested_join_st::counter=0 for all nested joins contained in
 
6204
    Recursively set NestedJoin::counter=0 for all nested joins contained in
5979
6205
    the passed join_list.
5980
6206
 
5981
6207
  @param join_list  List of nested joins to process. It may also contain base
5983
6209
*/
5984
6210
static void reset_nj_counters(List<TableList> *join_list)
5985
6211
{
5986
 
  List_iterator<TableList> li(*join_list);
 
6212
  List<TableList>::iterator li(join_list->begin());
5987
6213
  TableList *table;
5988
6214
  while ((table= li++))
5989
6215
  {
5990
 
    nested_join_st *nested_join;
 
6216
    NestedJoin *nested_join;
5991
6217
    if ((nested_join= table->getNestedJoin()))
5992
6218
    {
5993
6219
      nested_join->counter_= 0;
6073
6299
  Join *join= last->join;
6074
6300
  for (;last_emb != NULL; last_emb= last_emb->getEmbedding())
6075
6301
  {
6076
 
    nested_join_st *nest= last_emb->getNestedJoin();
 
6302
    NestedJoin *nest= last_emb->getNestedJoin();
6077
6303
    
6078
6304
    bool was_fully_covered= nest->is_fully_covered();
6079
6305