~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/join.cc

  • Committer: Andrew Hutchings
  • Date: 2010-10-23 10:43:00 UTC
  • mto: (1874.2.1 merge)
  • mto: This revision was merged to the branch mainline in revision 1876.
  • Revision ID: andrew@linuxjedi.co.uk-20101023104300-90rgyfw2eokcvsp3
Make port 4427 the default for client apps

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, Inc.
 
4
 *  Copyright (C) 2008-2009 Sun Microsystems
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
58
58
#include "drizzled/internal/my_bit.h"
59
59
#include "drizzled/internal/my_sys.h"
60
60
#include "drizzled/internal/iocache.h"
61
 
#include "drizzled/plugin/storage_engine.h"
62
 
 
63
 
#include <drizzled/debug.h>
64
61
 
65
62
#include <algorithm>
66
63
 
68
65
 
69
66
namespace drizzled
70
67
{
 
68
 
71
69
extern plugin::StorageEngine *heap_engine;
 
70
extern std::bitset<12> test_flags;
72
71
 
73
72
/** Declarations of static functions used in this source file. */
74
73
static bool make_group_fields(Join *main_join, Join *curr_join);
75
 
static void calc_group_buffer(Join *join, Order *group);
76
 
static bool alloc_group_fields(Join *join, Order *group);
 
74
static void calc_group_buffer(Join *join,order_st *group);
 
75
static bool alloc_group_fields(Join *join,order_st *group);
77
76
static uint32_t cache_record_length(Join *join, uint32_t index);
78
77
static double prev_record_reads(Join *join, uint32_t idx, table_map found_ref);
79
78
static bool get_best_combination(Join *join);
103
102
static bool make_join_select(Join *join, optimizer::SqlSelect *select,COND *item);
104
103
static bool make_join_readinfo(Join *join);
105
104
static void update_depend_map(Join *join);
106
 
static void update_depend_map(Join *join, Order *order);
107
 
static Order *remove_constants(Join *join,Order *first_order,COND *cond, bool change_list, bool *simple_order);
 
105
static void update_depend_map(Join *join, order_st *order);
 
106
static order_st *remove_constants(Join *join,order_st *first_order,COND *cond, bool change_list, bool *simple_order);
108
107
static int return_zero_rows(Join *join,
109
108
                            select_result *res,
110
109
                            TableList *tables,
122
121
                               List<Item> &fields,
123
122
                               List<Item> &all_fields,
124
123
                               COND **conds,
125
 
                               Order *order,
126
 
                               Order *group,
 
124
                               order_st *order,
 
125
                               order_st *group,
127
126
                               bool *hidden_group_fields);
128
127
static bool make_join_statistics(Join *join, TableList *leaves, COND *conds, DYNAMIC_ARRAY *keyuse);
129
128
static uint32_t build_bitmap_for_nested_joins(List<TableList> *join_list, uint32_t first_unused);
130
 
static Table *get_sort_by_table(Order *a, Order *b,TableList *tables);
 
129
static Table *get_sort_by_table(order_st *a,order_st *b,TableList *tables);
131
130
static void reset_nj_counters(List<TableList> *join_list);
132
 
static bool test_if_subpart(Order *a,Order *b);
 
131
static bool test_if_subpart(order_st *a,order_st *b);
133
132
static void restore_prev_nj_state(JoinTable *last);
134
133
static bool add_ref_to_table_cond(Session *session, JoinTable *join_tab);
135
134
static void free_blobs(Field **ptr); /* Rename this method...conflicts with another in global namespace... */
136
135
 
137
 
Join::Join(Session *session_arg, 
138
 
           List<Item> &fields_arg, 
139
 
           uint64_t select_options_arg,
140
 
           select_result *result_arg) :
141
 
  join_tab(NULL),
142
 
  best_ref(NULL),
143
 
  map2table(NULL),
144
 
  join_tab_save(NULL),
145
 
  table(NULL),
146
 
  all_tables(NULL),
147
 
  sort_by_table(NULL),
148
 
  tables(0),
149
 
  outer_tables(0),
150
 
  const_tables(0),
151
 
  send_group_parts(0),
152
 
  sort_and_group(false),
153
 
  first_record(false),
154
 
  full_join(false),
155
 
  group(false),
156
 
  no_field_update(false),
157
 
  do_send_rows(true),
158
 
  resume_nested_loop(false),
159
 
  no_const_tables(false),
160
 
  select_distinct(false),
161
 
  group_optimized_away(false),
162
 
  simple_order(false),
163
 
  simple_group(false),
164
 
  no_order(false),
165
 
  skip_sort_order(false),
166
 
  union_part(false),
167
 
  optimized(false),
168
 
  need_tmp(false),
169
 
  hidden_group_fields(false),
170
 
  const_table_map(0),
171
 
  found_const_table_map(0),
172
 
  outer_join(0),
173
 
  send_records(0),
174
 
  found_records(0),
175
 
  examined_rows(0),
176
 
  row_limit(0),
177
 
  select_limit(0),
178
 
  fetch_limit(HA_POS_ERROR),
179
 
  session(session_arg),
180
 
  fields_list(fields_arg), 
181
 
  join_list(NULL),
182
 
  unit(NULL),
183
 
  select_lex(NULL),
184
 
  select(NULL),
185
 
  exec_tmp_table1(NULL),
186
 
  exec_tmp_table2(NULL),
187
 
  sum_funcs(NULL),
188
 
  sum_funcs2(NULL),
189
 
  having(NULL),
190
 
  tmp_having(NULL),
191
 
  having_history(NULL),
192
 
  select_options(select_options_arg),
193
 
  result(result_arg),
194
 
  lock(session_arg->lock),
195
 
  tmp_join(NULL),
196
 
  all_fields(fields_arg),
197
 
  error(0),
198
 
  cond_equal(NULL),
199
 
  return_tab(NULL),
200
 
  ref_pointer_array(NULL),
201
 
  items0(NULL),
202
 
  items1(NULL),
203
 
  items2(NULL),
204
 
  items3(NULL),
205
 
  ref_pointer_array_size(0),
206
 
  zero_result_cause(NULL),
207
 
  sortorder(NULL),
208
 
  table_reexec(NULL),
209
 
  join_tab_reexec(NULL)
210
 
{
211
 
  select_distinct= test(select_options & SELECT_DISTINCT);
212
 
  if (&fields_list != &fields_arg) /* only copy if not same*/
213
 
    fields_list= fields_arg;
214
 
  memset(&keyuse, 0, sizeof(keyuse));
215
 
  tmp_table_param.init();
216
 
  tmp_table_param.end_write_records= HA_POS_ERROR;
217
 
  rollup.setState(Rollup::STATE_NONE);
218
 
}
219
 
 
220
 
  /** 
221
 
   * This method is currently only used when a subselect EXPLAIN is performed.
222
 
   * I pulled out the init() method and have simply reset the values to what
223
 
   * was previously in the init() method.  See the note about the hack in 
224
 
   * sql_union.cc...
225
 
   */
226
 
void Join::reset(Session *session_arg, 
227
 
                 List<Item> &fields_arg, 
228
 
                 uint64_t select_options_arg,
229
 
                 select_result *result_arg)
230
 
{
231
 
  join_tab= NULL;
232
 
  best_ref= NULL;
233
 
  map2table= NULL;
234
 
  join_tab_save= NULL;
235
 
  table= NULL;
236
 
  all_tables= NULL;
237
 
  sort_by_table= NULL;
238
 
  tables= 0;
239
 
  outer_tables= 0;
240
 
  const_tables= 0;
241
 
  send_group_parts= 0;
242
 
  sort_and_group= false;
243
 
  first_record= false;
244
 
  full_join= false;
245
 
  group= false;
246
 
  no_field_update= false;
247
 
  do_send_rows= true;
248
 
  resume_nested_loop= false;
249
 
  no_const_tables= false;
250
 
  select_distinct= false;
251
 
  group_optimized_away= false;
252
 
  simple_order= false;
253
 
  simple_group= false;
254
 
  no_order= false;
255
 
  skip_sort_order= false;
256
 
  union_part= false;
257
 
  optimized= false;
258
 
  need_tmp= false;
259
 
  hidden_group_fields= false;
260
 
  const_table_map= 0;
261
 
  found_const_table_map= 0;
262
 
  outer_join= 0;
263
 
  send_records= 0;
264
 
  found_records= 0;
265
 
  examined_rows= 0;
266
 
  row_limit= 0;
267
 
  select_limit= 0;
268
 
  fetch_limit= HA_POS_ERROR;
269
 
  session= session_arg;
270
 
  fields_list= fields_arg; 
271
 
  join_list= NULL;
272
 
  unit= NULL;
273
 
  select_lex= NULL;
274
 
  select= NULL;
275
 
  exec_tmp_table1= NULL;
276
 
  exec_tmp_table2= NULL;
277
 
  sum_funcs= NULL;
278
 
  sum_funcs2= NULL;
279
 
  having= NULL;
280
 
  tmp_having= NULL;
281
 
  having_history= NULL;
282
 
  select_options= select_options_arg;
283
 
  result= result_arg;
284
 
  lock= session_arg->lock;
285
 
  tmp_join= NULL;
286
 
  all_fields= fields_arg;
287
 
  error= 0;
288
 
  cond_equal= NULL;
289
 
  return_tab= NULL;
290
 
  ref_pointer_array= NULL;
291
 
  items0= NULL;
292
 
  items1= NULL;
293
 
  items2= NULL;
294
 
  items3= NULL;
295
 
  ref_pointer_array_size= 0;
296
 
  zero_result_cause= NULL;
297
 
  sortorder= NULL;
298
 
  table_reexec= NULL;
299
 
  join_tab_reexec= NULL;
300
 
  select_distinct= test(select_options & SELECT_DISTINCT);
301
 
  if (&fields_list != &fields_arg) /* only copy if not same*/
302
 
    fields_list= fields_arg;
303
 
  memset(&keyuse, 0, sizeof(keyuse));
304
 
  tmp_table_param.init();
305
 
  tmp_table_param.end_write_records= HA_POS_ERROR;
306
 
  rollup.setState(Rollup::STATE_NONE);
307
 
}
308
 
 
309
 
bool Join::is_top_level_join() const
310
 
{
311
 
  return (unit == &session->lex->unit && (unit->fake_select_lex == 0 ||
312
 
                                          select_lex == unit->fake_select_lex));
313
 
}
314
 
 
315
136
/**
316
137
  Prepare of whole select (including sub queries in future).
317
138
 
329
150
                  uint32_t wild_num,
330
151
                  COND *conds_init,
331
152
                  uint32_t og_num,
332
 
                  Order *order_init,
333
 
                  Order *group_init,
 
153
                  order_st *order_init,
 
154
                  order_st *group_init,
334
155
                  Item *having_init,
335
156
                  Select_Lex *select_lex_arg,
336
157
                  Select_Lex_Unit *unit_arg)
371
192
  for (table_ptr= select_lex->leaf_tables;
372
193
       table_ptr;
373
194
       table_ptr= table_ptr->next_leaf)
374
 
  {
375
195
    tables++;
376
 
  }
377
 
 
378
196
 
379
197
  if (setup_wild(session, fields_list, &all_fields, wild_num) ||
380
198
      select_lex->setup_ref_array(session, og_num) ||
391
209
  if (having)
392
210
  {
393
211
    nesting_map save_allow_sum_func= session->lex->allow_sum_func;
394
 
    session->setWhere("having clause");
 
212
    session->where="having clause";
395
213
    session->lex->allow_sum_func|= 1 << select_lex_arg->nest_level;
396
214
    select_lex->having_fix_field= 1;
397
215
    bool having_fix_rc= (!having->fixed &&
470
288
 
471
289
  if (order)
472
290
  {
473
 
    Order *ord;
 
291
    order_st *ord;
474
292
    for (ord= order; ord; ord= ord->next)
475
293
    {
476
294
      Item *item= *ord->item;
515
333
  {
516
334
    /* Caclulate the number of groups */
517
335
    send_group_parts= 0;
518
 
    for (Order *group_tmp= group_list ; group_tmp ; group_tmp= group_tmp->next)
 
336
    for (order_st *group_tmp= group_list ; group_tmp ; group_tmp= group_tmp->next)
519
337
      send_group_parts++;
520
338
  }
