~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/join.cc

Fix pidfile argument.

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
1267
1106
      If this join belongs to an uncacheable subquery save
1268
1107
      the original join
1269
1108
    */
1270
 
    if (select_lex->uncacheable.any() && 
1271
 
        ! is_top_level_join() &&
 
1109
    if (select_lex->uncacheable && !is_top_level_join() &&
1272
1110
        init_save_join_tab())
1273
 
    {
1274
 
      return -1;
1275
 
    }
 
1111
      return(-1);
1276
1112
  }
1277
1113
 
1278
1114
  error= 0;
1279
 
  return 0;
 
1115
  return(0);
1280
1116
 
1281
1117
setup_subq_exit:
1282
1118
  /* Even with zero matching rows, subqueries in the HAVING clause
1350
1186
*/
1351
1187
bool Join::init_save_join_tab()
1352
1188
{
1353
 
  if (!(tmp_join= (Join*)session->getMemRoot()->allocate(sizeof(Join))))
 
1189
  if (!(tmp_join= (Join*)session->alloc(sizeof(Join))))
1354
1190
    return 1;
1355
 
 
1356
1191
  error= 0;              // Ensure that tmp_join.error= 0
1357
1192
  restore_tmp();
1358
 
 
1359
1193
  return 0;
1360
1194
}
1361
1195
 
