~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/join.cc

  • Committer: Brian Aker
  • Date: 2011-01-06 05:17:09 UTC
  • Revision ID: brian@tangent.org-20110106051709-oa0se8ur02uc6i9o
Added native functions into the function table.

Show diffs side-by-side

added added

removed removed

Lines of Context:
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>
61
 
#include <drizzled/plugin/storage_engine.h>
62
 
#include <drizzled/session.h>
63
 
#include <drizzled/select_result.h>
64
 
 
65
 
#include <drizzled/debug.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"
66
61
 
67
62
#include <algorithm>
68
63
 
70
65
 
71
66
namespace drizzled
72
67
{
 
68
 
73
69
extern plugin::StorageEngine *heap_engine;
 
70
extern std::bitset<12> test_flags;
74
71
 
75
72
/** Declarations of static functions used in this source file. */
76
73
static bool make_group_fields(Join *main_join, Join *curr_join);
136
133
static bool add_ref_to_table_cond(Session *session, JoinTable *join_tab);
137
134
static void free_blobs(Field **ptr); /* Rename this method...conflicts with another in global namespace... */
138
135
 
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
 
 
317
136
/**
318
137
  Prepare of whole select (including sub queries in future).
319
138
 
351
170
  join_list= &select_lex->top_join_list;
352
171
  union_part= unit_arg->is_union();
353
172
 
354
 
  session->getLex()->current_select->is_item_list_lookup= 1;
 
173
  session->lex->current_select->is_item_list_lookup= 1;
355
174
  /*
356
175
    If we have already executed SELECT, then it have not sense to prevent
357
176
    its table from update (see unique_table())
392
211
 
393
212
  if (having)
394
213
  {
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;
 
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;
398
217
    select_lex->having_fix_field= 1;
399
218
    bool having_fix_rc= (!having->fixed &&
400
219
       (having->fix_fields(session, &having) ||
402
221
    select_lex->having_fix_field= 0;
403
222
    if (having_fix_rc || session->is_error())
404
223
      return(-1);
405
 
    session->getLex()->allow_sum_func= save_allow_sum_func;
 
224
    session->lex->allow_sum_func= save_allow_sum_func;
406
225
  }
407
226
 
408
227
  {
452
271
            in_subs  &&                                                   // 1
453
272
            !select_lex->master_unit()->first_select()->next_select() &&  // 2
454
273
            select_lex->master_unit()->first_select()->leaf_tables &&     // 3
455
 
            session->getLex()->sql_command == SQLCOM_SELECT)                       // *
 
274
            session->lex->sql_command == SQLCOM_SELECT)                       // *
456
275
        {
457
276
          if (in_subs->is_top_level_item() &&                             // 4
458
277
              !in_subs->is_correlated &&                                  // 5
625
444
    select_limit= HA_POS_ERROR;
626
445
  do_send_rows = (unit->select_limit_cnt) ? 1 : 0;
627
446
  // Ignore errors of execution if option IGNORE present
628
 
  if (session->getLex()->ignore)
629
 
    session->getLex()->current_select->no_error= 1;
 
447
  if (session->lex->ignore)
 
448
    session->lex->current_select->no_error= 1;
630
449
 
631
450
#ifdef HAVE_REF_TO_FIELDS     // Not done yet
632
451
  /* Add HAVING to WHERE if possible */
726
545
        conjunctions.
727
546
        Preserve conditions for EXPLAIN.
728
547
      */
729
 
      if (conds && !(session->getLex()->describe & DESCRIBE_EXTENDED))
 
548
      if (conds && !(session->lex->describe & DESCRIBE_EXTENDED))
730
549
      {
731
550
        COND *table_independent_conds= make_cond_for_table(conds, PSEUDO_TABLE_BITS, 0, 0);
732
551
        conds= table_independent_conds;
761
580
      !(select_options & SELECT_DESCRIBE) &&
762
581
      (!conds ||
763
582
       !(conds->used_tables() & RAND_TABLE_BIT) ||
764
 
       select_lex->master_unit() == &session->getLex()->unit)) // upper level SELECT
 
583
       select_lex->master_unit() == &session->lex->unit)) // upper level SELECT