521
339
 
522
340
  if (error)
523
 
    return(-1);
 
341
    goto err;
524
342
 
525
343
  /* 
526
344
   * The below will create the new table for
529
347
   * @see create_table_from_items() in drizzled/sql_insert.cc
530
348
   */
531
349
  if (result && result->prepare(fields_list, unit_arg))
532
 
    return(-1);
 
350
    goto err;
533
351
 
534
352
  /* Init join struct */
535
353
  count_field_types(select_lex, &tmp_table_param, all_fields, 0);
541
359
  if (sum_func_count && !group_list && (func_count || field_count))
542
360
  {
543
361
    my_message(ER_WRONG_SUM_SELECT,ER(ER_WRONG_SUM_SELECT),MYF(0));
544
 
    return(-1);
 
362
    goto err;
545
363
  }
546
364
#endif
547
365
  if (select_lex->olap == ROLLUP_TYPE && rollup_init())
548
 
    return(-1);
549
 
 
 
366
    goto err;
550
367
  if (alloc_func_list())
551
 
    return(-1);
552
 
 
553
 
  return 0; // All OK
 
368
    goto err;
 
369
 
 
370
  return(0); // All OK
 
371
 
 
372
err:
 
373
  return(-1);
554
374
}
555
375
 
556
376
/*
773
593
    return 1;
774
594
  }
775
595
  if (const_tables && !(select_options & SELECT_NO_UNLOCK))
776
 
    session->unlockSomeTables(table, const_tables);
 
596
    mysql_unlock_some_tables(session, table, const_tables);
777
597
  if (!conds && outer_join)
778
598
  {
779
599
    /* Handle the case where we have an OUTER JOIN without a WHERE */
835
655
 
836
656
  /* Optimize distinct away if possible */