1362
1196
bool Join::save_join_tab()
1363
1197
{
1364
 
  if (! join_tab_save && select_lex->master_unit()->uncacheable.any())
 
1198
  if (!join_tab_save && select_lex->master_unit()->uncacheable)
1365
1199
  {
1366
 
    if (!(join_tab_save= (JoinTable*)session->getMemRoot()->duplicate((unsigned char*) join_tab,
 
1200
    if (!(join_tab_save= (JoinTable*)session->memdup((unsigned char*) join_tab,
1367
1201
            sizeof(JoinTable) * tables)))
1368
1202
      return 1;
1369
1203
  }
1611
1445
              exec_tmp_table2= create_tmp_table(session,
1612
1446
                                                &curr_join->tmp_table_param,
1613
1447
                                                *curr_all_fields,
1614
 
                                                (Order*) 0,
 
1448
                                                (order_st*) 0,
1615
1449
                                                curr_join->select_distinct &&
1616
1450
                                                !curr_join->group_list,
1617
1451
                                                1, curr_join->select_options,
1765
1599
      if (sort_table_cond)
1766
1600
      {
1767
1601
        if (!curr_table->select)
1768
 
          if (!(curr_table->select= new optimizer::SqlSelect()))
 
1602
          if (!(curr_table->select= new optimizer::SqlSelect))
1769
1603
            return;
1770
1604
        if (!curr_table->select->cond)
1771
1605
          curr_table->select->cond= sort_table_cond;
1969
1803
    is called after all rows are sent, but before EOF packet is sent.
1970
1804
 
1971
1805
    For a simple SELECT with no subqueries this function performs a full
1972
 
    cleanup of the Join and calls unlockReadTables to free used base
 
1806
    cleanup of the Join and calls mysql_unlock_read_tables to free used base
1973
1807
    tables.
1974
1808
 
1975
1809
    If a Join is executed for a subquery or if it has a subquery, we can't
2001
1835
    Optimization: if not EXPLAIN and we are done with the Join,
2002
1836
    free all tables.
2003
1837
  */
2004
 
  bool full= (select_lex->uncacheable.none() && ! session->lex->describe);
 
1838
  bool full= (!select_lex->uncacheable && !session->lex->describe);
2005
1839
  bool can_unlock= full;
2006
1840
 
2007
1841
  cleanup(full);
2012
1846
    for (sl= tmp_unit->first_select(); sl; sl= sl->next_select())
2013
1847
    {
2014
1848
      Item_subselect *subselect= sl->master_unit()->item;
2015
 
      bool full_local= full && (!subselect || 
2016
 
                                (subselect->is_evaluated() &&
2017
 
                                !subselect->is_uncacheable()));
 
1849
      bool full_local= full && (!subselect || subselect->is_evaluated());
2018
1850
      /*
2019
1851
        If this join is evaluated, we can fully clean it up and clean up all
2020
1852
        its underlying joins even if they are correlated -- they will not be
2043
1875
      TODO: unlock tables even if the join isn't top level select in the
2044
1876
      tree.
2045
1877
    */
2046
 
    session->unlockReadTables(lock);           // Don't free join->lock
 
1878
    mysql_unlock_read_tables(session, lock);           // Don't free join->lock
2047
1879
    lock= 0;
2048
1880
  }
2049
1881
 
2066
1898
{
2067
1899
  if (table)
2068
1900
  {
 
1901
    JoinTable *tab,*end;
2069
1902
    /*
2070
1903
      Only a sorted table may be cached.  This sorted table is always the
2071
1904
      first non const table in join->table
2075
1908
      table[const_tables]->free_io_cache();
2076
1909
      table[const_tables]->filesort_free_buffers(full);
2077
1910
    }
2078
 
  }
2079
 
 
2080
 
  if (join_tab)
2081
 
  {
2082
 
    JoinTable *tab,*end;
2083
1911
 
2084
1912
    if (full)
2085
1913
    {
2096
1924
      }
2097
1925
    }
2098
1926
  }
2099
 
 
2100
1927
  /*
2101
1928
    We are not using tables anymore
2102
1929
    Unlock all tables. We may be in an INSERT .... SELECT statement.
2140
1967
    are not re-calculated.
2141
1968
  */
2142
1969
  for (uint32_t i= join->const_tables; i < join->tables; i++)
2143
 
  {
2144
1970
    join->table[i]->mark_as_null_row();   // All fields are NULL
2145
 
  }
2146
1971
}
2147
1972
 
2148
1973
/**
2163
1988
    If we are using rollup, we need a copy of the summary functions for
2164
1989
    each level
2165
1990
  */
2166
 
  if (rollup.getState() != Rollup::STATE_NONE)
 
1991
  if (rollup.state != ROLLUP::STATE_NONE)
2167
1992
    func_count*= (send_group_parts+1);
2168
1993
 
2169
1994
  group_parts= send_group_parts;
2180
2005
    */
2181
2006
    if (order)
2182
2007
    {
2183
 
      Order *ord;
 
2008
      order_st *ord;
2184
2009
      for (ord= order; ord; ord= ord->next)
2185
2010
        group_parts++;
2186
2011
    }
2226
2051
         ((Item_sum *)item)->depended_from() == select_lex))
2227
2052
      *func++= (Item_sum*) item;
2228
2053
  }
2229
 
  if (before_group_by && rollup.getState() == Rollup::STATE_INITED)
 
2054
  if (before_group_by && rollup.state == ROLLUP::STATE_INITED)
2230
2055
  {
2231
 
    rollup.setState(Rollup::STATE_READY);
 
2056
    rollup.state= ROLLUP::STATE_READY;
2232
2057
    if (rollup_make_fields(field_list, send_fields, &func))
2233
 
      return true;     // Should never happen
 
2058
      return(true);     // Should never happen
2234
2059
  }
2235
 
  else if (rollup.getState() == Rollup::STATE_NONE)
 
2060
  else if (rollup.state == ROLLUP::STATE_NONE)
2236
2061
  {
2237
2062
    for (uint32_t i=0 ; i <= send_group_parts ;i++)
2238
2063
      sum_funcs_end[i]= func;
2239
2064
  }
2240
 
  else if (rollup.getState() == Rollup::STATE_READY)
 
2065
  else if (rollup.state == ROLLUP::STATE_READY)
2241
2066
    return(false);                         // Don't put end marker
2242
2067
  *func=0;          // End marker
2243
2068
  return(false);
2246
2071
/** Allocate memory needed for other rollup functions. */
2247
2072
bool Join::rollup_init()
2248
2073
{
 
2074
  uint32_t i,j;
2249
2075
  Item **ref_array;
2250
2076
 
2251
2077
  tmp_table_param.quick_group= 0; // Can't create groups in tmp table
2252
 
  rollup.setState(Rollup::STATE_INITED);
 
2078
  rollup.state= ROLLUP::STATE_INITED;
2253
2079
 
2254
2080
  /*
2255
2081
    Create pointers to the different sum function groups
2257
2083
  */
2258
2084
  tmp_table_param.group_parts= send_group_parts;
2259
2085
 
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
 
  {
 
2086
  if (!(rollup.null_items= (Item_null_result**) session->alloc((sizeof(Item*) +
 
2087
                                                sizeof(Item**) +
 
2088
                                                sizeof(List<Item>) +
 
2089
                        ref_pointer_array_size)
 
2090
                        * send_group_parts )))
2267
2091
    return 1;
2268
 
  }
2269
2092
 
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);
 
2093
  rollup.fields= (List<Item>*) (rollup.null_items + send_group_parts);
 
2094
  rollup.ref_pointer_arrays= (Item***) (rollup.fields + send_group_parts);
 
2095
  ref_array= (Item**) (rollup.ref_pointer_arrays+send_group_parts);
2273
2096
 
2274
2097
  /*
2275
2098
    Prepare space for field list for the different levels
2276
2099
    These will be filled up in rollup_make_fields()
2277
2100
  */
2278
 
  for (uint32_t i= 0 ; i < send_group_parts ; i++)
 
2101
  for (i= 0 ; i < send_group_parts ; i++)
2279
2102
  {
2280
 
    rollup.getNullItems()[i]= new (session->mem_root) Item_null_result();
2281
 
    List<Item> *rollup_fields= &rollup.getFields()[i];
 
2103
    rollup.null_items[i]= new (session->mem_root) Item_null_result();
 
2104
    List<Item> *rollup_fields= &rollup.fields[i];
2282
2105
    rollup_fields->empty();
2283
 
    rollup.getRefPointerArrays()[i]= ref_array;
 
2106
    rollup.ref_pointer_arrays[i]= ref_array;
2284
2107
    ref_array+= all_fields.elements;
2285
2108
  }
2286
 
 
2287
 
  for (uint32_t i= 0 ; i < send_group_parts; i++)
 
2109
  for (i= 0 ; i < send_group_parts; i++)
2288
2110
  {
2289
 
    for (uint32_t j= 0 ; j < fields_list.elements ; j++)
2290
 
    {
2291
 
      rollup.getFields()[i].push_back(rollup.getNullItems()[i]);
2292
 
    }
 
2111
    for (j=0 ; j < fields_list.elements ; j++)
 
2112
      rollup.fields[i].push_back(rollup.null_items[i]);
2293
2113
  }
2294
 
 
2295
2114
  List_iterator<Item> it(all_fields);
2296
2115
  Item *item;
2297
2116
  while ((item= it++))
2298
2117
  {
2299
 
    Order *group_tmp;
 
2118
    order_st *group_tmp;
2300
2119
    bool found_in_group= 0;
2301
2120
 
2302
2121
    for (group_tmp= group_list; group_tmp; group_tmp= group_tmp->next)
2325
2144
            return 1;
2326
2145
          new_item->fix_fields(session, (Item **) 0);
2327
2146
          session->change_item_tree(it.ref(), new_item);
2328
 
          for (Order *tmp= group_tmp; tmp; tmp= tmp->next)
 
2147
          for (order_st *tmp= group_tmp; tmp; tmp= tmp->next)
2329
2148
          {
2330
2149
            if (*tmp->item == item)
2331
2150
              session->change_item_tree(tmp->item, new_item);
2398
2217
    uint32_t pos= send_group_parts - level -1;
2399
2218
    bool real_fields= 0;
2400
2219
    Item *item;
2401
 
    List_iterator<Item> new_it(rollup.getFields()[pos]);
2402
 
    Item **ref_array_start= rollup.getRefPointerArrays()[pos];
2403
 
    Order *start_group;
 
2220
    List_iterator<Item> new_it(rollup.fields[pos]);
 
2221
    Item **ref_array_start= rollup.ref_pointer_arrays[pos];
 
2222
    order_st *start_group;
2404
2223
 
2405
2224
    /* Point to first hidden field */
2406
2225
    Item **ref_array= ref_array_start + fields_arg.elements-1;
2442
2261
      else
2443
2262
      {
2444
2263
        /* Check if this is something that is part of this group by */
2445
 
        Order *group_tmp;
 
2264
        order_st *group_tmp;
2446
2265
        for (group_tmp= start_group, i= pos ;
2447
2266
                  group_tmp ; group_tmp= group_tmp->next, i++)
2448
2267
        {
2497
2316
*/
2498
2317
int Join::rollup_send_data(uint32_t idx)
2499
2318
{
2500
 
  for (uint32_t i= send_group_parts ; i-- > idx ; )
 
2319
  uint32_t i;
 
2320
  for (i= send_group_parts ; i-- > idx ; )
2501
2321
  {
2502
2322
    /* Get reference pointers to sum functions in place */
2503
 
    memcpy(ref_pointer_array, rollup.getRefPointerArrays()[i], ref_pointer_array_size);
2504
 
 
 
2323
    memcpy(ref_pointer_array, rollup.ref_pointer_arrays[i],
 
2324
     ref_pointer_array_size);
2505
2325
    if ((!having || having->val_int()))
2506
2326
    {
2507
 
      if (send_records < unit->select_limit_cnt && do_send_rows && result->send_data(rollup.getFields()[i]))
2508
 
      {
2509
 
        return 1;
2510
 
      }
 
2327
      if (send_records < unit->select_limit_cnt && do_send_rows &&
 
2328
    result->send_data(rollup.fields[i]))
 
2329
  return 1;
2511
2330
      send_records++;
2512
2331
    }
2513
2332
  }
2514
2333
  /* Restore ref_pointer_array */
2515
2334
  set_items_ref_array(current_ref_pointer_array);
2516
 
 
2517
2335
  return 0;
2518
2336
}
2519
2337
 
2538
2356
*/
2539
2357
int Join::rollup_write_data(uint32_t idx, Table *table_arg)
2540
2358
{
2541
 
  for (uint32_t i= send_group_parts ; i-- > idx ; )
 
2359
  uint32_t i;
 
2360
  for (i= send_group_parts ; i-- > idx ; )
2542
2361
  {
2543
2362
    /* Get reference pointers to sum functions in place */
2544
 
    memcpy(ref_pointer_array, rollup.getRefPointerArrays()[i],
 
2363
    memcpy(ref_pointer_array, rollup.ref_pointer_arrays[i],
2545
2364
           ref_pointer_array_size);
2546
2365
    if ((!having || having->val_int()))
2547
2366
    {
2548
2367
      int write_error;
2549
2368
      Item *item;
2550
 
      List_iterator_fast<Item> it(rollup.getFields()[i]);
 
2369
      List_iterator_fast<Item> it(rollup.fields[i]);
2551
2370
      while ((item= it++))
2552
2371
      {
2553
2372
        if (item->type() == Item::NULL_ITEM && item->is_result_field())
2563
2382
  }
2564
2383
  /* Restore ref_pointer_array */
2565
2384
  set_items_ref_array(current_ref_pointer_array);
2566
 
 
2567
2385
  return 0;
2568
2386
}
2569
2387
 
2659
2477
    return NESTED_LOOP_ERROR;
2660
2478
  if (error < 0)
2661
2479
    return NESTED_LOOP_NO_MORE_ROWS;
2662
 
  if (join->session->getKilled())                       // Aborted by user
 
2480
  if (join->session->killed)                    // Aborted by user
2663
2481
  {
2664
2482
    join->session->send_kill_message();
2665
2483
    return NESTED_LOOP_KILLED;
2871
2689
  info= &join_tab->read_record;
2872
2690
  do
2873
2691
  {
2874
 
    if (join->session->getKilled())
 
2692
    if (join->session->killed)
2875
2693
    {
2876
2694
      join->session->send_kill_message();
2877
2695
      return NESTED_LOOP_KILLED;
3003
2821
{
3004
2822
  Table *table= join->tmp_table;
3005
2823
 
3006
 
  if (join->session->getKilled())                       // Aborted by user
 
2824
  if (join->session->killed)                    // Aborted by user
3007
2825
  {
3008
2826
    join->session->send_kill_message();
3009
2827
    return NESTED_LOOP_KILLED;
3011
2829
  if (!end_of_records)
3012
2830
  {
3013
2831
    copy_fields(&join->tmp_table_param);
3014
 
    if (copy_funcs(join->tmp_table_param.items_to_copy, join->session))
3015
 
      return NESTED_LOOP_ERROR;
 
2832
    copy_funcs(join->tmp_table_param.items_to_copy);
3016
2833
    if (!join->having || join->having->val_int())
3017
2834
    {
3018
2835
      int error;
3020
2837
      if ((error=table->cursor->insertRecord(table->getInsertRecord())))
3021
2838
      {
3022
2839
        if (!table->cursor->is_fatal_error(error, HA_CHECK_DUP))
3023
 
        {
3024
 
          return NESTED_LOOP_OK;
3025
 
        }
 
2840
          goto end;
3026
2841
 
3027
2842
        my_error(ER_USE_SQL_BIG_RESULT, MYF(0));
3028
2843
        return NESTED_LOOP_ERROR;        // Table is_full error
3037
2852
      }
3038
2853
    }
3039
2854
  }
3040
 
 
 
2855
end:
3041
2856
  return NESTED_LOOP_OK;
3042
2857
}
3043
2858
 
3045
2860
enum_nested_loop_state end_update(Join *join, JoinTable *, bool end_of_records)
3046
2861
{
3047
2862
  Table *table= join->tmp_table;
3048
 
  Order *group;
 
2863
  order_st *group;
3049
2864
  int   error;
3050
2865
 
3051
2866
  if (end_of_records)
3052
2867
    return NESTED_LOOP_OK;
3053
 
  if (join->session->getKilled())                       // Aborted by user
 
2868
  if (join->session->killed)                    // Aborted by user
3054
2869
  {
3055
2870
    join->session->send_kill_message();
3056
2871
    return NESTED_LOOP_KILLED;
3097
2912
      memcpy(table->getInsertRecord()+key_part->offset, group->buff, 1);
3098
2913
  }
3099
2914
  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;
 
2915
  copy_funcs(join->tmp_table_param.items_to_copy);
3102
2916
  if ((error=table->cursor->insertRecord(table->getInsertRecord())))
3103
2917
  {
3104
2918
    my_error(ER_USE_SQL_BIG_RESULT, MYF(0));
3116
2930
 
3117
2931
  if (end_of_records)
3118
2932
    return NESTED_LOOP_OK;
3119
 
  if (join->session->getKilled())                       // Aborted by user
 
2933
  if (join->session->killed)                    // Aborted by user
3120
2934
  {
3121
2935
    join->session->send_kill_message();
3122
2936
    return NESTED_LOOP_KILLED;
3124
2938
 
3125
2939
  init_tmptable_sum_functions(join->sum_funcs);
3126
2940
  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;
 
2941
  copy_funcs(join->tmp_table_param.items_to_copy);
3129
2942
 
3130
2943
  if (!(error= table->cursor->insertRecord(table->getInsertRecord())))
3131
2944
    join->send_records++;                       // New group
3184
2997
/**
3185
2998
  calc how big buffer we need for comparing group entries.
3186
2999
*/
3187
 
static void calc_group_buffer(Join *join, Order *group)
 
3000
static void calc_group_buffer(Join *join,order_st *group)
3188
3001
{
3189
3002
  uint32_t key_length=0, parts=0, null_parts=0;
3190
3003
 
3210
3023
      case REAL_RESULT:
3211
3024
        key_length+= sizeof(double);
3212
3025
        break;
3213
 
 
3214
3026
      case INT_RESULT:
3215
3027
        key_length+= sizeof(int64_t);
3216
3028
        break;
3217
 
 
3218
3029
      case DECIMAL_RESULT:
3219
 
        key_length+= class_decimal_get_binary_size(group_item->max_length -
 
3030
        key_length+= my_decimal_get_binary_size(group_item->max_length -
3220
3031
                                                (group_item->decimals ? 1 : 0),
3221
3032
                                                group_item->decimals);
3222
3033
        break;
3223
 
 
3224
3034
      case STRING_RESULT:
3225
 
        {
3226
 
          enum enum_field_types type= group_item->field_type();
 
3035
      {
 
3036
        enum enum_field_types type= group_item->field_type();
 
3037
        /*
 
3038
          As items represented as DATE/TIME fields in the group buffer
 
3039
          have STRING_RESULT result type, we increase the length
 
3040
          by 8 as maximum pack length of such fields.
 
3041
        */
 
3042
        if (type == DRIZZLE_TYPE_DATE ||
 
3043
            type == DRIZZLE_TYPE_DATETIME ||
 
3044
            type == DRIZZLE_TYPE_TIMESTAMP)
 
3045
        {
 
3046
          key_length+= 8;
 
3047
        }
 
3048
        else
 
3049
        {
3227
3050
          /*
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.
 
3051
            Group strings are taken as varstrings and require an length field.
 
3052
            A field is not yet created by create_tmp_field()
 
3053
            and the sizes should match up.
3231
3054
          */
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;
 
3055
          key_length+= group_item->max_length + HA_KEY_BLOB_LENGTH;
3251
3056
        }
3252
 
 
3253
 
      case ROW_RESULT:
 
3057
        break;
 
3058
      }
 
3059
      default:
3254
3060
        /* This case should never be choosen */
3255
3061
        assert(0);
3256
3062
        my_error(ER_OUT_OF_RESOURCES, MYF(ME_FATALERROR));
3257
3063
      }
3258
3064
    }
3259
 
 
3260
3065
    parts++;
3261
 
 
3262
3066
    if (group_item->maybe_null)
3263
3067
      null_parts++;
3264
3068
  }
3265
 
 
3266
3069
  join->tmp_table_param.group_length=key_length+null_parts;
3267
3070
  join->tmp_table_param.group_parts=parts;
3268
3071
  join->tmp_table_param.group_null_parts=null_parts;
3273
3076
 
3274
3077
  Groups are saved in reverse order for easyer check loop.
3275
3078
*/
3276
 
static bool alloc_group_fields(Join *join, Order *group)
 
3079
static bool alloc_group_fields(Join *join,order_st *group)
3277
3080
{
3278
3081
  if (group)
3279
3082
  {
3405
3208
 
3406
3209
  table_count=join->tables;
3407
3210
  if (!(join->join_tab=join_tab=
3408
 
  (JoinTable*) session->getMemRoot()->allocate(sizeof(JoinTable)*table_count)))
 
3211
  (JoinTable*) session->alloc(sizeof(JoinTable)*table_count)))
3409
3212
    return(true);
3410
3213
 
3411
 
  for (i= 0; i < table_count; i++)
3412
 
    new (join_tab+i) JoinTable();
3413
 
 
3414
3214
  join->full_join=0;
3415
3215
 
3416
3216
  used_tables= OUTER_REF_TABLE_BIT;   // Outer row is already read
4395
4195
                                             uint32_t prune_level)
4396
4196
{
4397
4197
  Session *session= join->session;
4398
 
  if (session->getKilled())  // Abort
 
4198
  if (session->killed)  // Abort
4399
4199
    return(true);
4400
4200
 
4401
4201
  /*
4563
4363
  */
4564
4364
  if (!join->table_reexec)
4565
4365
  {
4566
 
    if (!(join->table_reexec= (Table**) join->session->getMemRoot()->allocate(sizeof(Table*))))
 
4366
    if (!(join->table_reexec= (Table**) join->session->alloc(sizeof(Table*))))
4567
4367
      return(true);
4568
4368
    if (join->tmp_join)
4569
4369
      join->tmp_join->table_reexec= join->table_reexec;
4571
4371
  if (!join->join_tab_reexec)
4572
4372
  {
4573
4373
    if (!(join->join_tab_reexec=
4574
 
          (JoinTable*) join->session->getMemRoot()->allocate(sizeof(JoinTable))))
 
4374
          (JoinTable*) join->session->alloc(sizeof(JoinTable))))
4575
4375
      return(true);
4576
 
    new (join->join_tab_reexec) JoinTable();
4577
4376
    if (join->tmp_join)
4578
4377
      join->tmp_join->join_tab_reexec= join->join_tab_reexec;
4579
4378
  }
4594
4393
  join->row_limit=join->unit->select_limit_cnt;
4595
4394
  join->do_send_rows = (join->row_limit) ? 1 : 0;
4596
4395
 
 
4396
  join_tab->cache.buff=0;                       /* No caching */
4597
4397
  join_tab->table=tmp_table;
4598
4398
  join_tab->select=0;
4599
4399
  join_tab->select_cond=0;
4684
4484
      /* Ignore sj-nests: */
4685
4485
      if (!embedding->on_expr)
4686
4486
        continue;
4687
 
      NestedJoin *nested_join= embedding->getNestedJoin();
 
4487
      nested_join_st *nested_join= embedding->getNestedJoin();
4688
4488
      if (!nested_join->counter_)
4689
4489
      {
4690
4490
        /*
4802
4602
          join->full_join= 1;
4803
4603
      }
4804
4604
 
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
4605
      tmp= NULL;
4812
4606
      if (cond)
4813
4607
        tmp= make_cond_for_table(cond,used_tables,current_map, 0);
4838
4632
          tab->type == AM_EQ_REF)
4839
4633
      {
4840
4634
        optimizer::SqlSelect *sel= tab->select= ((optimizer::SqlSelect*)
4841
 
            session->getMemRoot()->duplicate((unsigned char*) select,
 
4635
            session->memdup((unsigned char*) select,
4842
4636
              sizeof(*select)));
4843
4637
        if (! sel)
4844
4638
          return 1;                     // End of memory
4976
4770
                                         current_map, 0)))
4977
4771
            {
4978
4772
              tab->cache.select= (optimizer::SqlSelect*)
4979
 
                session->getMemRoot()->duplicate((unsigned char*) sel, sizeof(optimizer::SqlSelect));
 
4773
                session->memdup((unsigned char*) sel, sizeof(optimizer::SqlSelect));
4980
4774
              tab->cache.select->cond= tmp;
4981
4775
              tab->cache.select->read_tables= join->const_table_map;
4982
4776
            }
5112
4906
 
5113
4907
    if (tab->insideout_match_tab)
5114
4908
    {
5115
 
      if (! (tab->insideout_buf= (unsigned char*) join->session->getMemRoot()->allocate(tab->table->key_info
 
4909
      if (! (tab->insideout_buf= (unsigned char*) join->session->alloc(tab->table->key_info
5116
4910
                                                                       [tab->index].
5117
4911
                                                                       key_length)))
5118
4912
        return true;
5163
4957
}
5164
4958
 
5165
4959
/** Update the dependency map for the sort order. */
5166
 
static void update_depend_map(Join *join, Order *order)
 
4960
static void update_depend_map(Join *join, order_st *order)
5167
4961
{
5168
4962
  for (; order ; order=order->next)
5169
4963
  {
5201
4995
  @return
5202
4996
    Returns new sort order
5203
4997
*/
5204
 
static Order *remove_constants(Join *join,Order *first_order, COND *cond, bool change_list, bool *simple_order)
 
4998
static order_st *remove_constants(Join *join,order_st *first_order, COND *cond, bool change_list, bool *simple_order)
5205
4999
{
5206
5000
  if (join->tables == join->const_tables)
5207
5001
    return change_list ? 0 : first_order;               // No need to sort
5208
5002
 
5209
 
  Order *order,**prev_ptr;
 
5003
  order_st *order,**prev_ptr;
5210
5004
  table_map first_table= join->join_tab[join->const_tables].table->map;
5211
5005
  table_map not_const_tables= ~join->const_table_map;
5212
5006
  table_map ref;
5430
5224
static COND *simplify_joins(Join *join, List<TableList> *join_list, COND *conds, bool top)
5431
5225
{
5432
5226
  TableList *table;
5433
 
  NestedJoin *nested_join;
 
5227
  nested_join_st *nested_join;
5434
5228
  TableList *prev_table= 0;
5435
5229
  List_iterator<TableList> li(*join_list);
5436
5230
 
5647
5441
                               List<Item> &fields,
5648
5442
                               List<Item> &all_fields,
5649
5443
                               COND **conds,
5650
 
                               Order *order,
5651
 
                               Order *group,
 
5444
                               order_st *order,
 
5445
                               order_st *group,
5652
5446
                               bool *hidden_group_fields)
5653
5447
{
5654
5448
  int res;
5703
5497
 
5704
5498
  table_count= join->tables;
5705
5499
  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));
 
5500
  stat_ref= (JoinTable**) join->session->alloc(sizeof(JoinTable*)*MAX_TABLES);
 
5501
  table_vector= (Table**) join->session->alloc(sizeof(Table*)*(table_count*2));
5708
5502
  if (! stat || ! stat_ref || ! table_vector)
5709
5503
    return 1;
5710
5504
 
5768
5562
      s->embedding_map.reset();
5769
5563
      do
5770
5564
      {
5771
 
        NestedJoin *nested_join= embedding->getNestedJoin();
 
5565
        nested_join_st *nested_join= embedding->getNestedJoin();
5772
5566
        s->embedding_map|= nested_join->nj_map;
5773
5567
        s->dependent|= embedding->getDepTables();
5774
5568
        embedding= embedding->getEmbedding();
5797
5591
       As we use bitmaps to represent the relation the complexity
5798
5592
       of the algorithm is O((number of tables)^2).
5799
5593
    */
5800
 
    for (i= 0; i < table_count; i++)
 
5594
    for (i= 0, s= stat ; i < table_count ; i++, s++)
5801
5595
    {
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++)
 
5596
      for (uint32_t j= 0 ; j < table_count ; j++)
5809
5597
      {
 
5598
        table= stat[j].table;
5810
5599
        if (s->dependent & table->map)
5811
 
        {
5812
 
          table_map was_dependent= s->dependent;
5813
5600
          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
5601
      }
 
5602
      if (s->dependent)
 
5603
        s->table->maybe_null= 1;
5821
5604
    }
5822
5605
    /* Catch illegal cross references for outer joins */
5823
5606
    for (i= 0, s= stat ; i < table_count ; i++, s++)
5828
5611
        my_message(ER_WRONG_OUTER_JOIN, ER(ER_WRONG_OUTER_JOIN), MYF(0));
5829
5612
        return 1;
5830
5613
      }
5831
 
      if (outer_join & s->table->map)
5832
 
        s->table->maybe_null= 1;
5833
 
 
5834
5614
      s->key_dependent= s->dependent;
5835
5615
    }
5836
5616
  }
5852
5632
    s= p_pos->getJoinTable();
5853
5633
    s->type= AM_SYSTEM;
5854
5634
    join->const_table_map|=s->table->map;
5855
 
    if ((tmp= s->joinReadConstTable(p_pos)))
 
5635
    if ((tmp= join_read_const_table(s, p_pos)))
5856
5636
    {
5857
5637
      if (tmp > 0)
5858
5638
        return 1;                       // Fatal error
5926
5706
          join->const_table_map|=table->map;
5927
5707
          set_position(join, const_count++, s, (optimizer::KeyUse*) 0);
5928
5708
          partial_pos= join->getSpecificPosInPartialPlan(const_count - 1);
5929
 
          if ((tmp= s->joinReadConstTable(partial_pos)))
 
5709
          if ((tmp= join_read_const_table(s, partial_pos)))
5930
5710
          {
5931
5711
            if (tmp > 0)
5932
5712
              return 1;                 // Fatal error
5978
5758
                if (create_ref_for_key(join, s, start_keyuse, found_const_table_map))
5979
5759
                  return 1;
5980
5760
                partial_pos= join->getSpecificPosInPartialPlan(const_count - 1);
5981
 
                if ((tmp=s->joinReadConstTable(partial_pos)))
 
5761
                if ((tmp=join_read_const_table(s, partial_pos)))
5982
5762
                {
5983
5763
                  if (tmp > 0)
5984
5764
                    return 1;                   // Fatal error
6062
5842
      s->quick=select->quick;
6063
5843
      s->needed_reg=select->needed_reg;
6064
5844
      select->quick=0;
6065
 
 
6066
5845
      if (records == 0 && s->table->reginfo.impossible_range)
6067
5846
      {
6068
5847
        /*
6102
5881
  if (join->const_tables != join->tables)
6103
5882
  {
6104
5883
    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);
 
5884
    DRIZZLE_QUERY_OPT_CHOOSE_PLAN_START(join->session->query.c_str(), join->session->thread_id);
6108
5885
    bool res= choose_plan(join, all_table_map & ~join->const_table_map);
6109
5886
    DRIZZLE_QUERY_OPT_CHOOSE_PLAN_DONE(res ? 1 : 0);
6110
5887
    if (res)
6116
5893
    join->best_read= 1.0;
6117
5894
  }
6118
5895
  /* Generate an execution plan from the found optimal join order. */
6119
 
  return (join->session->getKilled() || get_best_combination(join));
 
5896
  return (join->session->killed || get_best_combination(join));
6120
5897
}
6121
5898
 
6122
5899
/**
6144
5921
  TableList *table;
6145
5922
  while ((table= li++))
6146
5923
  {
6147
 
    NestedJoin *nested_join;
 
5924
    nested_join_st *nested_join;
6148
5925
    if ((nested_join= table->getNestedJoin()))
6149
5926
    {
6150
5927
      /*
6176
5953
  Return table number if there is only one table in sort order
6177
5954
  and group and order is compatible, else return 0.
6178
5955
*/
6179
 
static Table *get_sort_by_table(Order *a, Order *b,TableList *tables)
 
5956
static Table *get_sort_by_table(order_st *a,order_st *b,TableList *tables)
6180
5957
{
6181
5958
  table_map map= (table_map) 0;
6182
5959
 
6201
5978
}
6202
5979
 
6203
5980
/**
6204
 
  Set NestedJoin::counter=0 in all nested joins in passed list.
 
5981
  Set nested_join_st::counter=0 in all nested joins in passed list.
6205
5982
 
6206
 
    Recursively set NestedJoin::counter=0 for all nested joins contained in
 
5983
    Recursively set nested_join_st::counter=0 for all nested joins contained in
6207
5984
    the passed join_list.
6208
5985
 
6209
5986
  @param join_list  List of nested joins to process. It may also contain base
6215
5992
  TableList *table;
6216
5993
  while ((table= li++))
6217
5994
  {
6218
 
    NestedJoin *nested_join;
 
5995
    nested_join_st *nested_join;
6219
5996
    if ((nested_join= table->getNestedJoin()))
6220
5997
    {
6221
5998
      nested_join->counter_= 0;
6231
6008
  If first parts has different direction, change it to second part
6232
6009
  (group is sorted like order)
6233
6010
*/
6234
 
static bool test_if_subpart(Order *a, Order *b)
 
6011
static bool test_if_subpart(order_st *a,order_st *b)
6235
6012
{
6236
6013
  for (; a && b; a=a->next,b=b->next)
6237
6014
  {
6301
6078
  Join *join= last->join;
6302
6079
  for (;last_emb != NULL; last_emb= last_emb->getEmbedding())
6303
6080
  {
6304
 
    NestedJoin *nest= last_emb->getNestedJoin();
 
6081
    nested_join_st *nest= last_emb->getNestedJoin();
6305
6082
    
6306
6083
    bool was_fully_covered= nest->is_fully_covered();
6307
6084