765
584
  {
766
585
    zero_result_cause= "no matching row in const table";
767
586
    goto setup_subq_exit;
821
640
 
822
641
  if (conds &&!outer_join && const_table_map != found_const_table_map &&
823
642
      (select_options & SELECT_DESCRIBE) &&
824
 
      select_lex->master_unit() == &session->getLex()->unit) // upper level SELECT
 
643
      select_lex->master_unit() == &session->lex->unit) // upper level SELECT
825
644
  {
826
645
    conds=new Item_int((int64_t) 0,1);  // Always false
827
646
  }
909
728
  }
910
729
  if (group_list || tmp_table_param.sum_func_count)
911
730
  {
912
 
    if (! hidden_group_fields && rollup.getState() == Rollup::STATE_NONE)
 
731
    if (! hidden_group_fields && rollup.state == ROLLUP::STATE_NONE)
913
732
      select_distinct=0;
914
733
  }
915
734
  else if (select_distinct && tables - const_tables == 1)
973
792
  {
974
793
    Order *old_group_list;
975
794
    group_list= remove_constants(this, (old_group_list= group_list), conds,
976
 
                                 rollup.getState() == Rollup::STATE_NONE,
 
795
                                 rollup.state == ROLLUP::STATE_NONE,
977
796
                                 &simple_group);
978
797
    if (session->is_error())
979
798
    {
1165
984
 
1166
985
    tmp_table_param.hidden_field_count= (all_fields.elements -
1167
986
           fields_list.elements);
1168
 
    Order *tmp_group= (((not simple_group) or not (getDebug().test(debug::NO_KEY_GROUP))) ? group_list : (Order*) 0);
1169
 
 
 
987
    Order *tmp_group= ((!simple_group &&
 
988
                           ! (test_flags.test(TEST_NO_KEY_GROUP))) ? group_list :
 
989
                                                                     (Order*) 0);
1170
990
    /*
1171
991
      Pushing LIMIT to the temporary table creation is not applicable
1172
992
      when there is ORDER BY or GROUP BY or there is no GROUP BY, but
1175
995
    */
1176
996
    ha_rows tmp_rows_limit= ((order == 0 || skip_sort_order) &&
1177
997
                             !tmp_group &&
1178
 
                             !session->getLex()->current_select->with_sum_func) ?
 
998
                             !session->lex->current_select->with_sum_func) ?
1179
999
                            select_limit : HA_POS_ERROR;
1180
1000
 
1181
1001
    if (!(exec_tmp_table1=
1352
1172
*/
1353
1173
bool Join::init_save_join_tab()
1354
1174
{
1355
 
  if (!(tmp_join= (Join*)session->getMemRoot()->allocate(sizeof(Join))))
 
1175
  if (!(tmp_join= (Join*)session->alloc(sizeof(Join))))
1356
1176
    return 1;
1357
1177
 
1358
1178
  error= 0;              // Ensure that tmp_join.error= 0
1365
1185
{
1366
1186
  if (! join_tab_save && select_lex->master_unit()->uncacheable.any())
1367
1187
  {
1368
 
    if (!(join_tab_save= (JoinTable*)session->getMemRoot()->duplicate((unsigned char*) join_tab,
 
1188
    if (!(join_tab_save= (JoinTable*)session->memdup((unsigned char*) join_tab,
1369
1189
            sizeof(JoinTable) * tables)))
1370
1190
      return 1;
1371
1191
  }
1871
1691
    for a derived table which is always materialized.
1872
1692
    Otherwise we would not be able to print the query  correctly.
1873
1693
  */
1874
 
  if (items0 && (session->getLex()->describe & DESCRIBE_EXTENDED) && select_lex->linkage == DERIVED_TABLE_TYPE)
 
1694
  if (items0 && (session->lex->describe & DESCRIBE_EXTENDED) && select_lex->linkage == DERIVED_TABLE_TYPE)
1875
1695
    set_items_ref_array(items0);
1876
1696
 
1877
1697
  return;
2003
1823
    Optimization: if not EXPLAIN and we are done with the Join,
2004
1824
    free all tables.
2005
1825
  */
2006
 
  bool full= (select_lex->uncacheable.none() && ! session->getLex()->describe);
 
1826
  bool full= (select_lex->uncacheable.none() && ! session->lex->describe);
2007
1827
  bool can_unlock= full;
2008
1828
 
2009
1829
  cleanup(full);
2014
1834
    for (sl= tmp_unit->first_select(); sl; sl= sl->next_select())
2015
1835
    {
2016
1836
      Item_subselect *subselect= sl->master_unit()->item;
2017
 
      bool full_local= full && (!subselect || 
2018
 
                                (subselect->is_evaluated() &&
2019
 
                                !subselect->is_uncacheable()));
 
1837
      bool full_local= full && (!subselect || subselect->is_evaluated());
2020
1838
      /*
2021
1839
        If this join is evaluated, we can fully clean it up and clean up all
2022
1840
        its underlying joins even if they are correlated -- they will not be
2038
1856
  if (can_unlock && lock && session->lock &&
2039
1857
      !(select_options & SELECT_NO_UNLOCK) &&
2040
1858
      !select_lex->subquery_in_having &&
2041
 
      (select_lex == (session->getLex()->unit.fake_select_lex ?
2042
 
                      session->getLex()->unit.fake_select_lex : &session->getLex()->select_lex)))
 
1859
      (select_lex == (session->lex->unit.fake_select_lex ?
 
1860
                      session->lex->unit.fake_select_lex : &session->lex->select_lex)))
2043
1861
  {
2044
1862
    /*
2045
1863
      TODO: unlock tables even if the join isn't top level select in the
2112
1930
      We can't call delete_elements() on copy_funcs as this will cause
2113
1931
      problems in free_elements() as some of the elements are then deleted.
2114
1932
    */
2115
 
    tmp_table_param.copy_funcs.clear();
 
1933
    tmp_table_param.copy_funcs.empty();
2116
1934
    /*
2117
1935
      If we have tmp_join and 'this' Join is not tmp_join and
2118
1936
      tmp_table_param.copy_field's  of them are equal then we have to remove
2142
1960
    are not re-calculated.
2143
1961
  */
2144
1962
  for (uint32_t i= join->const_tables; i < join->tables; i++)
2145
 
  {
2146
1963
    join->table[i]->mark_as_null_row();   // All fields are NULL
2147
 
  }
2148
1964
}
2149
1965
 
2150
1966
/**
2165
1981
    If we are using rollup, we need a copy of the summary functions for
2166
1982
    each level
2167
1983
  */
2168
 
  if (rollup.getState() != Rollup::STATE_NONE)
 
1984
  if (rollup.state != ROLLUP::STATE_NONE)
2169
1985
    func_count*= (send_group_parts+1);
2170
1986
 
2171
1987
  group_parts= send_group_parts;
2213
2029
                              bool before_group_by, 
2214
2030
                              bool recompute)
2215
2031
{
2216
 
  List<Item>::iterator it(field_list.begin());
 
2032
  List_iterator_fast<Item> it(field_list);
2217
2033
  Item_sum **func;
2218
2034
  Item *item;
2219
2035
 
2228
2044
         ((Item_sum *)item)->depended_from() == select_lex))
2229
2045
      *func++= (Item_sum*) item;
2230
2046
  }
2231
 
  if (before_group_by && rollup.getState() == Rollup::STATE_INITED)
 
2047
  if (before_group_by && rollup.state == ROLLUP::STATE_INITED)
2232
2048
  {
2233
 
    rollup.setState(Rollup::STATE_READY);
 
2049
    rollup.state= ROLLUP::STATE_READY;
2234
2050
    if (rollup_make_fields(field_list, send_fields, &func))
2235
2051
      return true;     // Should never happen
2236
2052
  }
2237
 
  else if (rollup.getState() == Rollup::STATE_NONE)
 
2053
  else if (rollup.state == ROLLUP::STATE_NONE)
2238
2054
  {
2239
2055
    for (uint32_t i=0 ; i <= send_group_parts ;i++)
2240
2056
      sum_funcs_end[i]= func;
2241
2057
  }
2242
 
  else if (rollup.getState() == Rollup::STATE_READY)
 
2058
  else if (rollup.state == ROLLUP::STATE_READY)
2243
2059
    return(false);                         // Don't put end marker
2244
2060
  *func=0;          // End marker
2245
2061
  return(false);
2248
2064
/** Allocate memory needed for other rollup functions. */
2249
2065
bool Join::rollup_init()
2250
2066
{
 
2067
  uint32_t i,j;
2251
2068
  Item **ref_array;
2252
2069
 
2253
2070
  tmp_table_param.quick_group= 0; // Can't create groups in tmp table
2254
 
  rollup.setState(Rollup::STATE_INITED);
 
2071
  rollup.state= ROLLUP::STATE_INITED;
2255
2072
 
2256
2073
  /*
2257
2074
    Create pointers to the different sum function groups
2259
2076
  */
2260
2077
  tmp_table_param.group_parts= send_group_parts;
2261
2078
 
2262
 
  rollup.setNullItems((Item_null_result**) session->getMemRoot()->allocate((sizeof(Item*) +
 
2079
  if (!(rollup.null_items= (Item_null_result**) session->alloc((sizeof(Item*) +
2263
2080
                                                                sizeof(Item**) +
2264
2081
                                                                sizeof(List<Item>) +
2265
2082
                                                                ref_pointer_array_size)
2266
 
                                                               * send_group_parts ));
2267
 
  if (! rollup.getNullItems())
 
2083
                                                               * send_group_parts )))
2268
2084
  {
2269
2085
    return 1;
2270
2086
  }
2271
2087
 
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);
 
2088
  rollup.fields= (List<Item>*) (rollup.null_items + send_group_parts);
 
2089
  rollup.ref_pointer_arrays= (Item***) (rollup.fields + send_group_parts);
 
2090
  ref_array= (Item**) (rollup.ref_pointer_arrays+send_group_parts);
2275
2091
 
2276
2092
  /*
2277
2093
    Prepare space for field list for the different levels
2278
2094
    These will be filled up in rollup_make_fields()
2279
2095
  */
2280
 
  for (uint32_t i= 0 ; i < send_group_parts ; i++)
 
2096
  for (i= 0 ; i < send_group_parts ; i++)
2281
2097
  {
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;
 
2098
    rollup.null_items[i]= new (session->mem_root) Item_null_result();
 
2099
    List<Item> *rollup_fields= &rollup.fields[i];
 
2100
    rollup_fields->empty();
 
2101
    rollup.ref_pointer_arrays[i]= ref_array;
2286
2102
    ref_array+= all_fields.elements;
2287
2103
  }
2288
 
 
2289
 
  for (uint32_t i= 0 ; i < send_group_parts; i++)
 
2104
  for (i= 0 ; i < send_group_parts; i++)
2290
2105
  {
2291
 
    for (uint32_t j= 0 ; j < fields_list.elements ; j++)
2292
 
    {
2293
 
      rollup.getFields()[i].push_back(rollup.getNullItems()[i]);
2294
 
    }
 
2106
    for (j=0 ; j < fields_list.elements ; j++)
 
2107
      rollup.fields[i].push_back(rollup.null_items[i]);
2295
2108
  }
2296
 
 
2297
 
  List<Item>::iterator it(all_fields.begin());
 
2109
  List_iterator<Item> it(all_fields);
2298
2110
  Item *item;
2299
2111
  while ((item= it++))
2300
2112
  {
2369
2181
*/
2370
2182
bool Join::rollup_make_fields(List<Item> &fields_arg, List<Item> &sel_fields, Item_sum ***func)
2371
2183
{
2372
 
  List<Item>::iterator it(fields_arg.begin());
 
2184
  List_iterator_fast<Item> it(fields_arg);
2373
2185
  Item *first_field= sel_fields.head();
2374
2186
  uint32_t level;
2375
2187
 
2400
2212
    uint32_t pos= send_group_parts - level -1;
2401
2213
    bool real_fields= 0;
2402
2214
    Item *item;
2403
 
    List<Item>::iterator new_it(rollup.getFields()[pos].begin());
2404
 
    Item **ref_array_start= rollup.getRefPointerArrays()[pos];
 
2215
    List_iterator<Item> new_it(rollup.fields[pos]);
 
2216
    Item **ref_array_start= rollup.ref_pointer_arrays[pos];
2405
2217
    Order *start_group;
2406
2218
 
2407
2219
    /* Point to first hidden field */
2414
2226
    for (i= 0, start_group= group_list ;i++ < pos ;start_group= start_group->next)
2415
2227
    {}
2416
2228
 
2417
 
    it= fields_arg.begin();
 
2229
    it.rewind();
2418
2230
    while ((item= it++))
2419
2231
    {
2420
2232
      if (item == first_field)
2499
2311
*/
2500
2312
int Join::rollup_send_data(uint32_t idx)
2501
2313
{
2502
 
  for (uint32_t i= send_group_parts ; i-- > idx ; )
 
2314
  uint32_t i;
 
2315
  for (i= send_group_parts ; i-- > idx ; )
2503
2316
  {
2504
2317
    /* Get reference pointers to sum functions in place */
2505
 
    memcpy(ref_pointer_array, rollup.getRefPointerArrays()[i], ref_pointer_array_size);
2506
 
 
 
2318
    memcpy(ref_pointer_array, rollup.ref_pointer_arrays[i],
 
2319
     ref_pointer_array_size);
2507
2320
    if ((!having || having->val_int()))
2508
2321
    {
2509
 
      if (send_records < unit->select_limit_cnt && do_send_rows && result->send_data(rollup.getFields()[i]))
2510
 
      {
2511
 
        return 1;
2512
 
      }
 
2322
      if (send_records < unit->select_limit_cnt && do_send_rows &&
 
2323
    result->send_data(rollup.fields[i]))
 
2324
  return 1;
2513
2325
      send_records++;
2514
2326
    }
2515
2327
  }
2516
2328
  /* Restore ref_pointer_array */
2517
2329
  set_items_ref_array(current_ref_pointer_array);
2518
 
 
2519
2330
  return 0;
2520
2331
}
2521
2332
 
2540
2351
*/
2541
2352
int Join::rollup_write_data(uint32_t idx, Table *table_arg)
2542
2353
{
2543
 
  for (uint32_t i= send_group_parts ; i-- > idx ; )
 
2354
  uint32_t i;
 
2355
  for (i= send_group_parts ; i-- > idx ; )
2544
2356
  {
2545
2357
    /* Get reference pointers to sum functions in place */
2546
 
    memcpy(ref_pointer_array, rollup.getRefPointerArrays()[i],
 
2358
    memcpy(ref_pointer_array, rollup.ref_pointer_arrays[i],
2547
2359
           ref_pointer_array_size);
2548
2360
    if ((!having || having->val_int()))
2549
2361
    {
2550
2362
      int write_error;
2551
2363
      Item *item;
2552
 
      List<Item>::iterator it(rollup.getFields()[i].begin());
 
2364
      List_iterator_fast<Item> it(rollup.fields[i]);
2553
2365
      while ((item= it++))
2554
2366
      {
2555
2367
        if (item->type() == Item::NULL_ITEM && item->is_result_field())
2565
2377
  }
2566
2378
  /* Restore ref_pointer_array */
2567
2379
  set_items_ref_array(current_ref_pointer_array);
2568
 
 
2569
2380
  return 0;
2570
2381
}
2571
2382
 
3231
3042
            have STRING_RESULT result type, we increase the length
3232
3043
            by 8 as maximum pack length of such fields.
3233
3044
          */
3234
 
          if (field::isDateTime(type))
 
3045
          if (type == DRIZZLE_TYPE_DATE ||
 
3046
              type == DRIZZLE_TYPE_TIME ||
 
3047
              type == DRIZZLE_TYPE_DATETIME ||
 
3048
              type == DRIZZLE_TYPE_TIMESTAMP)
3235
3049
          {
3236
3050
            key_length+= 8;
3237
3051
          }
3403
3217
 
3404
3218
  table_count=join->tables;
3405
3219
  if (!(join->join_tab=join_tab=
3406
 
  (JoinTable*) session->getMemRoot()->allocate(sizeof(JoinTable)*table_count)))
 
3220
  (JoinTable*) session->alloc(sizeof(JoinTable)*table_count)))
3407
3221
    return(true);
3408
3222
 
3409
3223
  for (i= 0; i < table_count; i++)
3527
3341
    i.e. they have subqueries, unions or call stored procedures.
3528
3342
    TODO: calculate a correct cost for a query with subqueries and UNIONs.
3529
3343
  */
3530
 
  if (join->session->getLex()->is_single_level_stmt())
 
3344
  if (join->session->lex->is_single_level_stmt())
3531
3345
    join->session->status_var.last_query_cost= join->best_read;
3532
3346
  return(false);
3533
3347
}
4040
3854
        will ensure that this will be used
4041
3855
      */
4042
3856
      best= tmp;
4043
 
      records= rnd_records;
 
3857
      records= rows2double(rnd_records);
4044
3858
      best_key= 0;
4045
3859
      /* range/index_merge/ALL/index access method are "independent", so: */
4046
3860
      best_ref_depends_map= 0;
4561
4375
  */
4562
4376
  if (!join->table_reexec)
4563
4377
  {
4564
 
    if (!(join->table_reexec= (Table**) join->session->getMemRoot()->allocate(sizeof(Table*))))
 
4378
    if (!(join->table_reexec= (Table**) join->session->alloc(sizeof(Table*))))
4565
4379
      return(true);
4566
4380
    if (join->tmp_join)
4567
4381
      join->tmp_join->table_reexec= join->table_reexec;
4569
4383
  if (!join->join_tab_reexec)
4570
4384
  {
4571
4385
    if (!(join->join_tab_reexec=
4572
 
          (JoinTable*) join->session->getMemRoot()->allocate(sizeof(JoinTable))))
 
4386
          (JoinTable*) join->session->alloc(sizeof(JoinTable))))
4573
4387
      return(true);
4574
4388
    new (join->join_tab_reexec) JoinTable();
4575
4389
    if (join->tmp_join)
4682
4496
      /* Ignore sj-nests: */
4683
4497
      if (!embedding->on_expr)
4684
4498
        continue;
4685
 
      NestedJoin *nested_join= embedding->getNestedJoin();
 
4499
      nested_join_st *nested_join= embedding->getNestedJoin();
4686
4500
      if (!nested_join->counter_)
4687
4501
      {
4688
4502
        /*
4721
4535
      if (join->tables > 1)
4722
4536
        cond->update_used_tables();             // Tablenr may have changed
4723
4537
      if (join->const_tables == join->tables &&
4724
 
          session->getLex()->current_select->master_unit() ==
4725
 
          &session->getLex()->unit)             // not upper level SELECT
 
4538
          session->lex->current_select->master_unit() ==
 
4539
          &session->lex->unit)          // not upper level SELECT
4726
4540
        join->const_table_map|=RAND_TABLE_BIT;
4727
4541
      {                                         // Check const tables
4728
4542
        COND *const_cond=
4791
4605
        tab->ref.key= -1;
4792
4606
        tab->ref.key_parts= 0;          // Don't use ref key.
4793
4607
        cur_pos= join->getPosFromOptimalPlan(i);
4794
 
        cur_pos.setFanout(tab->quick->records);
 
4608
        cur_pos.setFanout(rows2double(tab->quick->records));
4795
4609
        /*
4796
4610
           We will use join cache here : prevent sorting of the first
4797
4611
           table only and sort at the end.
4800
4614
          join->full_join= 1;
4801
4615
      }
4802
4616
 
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
 
 
4809
4617
      tmp= NULL;
4810
4618
      if (cond)
4811
4619
        tmp= make_cond_for_table(cond,used_tables,current_map, 0);
4836
4644
          tab->type == AM_EQ_REF)
4837
4645
      {
4838
4646
        optimizer::SqlSelect *sel= tab->select= ((optimizer::SqlSelect*)
4839
 
            session->getMemRoot()->duplicate((unsigned char*) select,
 
4647
            session->memdup((unsigned char*) select,
4840
4648
              sizeof(*select)));
4841
4649
        if (! sel)
4842
4650
          return 1;                     // End of memory
4974
4782
                                         current_map, 0)))
4975
4783
            {
4976
4784
              tab->cache.select= (optimizer::SqlSelect*)
4977
 
                session->getMemRoot()->duplicate((unsigned char*) sel, sizeof(optimizer::SqlSelect));
 
4785
                session->memdup((unsigned char*) sel, sizeof(optimizer::SqlSelect));
4978
4786
              tab->cache.select->cond= tmp;
4979
4787
              tab->cache.select->read_tables= join->const_table_map;
4980
4788
            }
5110
4918
 
5111
4919
    if (tab->insideout_match_tab)
5112
4920
    {
5113
 
      if (! (tab->insideout_buf= (unsigned char*) join->session->getMemRoot()->allocate(tab->table->key_info
 
4921
      if (! (tab->insideout_buf= (unsigned char*) join->session->alloc(tab->table->key_info
5114
4922
                                                                       [tab->index].
5115
4923
                                                                       key_length)))
5116
4924
        return true;
5292
5100
  {
5293
5101
    if (send_row)
5294
5102
    {
5295
 
      List<Item>::iterator it(fields.begin());
 
5103
      List_iterator_fast<Item> it(fields);
5296
5104
      Item *item;
5297
5105
      while ((item= it++))
5298
5106
        item->no_rows_in_result();
5428
5236
static COND *simplify_joins(Join *join, List<TableList> *join_list, COND *conds, bool top)
5429
5237
{
5430
5238
  TableList *table;
5431
 
  NestedJoin *nested_join;
 
5239
  nested_join_st *nested_join;
5432
5240
  TableList *prev_table= 0;
5433
 
  List<TableList>::iterator li(join_list->begin());
 
5241
  List_iterator<TableList> li(*join_list);
5434
5242
 
5435
5243
  /*
5436
5244
    Try to simplify join operations from join_list.
5566
5374
    Flatten nested joins that can be flattened.
5567
5375
    no ON expression and not a semi-join => can be flattened.
5568
5376
  */
5569
 
  li= join_list->begin();
 
5377
  li.rewind();
5570
5378
  while ((table= li++))
5571
5379
  {
5572
5380
    nested_join= table->getNestedJoin();
5573
5381
    if (nested_join && !table->on_expr)
5574
5382
    {
5575
5383
      TableList *tbl;
5576
 
      List<TableList>::iterator it(nested_join->join_list.begin());
 
5384
      List_iterator<TableList> it(nested_join->join_list);
5577
5385
      while ((tbl= it++))
5578
5386
      {
5579
5387
        tbl->setEmbedding(table->getEmbedding());
5596
5404
 
5597
5405
  /* Calculate how many saved fields there is in list */
5598
5406
  field_count=0;
5599
 
  List<Item>::iterator it(fields.begin());
 
5407
  List_iterator<Item> it(fields);
5600
5408
  Item *item;
5601
5409
  while ((item=it++))
5602
5410
  {
5650
5458
                               bool *hidden_group_fields)
5651
5459
{
5652
5460
  int res;
5653
 
  nesting_map save_allow_sum_func=session->getLex()->allow_sum_func ;
 
5461
  nesting_map save_allow_sum_func=session->lex->allow_sum_func ;
5654
5462
 
5655
 
  session->getLex()->allow_sum_func&= ~(1 << session->getLex()->current_select->nest_level);
 
5463
  session->lex->allow_sum_func&= ~(1 << session->lex->current_select->nest_level);
5656
5464
  res= session->setup_conds(tables, conds);
5657
5465
 
5658
 
  session->getLex()->allow_sum_func|= 1 << session->getLex()->current_select->nest_level;
 
5466
  session->lex->allow_sum_func|= 1 << session->lex->current_select->nest_level;
5659
5467
  res= res || setup_order(session, ref_pointer_array, tables, fields, all_fields,
5660
5468
                          order);
5661
 
  session->getLex()->allow_sum_func&= ~(1 << session->getLex()->current_select->nest_level);
 
5469
  session->lex->allow_sum_func&= ~(1 << session->lex->current_select->nest_level);
5662
5470
  res= res || setup_group(session, ref_pointer_array, tables, fields, all_fields,
5663
5471
                          group, hidden_group_fields);
5664
 
  session->getLex()->allow_sum_func= save_allow_sum_func;
 
5472
  session->lex->allow_sum_func= save_allow_sum_func;
5665
5473
  return(res);
5666
5474
}
5667
5475
 
5701
5509
 
5702
5510
  table_count= join->tables;
5703
5511
  stat= (JoinTable*) join->session->calloc(sizeof(JoinTable)*table_count);
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));
 
5512
  stat_ref= (JoinTable**) join->session->alloc(sizeof(JoinTable*)*MAX_TABLES);
 
5513
  table_vector= (Table**) join->session->alloc(sizeof(Table*)*(table_count*2));
5706
5514
  if (! stat || ! stat_ref || ! table_vector)
5707
5515
    return 1;
5708
5516
 
5766
5574
      s->embedding_map.reset();
5767
5575
      do
5768
5576
      {
5769
 
        NestedJoin *nested_join= embedding->getNestedJoin();
 
5577
        nested_join_st *nested_join= embedding->getNestedJoin();
5770
5578
        s->embedding_map|= nested_join->nj_map;
5771
5579
        s->dependent|= embedding->getDepTables();
5772
5580
        embedding= embedding->getEmbedding();
5850
5658
    s= p_pos->getJoinTable();
5851
5659
    s->type= AM_SYSTEM;
5852
5660
    join->const_table_map|=s->table->map;
5853
 
    if ((tmp= s->joinReadConstTable(p_pos)))
 
5661
    if ((tmp= join_read_const_table(s, p_pos)))
5854
5662
    {
5855
5663
      if (tmp > 0)
5856
5664
        return 1;                       // Fatal error
5924
5732
          join->const_table_map|=table->map;
5925
5733
          set_position(join, const_count++, s, (optimizer::KeyUse*) 0);
5926
5734
          partial_pos= join->getSpecificPosInPartialPlan(const_count - 1);
5927
 
          if ((tmp= s->joinReadConstTable(partial_pos)))
 
5735
          if ((tmp= join_read_const_table(s, partial_pos)))
5928
5736
          {
5929
5737
            if (tmp > 0)
5930
5738
              return 1;                 // Fatal error
5976
5784
                if (create_ref_for_key(join, s, start_keyuse, found_const_table_map))
5977
5785
                  return 1;
5978
5786
                partial_pos= join->getSpecificPosInPartialPlan(const_count - 1);
5979
 
                if ((tmp=s->joinReadConstTable(partial_pos)))
 
5787
                if ((tmp=join_read_const_table(s, partial_pos)))
5980
5788
                {
5981
5789
                  if (tmp > 0)
5982
5790
                    return 1;                   // Fatal error
6060
5868
      s->quick=select->quick;
6061
5869
      s->needed_reg=select->needed_reg;
6062
5870
      select->quick=0;
6063
 
 
6064
5871
      if (records == 0 && s->table->reginfo.impossible_range)
6065
5872
      {
6066
5873
        /*
6138
5945
*/
6139
5946
static uint32_t build_bitmap_for_nested_joins(List<TableList> *join_list, uint32_t first_unused)
6140
5947
{
6141
 
  List<TableList>::iterator li(join_list->begin());
 
5948
  List_iterator<TableList> li(*join_list);
6142
5949
  TableList *table;
6143
5950
  while ((table= li++))
6144
5951
  {
6145
 
    NestedJoin *nested_join;
 
5952
    nested_join_st *nested_join;
6146
5953
    if ((nested_join= table->getNestedJoin()))
6147
5954
    {
6148
5955
      /*
6199
6006
}
6200
6007
 
6201
6008
/**
6202
 
  Set NestedJoin::counter=0 in all nested joins in passed list.
 
6009
  Set nested_join_st::counter=0 in all nested joins in passed list.
6203
6010
 
6204
 
    Recursively set NestedJoin::counter=0 for all nested joins contained in
 
6011
    Recursively set nested_join_st::counter=0 for all nested joins contained in
6205
6012
    the passed join_list.
6206
6013
 
6207
6014
  @param join_list  List of nested joins to process. It may also contain base
6209
6016
*/
6210
6017
static void reset_nj_counters(List<TableList> *join_list)
6211
6018
{
6212
 
  List<TableList>::iterator li(join_list->begin());
 
6019
  List_iterator<TableList> li(*join_list);
6213
6020
  TableList *table;
6214
6021
  while ((table= li++))
6215
6022
  {
6216
 
    NestedJoin *nested_join;
 
6023
    nested_join_st *nested_join;
6217
6024
    if ((nested_join= table->getNestedJoin()))
6218
6025
    {
6219
6026
      nested_join->counter_= 0;
6299
6106
  Join *join= last->join;
6300
6107
  for (;last_emb != NULL; last_emb= last_emb->getEmbedding())
6301
6108
  {
6302
 
    NestedJoin *nest= last_emb->getNestedJoin();
 
6109
    nested_join_st *nest= last_emb->getNestedJoin();
6303
6110
    
6304
6111
    bool was_fully_covered= nest->is_fully_covered();
6305
6112