837
657
  {
838
 
    Order *org_order= order;
 
658
    order_st *org_order= order;
839
659
    order= remove_constants(this, order,conds,1, &simple_order);
840
660
    if (session->is_error())
841
661
    {
907
727
  }
908
728
  if (group_list || tmp_table_param.sum_func_count)
909
729
  {
910
 
    if (! hidden_group_fields && rollup.getState() == Rollup::STATE_NONE)
 
730
    if (! hidden_group_fields && rollup.state == ROLLUP::STATE_NONE)
911
731
      select_distinct=0;
912
732
  }
913
733
  else if (select_distinct && tables - const_tables == 1)
969
789
  }
970
790
  simple_group= 0;
971
791
  {
972
 
    Order *old_group_list;
 
792
    order_st *old_group_list;
973
793
    group_list= remove_constants(this, (old_group_list= group_list), conds,
974
 
                                 rollup.getState() == Rollup::STATE_NONE,
 
794
                                 rollup.state == ROLLUP::STATE_NONE,
975
795
                                 &simple_group);
976
796
    if (session->is_error())
977
797
    {
1047
867
        save_index_subquery_explain_info(join_tab, where);
1048
868
        join_tab[0].type= AM_UNIQUE_SUBQUERY;
1049
869
        error= 0;
1050
 
        return(unit->item->change_engine(new subselect_uniquesubquery_engine(session, join_tab, unit->item, where)));
 
870
        return(unit->item->
 
871
                    change_engine(new
 
872
                                  subselect_uniquesubquery_engine(session,
 
873
                                                                  join_tab,
 
874
                                                                  unit->item,
 
875
                                                                  where)));
1051
876
      }
1052
877
      else if (join_tab[0].type == AM_REF &&
1053
878
         join_tab[0].ref.items[0]->name == in_left_expr_name)
1056
881
        save_index_subquery_explain_info(join_tab, where);
1057
882
        join_tab[0].type= AM_INDEX_SUBQUERY;
1058
883
        error= 0;
1059
 
        return(unit->item->change_engine(new subselect_indexsubquery_engine(session, join_tab, unit->item, where, NULL, 0)));
 
884
        return(unit->item->
 
885
                    change_engine(new
 
886
                                  subselect_indexsubquery_engine(session,
 
887
                                                                 join_tab,
 
888
                                                                 unit->item,
 
889
                                                                 where,
 
890
                                                                 NULL,
 
891
                                                                 0)));
1060
892
      }
1061
893
    } 
1062
894
    else if (join_tab[0].type == AM_REF_OR_NULL &&
1067
899
      error= 0;
1068
900
      conds= remove_additional_cond(conds);
1069
901
      save_index_subquery_explain_info(join_tab, conds);
1070
 
      return(unit->item->change_engine(new subselect_indexsubquery_engine(session, join_tab, unit->item, conds, having, 1)));
 
902
      return(unit->item->
 
903
      change_engine(new subselect_indexsubquery_engine(session,
 
904
                   join_tab,
 
905
                   unit->item,
 
906
                   conds,
 
907
                                                                   having,
 
908
                   1)));
1071
909
    }
1072
910
 
1073
911
  }
1119
957
        Force using of tmp table if sorting by a SP or UDF function due to
1120
958
        their expensive and probably non-deterministic nature.
1121
959
      */
1122
 
      for (Order *tmp_order= order; tmp_order ; tmp_order=tmp_order->next)
 
960
      for (order_st *tmp_order= order; tmp_order ; tmp_order=tmp_order->next)
1123
961
      {
1124
962
        Item *item= *tmp_order->item;
1125
963
        if (item->is_expensive())
1163
1001
 
1164
1002
    tmp_table_param.hidden_field_count= (all_fields.elements -
1165
1003
           fields_list.elements);
1166
 
    Order *tmp_group= (((not simple_group) or not (getDebug().test(debug::NO_KEY_GROUP))) ? group_list : (Order*) 0);
1167
 
 
 
1004
    order_st *tmp_group= ((!simple_group && 
 
1005
                           ! (test_flags.test(TEST_NO_KEY_GROUP))) ? group_list :
 
1006
                                                                     (order_st*) 0);
1168
1007
    /*
1169
1008
      Pushing LIMIT to the temporary table creation is not applicable
1170
1009
      when there is ORDER BY or GROUP BY or there is no GROUP BY, but
1350
1189
*/
1351
1190
bool Join::init_save_join_tab()
1352
1191
{
1353
 
  if (!(tmp_join= (Join*)session->getMemRoot()->allocate(sizeof(Join))))
 
1192
  if (!(tmp_join= (Join*)session->alloc(sizeof(Join))))
1354
1193
    return 1;
1355
 
 
1356
1194
  error= 0;              // Ensure that tmp_join.error= 0
1357
1195
  restore_tmp();
1358
 
 
1359
1196
  return 0;
1360
1197
}
1361
1198
 
1363
1200
{
1364
1201
  if (! join_tab_save && select_lex->master_unit()->uncacheable.any())
1365
1202
  {
1366
 
    if (!(join_tab_save= (JoinTable*)session->getMemRoot()->duplicate((unsigned char*) join_tab,
 
1203
    if (!(join_tab_save= (JoinTable*)session->memdup((unsigned char*) join_tab,
1367
1204
            sizeof(JoinTable) * tables)))
1368
1205
      return 1;
1369
1206
  }
1611
1448
              exec_tmp_table2= create_tmp_table(session,
1612
1449
                                                &curr_join->tmp_table_param,
1613
1450
                                                *curr_all_fields,
1614
 
                                                (Order*) 0,
 
1451
                                                (order_st*) 0,
1615
1452
                                                curr_join->select_distinct &&
1616
1453
                                                !curr_join->group_list,
1617
1454
                                                1, curr_join->select_options,
1765
1602
      if (sort_table_cond)
1766
1603
      {
1767
1604
        if (!curr_table->select)
1768
 
          if (!(curr_table->select= new optimizer::SqlSelect()))
 
1605
          if (!(curr_table->select= new optimizer::SqlSelect))
1769
1606
            return;
1770
1607
        if (!curr_table->select->cond)
1771
1608
          curr_table->select->cond= sort_table_cond;
1969
1806
    is called after all rows are sent, but before EOF packet is sent.
1970
1807
 
1971
1808
    For a simple SELECT with no subqueries this function performs a full
1972
 
    cleanup of the Join and calls unlockReadTables to free used base
 
1809
    cleanup of the Join and calls mysql_unlock_read_tables to free used base
1973
1810
    tables.
1974
1811
 
1975
1812
    If a Join is executed for a subquery or if it has a subquery, we can't
2012
1849
    for (sl= tmp_unit->first_select(); sl; sl= sl->next_select())
2013
1850
    {
2014
1851
      Item_subselect *subselect= sl->master_unit()->item;
2015
 
      bool full_local= full && (!subselect || 
2016
 
                                (subselect->is_evaluated() &&
2017
 
                                !subselect->is_uncacheable()));
 
1852
      bool full_local= full && (!subselect || subselect->is_evaluated());
2018
1853
      /*
2019
1854
        If this join is evaluated, we can fully clean it up and clean up all
2020
1855
        its underlying joins even if they are correlated -- they will not be
2043
1878
      TODO: unlock tables even if the join isn't top level select in the
2044
1879
      tree.
2045
1880
    */
2046
 
    session->unlockReadTables(lock);           // Don't free join->lock
 
1881
    mysql_unlock_read_tables(session, lock);           // Don't free join->lock
2047
1882
    lock= 0;
2048
1883
  }
2049
1884
 
2066
1901
{
2067
1902
  if (table)
2068
1903
  {
 
1904
    JoinTable *tab,*end;
2069
1905
    /*
2070
1906
      Only a sorted table may be cached.  This sorted table is always the
2071
1907
      first non const table in join->table
2075
1911
      table[const_tables]->free_io_cache();
2076
1912
      table[const_tables]->filesort_free_buffers(full);
2077
1913
    }
2078
 
  }
2079
 
 
2080
 
  if (join_tab)
2081
 
  {
2082
 
    JoinTable *tab,*end;
2083
1914
 
2084
1915
    if (full)
2085
1916
    {
2096
1927
      }
2097
1928
    }
2098
1929
  }
2099
 
 
2100
1930
  /*
2101
1931
    We are not using tables anymore
2102
1932
    Unlock all tables. We may be in an INSERT .... SELECT statement.
2140
1970
    are not re-calculated.
2141
1971
  */
2142
1972
  for (uint32_t i= join->const_tables; i < join->tables; i++)
2143
 
  {
2144
1973
    join->table[i]->mark_as_null_row();   // All fields are NULL
2145
 
  }
2146
1974
}
2147
1975
 
2148
1976
/**
2163
1991
    If we are using rollup, we need a copy of the summary functions for
2164
1992
    each level
2165
1993
  */
2166
 
  if (rollup.getState() != Rollup::STATE_NONE)
 
1994
  if (rollup.state != ROLLUP::STATE_NONE)
2167
1995
    func_count*= (send_group_parts+1);
2168
1996
 
2169
1997
  group_parts= send_group_parts;
2180
2008
    */
2181
2009
    if (order)
2182
2010
    {
2183
 
      Order *ord;
 
2011
      order_st *ord;
2184
2012
      for (ord= order; ord; ord= ord->next)
2185
2013
        group_parts++;
2186
2014
    }
2226
2054
         ((Item_sum *)item)->depended_from() == select_lex))
2227
2055
      *func++= (Item_sum*) item;
2228
2056
  }
2229
 
  if (before_group_by && rollup.getState() == Rollup::STATE_INITED)
 
2057
  if (before_group_by && rollup.state == ROLLUP::STATE_INITED)
2230
2058
  {
2231
 
    rollup.setState(Rollup::STATE_READY);
 
2059
    rollup.state= ROLLUP::STATE_READY;
2232
2060
    if (rollup_make_fields(field_list, send_fields, &func))
2233
 
      return true;     // Should never happen
 
2061
      return(true);     // Should never happen
2234
2062
  }
2235
 
  else if (rollup.getState() == Rollup::STATE_NONE)
 
2063
  else if (rollup.state == ROLLUP::STATE_NONE)
2236
2064
  {
2237
2065
    for (uint32_t i=0 ; i <= send_group_parts ;i++)
2238
2066
      sum_funcs_end[i]= func;
2239
2067
  }
2240
 
  else if (rollup.getState() == Rollup::STATE_READY)
 
2068
  else if (rollup.state == ROLLUP::STATE_READY)
2241
2069
    return(false);                         // Don't put end marker
2242
2070
  *func=0;          // End marker
2243
2071
  return(false);
2246
2074
/** Allocate memory needed for other rollup functions. */
2247
2075
bool Join::rollup_init()
2248
2076
{
 
2077
  uint32_t i,j;
2249
2078
  Item **ref_array;
2250
2079
 
2251
2080
  tmp_table_param.quick_group= 0; // Can't create groups in tmp table
2252
 
  rollup.setState(Rollup::STATE_INITED);
 
2081
  rollup.state= ROLLUP::STATE_INITED;
2253
2082
 
2254
2083
  /*
2255
2084
    Create pointers to the different sum function groups
2257
2086
  */
2258
2087
  tmp_table_param.group_parts= send_group_parts;
2259
2088
 
2260
 
  rollup.setNullItems((Item_null_result**) session->getMemRoot()->allocate((sizeof(Item*) +
2261
 
                                                                sizeof(Item**) +
2262
 
                                                                sizeof(List<Item>) +
2263
 
                                                                ref_pointer_array_size)
2264
 
                                                               * send_group_parts ));
2265
 
  if (! rollup.getNullItems())
2266
 
  {
 
2089
  if (!(rollup.null_items= (Item_null_result**) session->alloc((sizeof(Item*) +
 
2090
                                                sizeof(Item**) +
 
2091
                                                sizeof(List<Item>) +
 
2092
                        ref_pointer_array_size)
 
2093
                        * send_group_parts )))
2267
2094
    return 1;
2268
 
  }
2269
2095
 
2270
 
  rollup.setFields((List<Item>*) (rollup.getNullItems() + send_group_parts));
2271
 
  rollup.setRefPointerArrays((Item***) (rollup.getFields() + send_group_parts));
2272
 
  ref_array= (Item**) (rollup.getRefPointerArrays()+send_group_parts);
 
2096
  rollup.fields= (List<Item>*) (rollup.null_items + send_group_parts);
 
2097
  rollup.ref_pointer_arrays= (Item***) (rollup.fields + send_group_parts);
 
2098
  ref_array= (Item**) (rollup.ref_pointer_arrays+send_group_parts);
2273
2099
 
2274
2100
  /*
2275
2101
    Prepare space for field list for the different levels
2276
2102
    These will be filled up in rollup_make_fields()
2277
2103
  */
2278
 
  for (uint32_t i= 0 ; i < send_group_parts ; i++)
 
2104
  for (i= 0 ; i < send_group_parts ; i++)
2279
2105
  {
2280
 
    rollup.getNullItems()[i]= new (session->mem_root) Item_null_result();
2281
 
    List<Item> *rollup_fields= &rollup.getFields()[i];
 
2106
    rollup.null_items[i]= new (session->mem_root) Item_null_result();
 
2107
    List<Item> *rollup_fields= &rollup.fields[i];
2282
2108
    rollup_fields->empty();
2283
 
    rollup.getRefPointerArrays()[i]= ref_array;
 
2109
    rollup.ref_pointer_arrays[i]= ref_array;
2284
2110
    ref_array+= all_fields.elements;
2285
2111
  }
2286
 
 
2287
 
  for (uint32_t i= 0 ; i < send_group_parts; i++)
 
2112
  for (i= 0 ; i < send_group_parts; i++)
2288
2113
  {
2289
 
    for (uint32_t j= 0 ; j < fields_list.elements ; j++)
2290
 
    {
2291
 
      rollup.getFields()[i].push_back(rollup.getNullItems()[i]);
2292
 
    }
 
2114
    for (j=0 ; j < fields_list.elements ; j++)
 
2115
      rollup.fields[i].push_back(rollup.null_items[i]);
2293
2116
  }
2294
 
 
2295
2117
  List_iterator<Item> it(all_fields);
2296
2118
  Item *item;
2297
2119
  while ((item= it++))
2298
2120
  {
2299
 
    Order *group_tmp;
 
2121
    order_st *group_tmp;
2300
2122
    bool found_in_group= 0;
2301
2123
 
2302
2124
    for (group_tmp= group_list; group_tmp; group_tmp= group_tmp->next)
2325
2147
            return 1;
2326
2148
          new_item->fix_fields(session, (Item **) 0);
2327
2149
          session->change_item_tree(it.ref(), new_item);
2328
 
          for (Order *tmp= group_tmp; tmp; tmp= tmp->next)
 
2150
          for (order_st *tmp= group_tmp; tmp; tmp= tmp->next)
2329
2151
          {
2330
2152
            if (*tmp->item == item)
2331
2153
              session->change_item_tree(tmp->item, new_item);
2398
2220
    uint32_t pos= send_group_parts - level -1;
2399
2221
    bool real_fields= 0;
2400
2222
    Item *item;
2401
 
    List_iterator<Item> new_it(rollup.getFields()[pos]);
2402
 
    Item **ref_array_start= rollup.getRefPointerArrays()[pos];
2403
 
    Order *start_group;
 
2223
    List_iterator<Item> new_it(rollup.fields[pos]);
 
2224
    Item **ref_array_start= rollup.ref_pointer_arrays[pos];
 
2225
    order_st *start_group;
2404
2226
 
2405
2227
    /* Point to first hidden field */
2406
2228
    Item **ref_array= ref_array_start + fields_arg.elements-1;
2442
2264
      else
2443
2265
      {
2444
2266
        /* Check if this is something that is part of this group by */
2445
 
        Order *group_tmp;
 
2267
        order_st *group_tmp;
2446
2268
        for (group_tmp= start_group, i= pos ;
2447
2269
                  group_tmp ; group_tmp= group_tmp->next, i++)
2448
2270
        {
2497
2319
*/
2498
2320
int Join::rollup_send_data(uint32_t idx)
2499
2321
{
2500
 
  for (uint32_t i= send_group_parts ; i-- > idx ; )
 
2322
  uint32_t i;
 
2323
  for (i= send_group_parts ; i-- > idx ; )
2501
2324
  {
2502
2325
    /* Get reference pointers to sum functions in place */
2503
 
    memcpy(ref_pointer_array, rollup.getRefPointerArrays()[i], ref_pointer_array_size);
2504
 
 
 
2326
    memcpy(ref_pointer_array, rollup.ref_pointer_arrays[i],
 
2327
     ref_pointer_array_size);
2505
2328
    if ((!having || having->val_int()))
2506
2329
    {
2507
 
      if (send_records < unit->select_limit_cnt && do_send_rows && result->send_data(rollup.getFields()[i]))
2508
 
      {
2509
 
        return 1;
2510
 
      }
 
2330
      if (send_records < unit->select_limit_cnt && do_send_rows &&
 
2331
    result->send_data(rollup.fields[i]))
 
2332
  return 1;
2511
2333
      send_records++;
2512
2334
    }
2513
2335
  }
2514
2336
  /* Restore ref_pointer_array */
2515
2337
  set_items_ref_array(current_ref_pointer_array);
2516
 
 
2517
2338
  return 0;
2518
2339
}
2519
2340
 
2538
2359
*/
2539
2360
int Join::rollup_write_data(uint32_t idx, Table *table_arg)
2540
2361
{
2541
 
  for (uint32_t i= send_group_parts ; i-- > idx ; )
 
2362
  uint32_t i;
 
2363
  for (i= send_group_parts ; i-- > idx ; )
2542
2364
  {
2543
2365
    /* Get reference pointers to sum functions in place */
2544
 
    memcpy(ref_pointer_array, rollup.getRefPointerArrays()[i],
 
2366
    memcpy(ref_pointer_array, rollup.ref_pointer_arrays[i],
2545
2367
           ref_pointer_array_size);
2546
2368
    if ((!having || having->val_int()))
2547
2369
    {
2548
2370
      int write_error;
2549
2371
      Item *item;
2550
 
      List_iterator_fast<Item> it(rollup.getFields()[i]);
 
2372
      List_iterator_fast<Item> it(rollup.fields[i]);
2551
2373
      while ((item= it++))
2552
2374
      {
2553
2375
        if (item->type() == Item::NULL_ITEM && item->is_result_field())
2563
2385
  }
2564
2386
  /* Restore ref_pointer_array */
2565
2387
  set_items_ref_array(current_ref_pointer_array);
2566
 
 
2567
2388
  return 0;
2568
2389
}
2569
2390
 
2659
2480
    return NESTED_LOOP_ERROR;
2660
2481
  if (error < 0)
2661
2482
    return NESTED_LOOP_NO_MORE_ROWS;
2662
 
  if (join->session->getKilled())                       // Aborted by user
 
2483
  if (join->session->killed)                    // Aborted by user
2663
2484
  {
2664
2485
    join->session->send_kill_message();
2665
2486
    return NESTED_LOOP_KILLED;
2871
2692
  info= &join_tab->read_record;
2872
2693
  do
2873
2694
  {
2874
 
    if (join->session->getKilled())
 
2695
    if (join->session->killed)
2875
2696
    {
2876
2697
      join->session->send_kill_message();
2877
2698
      return NESTED_LOOP_KILLED;
3003
2824
{
3004
2825
  Table *table= join->tmp_table;
3005
2826
 
3006
 
  if (join->session->getKilled())                       // Aborted by user
 
2827
  if (join->session->killed)                    // Aborted by user
3007
2828
  {
3008
2829
    join->session->send_kill_message();
3009
2830
    return NESTED_LOOP_KILLED;
3011
2832
  if (!end_of_records)
3012
2833
  {
3013
2834
    copy_fields(&join->tmp_table_param);
3014
 
    if (copy_funcs(join->tmp_table_param.items_to_copy, join->session))
3015
 
      return NESTED_LOOP_ERROR;
 
2835
    copy_funcs(join->tmp_table_param.items_to_copy);
3016
2836
    if (!join->having || join->having->val_int())
3017
2837
    {
3018
2838
      int error;
3020
2840
      if ((error=table->cursor->insertRecord(table->getInsertRecord())))
3021
2841
      {
3022
2842
        if (!table->cursor->is_fatal_error(error, HA_CHECK_DUP))
3023
 
        {
3024
 
          return NESTED_LOOP_OK;
3025
 
        }
 
2843
          goto end;
3026
2844
 
3027
2845
        my_error(ER_USE_SQL_BIG_RESULT, MYF(0));
3028
2846
        return NESTED_LOOP_ERROR;        // Table is_full error
3037
2855
      }
3038
2856
    }
3039
2857
  }
3040
 
 
 
2858
end:
3041
2859
  return NESTED_LOOP_OK;
3042
2860
}
3043
2861
 
3045
2863
enum_nested_loop_state end_update(Join *join, JoinTable *, bool end_of_records)
3046
2864
{
3047
2865
  Table *table= join->tmp_table;
3048
 
  Order *group;
 
2866
  order_st *group;
3049
2867
  int   error;
3050
2868
 
3051
2869
  if (end_of_records)
3052
2870
    return NESTED_LOOP_OK;
3053
 
  if (join->session->getKilled())                       // Aborted by user
 
2871
  if (join->session->killed)                    // Aborted by user
3054
2872
  {
3055
2873
    join->session->send_kill_message();
3056
2874
    return NESTED_LOOP_KILLED;
3097
2915
      memcpy(table->getInsertRecord()+key_part->offset, group->buff, 1);
3098
2916
  }
3099
2917
  init_tmptable_sum_functions(join->sum_funcs);
3100
 
  if (copy_funcs(join->tmp_table_param.items_to_copy, join->session))
3101
 
    return NESTED_LOOP_ERROR;
 
2918
  copy_funcs(join->tmp_table_param.items_to_copy);
3102
2919
  if ((error=table->cursor->insertRecord(table->getInsertRecord())))
3103
2920
  {
3104
2921
    my_error(ER_USE_SQL_BIG_RESULT, MYF(0));
3116
2933
 
3117
2934
  if (end_of_records)
3118
2935
    return NESTED_LOOP_OK;
3119
 
  if (join->session->getKilled())                       // Aborted by user
 
2936
  if (join->session->killed)                    // Aborted by user
3120
2937
  {
3121
2938
    join->session->send_kill_message();
3122
2939
    return NESTED_LOOP_KILLED;
3124
2941
 
3125
2942
  init_tmptable_sum_functions(join->sum_funcs);
3126
2943
  copy_fields(&join->tmp_table_param);          // Groups are copied twice.
3127
 
  if (copy_funcs(join->tmp_table_param.items_to_copy, join->session))
3128
 
    return NESTED_LOOP_ERROR;
 
2944
  copy_funcs(join->tmp_table_param.items_to_copy);
3129
2945
 
3130
2946
  if (!(error= table->cursor->insertRecord(table->getInsertRecord())))
3131
2947
    join->send_records++;                       // New group
3184
3000
/**
3185
3001
  calc how big buffer we need for comparing group entries.
3186
3002
*/
3187
 
static void calc_group_buffer(Join *join, Order *group)
 
3003
static void calc_group_buffer(Join *join,order_st *group)
3188
3004
{
3189
3005
  uint32_t key_length=0, parts=0, null_parts=0;
3190
3006
 
3210
3026
      case REAL_RESULT:
3211
3027
        key_length+= sizeof(double);
3212
3028
        break;
3213
 
 
3214
3029
      case INT_RESULT:
3215
3030
        key_length+= sizeof(int64_t);
3216
3031
        break;
3217
 
 
3218
3032
      case DECIMAL_RESULT:
3219
 
        key_length+= class_decimal_get_binary_size(group_item->max_length -
 
3033
        key_length+= my_decimal_get_binary_size(group_item->max_length -
3220
3034
                                                (group_item->decimals ? 1 : 0),
3221
3035
                                                group_item->decimals);
3222
3036
        break;
3223
 
 
3224
3037
      case STRING_RESULT:
3225
 
        {
3226
 
          enum enum_field_types type= group_item->field_type();
 
3038
      {
 
3039
        enum enum_field_types type= group_item->field_type();
 
3040
        /*
 
3041
          As items represented as DATE/TIME fields in the group buffer
 
3042
          have STRING_RESULT result type, we increase the length
 
3043
          by 8 as maximum pack length of such fields.
 
3044
        */
 
3045
        if (type == DRIZZLE_TYPE_DATE ||
 
3046
            type == DRIZZLE_TYPE_DATETIME ||
 
3047
            type == DRIZZLE_TYPE_TIMESTAMP)
 
3048
        {
 
3049
          key_length+= 8;
 
3050
        }
 
3051
        else
 
3052
        {
3227
3053
          /*
3228
 
            As items represented as DATE/TIME fields in the group buffer
3229
 
            have STRING_RESULT result type, we increase the length
3230
 
            by 8 as maximum pack length of such fields.
 
3054
            Group strings are taken as varstrings and require an length field.
 
3055
            A field is not yet created by create_tmp_field()
 
3056
            and the sizes should match up.
3231
3057
          */
3232
 
          if (type == DRIZZLE_TYPE_DATE ||
3233
 
              type == DRIZZLE_TYPE_TIME ||
3234
 
              type == DRIZZLE_TYPE_DATETIME ||
3235
 
              type == DRIZZLE_TYPE_MICROTIME ||
3236
 
              type == DRIZZLE_TYPE_TIMESTAMP)
3237
 
          {
3238
 
            key_length+= 8;
3239
 
          }
3240
 
          else
3241
 
          {
3242
 
            /*
3243
 
              Group strings are taken as varstrings and require an length field.
3244
 
              A field is not yet created by create_tmp_field()
3245
 
              and the sizes should match up.
3246
 
            */
3247
 
            key_length+= group_item->max_length + HA_KEY_BLOB_LENGTH;
3248
 
          }
3249
 
 
3250
 
          break;
 
3058
          key_length+= group_item->max_length + HA_KEY_BLOB_LENGTH;
3251
3059
        }
3252
 
 
3253
 
      case ROW_RESULT:
 
3060
        break;
 
3061
      }
 
3062
      default:
3254
3063
        /* This case should never be choosen */
3255
3064
        assert(0);
3256
3065
        my_error(ER_OUT_OF_RESOURCES, MYF(ME_FATALERROR));
3257
3066
      }
3258
3067
    }
3259
 
 
3260
3068
    parts++;
3261
 
 
3262
3069
    if (group_item->maybe_null)
3263
3070
      null_parts++;
3264
3071
  }
3265
 
 
3266
3072
  join->tmp_table_param.group_length=key_length+null_parts;
3267
3073
  join->tmp_table_param.group_parts=parts;
3268
3074
  join->tmp_table_param.group_null_parts=null_parts;
3273
3079
 
3274
3080
  Groups are saved in reverse order for easyer check loop.
3275
3081
*/
3276
 
static bool alloc_group_fields(Join *join, Order *group)
 
3082
static bool alloc_group_fields(Join *join,order_st *group)
3277
3083
{
3278
3084
  if (group)
3279
3085
  {
3405
3211
 
3406
3212
  table_count=join->tables;
3407
3213
  if (!(join->join_tab=join_tab=
3408
 
  (JoinTable*) session->getMemRoot()->allocate(sizeof(JoinTable)*table_count)))
 
3214
  (JoinTable*) session->alloc(sizeof(JoinTable)*table_count)))
3409
3215
    return(true);
3410
3216
 
3411
 
  for (i= 0; i < table_count; i++)
3412
 
    new (join_tab+i) JoinTable();
3413
 
 
3414
3217
  join->full_join=0;
3415
3218
 
3416
3219
  used_tables= OUTER_REF_TABLE_BIT;   // Outer row is already read
4395
4198
                                             uint32_t prune_level)
4396
4199
{
4397
4200
  Session *session= join->session;
4398
 
  if (session->getKilled())  // Abort
 
4201
  if (session->killed)  // Abort
4399
4202
    return(true);
4400
4203
 
4401
4204
  /*
4563
4366
  */
4564
4367
  if (!join->table_reexec)
4565
4368
  {
4566
 
    if (!(join->table_reexec= (Table**) join->session->getMemRoot()->allocate(sizeof(Table*))))
 
4369
    if (!(join->table_reexec= (Table**) join->session->alloc(sizeof(Table*))))
4567
4370
      return(true);
4568
4371
    if (join->tmp_join)
4569
4372
      join->tmp_join->table_reexec= join->table_reexec;
4571
4374
  if (!join->join_tab_reexec)
4572
4375
  {
4573
4376
    if (!(join->join_tab_reexec=
4574
 
          (JoinTable*) join->session->getMemRoot()->allocate(sizeof(JoinTable))))
 
4377
          (JoinTable*) join->session->alloc(sizeof(JoinTable))))
4575
4378
      return(true);
4576
 
    new (join->join_tab_reexec) JoinTable();
4577
4379
    if (join->tmp_join)
4578
4380
      join->tmp_join->join_tab_reexec= join->join_tab_reexec;
4579
4381
  }
4594
4396
  join->row_limit=join->unit->select_limit_cnt;
4595
4397
  join->do_send_rows = (join->row_limit) ? 1 : 0;
4596
4398
 
 
4399
  join_tab->cache.buff=0;                       /* No caching */
4597
4400
  join_tab->table=tmp_table;
4598
4401
  join_tab->select=0;
4599
4402
  join_tab->select_cond=0;
4684
4487
      /* Ignore sj-nests: */
4685
4488
      if (!embedding->on_expr)
4686
4489
        continue;
4687
 
      NestedJoin *nested_join= embedding->getNestedJoin();
 
4490
      nested_join_st *nested_join= embedding->getNestedJoin();
4688
4491
      if (!nested_join->counter_)
4689
4492
      {
4690
4493
        /*
4802
4605
          join->full_join= 1;
4803
4606
      }
4804
4607
 
4805
 
      if (join->full_join and not session->lex->current_select->is_cross and not cond)
4806
 
      {
4807
 
        my_error(ER_CARTESIAN_JOIN_ATTEMPTED, MYF(0));
4808
 
        return 1;
4809
 
      }
4810
 
 
4811
4608
      tmp= NULL;
4812
4609
      if (cond)
4813
4610
        tmp= make_cond_for_table(cond,used_tables,current_map, 0);
4838
4635
          tab->type == AM_EQ_REF)
4839
4636
      {
4840
4637
        optimizer::SqlSelect *sel= tab->select= ((optimizer::SqlSelect*)
4841
 
            session->getMemRoot()->duplicate((unsigned char*) select,
 
4638
            session->memdup((unsigned char*) select,
4842
4639
              sizeof(*select)));
4843
4640
        if (! sel)
4844
4641
          return 1;                     // End of memory
4976
4773
                                         current_map, 0)))
4977
4774
            {
4978
4775
              tab->cache.select= (optimizer::SqlSelect*)
4979
 
                session->getMemRoot()->duplicate((unsigned char*) sel, sizeof(optimizer::SqlSelect));
 
4776
                session->memdup((unsigned char*) sel, sizeof(optimizer::SqlSelect));
4980
4777
              tab->cache.select->cond= tmp;
4981
4778
              tab->cache.select->read_tables= join->const_table_map;
4982
4779
            }
5112
4909
 
5113
4910
    if (tab->insideout_match_tab)
5114
4911
    {
5115
 
      if (! (tab->insideout_buf= (unsigned char*) join->session->getMemRoot()->allocate(tab->table->key_info
 
4912
      if (! (tab->insideout_buf= (unsigned char*) join->session->alloc(tab->table->key_info
5116
4913
                                                                       [tab->index].
5117
4914
                                                                       key_length)))
5118
4915
        return true;
5163
4960
}
5164
4961
 
5165
4962
/** Update the dependency map for the sort order. */
5166
 
static void update_depend_map(Join *join, Order *order)
 
4963
static void update_depend_map(Join *join, order_st *order)
5167
4964
{
5168
4965
  for (; order ; order=order->next)
5169
4966
  {
5201
4998
  @return
5202
4999
    Returns new sort order
5203
5000
*/
5204
 
static Order *remove_constants(Join *join,Order *first_order, COND *cond, bool change_list, bool *simple_order)
 
5001
static order_st *remove_constants(Join *join,order_st *first_order, COND *cond, bool change_list, bool *simple_order)
5205
5002
{
5206
5003
  if (join->tables == join->const_tables)
5207
5004
    return change_list ? 0 : first_order;               // No need to sort
5208
5005
 
5209
 
  Order *order,**prev_ptr;
 
5006
  order_st *order,**prev_ptr;
5210
5007
  table_map first_table= join->join_tab[join->const_tables].table->map;
5211
5008
  table_map not_const_tables= ~join->const_table_map;
5212
5009
  table_map ref;
5430
5227
static COND *simplify_joins(Join *join, List<TableList> *join_list, COND *conds, bool top)
5431
5228
{
5432
5229
  TableList *table;
5433
 
  NestedJoin *nested_join;
 
5230
  nested_join_st *nested_join;
5434
5231
  TableList *prev_table= 0;
5435
5232
  List_iterator<TableList> li(*join_list);
5436
5233
 
5647
5444
                               List<Item> &fields,
5648
5445
                               List<Item> &all_fields,
5649
5446
                               COND **conds,
5650
 
                               Order *order,
5651
 
                               Order *group,
 
5447
                               order_st *order,
 
5448
                               order_st *group,
5652
5449
                               bool *hidden_group_fields)
5653
5450
{
5654
5451
  int res;
5703
5500
 
5704
5501
  table_count= join->tables;
5705
5502
  stat= (JoinTable*) join->session->calloc(sizeof(JoinTable)*table_count);
5706
 
  stat_ref= (JoinTable**) join->session->getMemRoot()->allocate(sizeof(JoinTable*)*MAX_TABLES);
5707
 
  table_vector= (Table**) join->session->getMemRoot()->allocate(sizeof(Table*)*(table_count*2));
 
5503
  stat_ref= (JoinTable**) join->session->alloc(sizeof(JoinTable*)*MAX_TABLES);
 
5504
  table_vector= (Table**) join->session->alloc(sizeof(Table*)*(table_count*2));
5708
5505
  if (! stat || ! stat_ref || ! table_vector)
5709
5506
    return 1;
5710
5507
 
5768
5565
      s->embedding_map.reset();
5769
5566
      do
5770
5567
      {
5771
 
        NestedJoin *nested_join= embedding->getNestedJoin();
 
5568
        nested_join_st *nested_join= embedding->getNestedJoin();
5772
5569
        s->embedding_map|= nested_join->nj_map;
5773
5570
        s->dependent|= embedding->getDepTables();
5774
5571
        embedding= embedding->getEmbedding();
5797
5594
       As we use bitmaps to represent the relation the complexity
5798
5595
       of the algorithm is O((number of tables)^2).
5799
5596
    */
5800
 
    for (i= 0; i < table_count; i++)
 
5597
    for (i= 0, s= stat ; i < table_count ; i++, s++)
5801
5598
    {
5802
 
      uint32_t j;
5803
 
      table= stat[i].table;
5804
 
 
5805
 
      if (!table->reginfo.join_tab->dependent)
5806
 
        continue;
5807
 
 
5808
 
      for (j= 0, s= stat; j < table_count; j++, s++)
 
5599
      for (uint32_t j= 0 ; j < table_count ; j++)
5809
5600
      {
 
5601
        table= stat[j].table;
5810
5602
        if (s->dependent & table->map)
5811
 
        {
5812
 
          table_map was_dependent= s->dependent;
5813
5603
          s->dependent |= table->reginfo.join_tab->dependent;
5814
 
          if (i > j && s->dependent != was_dependent)
5815
 
          {
5816
 
            i= j= 1;
5817
 
            break;
5818
 
          }
5819
 
        }
5820
5604
      }
 
5605
      if (s->dependent)
 
5606
        s->table->maybe_null= 1;
5821
5607
    }
5822
5608
    /* Catch illegal cross references for outer joins */
5823
5609
    for (i= 0, s= stat ; i < table_count ; i++, s++)
5828
5614
        my_message(ER_WRONG_OUTER_JOIN, ER(ER_WRONG_OUTER_JOIN), MYF(0));
5829
5615
        return 1;
5830
5616
      }
5831
 
      if (outer_join & s->table->map)
5832
 
        s->table->maybe_null= 1;
5833
 
 
5834
5617
      s->key_dependent= s->dependent;
5835
5618
    }
5836
5619
  }
5852
5635
    s= p_pos->getJoinTable();
5853
5636
    s->type= AM_SYSTEM;
5854
5637
    join->const_table_map|=s->table->map;
5855
 
    if ((tmp= s->joinReadConstTable(p_pos)))
 
5638
    if ((tmp= join_read_const_table(s, p_pos)))
5856
5639
    {
5857
5640
      if (tmp > 0)
5858
5641
        return 1;                       // Fatal error
5926
5709
          join->const_table_map|=table->map;
5927
5710
          set_position(join, const_count++, s, (optimizer::KeyUse*) 0);
5928
5711
          partial_pos= join->getSpecificPosInPartialPlan(const_count - 1);
5929
 
          if ((tmp= s->joinReadConstTable(partial_pos)))
 
5712
          if ((tmp= join_read_const_table(s, partial_pos)))
5930
5713
          {
5931
5714
            if (tmp > 0)
5932
5715
              return 1;                 // Fatal error
5978
5761
                if (create_ref_for_key(join, s, start_keyuse, found_const_table_map))
5979
5762
                  return 1;
5980
5763
                partial_pos= join->getSpecificPosInPartialPlan(const_count - 1);
5981
 
                if ((tmp=s->joinReadConstTable(partial_pos)))
 
5764
                if ((tmp=join_read_const_table(s, partial_pos)))
5982
5765
                {
5983
5766
                  if (tmp > 0)
5984
5767
                    return 1;                   // Fatal error
6062
5845
      s->quick=select->quick;
6063
5846
      s->needed_reg=select->needed_reg;
6064
5847
      select->quick=0;
6065
 
 
6066
5848
      if (records == 0 && s->table->reginfo.impossible_range)
6067
5849
      {
6068
5850
        /*
6102
5884
  if (join->const_tables != join->tables)
6103
5885
  {
6104
5886
    optimize_keyuse(join, keyuse_array);
6105
 
    // @note c_str() is not likely to be valid here if dtrace expects it to
6106
 
    // exist for any period of time.
6107
 
    DRIZZLE_QUERY_OPT_CHOOSE_PLAN_START(join->session->getQueryString()->c_str(), join->session->thread_id);
 
5887
    DRIZZLE_QUERY_OPT_CHOOSE_PLAN_START(join->session->query.c_str(), join->session->thread_id);
6108
5888
    bool res= choose_plan(join, all_table_map & ~join->const_table_map);
6109
5889
    DRIZZLE_QUERY_OPT_CHOOSE_PLAN_DONE(res ? 1 : 0);
6110
5890
    if (res)
6116
5896
    join->best_read= 1.0;
6117
5897
  }
6118
5898
  /* Generate an execution plan from the found optimal join order. */
6119
 
  return (join->session->getKilled() || get_best_combination(join));
 
5899
  return (join->session->killed || get_best_combination(join));
6120
5900
}
6121
5901
 
6122
5902
/**
6144
5924
  TableList *table;
6145
5925
  while ((table= li++))
6146
5926
  {
6147
 
    NestedJoin *nested_join;
 
5927
    nested_join_st *nested_join;
6148
5928
    if ((nested_join= table->getNestedJoin()))
6149
5929
    {
6150
5930
      /*
6176
5956
  Return table number if there is only one table in sort order
6177
5957
  and group and order is compatible, else return 0.
6178
5958
*/
6179
 
static Table *get_sort_by_table(Order *a, Order *b,TableList *tables)
 
5959
static Table *get_sort_by_table(order_st *a,order_st *b,TableList *tables)
6180
5960
{
6181
5961
  table_map map= (table_map) 0;
6182
5962
 
6201
5981
}
6202
5982
 
6203
5983
/**
6204
 
  Set NestedJoin::counter=0 in all nested joins in passed list.
 
5984
  Set nested_join_st::counter=0 in all nested joins in passed list.
6205
5985
 
6206
 
    Recursively set NestedJoin::counter=0 for all nested joins contained in
 
5986
    Recursively set nested_join_st::counter=0 for all nested joins contained in
6207
5987
    the passed join_list.
6208
5988
 
6209
5989
  @param join_list  List of nested joins to process. It may also contain base
6215
5995
  TableList *table;
6216
5996
  while ((table= li++))
6217
5997
  {
6218
 
    NestedJoin *nested_join;
 
5998
    nested_join_st *nested_join;
6219
5999
    if ((nested_join= table->getNestedJoin()))
6220
6000
    {
6221
6001
      nested_join->counter_= 0;
6231
6011
  If first parts has different direction, change it to second part
6232
6012
  (group is sorted like order)
6233
6013
*/
6234
 
static bool test_if_subpart(Order *a, Order *b)
 
6014
static bool test_if_subpart(order_st *a,order_st *b)
6235
6015
{
6236
6016
  for (; a && b; a=a->next,b=b->next)
6237
6017
  {
6301
6081
  Join *join= last->join;
6302
6082
  for (;last_emb != NULL; last_emb= last_emb->getEmbedding())
6303
6083
  {
6304
 
    NestedJoin *nest= last_emb->getNestedJoin();
 
6084
    nested_join_st *nest= last_emb->getNestedJoin();
6305
6085
    
6306
6086
    bool was_fully_covered= nest->is_fully_covered();
6307
6087