~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/join.cc

  • Committer: Padraig O'Sullivan
  • Date: 2009-09-18 00:22:38 UTC
  • mto: This revision was merged to the branch mainline in revision 1139.
  • Revision ID: osullivan.padraig@gmail.com-20090918002238-zq7mui4r2yzoidz1
Extracted KeyUse into its own header file and placed it within the
drizzled::optimizer namespace.

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
21
21
/**
22
22
 * @file
23
23
 *
24
 
 * Implementation of the Join class
 
24
 * Implementation of the JOIN class
25
25
 * 
26
26
 * @defgroup Query_Optimizer  Query Optimizer
27
27
 * @{
28
28
 */
29
29
 
30
 
#include "config.h"
31
 
 
32
 
#include <float.h>
33
 
#include <math.h>
34
 
 
 
30
#include "drizzled/server_includes.h"
 
31
#include "drizzled/table_map_iterator.h"
35
32
#include "drizzled/item/cache.h"
36
33
#include "drizzled/item/cmpfunc.h"
37
34
#include "drizzled/item/copy_string.h"
48
45
#include "drizzled/optimizer/position.h"
49
46
#include "drizzled/optimizer/sargable_param.h"
50
47
#include "drizzled/optimizer/key_use.h"
51
 
#include "drizzled/optimizer/range.h"
52
 
#include "drizzled/optimizer/sum.h"
53
 
#include "drizzled/optimizer/explain_plan.h"
54
 
#include "drizzled/optimizer/access_method_factory.h"
55
 
#include "drizzled/optimizer/access_method.h"
56
 
#include "drizzled/records.h"
57
 
#include "drizzled/probes.h"
58
 
#include "drizzled/internal/my_bit.h"
59
 
#include "drizzled/internal/my_sys.h"
60
 
#include "drizzled/internal/iocache.h"
61
 
#include "drizzled/plugin/storage_engine.h"
62
 
 
63
 
#include <drizzled/debug.h>
 
48
#include "mysys/my_bit.h"
64
49
 
65
50
#include <algorithm>
66
51
 
67
52
using namespace std;
68
 
 
69
 
namespace drizzled
70
 
{
71
 
extern plugin::StorageEngine *heap_engine;
 
53
using namespace drizzled;
72
54
 
73
55
/** Declarations of static functions used in this source file. */
74
 
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);
77
 
static uint32_t cache_record_length(Join *join, uint32_t index);
78
 
static double prev_record_reads(Join *join, uint32_t idx, table_map found_ref);
79
 
static bool get_best_combination(Join *join);
80
 
static void set_position(Join *join,
 
56
static bool make_group_fields(JOIN *main_join, JOIN *curr_join);
 
57
static void calc_group_buffer(JOIN *join,order_st *group);
 
58
static bool alloc_group_fields(JOIN *join,order_st *group);
 
59
static uint32_t cache_record_length(JOIN *join, uint32_t index);
 
60
static double prev_record_reads(JOIN *join, uint32_t idx, table_map found_ref);
 
61
static bool get_best_combination(JOIN *join);
 
62
static void set_position(JOIN *join,
81
63
                         uint32_t index,
82
64
                         JoinTable *table,
83
65
                         optimizer::KeyUse *key);
84
 
static bool choose_plan(Join *join,table_map join_tables);
85
 
static void best_access_path(Join *join, JoinTable *s,
 
66
static bool choose_plan(JOIN *join,table_map join_tables);
 
67
static void best_access_path(JOIN *join, JoinTable *s,
86
68
                             Session *session,
87
69
                             table_map remaining_tables,
88
70
                             uint32_t idx,
89
71
                             double record_count,
90
72
                             double read_time);
91
 
static void optimize_straight_join(Join *join, table_map join_tables);
92
 
static bool greedy_search(Join *join, table_map remaining_tables, uint32_t depth, uint32_t prune_level);
93
 
static bool best_extension_by_limited_search(Join *join,
 
73
static void optimize_straight_join(JOIN *join, table_map join_tables);
 
74
static bool greedy_search(JOIN *join, table_map remaining_tables, uint32_t depth, uint32_t prune_level);
 
75
static bool best_extension_by_limited_search(JOIN *join,
94
76
                                             table_map remaining_tables,
95
77
                                             uint32_t idx,
96
78
                                             double record_count,
97
79
                                             double read_time,
98
80
                                             uint32_t depth,
99
81
                                             uint32_t prune_level);
100
 
static uint32_t determine_search_depth(Join* join);
101
 
static bool make_simple_join(Join *join,Table *tmp_table);
102
 
static void make_outerjoin_info(Join *join);
103
 
static bool make_join_select(Join *join, optimizer::SqlSelect *select,COND *item);
104
 
static bool make_join_readinfo(Join *join);
105
 
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);
108
 
static int return_zero_rows(Join *join,
 
82
static uint32_t determine_search_depth(JOIN* join);
 
83
static bool make_simple_join(JOIN *join,Table *tmp_table);
 
84
static void make_outerjoin_info(JOIN *join);
 
85
static bool make_join_select(JOIN *join,SQL_SELECT *select,COND *item);
 
86
static bool make_join_readinfo(JOIN *join, uint64_t options, uint32_t no_jbuf_after);
 
87
static void update_depend_map(JOIN *join);
 
88
static void update_depend_map(JOIN *join, order_st *order);
 
89
static order_st *remove_constants(JOIN *join,order_st *first_order,COND *cond, bool change_list, bool *simple_order);
 
90
static int return_zero_rows(JOIN *join,
109
91
                            select_result *res,
110
92
                            TableList *tables,
111
93
                            List<Item> &fields,
113
95
                            uint64_t select_options,
114
96
                            const char *info,
115
97
                            Item *having);
116
 
static COND *simplify_joins(Join *join, List<TableList> *join_list, COND *conds, bool top);
117
 
static int remove_duplicates(Join *join,Table *entry,List<Item> &fields, Item *having);
 
98
static COND *simplify_joins(JOIN *join, List<TableList> *join_list, COND *conds, bool top);
 
99
static int remove_duplicates(JOIN *join,Table *entry,List<Item> &fields, Item *having);
118
100
static int setup_without_group(Session *session, 
119
101
                               Item **ref_pointer_array,
120
102
                               TableList *tables,
122
104
                               List<Item> &fields,
123
105
                               List<Item> &all_fields,
124
106
                               COND **conds,
125
 
                               Order *order,
126
 
                               Order *group,
 
107
                               order_st *order,
 
108
                               order_st *group,
127
109
                               bool *hidden_group_fields);
128
 
static bool make_join_statistics(Join *join, TableList *leaves, COND *conds, DYNAMIC_ARRAY *keyuse);
 
110
static bool make_join_statistics(JOIN *join, TableList *leaves, COND *conds, DYNAMIC_ARRAY *keyuse);
129
111
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);
 
112
static Table *get_sort_by_table(order_st *a,order_st *b,TableList *tables);
131
113
static void reset_nj_counters(List<TableList> *join_list);
132
 
static bool test_if_subpart(Order *a,Order *b);
 
114
static bool test_if_subpart(order_st *a,order_st *b);
133
115
static void restore_prev_nj_state(JoinTable *last);
 
116
static uint32_t make_join_orderinfo(JOIN *join);
134
117
static bool add_ref_to_table_cond(Session *session, JoinTable *join_tab);
135
118
static void free_blobs(Field **ptr); /* Rename this method...conflicts with another in global namespace... */
136
119
 
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
120
/**
316
121
  Prepare of whole select (including sub queries in future).
317
122
 
324
129
  @retval
325
130
    0   on success
326
131
*/
327
 
int Join::prepare(Item ***rref_pointer_array,
 
132
int JOIN::prepare(Item ***rref_pointer_array,
328
133
                  TableList *tables_init,
329
134
                  uint32_t wild_num,
330
135
                  COND *conds_init,
331
136
                  uint32_t og_num,
332
 
                  Order *order_init,
333
 
                  Order *group_init,
 
137
                  order_st *order_init,
 
138
                  order_st *group_init,
334
139
                  Item *having_init,
335
140
                  Select_Lex *select_lex_arg,
336
141
                  Select_Lex_Unit *unit_arg)
363
168
      setup_tables_and_check_access(session, &select_lex->context, join_list,
364
169
                                    tables_list, &select_lex->leaf_tables,
365
170
                                    false))
366
 
  {
367
171
      return(-1);
368
 
  }
369
172
 
370
173
  TableList *table_ptr;
371
174
  for (table_ptr= select_lex->leaf_tables;
372
175
       table_ptr;
373
176
       table_ptr= table_ptr->next_leaf)
374
 
  {
375
177
    tables++;
376
 
  }
377
 
 
378
178
 
379
179
  if (setup_wild(session, fields_list, &all_fields, wild_num) ||
380
180
      select_lex->setup_ref_array(session, og_num) ||
384
184
        select_lex->leaf_tables, fields_list,
385
185
        all_fields, &conds, order, group_list,
386
186
        &hidden_group_fields))
387
 
    return(-1);
 
187
    return(-1);       /* purecov: inspected */
388
188
 
389
189
  ref_pointer_array= *rref_pointer_array;
390
190
 
391
191
  if (having)
392
192
  {
393
193
    nesting_map save_allow_sum_func= session->lex->allow_sum_func;
394
 
    session->setWhere("having clause");
 
194
    session->where="having clause";
395
195
    session->lex->allow_sum_func|= 1 << select_lex_arg->nest_level;
396
196
    select_lex->having_fix_field= 1;
397
197
    bool having_fix_rc= (!having->fixed &&
399
199
        having->check_cols(1)));
400
200
    select_lex->having_fix_field= 0;
401
201
    if (having_fix_rc || session->is_error())
402
 
      return(-1);
 
202
      return(-1);       /* purecov: inspected */
403
203
    session->lex->allow_sum_func= save_allow_sum_func;
404
204
  }
405
205
 
416
216
        in_subs= (Item_in_subselect*)subselect;
417
217
 
418
218
      {
419
 
        bool do_materialize= true;
 
219
        bool do_materialize= !test(session->variables.optimizer_switch &
 
220
                                   OPTIMIZER_SWITCH_NO_MATERIALIZATION);
420
221
        /*
421
222
          Check if the subquery predicate can be executed via materialization.
422
223
          The required conditions are:
434
235
             (Subquery is non-correlated ||
435
236
              Subquery is correlated to any query outer to IN predicate ||
436
237
              (Subquery is correlated to the immediate outer query &&
437
 
               Subquery !contains {GROUP BY, ORDER BY [LIMIT],
 
238
               Subquery !contains {GROUP BY, order_st BY [LIMIT],
438
239
               aggregate functions) && subquery predicate is not under "NOT IN"))
439
240
          6. No execution method was already chosen (by a prepared statement).
440
241
 
470
271
 
471
272
  if (order)
472
273
  {
473
 
    Order *ord;
 
274
    order_st *ord;
474
275
    for (ord= order; ord; ord= ord->next)
475
276
    {
476
277
      Item *item= *ord->item;
515
316
  {
516
317
    /* Caclulate the number of groups */
517
318
    send_group_parts= 0;
518
 
    for (Order *group_tmp= group_list ; group_tmp ; group_tmp= group_tmp->next)
 
319
    for (order_st *group_tmp= group_list ; group_tmp ; group_tmp= group_tmp->next)
519
320
      send_group_parts++;
520
321
  }
521
322
 
522
323
  if (error)
523
 
    return(-1);
 
324
    goto err;         /* purecov: inspected */
524
325
 
525
 
  /* 
526
 
   * The below will create the new table for
527
 
   * CREATE TABLE ... SELECT
528
 
   *
529
 
   * @see create_table_from_items() in drizzled/sql_insert.cc
530
 
   */
531
326
  if (result && result->prepare(fields_list, unit_arg))
532
 
    return(-1);
 
327
    goto err;         /* purecov: inspected */
533
328
 
534
329
  /* Init join struct */
535
330
  count_field_types(select_lex, &tmp_table_param, all_fields, 0);
541
336
  if (sum_func_count && !group_list && (func_count || field_count))
542
337
  {
543
338
    my_message(ER_WRONG_SUM_SELECT,ER(ER_WRONG_SUM_SELECT),MYF(0));
544
 
    return(-1);
 
339
    goto err;
545
340
  }
546
341
#endif
547
342
  if (select_lex->olap == ROLLUP_TYPE && rollup_init())
548
 
    return(-1);
549
 
 
 
343
    goto err;
550
344
  if (alloc_func_list())
551
 
    return(-1);
552
 
 
553
 
  return 0; // All OK
 
345
    goto err;
 
346
 
 
347
  return(0); // All OK
 
348
 
 
349
err:
 
350
  return(-1);       /* purecov: inspected */
554
351
}
555
352
 
556
353
/*
557
354
  Remove the predicates pushed down into the subquery
558
355
 
559
356
  SYNOPSIS
560
 
    Join::remove_subq_pushed_predicates()
 
357
    JOIN::remove_subq_pushed_predicates()
561
358
      where   IN  Must be NULL
562
359
              OUT The remaining WHERE condition, or NULL
563
360
 
582
379
    that is searched in a byte. But this requires homogenization of the return
583
380
    codes of all Field*::store() methods.
584
381
*/
585
 
void Join::remove_subq_pushed_predicates(Item **where)
 
382
void JOIN::remove_subq_pushed_predicates(Item **where)
586
383
{
587
384
  if (conds->type() == Item::FUNC_ITEM &&
588
385
      ((Item_func *)this->conds)->functype() == Item_func::EQ_FUNC &&
607
404
  @retval
608
405
    1   error
609
406
*/
610
 
int Join::optimize()
 
407
int JOIN::optimize()
611
408
{
612
409
  // to prevent double initialization on EXPLAIN
613
410
  if (optimized)
614
 
    return 0;
 
411
    return(0);
615
412
  optimized= 1;
616
413
 
617
414
  session->set_proc_info("optimizing");
677
474
    {           /* Impossible cond */
678
475
      zero_result_cause=  having_value == Item::COND_FALSE ?
679
476
                           "Impossible HAVING" : "Impossible WHERE";
680
 
      tables = 0;
681
 
      goto setup_subq_exit;
 
477
      error= 0;
 
478
      return(0);
682
479
    }
683
480
  }
684
481
 
687
484
  {
688
485
    int res;
689
486
    /*
690
 
      optimizer::sum_query() returns HA_ERR_KEY_NOT_FOUND if no rows match
 
487
      opt_sum_query() returns HA_ERR_KEY_NOT_FOUND if no rows match
691
488
      to the WHERE conditions,
692
489
      or 1 if all items were resolved,
693
490
      or 0, or an error number HA_ERR_...
694
491
    */
695
 
    if ((res= optimizer::sum_query(select_lex->leaf_tables, all_fields, conds)))
 
492
    if ((res=opt_sum_query(select_lex->leaf_tables, all_fields, conds)))
696
493
    {
697
494
      if (res == HA_ERR_KEY_NOT_FOUND)
698
495
      {
699
496
        zero_result_cause= "No matching min/max row";
700
 
        tables = 0;
701
 
        goto setup_subq_exit;
 
497
        error=0;
 
498
        return(0);
702
499
      }
703
500
      if (res > 1)
704
501
      {
708
505
      if (res < 0)
709
506
      {
710
507
        zero_result_cause= "No matching min/max row";
711
 
        tables = 0;
712
 
        goto setup_subq_exit;
 
508
        error=0;
 
509
        return(0);
713
510
      }
714
511
      zero_result_cause= "Select tables optimized away";
715
512
      tables_list= 0;       // All tables resolved
716
 
      const_tables= tables;
717
513
      /*
718
514
        Extract all table-independent conditions and replace the WHERE
719
 
        clause with them. All other conditions were computed by optimizer::sum_query
 
515
        clause with them. All other conditions were computed by opt_sum_query
720
516
        and the MIN/MAX/COUNT function(s) have been replaced by constants,
721
517
        so there is no need to compute the whole WHERE clause again.
722
518
        Notice that make_cond_for_table() will always succeed to remove all
723
 
        computed conditions, because optimizer::sum_query() is applicable only to
 
519
        computed conditions, because opt_sum_query() is applicable only to
724
520
        conjunctions.
725
521
        Preserve conditions for EXPLAIN.
726
522
      */
729
525
        COND *table_independent_conds= make_cond_for_table(conds, PSEUDO_TABLE_BITS, 0, 0);
730
526
        conds= table_independent_conds;
731
527
      }
732
 
      goto setup_subq_exit;
733
528
    }
734
529
  }
735
530
  if (!tables_list)
762
557
       select_lex->master_unit() == &session->lex->unit)) // upper level SELECT
763
558
  {
764
559
    zero_result_cause= "no matching row in const table";
765
 
    goto setup_subq_exit;
 
560
    error= 0;
 
561
    return(0);
766
562
  }
767
563
  if (!(session->options & OPTION_BIG_SELECTS) &&
768
564
      best_read > (double) session->variables.max_join_size &&
769
565
      !(select_options & SELECT_DESCRIBE))
770
 
  {
 
566
  {           /* purecov: inspected */
771
567
    my_message(ER_TOO_BIG_SELECT, ER(ER_TOO_BIG_SELECT), MYF(0));
772
568
    error= -1;
773
569
    return 1;
774
570
  }
775
571
  if (const_tables && !(select_options & SELECT_NO_UNLOCK))
776
 
    session->unlockSomeTables(table, const_tables);
 
572
    mysql_unlock_some_tables(session, table, const_tables);
777
573
  if (!conds && outer_join)
778
574
  {
779
575
    /* Handle the case where we have an OUTER JOIN without a WHERE */
780
576
    conds=new Item_int((int64_t) 1,1);  // Always true
781
577
  }
782
 
  select= optimizer::make_select(*table, const_table_map,
783
 
                                 const_table_map, conds, 1, &error);
 
578
  select= make_select(*table, const_table_map,
 
579
                      const_table_map, conds, 1, &error);
784
580
  if (error)
785
 
  {
786
 
    error= -1;
 
581
  {           /* purecov: inspected */
 
582
    error= -1;          /* purecov: inspected */
787
583
    return 1;
788
584
  }
789
585
 
823
619
  {
824
620
    conds=new Item_int((int64_t) 0,1);  // Always false
825
621
  }
826
 
 
827
622
  if (make_join_select(this, select, conds))
828
623
  {
829
624
    zero_result_cause=
830
625
      "Impossible WHERE noticed after reading const tables";
831
 
    goto setup_subq_exit;
 
626
    return(0);        // error == 0
832
627
  }
833
628
 
834
629
  error= -1;          /* if goto err */
835
630
 
836
631
  /* Optimize distinct away if possible */
837
632
  {
838
 
    Order *org_order= order;
 
633
    order_st *org_order= order;
839
634
    order= remove_constants(this, order,conds,1, &simple_order);
840
635
    if (session->is_error())
841
636
    {
844
639
    }
845
640
 
846
641
    /*
847
 
      If we are using ORDER BY NULL or ORDER BY const_expression,
 
642
      If we are using order_st BY NULL or order_st BY const_expression,
848
643
      return result in any order (even if we are using a GROUP BY)
849
644
    */
850
645
    if (!order && org_order)
863
658
     The FROM clause must contain a single non-constant table.
864
659
  */
865
660
  if (tables - const_tables == 1 && (group_list || select_distinct) &&
866
 
      ! tmp_table_param.sum_func_count &&
867
 
      (! join_tab[const_tables].select ||
868
 
       ! join_tab[const_tables].select->quick ||
 
661
      !tmp_table_param.sum_func_count &&
 
662
      (!join_tab[const_tables].select ||
 
663
       !join_tab[const_tables].select->quick ||
869
664
       join_tab[const_tables].select->quick->get_type() !=
870
 
       optimizer::QuickSelectInterface::QS_TYPE_GROUP_MIN_MAX))
 
665
       QUICK_SELECT_I::QS_TYPE_GROUP_MIN_MAX))
871
666
  {
872
667
    if (group_list && list_contains_unique_index(join_tab[const_tables].table, find_field_in_order_list, (void *) group_list))
873
668
    {
875
670
        We have found that grouping can be removed since groups correspond to
876
671
        only one row anyway, but we still have to guarantee correct result
877
672
        order. The line below effectively rewrites the query from GROUP BY
878
 
        <fields> to ORDER BY <fields>. There are two exceptions:
 
673
        <fields> to order_st BY <fields>. There are two exceptions:
879
674
        - if skip_sort_order is set (see above), then we can simply skip
880
675
          GROUP BY;
881
 
        - we can only rewrite ORDER BY if the ORDER BY fields are 'compatible'
 
676
        - we can only rewrite order_st BY if the order_st BY fields are 'compatible'
882
677
          with the GROUP BY ones, i.e. either one is a prefix of another.
883
 
          We only check if the ORDER BY is a prefix of GROUP BY. In this case
 
678
          We only check if the order_st BY is a prefix of GROUP BY. In this case
884
679
          test_if_subpart() copies the ASC/DESC attributes from the original
885
 
          ORDER BY fields.
 
680
          order_st BY fields.
886
681
          If GROUP BY is a prefix of order_st BY, then it is safe to leave
887
682
          'order' as is.
888
683
       */
889
 
      if (! order || test_if_subpart(group_list, order))
 
684
      if (!order || test_if_subpart(group_list, order))
890
685
          order= skip_sort_order ? 0 : group_list;
891
686
      /*
892
687
        If we have an IGNORE INDEX FOR GROUP BY(fields) clause, this must be
907
702
  }
908
703
  if (group_list || tmp_table_param.sum_func_count)
909
704
  {
910
 
    if (! hidden_group_fields && rollup.getState() == Rollup::STATE_NONE)
 
705
    if (! hidden_group_fields && rollup.state == ROLLUP::STATE_NONE)
911
706
      select_distinct=0;
912
707
  }
913
708
  else if (select_distinct && tables - const_tables == 1)
921
716
      - We are scanning the whole table without LIMIT
922
717
        This can happen if:
923
718
        - We are using CALC_FOUND_ROWS
924
 
        - We are using an ORDER BY that can't be optimized away.
 
719
        - We are using an order_st BY that can't be optimized away.
925
720
 
926
721
      We don't want to use this optimization when we are using LIMIT
927
722
      because in this case we can just create a temporary table that
953
748
          {
954
749
            /*
955
750
              Force MySQL to read the table in sorted order to get result in
956
 
              ORDER BY order.
 
751
              order_st BY order.
957
752
            */
958
753
            tmp_table_param.quick_group=0;
959
754
          }
969
764
  }
970
765
  simple_group= 0;
971
766
  {
972
 
    Order *old_group_list;
 
767
    order_st *old_group_list;
973
768
    group_list= remove_constants(this, (old_group_list= group_list), conds,
974
 
                                 rollup.getState() == Rollup::STATE_NONE,
 
769
                                 rollup.state == ROLLUP::STATE_NONE,
975
770
                                 &simple_group);
976
771
    if (session->is_error())
977
772
    {
1010
805
    This has to be done if all tables are not already read (const tables)
1011
806
    and one of the following conditions holds:
1012
807
    - We are using DISTINCT (simple distinct's are already optimized away)
1013
 
    - We are using an ORDER BY or GROUP BY on fields not in the first table
1014
 
    - We are using different ORDER BY and GROUP BY orders
 
808
    - We are using an order_st BY or GROUP BY on fields not in the first table
 
809
    - We are using different order_st BY and GROUP BY orders
1015
810
    - The user wants us to buffer the result.
1016
811
  */
1017
812
  need_tmp= (const_tables != tables &&
1019
814
        (group_list && order) ||
1020
815
        test(select_options & OPTION_BUFFER_RESULT)));
1021
816
 
 
817
  uint32_t no_jbuf_after= make_join_orderinfo(this);
 
818
  uint64_t select_opts_for_readinfo=
 
819
    (select_options & (SELECT_DESCRIBE | SELECT_NO_JOIN_CACHE)) | (0);
 
820
 
1022
821
  // No cache for MATCH == 'Don't use join buffering when we use MATCH'.
1023
 
  if (make_join_readinfo(this))
 
822
  if (make_join_readinfo(this, select_opts_for_readinfo, no_jbuf_after))
1024
823
    return 1;
1025
824
 
1026
825
  /* Create all structures needed for materialized subquery execution. */
1027
826
  if (setup_subquery_materialization())
1028
827
    return 1;
1029
828
 
1030
 
  /* Cache constant expressions in WHERE, HAVING, ON clauses. */
1031
 
  cache_const_exprs();
1032
 
 
1033
829
  /*
1034
830
    is this simple IN subquery?
1035
831
  */
1047
843
        save_index_subquery_explain_info(join_tab, where);
1048
844
        join_tab[0].type= AM_UNIQUE_SUBQUERY;
1049
845
        error= 0;
1050
 
        return(unit->item->change_engine(new subselect_uniquesubquery_engine(session, join_tab, unit->item, where)));
 
846
        return(unit->item->
 
847
                    change_engine(new
 
848
                                  subselect_uniquesubquery_engine(session,
 
849
                                                                  join_tab,
 
850
                                                                  unit->item,
 
851
                                                                  where)));
1051
852
      }
1052
853
      else if (join_tab[0].type == AM_REF &&
1053
854
         join_tab[0].ref.items[0]->name == in_left_expr_name)
1056
857
        save_index_subquery_explain_info(join_tab, where);
1057
858
        join_tab[0].type= AM_INDEX_SUBQUERY;
1058
859
        error= 0;
1059
 
        return(unit->item->change_engine(new subselect_indexsubquery_engine(session, join_tab, unit->item, where, NULL, 0)));
 
860
        return(unit->item->
 
861
                    change_engine(new
 
862
                                  subselect_indexsubquery_engine(session,
 
863
                                                                 join_tab,
 
864
                                                                 unit->item,
 
865
                                                                 where,
 
866
                                                                 NULL,
 
867
                                                                 0)));
1060
868
      }
1061
869
    } 
1062
870
    else if (join_tab[0].type == AM_REF_OR_NULL &&
1067
875
      error= 0;
1068
876
      conds= remove_additional_cond(conds);
1069
877
      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)));
 
878
      return(unit->item->
 
879
      change_engine(new subselect_indexsubquery_engine(session,
 
880
                   join_tab,
 
881
                   unit->item,
 
882
                   conds,
 
883
                                                                   having,
 
884
                   1)));
1071
885
    }
1072
886
 
1073
887
  }
1119
933
        Force using of tmp table if sorting by a SP or UDF function due to
1120
934
        their expensive and probably non-deterministic nature.
1121
935
      */
1122
 
      for (Order *tmp_order= order; tmp_order ; tmp_order=tmp_order->next)
 
936
      for (order_st *tmp_order= order; tmp_order ; tmp_order=tmp_order->next)
1123
937
      {
1124
938
        Item *item= *tmp_order->item;
1125
939
        if (item->is_expensive())
1163
977
 
1164
978
    tmp_table_param.hidden_field_count= (all_fields.elements -
1165
979
           fields_list.elements);
1166
 
    Order *tmp_group= (((not simple_group) or not (getDebug().test(debug::NO_KEY_GROUP))) ? group_list : (Order*) 0);
1167
 
 
 
980
    order_st *tmp_group= ((!simple_group && 
 
981
                           ! (test_flags.test(TEST_NO_KEY_GROUP))) ? group_list :
 
982
                                                                     (order_st*) 0);
1168
983
    /*
1169
984
      Pushing LIMIT to the temporary table creation is not applicable
1170
 
      when there is ORDER BY or GROUP BY or there is no GROUP BY, but
 
985
      when there is order_st BY or GROUP BY or there is no GROUP BY, but
1171
986
      there are aggregate functions, because in all these cases we need
1172
987
      all result rows.
1173
988
    */
1267
1082
      If this join belongs to an uncacheable subquery save
1268
1083
      the original join
1269
1084
    */
1270
 
    if (select_lex->uncacheable.any() && 
1271
 
        ! is_top_level_join() &&
 
1085
    if (select_lex->uncacheable && !is_top_level_join() &&
1272
1086
        init_save_join_tab())
1273
 
    {
1274
 
      return -1;
1275
 
    }
 
1087
      return(-1);                         /* purecov: inspected */
1276
1088
  }
1277
1089
 
1278
1090
  error= 0;
1279
 
  return 0;
1280
 
 
1281
 
setup_subq_exit:
1282
 
  /* Even with zero matching rows, subqueries in the HAVING clause
1283
 
     may need to be evaluated if there are aggregate functions in the query.
1284
 
  */
1285
 
  if (setup_subquery_materialization())
1286
 
    return 1;
1287
 
  error= 0;
1288
 
  return 0;
 
1091
  return(0);
1289
1092
}
1290
1093
 
1291
1094
/**
1292
1095
  Restore values in temporary join.
1293
1096
*/
1294
 
void Join::restore_tmp()
 
1097
void JOIN::restore_tmp()
1295
1098
{
1296
 
  memcpy(tmp_join, this, (size_t) sizeof(Join));
 
1099
  memcpy(tmp_join, this, (size_t) sizeof(JOIN));
1297
1100
}
1298
1101
 
1299
 
int Join::reinit()
 
1102
int JOIN::reinit()
1300
1103
{
1301
1104
  unit->offset_limit_cnt= (ha_rows)(select_lex->offset_limit ?
1302
1105
                                    select_lex->offset_limit->val_uint() :
1306
1109
 
1307
1110
  if (exec_tmp_table1)
1308
1111
  {
1309
 
    exec_tmp_table1->cursor->extra(HA_EXTRA_RESET_STATE);
1310
 
    exec_tmp_table1->cursor->ha_delete_all_rows();
 
1112
    exec_tmp_table1->file->extra(HA_EXTRA_RESET_STATE);
 
1113
    exec_tmp_table1->file->ha_delete_all_rows();
1311
1114
    exec_tmp_table1->free_io_cache();
1312
1115
    exec_tmp_table1->filesort_free_buffers();
1313
1116
  }
1314
1117
  if (exec_tmp_table2)
1315
1118
  {
1316
 
    exec_tmp_table2->cursor->extra(HA_EXTRA_RESET_STATE);
1317
 
    exec_tmp_table2->cursor->ha_delete_all_rows();
 
1119
    exec_tmp_table2->file->extra(HA_EXTRA_RESET_STATE);
 
1120
    exec_tmp_table2->file->ha_delete_all_rows();
1318
1121
    exec_tmp_table2->free_io_cache();
1319
1122
    exec_tmp_table2->filesort_free_buffers();
1320
1123
  }
1348
1151
   @retval 0      success.
1349
1152
   @retval 1      error occurred.
1350
1153
*/
1351
 
bool Join::init_save_join_tab()
 
1154
bool JOIN::init_save_join_tab()
1352
1155
{
1353
 
  if (!(tmp_join= (Join*)session->getMemRoot()->allocate(sizeof(Join))))
1354
 
    return 1;
1355
 
 
 
1156
  if (!(tmp_join= (JOIN*)session->alloc(sizeof(JOIN))))
 
1157
    return 1;                                  /* purecov: inspected */
1356
1158
  error= 0;              // Ensure that tmp_join.error= 0
1357
1159
  restore_tmp();
1358
 
 
1359
1160
  return 0;
1360
1161
}
1361
1162
 
1362
 
bool Join::save_join_tab()
 
1163
bool JOIN::save_join_tab()
1363
1164
{
1364
 
  if (! join_tab_save && select_lex->master_unit()->uncacheable.any())
 
1165
  if (!join_tab_save && select_lex->master_unit()->uncacheable)
1365
1166
  {
1366
 
    if (!(join_tab_save= (JoinTable*)session->getMemRoot()->duplicate((unsigned char*) join_tab,
 
1167
    if (!(join_tab_save= (JoinTable*)session->memdup((unsigned char*) join_tab,
1367
1168
            sizeof(JoinTable) * tables)))
1368
1169
      return 1;
1369
1170
  }
1381
1182
  @todo
1382
1183
    When can we have here session->net.report_error not zero?
1383
1184
*/
1384
 
void Join::exec()
 
1185
void JOIN::exec()
1385
1186
{
1386
1187
  List<Item> *columns_list= &fields_list;
1387
1188
  int      tmp_error;
1393
1194
  {                                           
1394
1195
    /* Only test of functions */
1395
1196
    if (select_options & SELECT_DESCRIBE)
1396
 
    {
1397
 
      optimizer::ExplainPlan planner(this, 
1398
 
                                     false,
1399
 
                                     false,
1400
 
                                     false,
1401
 
                                     (zero_result_cause ? zero_result_cause : "No tables used"));
1402
 
      planner.printPlan();
1403
 
    }
 
1197
      select_describe(this, false, false, false, (zero_result_cause?zero_result_cause:"No tables used"));
1404
1198
    else
1405
1199
    {
1406
1200
      result->send_fields(*columns_list);
1451
1245
    return;
1452
1246
  }
1453
1247
 
 
1248
  if ((this->select_lex->options & OPTION_SCHEMA_TABLE) && get_schema_tables_result(this, PROCESSED_BY_JOIN_EXEC))
 
1249
    return;
 
1250
 
1454
1251
  if (select_options & SELECT_DESCRIBE)
1455
1252
  {
1456
1253
    /*
1457
 
      Check if we managed to optimize ORDER BY away and don't use temporary
 
1254
      Check if we managed to optimize order_st BY away and don't use temporary
1458
1255
      table to resolve order_st BY: in that case, we only may need to do
1459
1256
      filesort for GROUP BY.
1460
1257
    */
1473
1270
      order= 0;
1474
1271
    }
1475
1272
    having= tmp_having;
1476
 
    optimizer::ExplainPlan planner(this,
1477
 
                                   need_tmp,
1478
 
                                   order != 0 && ! skip_sort_order,
1479
 
                                   select_distinct,
1480
 
                                   ! tables ? "No tables used" : NULL);
1481
 
    planner.printPlan();
 
1273
    select_describe(this, need_tmp, order != 0 && !skip_sort_order,  select_distinct, !tables ? "No tables used" : NULL);
1482
1274
    return;
1483
1275
  }
1484
1276
 
1485
 
  Join *curr_join= this;
 
1277
  JOIN *curr_join= this;
1486
1278
  List<Item> *curr_all_fields= &all_fields;
1487
1279
  List<Item> *curr_fields_list= &fields_list;
1488
1280
  Table *curr_tmp_table= 0;
1517
1309
      error= tmp_error;
1518
1310
      return;
1519
1311
    }
1520
 
    curr_tmp_table->cursor->info(HA_STATUS_VARIABLE);
 
1312
    curr_tmp_table->file->info(HA_STATUS_VARIABLE);
1521
1313
 
1522
1314
    if (curr_join->having)
1523
1315
      curr_join->having= curr_join->tmp_having= 0; // Allready done
1592
1384
                                                   - curr_join->tmp_fields_list1.elements;
1593
1385
 
1594
1386
      if (exec_tmp_table2)
1595
 
      {
1596
1387
        curr_tmp_table= exec_tmp_table2;
1597
 
      }
1598
1388
      else
1599
1389
      {
1600
1390
        /* group data to new table */
1602
1392
        /*
1603
1393
          If the access method is loose index scan then all MIN/MAX
1604
1394
          functions are precomputed, and should be treated as regular
1605
 
          functions. See extended comment in Join::exec.
 
1395
          functions. See extended comment in JOIN::exec.
1606
1396
        */
1607
1397
        if (curr_join->join_tab->is_using_loose_index_scan())
1608
1398
          curr_join->tmp_table_param.precomputed_group_by= true;
1611
1401
              exec_tmp_table2= create_tmp_table(session,
1612
1402
                                                &curr_join->tmp_table_param,
1613
1403
                                                *curr_all_fields,
1614
 
                                                (Order*) 0,
 
1404
                                                (order_st*) 0,
1615
1405
                                                curr_join->select_distinct &&
1616
1406
                                                !curr_join->group_list,
1617
1407
                                                1, curr_join->select_options,
1618
1408
                                                HA_POS_ERROR,
1619
1409
                                                (char *) "")))
1620
 
        {
1621
1410
          return;
1622
 
        }
1623
 
 
1624
1411
        curr_join->exec_tmp_table2= exec_tmp_table2;
1625
1412
      }
1626
1413
      if (curr_join->group_list)
1668
1455
        error= tmp_error;
1669
1456
        return;
1670
1457
      }
1671
 
      curr_join->join_tab->read_record.end_read_record();
 
1458
      end_read_record(&curr_join->join_tab->read_record);
1672
1459
      curr_join->const_tables= curr_join->tables; // Mark free for cleanup()
1673
1460
      curr_join->join_tab[0].table= 0;           // Table is freed
1674
1461
 
1765
1552
      if (sort_table_cond)
1766
1553
      {
1767
1554
        if (!curr_table->select)
1768
 
          if (!(curr_table->select= new optimizer::SqlSelect()))
 
1555
          if (!(curr_table->select= new SQL_SELECT))
1769
1556
            return;
1770
1557
        if (!curr_table->select->cond)
1771
1558
          curr_table->select->cond= sort_table_cond;
1879
1666
  Clean up join.
1880
1667
 
1881
1668
  @return
1882
 
    Return error that hold Join.
 
1669
    Return error that hold JOIN.
1883
1670
*/
1884
 
int Join::destroy()
 
1671
int JOIN::destroy()
1885
1672
{
1886
1673
  select_lex->join= 0;
1887
1674
 
1900
1687
  cond_equal= 0;
1901
1688
 
1902
1689
  cleanup(1);
1903
 
  exec_tmp_table1= NULL;
1904
 
  exec_tmp_table2= NULL;
 
1690
  if (exec_tmp_table1)
 
1691
    exec_tmp_table1->free_tmp_table(session);
 
1692
  if (exec_tmp_table2)
 
1693
    exec_tmp_table2->free_tmp_table(session);
1905
1694
  delete select;
1906
1695
  delete_dynamic(&keyuse);
1907
 
 
1908
1696
  return(error);
1909
1697
}
1910
1698
 
1917
1705
  - try to initialize all data structures needed for the materialized execution
1918
1706
    of the IN predicate,
1919
1707
  - if this fails, then perform the IN=>EXISTS transformation which was
1920
 
    previously blocked during Join::prepare.
 
1708
    previously blocked during JOIN::prepare.
1921
1709
 
1922
1710
  This method is part of the "code generation" query processing phase.
1923
1711
 
1930
1718
  @retval false     success.
1931
1719
  @retval true      error occurred.
1932
1720
*/
1933
 
bool Join::setup_subquery_materialization()
 
1721
bool JOIN::setup_subquery_materialization()
1934
1722
{
1935
1723
  for (Select_Lex_Unit *un= select_lex->first_inner_unit(); un;
1936
1724
       un= un->next_unit())
1952
1740
}
1953
1741
 
1954
1742
/**
1955
 
  Partially cleanup Join after it has executed: close index or rnd read
 
1743
  Partially cleanup JOIN after it has executed: close index or rnd read
1956
1744
  (table cursors), free quick selects.
1957
1745
 
1958
 
    This function is called in the end of execution of a Join, before the used
 
1746
    This function is called in the end of execution of a JOIN, before the used
1959
1747
    tables are unlocked and closed.
1960
1748
 
1961
1749
    For a join that is resolved using a temporary table, the first sweep is
1969
1757
    is called after all rows are sent, but before EOF packet is sent.
1970
1758
 
1971
1759
    For a simple SELECT with no subqueries this function performs a full
1972
 
    cleanup of the Join and calls unlockReadTables to free used base
 
1760
    cleanup of the JOIN and calls mysql_unlock_read_tables to free used base
1973
1761
    tables.
1974
1762
 
1975
 
    If a Join is executed for a subquery or if it has a subquery, we can't
 
1763
    If a JOIN is executed for a subquery or if it has a subquery, we can't
1976
1764
    do the full cleanup and need to do a partial cleanup only.
1977
 
    - If a Join is not the top level join, we must not unlock the tables
 
1765
    - If a JOIN is not the top level join, we must not unlock the tables
1978
1766
    because the outer select may not have been evaluated yet, and we
1979
1767
    can't unlock only selected tables of a query.
1980
 
    - Additionally, if this Join corresponds to a correlated subquery, we
 
1768
    - Additionally, if this JOIN corresponds to a correlated subquery, we
1981
1769
    should not free quick selects and join buffers because they will be
1982
1770
    needed for the next execution of the correlated subquery.
1983
 
    - However, if this is a Join for a [sub]select, which is not
 
1771
    - However, if this is a JOIN for a [sub]select, which is not
1984
1772
    a correlated subquery itself, but has subqueries, we can free it
1985
 
    fully and also free Joins of all its subqueries. The exception
 
1773
    fully and also free JOINs of all its subqueries. The exception
1986
1774
    is a subquery in SELECT list, e.g: @n
1987
1775
    SELECT a, (select cmax(b) from t1) group by c @n
1988
1776
    This subquery will not be evaluated at first sweep and its value will
1993
1781
  @todo
1994
1782
    Unlock tables even if the join isn't top level select in the tree
1995
1783
*/
1996
 
void Join::join_free()
 
1784
void JOIN::join_free()
1997
1785
{
1998
1786
  Select_Lex_Unit *tmp_unit;
1999
1787
  Select_Lex *sl;
2000
1788
  /*
2001
 
    Optimization: if not EXPLAIN and we are done with the Join,
 
1789
    Optimization: if not EXPLAIN and we are done with the JOIN,
2002
1790
    free all tables.
2003
1791
  */
2004
 
  bool full= (select_lex->uncacheable.none() && ! session->lex->describe);
 
1792
  bool full= (!select_lex->uncacheable && !session->lex->describe);
2005
1793
  bool can_unlock= full;
2006
1794
 
2007
1795
  cleanup(full);
2012
1800
    for (sl= tmp_unit->first_select(); sl; sl= sl->next_select())
2013
1801
    {
2014
1802
      Item_subselect *subselect= sl->master_unit()->item;
2015
 
      bool full_local= full && (!subselect || 
2016
 
                                (subselect->is_evaluated() &&
2017
 
                                !subselect->is_uncacheable()));
 
1803
      bool full_local= full && (!subselect || subselect->is_evaluated());
2018
1804
      /*
2019
1805
        If this join is evaluated, we can fully clean it up and clean up all
2020
1806
        its underlying joins even if they are correlated -- they will not be
2025
1811
        but all table cursors must be closed before the unlock.
2026
1812
      */
2027
1813
      sl->cleanup_all_joins(full_local);
2028
 
      /* Can't unlock if at least one Join is still needed */
 
1814
      /* Can't unlock if at least one JOIN is still needed */
2029
1815
      can_unlock= can_unlock && full_local;
2030
1816
    }
2031
1817
 
2043
1829
      TODO: unlock tables even if the join isn't top level select in the
2044
1830
      tree.
2045
1831
    */
2046
 
    session->unlockReadTables(lock);           // Don't free join->lock
 
1832
    mysql_unlock_read_tables(session, lock);           // Don't free join->lock
2047
1833
    lock= 0;
2048
1834
  }
2049
1835
 
2062
1848
    With subquery this function definitely will be called several times,
2063
1849
    but even for simple query it can be called several times.
2064
1850
*/
2065
 
void Join::cleanup(bool full)
 
1851
void JOIN::cleanup(bool full)
2066
1852
{
2067
1853
  if (table)
2068
1854
  {
 
1855
    JoinTable *tab,*end;
2069
1856
    /*
2070
1857
      Only a sorted table may be cached.  This sorted table is always the
2071
1858
      first non const table in join->table
2075
1862
      table[const_tables]->free_io_cache();
2076
1863
      table[const_tables]->filesort_free_buffers(full);
2077
1864
    }
2078
 
  }
2079
 
 
2080
 
  if (join_tab)
2081
 
  {
2082
 
    JoinTable *tab,*end;
2083
1865
 
2084
1866
    if (full)
2085
1867
    {
2092
1874
      for (tab= join_tab, end= tab+tables; tab != end; tab++)
2093
1875
      {
2094
1876
        if (tab->table)
2095
 
          tab->table->cursor->ha_index_or_rnd_end();
 
1877
          tab->table->file->ha_index_or_rnd_end();
2096
1878
      }
2097
1879
    }
2098
1880
  }
2099
 
 
2100
1881
  /*
2101
1882
    We are not using tables anymore
2102
1883
    Unlock all tables. We may be in an INSERT .... SELECT statement.
2112
1893
    */
2113
1894
    tmp_table_param.copy_funcs.empty();
2114
1895
    /*
2115
 
      If we have tmp_join and 'this' Join is not tmp_join and
 
1896
      If we have tmp_join and 'this' JOIN is not tmp_join and
2116
1897
      tmp_table_param.copy_field's  of them are equal then we have to remove
2117
1898
      pointer to  tmp_table_param.copy_field from tmp_join, because it qill
2118
1899
      be removed in tmp_table_param.cleanup().
2131
1912
}
2132
1913
 
2133
1914
/*
2134
 
  used only in Join::clear
 
1915
  used only in JOIN::clear
2135
1916
*/
2136
 
static void clear_tables(Join *join)
 
1917
static void clear_tables(JOIN *join)
2137
1918
{
2138
1919
  /*
2139
1920
    must clear only the non-const tables, as const tables
2140
1921
    are not re-calculated.
2141
1922
  */
2142
1923
  for (uint32_t i= join->const_tables; i < join->tables; i++)
2143
 
  {
2144
1924
    join->table[i]->mark_as_null_row();   // All fields are NULL
2145
 
  }
2146
1925
}
2147
1926
 
2148
1927
/**
2154
1933
  @retval
2155
1934
    1 Error
2156
1935
*/
2157
 
bool Join::alloc_func_list()
 
1936
bool JOIN::alloc_func_list()
2158
1937
{
2159
1938
  uint32_t func_count, group_parts;
2160
1939
 
2163
1942
    If we are using rollup, we need a copy of the summary functions for
2164
1943
    each level
2165
1944
  */
2166
 
  if (rollup.getState() != Rollup::STATE_NONE)
 
1945
  if (rollup.state != ROLLUP::STATE_NONE)
2167
1946
    func_count*= (send_group_parts+1);
2168
1947
 
2169
1948
  group_parts= send_group_parts;
2180
1959
    */
2181
1960
    if (order)
2182
1961
    {
2183
 
      Order *ord;
 
1962
      order_st *ord;
2184
1963
      for (ord= order; ord; ord= ord->next)
2185
1964
        group_parts++;
2186
1965
    }
2206
1985
  @retval
2207
1986
    1  error
2208
1987
*/
2209
 
bool Join::make_sum_func_list(List<Item> &field_list, 
 
1988
bool JOIN::make_sum_func_list(List<Item> &field_list, 
2210
1989
                              List<Item> &send_fields,
2211
1990
                              bool before_group_by, 
2212
1991
                              bool recompute)
2226
2005
         ((Item_sum *)item)->depended_from() == select_lex))
2227
2006
      *func++= (Item_sum*) item;
2228
2007
  }
2229
 
  if (before_group_by && rollup.getState() == Rollup::STATE_INITED)
 
2008
  if (before_group_by && rollup.state == ROLLUP::STATE_INITED)
2230
2009
  {
2231
 
    rollup.setState(Rollup::STATE_READY);
 
2010
    rollup.state= ROLLUP::STATE_READY;
2232
2011
    if (rollup_make_fields(field_list, send_fields, &func))
2233
 
      return true;     // Should never happen
 
2012
      return(true);     // Should never happen
2234
2013
  }
2235
 
  else if (rollup.getState() == Rollup::STATE_NONE)
 
2014
  else if (rollup.state == ROLLUP::STATE_NONE)
2236
2015
  {
2237
2016
    for (uint32_t i=0 ; i <= send_group_parts ;i++)
2238
2017
      sum_funcs_end[i]= func;
2239
2018
  }
2240
 
  else if (rollup.getState() == Rollup::STATE_READY)
 
2019
  else if (rollup.state == ROLLUP::STATE_READY)
2241
2020
    return(false);                         // Don't put end marker
2242
2021
  *func=0;          // End marker
2243
2022
  return(false);
2244
2023
}
2245
2024
 
2246
2025
/** Allocate memory needed for other rollup functions. */
2247
 
bool Join::rollup_init()
 
2026
bool JOIN::rollup_init()
2248
2027
{
 
2028
  uint32_t i,j;
2249
2029
  Item **ref_array;
2250
2030
 
2251
2031
  tmp_table_param.quick_group= 0; // Can't create groups in tmp table
2252
 
  rollup.setState(Rollup::STATE_INITED);
 
2032
  rollup.state= ROLLUP::STATE_INITED;
2253
2033
 
2254
2034
  /*
2255
2035
    Create pointers to the different sum function groups
2257
2037
  */
2258
2038
  tmp_table_param.group_parts= send_group_parts;
2259
2039
 
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
 
  {
 
2040
  if (!(rollup.null_items= (Item_null_result**) session->alloc((sizeof(Item*) +
 
2041
                                                sizeof(Item**) +
 
2042
                                                sizeof(List<Item>) +
 
2043
                        ref_pointer_array_size)
 
2044
                        * send_group_parts )))
2267
2045
    return 1;
2268
 
  }
2269
2046
 
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);
 
2047
  rollup.fields= (List<Item>*) (rollup.null_items + send_group_parts);
 
2048
  rollup.ref_pointer_arrays= (Item***) (rollup.fields + send_group_parts);
 
2049
  ref_array= (Item**) (rollup.ref_pointer_arrays+send_group_parts);
2273
2050
 
2274
2051
  /*
2275
2052
    Prepare space for field list for the different levels
2276
2053
    These will be filled up in rollup_make_fields()
2277
2054
  */
2278
 
  for (uint32_t i= 0 ; i < send_group_parts ; i++)
 
2055
  for (i= 0 ; i < send_group_parts ; i++)
2279
2056
  {
2280
 
    rollup.getNullItems()[i]= new (session->mem_root) Item_null_result();
2281
 
    List<Item> *rollup_fields= &rollup.getFields()[i];
 
2057
    rollup.null_items[i]= new (session->mem_root) Item_null_result();
 
2058
    List<Item> *rollup_fields= &rollup.fields[i];
2282
2059
    rollup_fields->empty();
2283
 
    rollup.getRefPointerArrays()[i]= ref_array;
 
2060
    rollup.ref_pointer_arrays[i]= ref_array;
2284
2061
    ref_array+= all_fields.elements;
2285
2062
  }
2286
 
 
2287
 
  for (uint32_t i= 0 ; i < send_group_parts; i++)
 
2063
  for (i= 0 ; i < send_group_parts; i++)
2288
2064
  {
2289
 
    for (uint32_t j= 0 ; j < fields_list.elements ; j++)
2290
 
    {
2291
 
      rollup.getFields()[i].push_back(rollup.getNullItems()[i]);
2292
 
    }
 
2065
    for (j=0 ; j < fields_list.elements ; j++)
 
2066
      rollup.fields[i].push_back(rollup.null_items[i]);
2293
2067
  }
2294
 
 
2295
2068
  List_iterator<Item> it(all_fields);
2296
2069
  Item *item;
2297
2070
  while ((item= it++))
2298
2071
  {
2299
 
    Order *group_tmp;
 
2072
    order_st *group_tmp;
2300
2073
    bool found_in_group= 0;
2301
2074
 
2302
2075
    for (group_tmp= group_list; group_tmp; group_tmp= group_tmp->next)
2325
2098
            return 1;
2326
2099
          new_item->fix_fields(session, (Item **) 0);
2327
2100
          session->change_item_tree(it.ref(), new_item);
2328
 
          for (Order *tmp= group_tmp; tmp; tmp= tmp->next)
 
2101
          for (order_st *tmp= group_tmp; tmp; tmp= tmp->next)
2329
2102
          {
2330
2103
            if (*tmp->item == item)
2331
2104
              session->change_item_tree(tmp->item, new_item);
2365
2138
  @retval
2366
2139
    1    on error
2367
2140
*/
2368
 
bool Join::rollup_make_fields(List<Item> &fields_arg, List<Item> &sel_fields, Item_sum ***func)
 
2141
bool JOIN::rollup_make_fields(List<Item> &fields_arg, List<Item> &sel_fields, Item_sum ***func)
2369
2142
{
2370
2143
  List_iterator_fast<Item> it(fields_arg);
2371
2144
  Item *first_field= sel_fields.head();
2398
2171
    uint32_t pos= send_group_parts - level -1;
2399
2172
    bool real_fields= 0;
2400
2173
    Item *item;
2401
 
    List_iterator<Item> new_it(rollup.getFields()[pos]);
2402
 
    Item **ref_array_start= rollup.getRefPointerArrays()[pos];
2403
 
    Order *start_group;
 
2174
    List_iterator<Item> new_it(rollup.fields[pos]);
 
2175
    Item **ref_array_start= rollup.ref_pointer_arrays[pos];
 
2176
    order_st *start_group;
2404
2177
 
2405
2178
    /* Point to first hidden field */
2406
2179
    Item **ref_array= ref_array_start + fields_arg.elements-1;
2442
2215
      else
2443
2216
      {
2444
2217
        /* Check if this is something that is part of this group by */
2445
 
        Order *group_tmp;
 
2218
        order_st *group_tmp;
2446
2219
        for (group_tmp= start_group, i= pos ;
2447
2220
                  group_tmp ; group_tmp= group_tmp->next, i++)
2448
2221
        {
2495
2268
  @retval
2496
2269
    1   If send_data_failed()
2497
2270
*/
2498
 
int Join::rollup_send_data(uint32_t idx)
 
2271
int JOIN::rollup_send_data(uint32_t idx)
2499
2272
{
2500
 
  for (uint32_t i= send_group_parts ; i-- > idx ; )
 
2273
  uint32_t i;
 
2274
  for (i= send_group_parts ; i-- > idx ; )
2501
2275
  {
2502
2276
    /* Get reference pointers to sum functions in place */
2503
 
    memcpy(ref_pointer_array, rollup.getRefPointerArrays()[i], ref_pointer_array_size);
2504
 
 
 
2277
    memcpy(ref_pointer_array, rollup.ref_pointer_arrays[i],
 
2278
     ref_pointer_array_size);
2505
2279
    if ((!having || having->val_int()))
2506
2280
    {
2507
 
      if (send_records < unit->select_limit_cnt && do_send_rows && result->send_data(rollup.getFields()[i]))
2508
 
      {
2509
 
        return 1;
2510
 
      }
 
2281
      if (send_records < unit->select_limit_cnt && do_send_rows &&
 
2282
    result->send_data(rollup.fields[i]))
 
2283
  return 1;
2511
2284
      send_records++;
2512
2285
    }
2513
2286
  }
2514
2287
  /* Restore ref_pointer_array */
2515
2288
  set_items_ref_array(current_ref_pointer_array);
2516
 
 
2517
2289
  return 0;
2518
2290
}
2519
2291
 
2536
2308
  @retval
2537
2309
    1   if write_data_failed()
2538
2310
*/
2539
 
int Join::rollup_write_data(uint32_t idx, Table *table_arg)
 
2311
int JOIN::rollup_write_data(uint32_t idx, Table *table_arg)
2540
2312
{
2541
 
  for (uint32_t i= send_group_parts ; i-- > idx ; )
 
2313
  uint32_t i;
 
2314
  for (i= send_group_parts ; i-- > idx ; )
2542
2315
  {
2543
2316
    /* Get reference pointers to sum functions in place */
2544
 
    memcpy(ref_pointer_array, rollup.getRefPointerArrays()[i],
2545
 
           ref_pointer_array_size);
 
2317
    memcpy(ref_pointer_array, rollup.ref_pointer_arrays[i],
 
2318
     ref_pointer_array_size);
2546
2319
    if ((!having || having->val_int()))
2547
2320
    {
2548
2321
      int write_error;
2549
2322
      Item *item;
2550
 
      List_iterator_fast<Item> it(rollup.getFields()[i]);
 
2323
      List_iterator_fast<Item> it(rollup.fields[i]);
2551
2324
      while ((item= it++))
2552
2325
      {
2553
2326
        if (item->type() == Item::NULL_ITEM && item->is_result_field())
2554
2327
          item->save_in_result_field(1);
2555
2328
      }
2556
2329
      copy_sum_funcs(sum_funcs_end[i+1], sum_funcs_end[i]);
2557
 
      if ((write_error= table_arg->cursor->insertRecord(table_arg->getInsertRecord())))
 
2330
      if ((write_error= table_arg->file->ha_write_row(table_arg->record[0])))
2558
2331
      {
2559
 
        my_error(ER_USE_SQL_BIG_RESULT, MYF(0));
2560
 
        return 1;
 
2332
  if (create_myisam_from_heap(session, table_arg,
 
2333
                                    tmp_table_param.start_recinfo,
 
2334
                                    &tmp_table_param.recinfo,
 
2335
                                    write_error, 0))
 
2336
    return 1;
2561
2337
      }
2562
2338
    }
2563
2339
  }
2564
2340
  /* Restore ref_pointer_array */
2565
2341
  set_items_ref_array(current_ref_pointer_array);
2566
 
 
2567
2342
  return 0;
2568
2343
}
2569
2344
 
2571
2346
  clear results if there are not rows found for group
2572
2347
  (end_send_group/end_write_group)
2573
2348
*/
2574
 
void Join::clear()
 
2349
void JOIN::clear()
2575
2350
{
2576
2351
  clear_tables(this);
2577
2352
  copy_fields(&tmp_table_param);
2585
2360
}
2586
2361
 
2587
2362
/**
2588
 
  change select_result object of Join.
 
2363
  change select_result object of JOIN.
2589
2364
 
2590
2365
  @param res    new select_result object
2591
2366
 
2594
2369
  @retval
2595
2370
    true    error
2596
2371
*/
2597
 
bool Join::change_result(select_result *res)
 
2372
bool JOIN::change_result(select_result *res)
2598
2373
{
2599
2374
  result= res;
2600
2375
  if (result->prepare(fields_list, select_lex->master_unit()))
2605
2380
}
2606
2381
 
2607
2382
/**
2608
 
  Cache constant expressions in WHERE, HAVING, ON conditions.
2609
 
*/
2610
 
 
2611
 
void Join::cache_const_exprs()
2612
 
{
2613
 
  bool cache_flag= false;
2614
 
  bool *analyzer_arg= &cache_flag;
2615
 
 
2616
 
  /* No need in cache if all tables are constant. */
2617
 
  if (const_tables == tables)
2618
 
    return;
2619
 
 
2620
 
  if (conds)
2621
 
    conds->compile(&Item::cache_const_expr_analyzer, (unsigned char **)&analyzer_arg,
2622
 
                  &Item::cache_const_expr_transformer, (unsigned char *)&cache_flag);
2623
 
  cache_flag= false;
2624
 
  if (having)
2625
 
    having->compile(&Item::cache_const_expr_analyzer, (unsigned char **)&analyzer_arg,
2626
 
                    &Item::cache_const_expr_transformer, (unsigned char *)&cache_flag);
2627
 
 
2628
 
  for (JoinTable *tab= join_tab + const_tables; tab < join_tab + tables ; tab++)
2629
 
  {
2630
 
    if (*tab->on_expr_ref)
2631
 
    {
2632
 
      cache_flag= false;
2633
 
      (*tab->on_expr_ref)->compile(&Item::cache_const_expr_analyzer,
2634
 
                                 (unsigned char **)&analyzer_arg,
2635
 
                                 &Item::cache_const_expr_transformer,
2636
 
                                 (unsigned char *)&cache_flag);
2637
 
    }
2638
 
  }
2639
 
}
2640
 
 
2641
 
/**
2642
2383
  @brief
2643
2384
  
2644
2385
  Process one record of the nested loop join.
2649
2390
  applicable to the partial record on hand and in case of success
2650
2391
  submit this record to the next level of the nested loop.
2651
2392
*/
2652
 
enum_nested_loop_state evaluate_join_record(Join *join, JoinTable *join_tab, int error)
 
2393
enum_nested_loop_state evaluate_join_record(JOIN *join, JoinTable *join_tab, int error)
2653
2394
{
2654
2395
  bool not_used_in_distinct= join_tab->not_used_in_distinct;
2655
2396
  ha_rows found_records= join->found_records;
2659
2400
    return NESTED_LOOP_ERROR;
2660
2401
  if (error < 0)
2661
2402
    return NESTED_LOOP_NO_MORE_ROWS;
2662
 
  if (join->session->getKilled())                       // Aborted by user
 
2403
  if (join->session->killed)                    // Aborted by user
2663
2404
  {
2664
2405
    join->session->send_kill_message();
2665
 
    return NESTED_LOOP_KILLED;
 
2406
    return NESTED_LOOP_KILLED;               /* purecov: inspected */
2666
2407
  }
2667
2408
  if (!select_cond || select_cond->val_int())
2668
2409
  {
2752
2493
        return NESTED_LOOP_NO_MORE_ROWS;
2753
2494
    }
2754
2495
    else
2755
 
      join_tab->read_record.cursor->unlock_row();
 
2496
      join_tab->read_record.file->unlock_row();
2756
2497
  }
2757
2498
  else
2758
2499
  {
2762
2503
    */
2763
2504
    join->examined_rows++;
2764
2505
    join->session->row_count++;
2765
 
    join_tab->read_record.cursor->unlock_row();
 
2506
    join_tab->read_record.file->unlock_row();
2766
2507
  }
2767
2508
  return NESTED_LOOP_OK;
2768
2509
}
2773
2514
    level of the nested loop. This function is used in case we have
2774
2515
    an OUTER join and no matching record was found.
2775
2516
*/
2776
 
enum_nested_loop_state evaluate_null_complemented_join_record(Join *join, JoinTable *join_tab)
 
2517
enum_nested_loop_state evaluate_null_complemented_join_record(JOIN *join, JoinTable *join_tab)
2777
2518
{
2778
2519
  /*
2779
2520
    The table join_tab is the first inner table of a outer join operation
2829
2570
  return (*join_tab->next_select)(join, join_tab+1, 0);
2830
2571
}
2831
2572
 
2832
 
enum_nested_loop_state flush_cached_records(Join *join, JoinTable *join_tab, bool skip_last)
 
2573
enum_nested_loop_state flush_cached_records(JOIN *join, JoinTable *join_tab, bool skip_last)
2833
2574
{
2834
2575
  enum_nested_loop_state rc= NESTED_LOOP_OK;
2835
2576
  int error;
2836
 
  ReadRecord *info;
 
2577
  READ_RECORD *info;
2837
2578
 
2838
2579
  join_tab->table->null_row= 0;
2839
2580
  if (!join_tab->cache.records)
2840
 
  {
2841
2581
    return NESTED_LOOP_OK;                      /* Nothing to do */
2842
 
  }
2843
 
 
2844
2582
  if (skip_last)
2845
 
  {
2846
 
    (void) join_tab->cache.store_record_in_cache(); // Must save this for later
2847
 
  }
2848
 
 
2849
 
 
 
2583
    (void) store_record_in_cache(&join_tab->cache); // Must save this for later
2850
2584
  if (join_tab->use_quick == 2)
2851
2585
  {
2852
2586
    if (join_tab->select->quick)
2858
2592
  /* read through all records */
2859
2593
  if ((error=join_init_read_record(join_tab)))
2860
2594
  {
2861
 
    join_tab->cache.reset_cache_write();
 
2595
    reset_cache_write(&join_tab->cache);
2862
2596
    return error < 0 ? NESTED_LOOP_NO_MORE_ROWS: NESTED_LOOP_ERROR;
2863
2597
  }
2864
2598
 
2871
2605
  info= &join_tab->read_record;
2872
2606
  do
2873
2607
  {
2874
 
    if (join->session->getKilled())
 
2608
    if (join->session->killed)
2875
2609
    {
2876
2610
      join->session->send_kill_message();
2877
 
      return NESTED_LOOP_KILLED;
 
2611
      return NESTED_LOOP_KILLED; // Aborted by user /* purecov: inspected */
2878
2612
    }
2879
 
    optimizer::SqlSelect *select= join_tab->select;
 
2613
    SQL_SELECT *select=join_tab->select;
2880
2614
    if (rc == NESTED_LOOP_OK &&
2881
2615
        (!join_tab->cache.select || !join_tab->cache.select->skip_record()))
2882
2616
    {
2883
2617
      uint32_t i;
2884
 
      join_tab->cache.reset_cache_read();
 
2618
      reset_cache_read(&join_tab->cache);
2885
2619
      for (i=(join_tab->cache.records- (skip_last ? 1 : 0)) ; i-- > 0 ;)
2886
2620
      {
2887
2621
              join_tab->readCachedRecord();
2892
2626
          rc= (join_tab->next_select)(join,join_tab+1,0);
2893
2627
          if (rc != NESTED_LOOP_OK && rc != NESTED_LOOP_NO_MORE_ROWS)
2894
2628
          {
2895
 
            join_tab->cache.reset_cache_write();
 
2629
            reset_cache_write(&join_tab->cache);
2896
2630
            return rc;
2897
2631
          }
2898
2632
 
2905
2639
 
2906
2640
  if (skip_last)
2907
2641
    join_tab->readCachedRecord();               // Restore current record
2908
 
  join_tab->cache.reset_cache_write();
 
2642
  reset_cache_write(&join_tab->cache);
2909
2643
  if (error > 0)                                // Fatal error
2910
 
    return NESTED_LOOP_ERROR;
 
2644
    return NESTED_LOOP_ERROR;                   /* purecov: inspected */
2911
2645
  for (JoinTable *tmp2=join->join_tab; tmp2 != join_tab ; tmp2++)
2912
2646
    tmp2->table->status=tmp2->status;
2913
2647
  return NESTED_LOOP_OK;
2937
2671
                               operation.
2938
2672
   All return values except NESTED_LOOP_OK abort the nested loop.
2939
2673
*****************************************************************************/
2940
 
enum_nested_loop_state end_send(Join *join, JoinTable *, bool end_of_records)
 
2674
enum_nested_loop_state end_send(JOIN *join, JoinTable *, bool end_of_records)
2941
2675
{
2942
2676
  if (! end_of_records)
2943
2677
  {
2948
2682
    if (join->do_send_rows)
2949
2683
      error=join->result->send_data(*join->fields);
2950
2684
    if (error)
2951
 
      return NESTED_LOOP_ERROR;
 
2685
      return NESTED_LOOP_ERROR; /* purecov: inspected */
2952
2686
    if (++join->send_records >= join->unit->select_limit_cnt && join->do_send_rows)
2953
2687
    {
2954
2688
      if (join->select_options & OPTION_FOUND_ROWS)
2957
2691
        if ((join->tables == 1) && !join->tmp_table && !join->sort_and_group
2958
2692
            && !join->send_group_parts && !join->having && !jt->select_cond &&
2959
2693
            !(jt->select && jt->select->quick) &&
2960
 
            (jt->table->cursor->getEngine()->check_flag(HTON_BIT_STATS_RECORDS_IS_EXACT)) &&
 
2694
            (jt->table->file->ha_table_flags() & HA_STATS_RECORDS_IS_EXACT) &&
2961
2695
                  (jt->ref.key < 0))
2962
2696
        {
2963
2697
          /* Join over all rows in table;  Return number of found rows */
2972
2706
          }
2973
2707
          else
2974
2708
          {
2975
 
            table->cursor->info(HA_STATUS_VARIABLE);
2976
 
            join->send_records= table->cursor->stats.records;
 
2709
            table->file->info(HA_STATUS_VARIABLE);
 
2710
            join->send_records= table->file->stats.records;
2977
2711
          }
2978
2712
        }
2979
2713
        else
2999
2733
  return NESTED_LOOP_OK;
3000
2734
}
3001
2735
 
3002
 
enum_nested_loop_state end_write(Join *join, JoinTable *, bool end_of_records)
 
2736
enum_nested_loop_state end_write(JOIN *join, JoinTable *, bool end_of_records)
3003
2737
{
3004
2738
  Table *table= join->tmp_table;
3005
2739
 
3006
 
  if (join->session->getKilled())                       // Aborted by user
 
2740
  if (join->session->killed)                    // Aborted by user
3007
2741
  {
3008
2742
    join->session->send_kill_message();
3009
 
    return NESTED_LOOP_KILLED;
 
2743
    return NESTED_LOOP_KILLED;             /* purecov: inspected */
3010
2744
  }
3011
2745
  if (!end_of_records)
3012
2746
  {
3013
2747
    copy_fields(&join->tmp_table_param);
3014
 
    if (copy_funcs(join->tmp_table_param.items_to_copy, join->session))
3015
 
      return NESTED_LOOP_ERROR;
 
2748
    copy_funcs(join->tmp_table_param.items_to_copy);
3016
2749
    if (!join->having || join->having->val_int())
3017
2750
    {
3018
2751
      int error;
3019
2752
      join->found_records++;
3020
 
      if ((error=table->cursor->insertRecord(table->getInsertRecord())))
 
2753
      if ((error=table->file->ha_write_row(table->record[0])))
3021
2754
      {
3022
 
        if (!table->cursor->is_fatal_error(error, HA_CHECK_DUP))
3023
 
        {
3024
 
          return NESTED_LOOP_OK;
3025
 
        }
3026
 
 
3027
 
        my_error(ER_USE_SQL_BIG_RESULT, MYF(0));
3028
 
        return NESTED_LOOP_ERROR;        // Table is_full error
 
2755
        if (!table->file->is_fatal_error(error, HA_CHECK_DUP))
 
2756
          goto end;
 
2757
        if (create_myisam_from_heap(join->session, table,
 
2758
                                          join->tmp_table_param.start_recinfo,
 
2759
                                          &join->tmp_table_param.recinfo,
 
2760
                  error, 1))
 
2761
          return NESTED_LOOP_ERROR;        // Not a table_is_full error
 
2762
        table->s->uniques= 0;                   // To ensure rows are the same
3029
2763
      }
3030
2764
      if (++join->send_records >= join->tmp_table_param.end_write_records && join->do_send_rows)
3031
2765
      {
3037
2771
      }
3038
2772
    }
3039
2773
  }
3040
 
 
 
2774
end:
3041
2775
  return NESTED_LOOP_OK;
3042
2776
}
3043
2777
 
3044
2778
/** Group by searching after group record and updating it if possible. */
3045
 
enum_nested_loop_state end_update(Join *join, JoinTable *, bool end_of_records)
 
2779
enum_nested_loop_state end_update(JOIN *join, JoinTable *, bool end_of_records)
3046
2780
{
3047
2781
  Table *table= join->tmp_table;
3048
 
  Order *group;
 
2782
  order_st *group;
3049
2783
  int   error;
3050
2784
 
3051
2785
  if (end_of_records)
3052
2786
    return NESTED_LOOP_OK;
3053
 
  if (join->session->getKilled())                       // Aborted by user
 
2787
  if (join->session->killed)                    // Aborted by user
3054
2788
  {
3055
2789
    join->session->send_kill_message();
3056
 
    return NESTED_LOOP_KILLED;
 
2790
    return NESTED_LOOP_KILLED;             /* purecov: inspected */
3057
2791
  }
3058
2792
 
3059
2793
  join->found_records++;
3067
2801
    if (item->maybe_null)
3068
2802
      group->buff[-1]= (char) group->field->is_null();
3069
2803
  }
3070
 
  if (!table->cursor->index_read_map(table->getUpdateRecord(),
 
2804
  if (!table->file->index_read_map(table->record[1],
3071
2805
                                   join->tmp_table_param.group_buff,
3072
2806
                                   HA_WHOLE_KEY,
3073
2807
                                   HA_READ_KEY_EXACT))
3074
2808
  {                                             /* Update old record */
3075
2809
    table->restoreRecord();
3076
2810
    update_tmptable_sum_func(join->sum_funcs,table);
3077
 
    if ((error= table->cursor->updateRecord(table->getUpdateRecord(),
3078
 
                                          table->getInsertRecord())))
 
2811
    if ((error= table->file->ha_update_row(table->record[1],
 
2812
                                          table->record[0])))
3079
2813
    {
3080
 
      table->print_error(error,MYF(0));
3081
 
      return NESTED_LOOP_ERROR;
 
2814
      table->file->print_error(error,MYF(0));   /* purecov: inspected */
 
2815
      return NESTED_LOOP_ERROR;            /* purecov: inspected */
3082
2816
    }
3083
2817
    return NESTED_LOOP_OK;
3084
2818
  }
3088
2822
    We can't copy all data as the key may have different format
3089
2823
    as the row data (for example as with VARCHAR keys)
3090
2824
  */
3091
 
  KeyPartInfo *key_part;
 
2825
  KEY_PART_INFO *key_part;
3092
2826
  for (group=table->group,key_part=table->key_info[0].key_part;
3093
2827
       group ;
3094
2828
       group=group->next,key_part++)
3095
2829
  {
3096
2830
    if (key_part->null_bit)
3097
 
      memcpy(table->getInsertRecord()+key_part->offset, group->buff, 1);
 
2831
      memcpy(table->record[0]+key_part->offset, group->buff, 1);
3098
2832
  }
3099
2833
  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;
3102
 
  if ((error=table->cursor->insertRecord(table->getInsertRecord())))
 
2834
  copy_funcs(join->tmp_table_param.items_to_copy);
 
2835
  if ((error=table->file->ha_write_row(table->record[0])))
3103
2836
  {
3104
 
    my_error(ER_USE_SQL_BIG_RESULT, MYF(0));
3105
 
    return NESTED_LOOP_ERROR;        // Table is_full error
 
2837
    if (create_myisam_from_heap(join->session, table,
 
2838
                                join->tmp_table_param.start_recinfo,
 
2839
                                &join->tmp_table_param.recinfo,
 
2840
                                error, 0))
 
2841
      return NESTED_LOOP_ERROR;            // Not a table_is_full error
 
2842
    /* Change method to update rows */
 
2843
    table->file->ha_index_init(0, 0);
 
2844
    join->join_tab[join->tables-1].next_select= end_unique_update;
3106
2845
  }
3107
2846
  join->send_records++;
3108
2847
  return NESTED_LOOP_OK;
3109
2848
}
3110
2849
 
3111
2850
/** Like end_update, but this is done with unique constraints instead of keys.  */
3112
 
enum_nested_loop_state end_unique_update(Join *join, JoinTable *, bool end_of_records)
 
2851
enum_nested_loop_state end_unique_update(JOIN *join, JoinTable *, bool end_of_records)
3113
2852
{
3114
2853
  Table *table= join->tmp_table;
3115
2854
  int   error;
3116
2855
 
3117
2856
  if (end_of_records)
3118
2857
    return NESTED_LOOP_OK;
3119
 
  if (join->session->getKilled())                       // Aborted by user
 
2858
  if (join->session->killed)                    // Aborted by user
3120
2859
  {
3121
2860
    join->session->send_kill_message();
3122
 
    return NESTED_LOOP_KILLED;
 
2861
    return NESTED_LOOP_KILLED;             /* purecov: inspected */
3123
2862
  }
3124
2863
 
3125
2864
  init_tmptable_sum_functions(join->sum_funcs);
3126
2865
  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;
 
2866
  copy_funcs(join->tmp_table_param.items_to_copy);
3129
2867
 
3130
 
  if (!(error= table->cursor->insertRecord(table->getInsertRecord())))
 
2868
  if (!(error= table->file->ha_write_row(table->record[0])))
3131
2869
    join->send_records++;                       // New group
3132
2870
  else
3133
2871
  {
3134
 
    if ((int) table->get_dup_key(error) < 0)
 
2872
    if ((int) table->file->get_dup_key(error) < 0)
3135
2873
    {
3136
 
      table->print_error(error,MYF(0));
3137
 
      return NESTED_LOOP_ERROR;
 
2874
      table->file->print_error(error,MYF(0));   /* purecov: inspected */
 
2875
      return NESTED_LOOP_ERROR;            /* purecov: inspected */
3138
2876
    }
3139
 
    if (table->cursor->rnd_pos(table->getUpdateRecord(),table->cursor->dup_ref))
 
2877
    if (table->file->rnd_pos(table->record[1],table->file->dup_ref))
3140
2878
    {
3141
 
      table->print_error(error,MYF(0));
3142
 
      return NESTED_LOOP_ERROR;
 
2879
      table->file->print_error(error,MYF(0));   /* purecov: inspected */
 
2880
      return NESTED_LOOP_ERROR;            /* purecov: inspected */
3143
2881
    }
3144
2882
    table->restoreRecord();
3145
2883
    update_tmptable_sum_func(join->sum_funcs,table);
3146
 
    if ((error= table->cursor->updateRecord(table->getUpdateRecord(),
3147
 
                                          table->getInsertRecord())))
 
2884
    if ((error= table->file->ha_update_row(table->record[1],
 
2885
                                          table->record[0])))
3148
2886
    {
3149
 
      table->print_error(error,MYF(0));
3150
 
      return NESTED_LOOP_ERROR;
 
2887
      table->file->print_error(error,MYF(0));   /* purecov: inspected */
 
2888
      return NESTED_LOOP_ERROR;            /* purecov: inspected */
3151
2889
    }
3152
2890
  }
3153
2891
  return NESTED_LOOP_OK;
3165
2903
  @retval
3166
2904
    1   failed
3167
2905
*/
3168
 
static bool make_group_fields(Join *main_join, Join *curr_join)
 
2906
static bool make_group_fields(JOIN *main_join, JOIN *curr_join)
3169
2907
{
3170
2908
  if (main_join->group_fields_cache.elements)
3171
2909
  {
3184
2922
/**
3185
2923
  calc how big buffer we need for comparing group entries.
3186
2924
*/
3187
 
static void calc_group_buffer(Join *join, Order *group)
 
2925
static void calc_group_buffer(JOIN *join,order_st *group)
3188
2926
{
3189
2927
  uint32_t key_length=0, parts=0, null_parts=0;
3190
2928
 
3210
2948
      case REAL_RESULT:
3211
2949
        key_length+= sizeof(double);
3212
2950
        break;
3213
 
 
3214
2951
      case INT_RESULT:
3215
2952
        key_length+= sizeof(int64_t);
3216
2953
        break;
3217
 
 
3218
2954
      case DECIMAL_RESULT:
3219
 
        key_length+= class_decimal_get_binary_size(group_item->max_length -
 
2955
        key_length+= my_decimal_get_binary_size(group_item->max_length -
3220
2956
                                                (group_item->decimals ? 1 : 0),
3221
2957
                                                group_item->decimals);
3222
2958
        break;
3223
 
 
3224
2959
      case STRING_RESULT:
3225
 
        {
3226
 
          enum enum_field_types type= group_item->field_type();
 
2960
      {
 
2961
        enum enum_field_types type= group_item->field_type();
 
2962
        /*
 
2963
          As items represented as DATE/TIME fields in the group buffer
 
2964
          have STRING_RESULT result type, we increase the length
 
2965
          by 8 as maximum pack length of such fields.
 
2966
        */
 
2967
        if (type == DRIZZLE_TYPE_DATE ||
 
2968
            type == DRIZZLE_TYPE_DATETIME ||
 
2969
            type == DRIZZLE_TYPE_TIMESTAMP)
 
2970
        {
 
2971
          key_length+= 8;
 
2972
        }
 
2973
        else
 
2974
        {
3227
2975
          /*
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.
 
2976
            Group strings are taken as varstrings and require an length field.
 
2977
            A field is not yet created by create_tmp_field()
 
2978
            and the sizes should match up.
3231
2979
          */
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;
 
2980
          key_length+= group_item->max_length + HA_KEY_BLOB_LENGTH;
3251
2981
        }
3252
 
 
3253
 
      case ROW_RESULT:
 
2982
        break;
 
2983
      }
 
2984
      default:
3254
2985
        /* This case should never be choosen */
3255
2986
        assert(0);
3256
2987
        my_error(ER_OUT_OF_RESOURCES, MYF(ME_FATALERROR));
3257
2988
      }
3258
2989
    }
3259
 
 
3260
2990
    parts++;
3261
 
 
3262
2991
    if (group_item->maybe_null)
3263
2992
      null_parts++;
3264
2993
  }
3265
 
 
3266
2994
  join->tmp_table_param.group_length=key_length+null_parts;
3267
2995
  join->tmp_table_param.group_parts=parts;
3268
2996
  join->tmp_table_param.group_null_parts=null_parts;
3273
3001
 
3274
3002
  Groups are saved in reverse order for easyer check loop.
3275
3003
*/
3276
 
static bool alloc_group_fields(Join *join, Order *group)
 
3004
static bool alloc_group_fields(JOIN *join,order_st *group)
3277
3005
{
3278
3006
  if (group)
3279
3007
  {
3280
3008
    for (; group ; group=group->next)
3281
3009
    {
3282
 
      Cached_item *tmp= new_Cached_item(join->session, *group->item);
 
3010
      Cached_item *tmp=new_Cached_item(join->session, *group->item, false);
3283
3011
      if (!tmp || join->group_fields.push_front(tmp))
3284
3012
        return true;
3285
3013
    }
3288
3016
  return false;
3289
3017
}
3290
3018
 
3291
 
static uint32_t cache_record_length(Join *join,uint32_t idx)
 
3019
static uint32_t cache_record_length(JOIN *join,uint32_t idx)
3292
3020
{
3293
3021
  uint32_t length=0;
3294
3022
  JoinTable **pos,**end;
3356
3084
  RETURN
3357
3085
    Expected number of row combinations
3358
3086
*/
3359
 
static double prev_record_reads(Join *join, uint32_t idx, table_map found_ref)
 
3087
static double prev_record_reads(JOIN *join, uint32_t idx, table_map found_ref)
3360
3088
{
3361
3089
  double found=1.0;
3362
3090
  optimizer::Position *pos_end= join->getSpecificPosInPartialPlan(-1);
3368
3096
    {
3369
3097
      found_ref|= pos->getRefDependMap();
3370
3098
      /*
3371
 
        For the case of "t1 LEFT Join t2 ON ..." where t2 is a const table
 
3099
        For the case of "t1 LEFT JOIN t2 ON ..." where t2 is a const table
3372
3100
        with no matching row we will get position[t2].records_read==0.
3373
3101
        Actually the size of output is one null-complemented row, therefore
3374
3102
        we will use value of 1 whenever we get records_read==0.
3393
3121
/**
3394
3122
  Set up join struct according to best position.
3395
3123
*/
3396
 
static bool get_best_combination(Join *join)
 
3124
static bool get_best_combination(JOIN *join)
3397
3125
{
3398
3126
  uint32_t i,tablenr;
3399
3127
  table_map used_tables;
3405
3133
 
3406
3134
  table_count=join->tables;
3407
3135
  if (!(join->join_tab=join_tab=
3408
 
  (JoinTable*) session->getMemRoot()->allocate(sizeof(JoinTable)*table_count)))
 
3136
  (JoinTable*) session->alloc(sizeof(JoinTable)*table_count)))
3409
3137
    return(true);
3410
3138
 
3411
 
  for (i= 0; i < table_count; i++)
3412
 
    new (join_tab+i) JoinTable();
3413
 
 
3414
3139
  join->full_join=0;
3415
3140
 
3416
3141
  used_tables= OUTER_REF_TABLE_BIT;   // Outer row is already read
3423
3148
    used_tables|= form->map;
3424
3149
    form->reginfo.join_tab=j;
3425
3150
    if (!*j->on_expr_ref)
3426
 
      form->reginfo.not_exists_optimize=0;  // Only with LEFT Join
 
3151
      form->reginfo.not_exists_optimize=0;  // Only with LEFT JOIN
3427
3152
    if (j->type == AM_CONST)
3428
3153
      continue;         // Handled in make_join_stat..
3429
3154
 
3449
3174
}
3450
3175
 
3451
3176
/** Save const tables first as used tables. */
3452
 
static void set_position(Join *join,
 
3177
static void set_position(JOIN *join,
3453
3178
                         uint32_t idx,
3454
3179
                         JoinTable *table,
3455
3180
                         optimizer::KeyUse *key)
3491
3216
  @retval
3492
3217
    true        Fatal error
3493
3218
*/
3494
 
static bool choose_plan(Join *join, table_map join_tables)
 
3219
static bool choose_plan(JOIN *join, table_map join_tables)
3495
3220
{
3496
3221
  uint32_t search_depth= join->session->variables.optimizer_search_depth;
3497
3222
  uint32_t prune_level=  join->session->variables.optimizer_prune_level;
3507
3232
      Apply heuristic: pre-sort all access plans with respect to the number of
3508
3233
      records accessed.
3509
3234
  */
3510
 
  internal::my_qsort(join->best_ref + join->const_tables,
3511
 
                     join->tables - join->const_tables, sizeof(JoinTable*),
3512
 
                     straight_join ? join_tab_cmp_straight : join_tab_cmp);
 
3235
  my_qsort(join->best_ref + join->const_tables,
 
3236
           join->tables - join->const_tables, sizeof(JoinTable*),
 
3237
           straight_join ? join_tab_cmp_straight : join_tab_cmp);
3513
3238
  if (straight_join)
3514
3239
  {
3515
3240
    optimize_straight_join(join, join_tables);
3558
3283
  @return
3559
3284
    None
3560
3285
*/
3561
 
static void best_access_path(Join *join,
 
3286
static void best_access_path(JOIN *join,
3562
3287
                             JoinTable *s,
3563
3288
                             Session *session,
3564
3289
                             table_map remaining_tables,
3566
3291
                             double record_count,
3567
3292
                             double)
3568
3293
{
3569
 
  optimizer::KeyUse *best_key= NULL;
3570
 
  uint32_t best_max_key_part= 0;
 
3294
  optimizer::KeyUse *best_key=         0;
 
3295
  uint32_t best_max_key_part=   0;
3571
3296
  bool found_constraint= 0;
3572
 
  double best= DBL_MAX;
3573
 
  double best_time= DBL_MAX;
3574
 
  double records= DBL_MAX;
 
3297
  double best=              DBL_MAX;
 
3298
  double best_time=         DBL_MAX;
 
3299
  double records=           DBL_MAX;
3575
3300
  table_map best_ref_depends_map= 0;
3576
3301
  double tmp;
3577
3302
  ha_rows rec;
3579
3304
  if (s->keyuse)
3580
3305
  {                                            /* Use key if possible */
3581
3306
    Table *table= s->table;
3582
 
    optimizer::KeyUse *keyuse= NULL;
3583
 
    optimizer::KeyUse *start_key= NULL;
 
3307
    optimizer::KeyUse *keyuse,*start_key=0;
3584
3308
    double best_records= DBL_MAX;
3585
3309
    uint32_t max_key_part=0;
3586
3310
 
3587
3311
    /* Test how we can use keys */
3588
3312
    rec= s->records/MATCHING_ROWS_IN_OTHER_TABLE;  // Assumed records/key
3589
 
    for (keyuse= s->keyuse; keyuse->getTable() == table; )
 
3313
    for (keyuse=s->keyuse ; keyuse->table == table ;)
3590
3314
    {
3591
3315
      key_part_map found_part= 0;
3592
3316
      table_map found_ref= 0;
3593
 
      uint32_t key= keyuse->getKey();
3594
 
      KeyInfo *keyinfo= table->key_info + key;
 
3317
      uint32_t key= keyuse->key;
 
3318
      KEY *keyinfo= table->key_info+key;
3595
3319
      /* Bitmap of keyparts where the ref access is over 'keypart=const': */
3596
3320
      key_part_map const_part= 0;
3597
3321
      /* The or-null keypart in ref-or-null access: */
3602
3326
 
3603
3327
      do /* For each keypart */
3604
3328
      {
3605
 
        uint32_t keypart= keyuse->getKeypart();
 
3329
        uint32_t keypart= keyuse->keypart;
3606
3330
        table_map best_part_found_ref= 0;
3607
3331
        double best_prev_record_reads= DBL_MAX;
3608
3332
 
3613
3337
            if 1. expression doesn't refer to forward tables
3614
3338
               2. we won't get two ref-or-null's
3615
3339
          */
3616
 
          if (! (remaining_tables & keyuse->getUsedTables()) &&
3617
 
              ! (ref_or_null_part && (keyuse->getOptimizeFlags() &
3618
 
                                      KEY_OPTIMIZE_REF_OR_NULL)))
 
3340
          if (!(remaining_tables & keyuse->used_tables) &&
 
3341
              !(ref_or_null_part && (keyuse->optimize &
 
3342
                                     KEY_OPTIMIZE_REF_OR_NULL)))
3619
3343
          {
3620
 
            found_part|= keyuse->getKeypartMap();
3621
 
            if (! (keyuse->getUsedTables() & ~join->const_table_map))
3622
 
              const_part|= keyuse->getKeypartMap();
 
3344
            found_part|= keyuse->keypart_map;
 
3345
            if (!(keyuse->used_tables & ~join->const_table_map))
 
3346
              const_part|= keyuse->keypart_map;
3623
3347
 
3624
3348
            double tmp2= prev_record_reads(join, idx, (found_ref |
3625
 
                                                       keyuse->getUsedTables()));
 
3349
                                                      keyuse->used_tables));
3626
3350
            if (tmp2 < best_prev_record_reads)
3627
3351
            {
3628
 
              best_part_found_ref= keyuse->getUsedTables() & ~join->const_table_map;
 
3352
              best_part_found_ref= keyuse->used_tables & ~join->const_table_map;
3629
3353
              best_prev_record_reads= tmp2;
3630
3354
            }
3631
 
            if (rec > keyuse->getTableRows())
3632
 
              rec= keyuse->getTableRows();
 
3355
            if (rec > keyuse->ref_table_rows)
 
3356
              rec= keyuse->ref_table_rows;
3633
3357
      /*
3634
3358
        If there is one 'key_column IS NULL' expression, we can
3635
3359
        use this ref_or_null optimisation of this field
3636
3360
      */
3637
 
            if (keyuse->getOptimizeFlags() & KEY_OPTIMIZE_REF_OR_NULL)
3638
 
              ref_or_null_part|= keyuse->getKeypartMap();
 
3361
            if (keyuse->optimize & KEY_OPTIMIZE_REF_OR_NULL)
 
3362
              ref_or_null_part |= keyuse->keypart_map;
3639
3363
          }
3640
3364
 
3641
3365
          keyuse++;
3642
 
        } while (keyuse->getTable() == table && keyuse->getKey() == key &&
3643
 
                 keyuse->getKeypart() == keypart);
3644
 
        found_ref|= best_part_found_ref;
3645
 
      } while (keyuse->getTable() == table && keyuse->getKey() == key);
 
3366
        } while (keyuse->table == table && keyuse->key == key &&
 
3367
                 keyuse->keypart == keypart);
 
3368
  found_ref|= best_part_found_ref;
 
3369
      } while (keyuse->table == table && keyuse->key == key);
3646
3370
 
3647
3371
      /*
3648
3372
        Assume that that each key matches a proportional part of table.
3704
3428
                records=
3705
3429
                  ((double) s->records / (double) rec *
3706
3430
                   (1.0 +
3707
 
                    ((double) (table->getShare()->max_key_length-keyinfo->key_length) /
3708
 
                     (double) table->getShare()->max_key_length)));
 
3431
                    ((double) (table->s->max_key_length-keyinfo->key_length) /
 
3432
                     (double) table->s->max_key_length)));
3709
3433
                if (records < 2.0)
3710
3434
                  records=2.0;               /* Can't be as good as a unique */
3711
3435
              }
3733
3457
            if (table->covering_keys.test(key))
3734
3458
            {
3735
3459
              /* we can use only index tree */
3736
 
              tmp= record_count * table->cursor->index_only_read_time(key, tmp);
 
3460
              tmp= record_count * table->file->index_only_read_time(key, tmp);
3737
3461
            }
3738
3462
            else
3739
3463
              tmp= record_count * min(tmp,s->worst_seeks);
3747
3471
            Set tmp to (previous record count) * (records / combination)
3748
3472
          */
3749
3473
          if ((found_part & 1) &&
3750
 
              (!(table->index_flags(key) & HA_ONLY_WHOLE_INDEX) ||
3751
 
               found_part == PREV_BITS(uint, keyinfo->key_parts)))
 
3474
              (!(table->file->index_flags(key, 0, 0) & HA_ONLY_WHOLE_INDEX) ||
 
3475
               found_part == PREV_BITS(uint,keyinfo->key_parts)))
3752
3476
          {
3753
3477
            max_key_part= max_part_bit(found_part);
3754
3478
            /*
3827
3551
              else
3828
3552
              {
3829
3553
                /*
3830
 
                  Assume that the first key part matches 1% of the cursor
 
3554
                  Assume that the first key part matches 1% of the file
3831
3555
                  and that the whole key matches 10 (duplicates) or 1
3832
3556
                  (unique) records.
3833
3557
                  Assume also that more key matches proportionally more
3898
3622
            if (table->covering_keys.test(key))
3899
3623
            {
3900
3624
              /* we can use only index tree */
3901
 
              tmp= record_count * table->cursor->index_only_read_time(key, tmp);
 
3625
              tmp= record_count * table->file->index_only_read_time(key, tmp);
3902
3626
            }
3903
3627
            else
3904
3628
              tmp= record_count * min(tmp,s->worst_seeks);
3950
3674
        scan.
3951
3675
  */
3952
3676
  if ((records >= s->found_records || best > s->read_time) &&            // (1)
3953
 
      ! (s->quick && best_key && s->quick->index == best_key->getKey() &&      // (2)
3954
 
        best_max_key_part >= s->table->quick_key_parts[best_key->getKey()]) &&// (2)
3955
 
      ! ((s->table->cursor->getEngine()->check_flag(HTON_BIT_TABLE_SCAN_ON_INDEX)) &&   // (3)
3956
 
        ! s->table->covering_keys.none() && best_key && !s->quick) && // (3)
3957
 
      ! (s->table->force_index && best_key && !s->quick))                 // (4)
 
3677
      !(s->quick && best_key && s->quick->index == best_key->key &&      // (2)
 
3678
        best_max_key_part >= s->table->quick_key_parts[best_key->key]) &&// (2)
 
3679
      !((s->table->file->ha_table_flags() & HA_TABLE_SCAN_ON_INDEX) &&   // (3)
 
3680
        ! s->table->covering_keys.none() && best_key && !s->quick) &&// (3)
 
3681
      !(s->table->force_index && best_key && !s->quick))                 // (4)
3958
3682
  {                                             // Check full join
3959
3683
    ha_rows rnd_records= s->found_records;
3960
3684
    /*
3999
3723
    else
4000
3724
    {
4001
3725
      /* Estimate cost of reading table. */
4002
 
      tmp= s->table->cursor->scan_time();
 
3726
      tmp= s->table->file->scan_time();
4003
3727
      if (s->table->map & join->outer_join)     // Can't use join cache
4004
3728
      {
4005
3729
        /*
4088
3812
    Thus 'optimize_straight_join' can be used at any stage of the query
4089
3813
    optimization process to finalize a QEP as it is.
4090
3814
*/
4091
 
static void optimize_straight_join(Join *join, table_map join_tables)
 
3815
static void optimize_straight_join(JOIN *join, table_map join_tables)
4092
3816
{
4093
3817
  JoinTable *s;
4094
3818
  optimizer::Position partial_pos;
4198
3922
  @retval
4199
3923
    true        Fatal error
4200
3924
*/
4201
 
static bool greedy_search(Join      *join,
 
3925
static bool greedy_search(JOIN      *join,
4202
3926
              table_map remaining_tables,
4203
3927
              uint32_t      search_depth,
4204
3928
              uint32_t      prune_level)
4212
3936
  JoinTable  *best_table; // the next plan node to be added to the curr QEP
4213
3937
 
4214
3938
  /* number of tables that remain to be optimized */
4215
 
  size_remain= internal::my_count_bits(remaining_tables);
 
3939
  size_remain= my_count_bits(remaining_tables);
4216
3940
 
4217
3941
  do {
4218
3942
    /* Find the extension of the current QEP with the lowest cost */
4240
3964
    */
4241
3965
    join->setPosInPartialPlan(idx, best_pos);
4242
3966
 
4243
 
    /*
4244
 
      We need to make best_extension_by_limited_search aware of the fact
4245
 
      that it's not starting from top level, but from a rather specific
4246
 
      position in the list of nested joins.
4247
 
    */
4248
 
    check_interleaving_with_nj (best_table);
4249
 
    
4250
 
      
4251
 
 
4252
3967
    /* find the position of 'best_table' in 'join->best_ref' */
4253
3968
    best_idx= idx;
4254
3969
    JoinTable *pos= join->best_ref[best_idx];
4386
4101
  @retval
4387
4102
    true        Fatal error
4388
4103
*/
4389
 
static bool best_extension_by_limited_search(Join *join,
 
4104
static bool best_extension_by_limited_search(JOIN *join,
4390
4105
                                             table_map remaining_tables,
4391
4106
                                             uint32_t idx,
4392
4107
                                             double record_count,
4395
4110
                                             uint32_t prune_level)
4396
4111
{
4397
4112
  Session *session= join->session;
4398
 
  if (session->getKilled())  // Abort
 
4113
  if (session->killed)  // Abort
4399
4114
    return(true);
4400
4115
 
4401
4116
  /*
4410
4125
  for (JoinTable **pos= join->best_ref + idx ; (s= *pos) ; pos++)
4411
4126
  {
4412
4127
    table_map real_table_bit= s->table->map;
 
4128
    if (idx)
 
4129
    {
 
4130
      partial_pos= join->getPosFromPartialPlan(idx - 1);
 
4131
    }
4413
4132
    if ((remaining_tables & real_table_bit) &&
4414
4133
        ! (remaining_tables & s->dependent) &&
4415
 
        (! idx || ! check_interleaving_with_nj(s)))
 
4134
        (! idx || ! check_interleaving_with_nj(partial_pos.getJoinTable(), s)))
4416
4135
    {
4417
4136
      double current_record_count, current_read_time;
4418
4137
 
4533
4252
    exhaustiveness) of the depth-first search algorithm used by
4534
4253
    'greedy_search'.
4535
4254
*/
4536
 
static uint32_t determine_search_depth(Join *join)
 
4255
static uint32_t determine_search_depth(JOIN *join)
4537
4256
{
4538
4257
  uint32_t table_count=  join->tables - join->const_tables;
4539
4258
  uint32_t search_depth;
4552
4271
  return search_depth;
4553
4272
}
4554
4273
 
4555
 
static bool make_simple_join(Join *join,Table *tmp_table)
 
4274
static bool make_simple_join(JOIN *join,Table *tmp_table)
4556
4275
{
4557
4276
  Table **tableptr;
4558
4277
  JoinTable *join_tab;
4559
4278
 
4560
4279
  /*
4561
4280
    Reuse Table * and JoinTable if already allocated by a previous call
4562
 
    to this function through Join::exec (may happen for sub-queries).
 
4281
    to this function through JOIN::exec (may happen for sub-queries).
4563
4282
  */
4564
4283
  if (!join->table_reexec)
4565
4284
  {
4566
 
    if (!(join->table_reexec= (Table**) join->session->getMemRoot()->allocate(sizeof(Table*))))
4567
 
      return(true);
 
4285
    if (!(join->table_reexec= (Table**) join->session->alloc(sizeof(Table*))))
 
4286
      return(true);                        /* purecov: inspected */
4568
4287
    if (join->tmp_join)
4569
4288
      join->tmp_join->table_reexec= join->table_reexec;
4570
4289
  }
4571
4290
  if (!join->join_tab_reexec)
4572
4291
  {
4573
4292
    if (!(join->join_tab_reexec=
4574
 
          (JoinTable*) join->session->getMemRoot()->allocate(sizeof(JoinTable))))
4575
 
      return(true);
4576
 
    new (join->join_tab_reexec) JoinTable();
 
4293
          (JoinTable*) join->session->alloc(sizeof(JoinTable))))
 
4294
      return(true);                        /* purecov: inspected */
4577
4295
    if (join->tmp_join)
4578
4296
      join->tmp_join->join_tab_reexec= join->join_tab_reexec;
4579
4297
  }
4594
4312
  join->row_limit=join->unit->select_limit_cnt;
4595
4313
  join->do_send_rows = (join->row_limit) ? 1 : 0;
4596
4314
 
 
4315
  join_tab->cache.buff=0;                       /* No caching */
4597
4316
  join_tab->table=tmp_table;
4598
4317
  join_tab->select=0;
4599
4318
  join_tab->select_cond=0;
4609
4328
  join_tab->read_first_record= join_init_read_record;
4610
4329
  join_tab->join=join;
4611
4330
  join_tab->ref.key_parts= 0;
4612
 
  join_tab->read_record.init();
 
4331
  memset(&join_tab->read_record, 0, sizeof(join_tab->read_record));
4613
4332
  tmp_table->status=0;
4614
4333
  tmp_table->null_row=0;
4615
 
 
4616
 
  return false;
 
4334
  return(false);
4617
4335
}
4618
4336
 
4619
4337
/**
4657
4375
    This function can be called only after the execution plan
4658
4376
    has been chosen.
4659
4377
*/
4660
 
static void make_outerjoin_info(Join *join)
 
4378
static void make_outerjoin_info(JOIN *join)
4661
4379
{
4662
4380
  for (uint32_t i=join->const_tables ; i < join->tables ; i++)
4663
4381
  {
4664
4382
    JoinTable *tab=join->join_tab+i;
4665
4383
    Table *table=tab->table;
4666
4384
    TableList *tbl= table->pos_in_table_list;
4667
 
    TableList *embedding= tbl->getEmbedding();
 
4385
    TableList *embedding= tbl->embedding;
4668
4386
 
4669
4387
    if (tbl->outer_join)
4670
4388
    {
4677
4395
      tab->on_expr_ref= &tbl->on_expr;
4678
4396
      tab->cond_equal= tbl->cond_equal;
4679
4397
      if (embedding)
4680
 
        tab->first_upper= embedding->getNestedJoin()->first_nested;
 
4398
        tab->first_upper= embedding->nested_join->first_nested;
4681
4399
    }
4682
 
    for ( ; embedding ; embedding= embedding->getEmbedding())
 
4400
    for ( ; embedding ; embedding= embedding->embedding)
4683
4401
    {
4684
4402
      /* Ignore sj-nests: */
4685
4403
      if (!embedding->on_expr)
4686
4404
        continue;
4687
 
      NestedJoin *nested_join= embedding->getNestedJoin();
 
4405
      nested_join_st *nested_join= embedding->nested_join;
4688
4406
      if (!nested_join->counter_)
4689
4407
      {
4690
4408
        /*
4694
4412
        nested_join->first_nested= tab;
4695
4413
        tab->on_expr_ref= &embedding->on_expr;
4696
4414
        tab->cond_equal= tbl->cond_equal;
4697
 
        if (embedding->getEmbedding())
4698
 
          tab->first_upper= embedding->getEmbedding()->getNestedJoin()->first_nested;
 
4415
        if (embedding->embedding)
 
4416
          tab->first_upper= embedding->embedding->nested_join->first_nested;
4699
4417
      }
4700
4418
      if (!tab->first_inner)
4701
4419
        tab->first_inner= nested_join->first_nested;
4708
4426
  return;
4709
4427
}
4710
4428
 
4711
 
static bool make_join_select(Join *join,
4712
 
                             optimizer::SqlSelect *select,
4713
 
                             COND *cond)
 
4429
static bool make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
4714
4430
{
4715
4431
  Session *session= join->session;
4716
4432
  optimizer::Position cur_pos;
4802
4518
          join->full_join= 1;
4803
4519
      }
4804
4520
 
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
4521
      tmp= NULL;
4812
4522
      if (cond)
4813
4523
        tmp= make_cond_for_table(cond,used_tables,current_map, 0);
4837
4547
      if (tmp || !cond || tab->type == AM_REF || tab->type == AM_REF_OR_NULL ||
4838
4548
          tab->type == AM_EQ_REF)
4839
4549
      {
4840
 
        optimizer::SqlSelect *sel= tab->select= ((optimizer::SqlSelect*)
4841
 
            session->getMemRoot()->duplicate((unsigned char*) select,
 
4550
        SQL_SELECT *sel= tab->select= ((SQL_SELECT*)
 
4551
            session->memdup((unsigned char*) select,
4842
4552
              sizeof(*select)));
4843
4553
        if (! sel)
4844
4554
          return 1;                     // End of memory
4975
4685
                                         current_map,
4976
4686
                                         current_map, 0)))
4977
4687
            {
4978
 
              tab->cache.select= (optimizer::SqlSelect*)
4979
 
                session->getMemRoot()->duplicate((unsigned char*) sel, sizeof(optimizer::SqlSelect));
 
4688
              tab->cache.select= (SQL_SELECT*)
 
4689
                session->memdup((unsigned char*) sel, sizeof(SQL_SELECT));
4980
4690
              tab->cache.select->cond= tmp;
4981
4691
              tab->cache.select->read_tables= join->const_table_map;
4982
4692
            }
5092
4802
    false - OK
5093
4803
    true  - Out of memory
5094
4804
*/
5095
 
static bool make_join_readinfo(Join *join)
 
4805
static bool make_join_readinfo(JOIN *join, uint64_t options, uint32_t no_jbuf_after)
5096
4806
{
5097
 
  bool sorted= true;
 
4807
  uint32_t i;
 
4808
  bool statistics= test(!(join->select_options & SELECT_DESCRIBE));
 
4809
  bool sorted= 1;
5098
4810
 
5099
 
  for (uint32_t i= join->const_tables ; i < join->tables ; i++)
 
4811
  for (i=join->const_tables ; i < join->tables ; i++)
5100
4812
  {
5101
4813
    JoinTable *tab=join->join_tab+i;
5102
4814
    Table *table=tab->table;
 
4815
    bool using_join_cache;
5103
4816
    tab->read_record.table= table;
5104
 
    tab->read_record.cursor= table->cursor;
 
4817
    tab->read_record.file=table->file;
5105
4818
    tab->next_select=sub_select;                /* normal select */
5106
4819
    /*
5107
4820
      TODO: don't always instruct first table's ref/range access method to
5108
4821
      produce sorted output.
5109
4822
    */
5110
4823
    tab->sorted= sorted;
5111
 
    sorted= false; // only first must be sorted
5112
 
 
 
4824
    sorted= 0;                                  // only first must be sorted
5113
4825
    if (tab->insideout_match_tab)
5114
4826
    {
5115
 
      if (! (tab->insideout_buf= (unsigned char*) join->session->getMemRoot()->allocate(tab->table->key_info
5116
 
                                                                       [tab->index].
5117
 
                                                                       key_length)))
 
4827
      if (!(tab->insideout_buf= (unsigned char*)join->session->alloc(tab->table->key_info
 
4828
                                                         [tab->index].
 
4829
                                                         key_length)))
5118
4830
        return true;
5119
4831
    }
5120
 
 
5121
 
    optimizer::AccessMethodFactory &factory= optimizer::AccessMethodFactory::singleton();
5122
 
    boost::shared_ptr<optimizer::AccessMethod> access_method(factory.createAccessMethod(tab->type));
5123
 
 
5124
 
    if (! access_method)
5125
 
    {
5126
 
      /**
5127
 
       * @todo
5128
 
       * Is abort() the correct thing to call here? I call this here because it was what was called in
5129
 
       * the default case for the switch statement that used to be here.
5130
 
       */
5131
 
      abort();
 
4832
    switch (tab->type) {
 
4833
    case AM_SYSTEM:                             // Only happens with left join
 
4834
      table->status=STATUS_NO_RECORD;
 
4835
      tab->read_first_record= join_read_system;
 
4836
      tab->read_record.read_record= join_no_more_records;
 
4837
      break;
 
4838
    case AM_CONST:                              // Only happens with left join
 
4839
      table->status=STATUS_NO_RECORD;
 
4840
      tab->read_first_record= join_read_const;
 
4841
      tab->read_record.read_record= join_no_more_records;
 
4842
      if (table->covering_keys.test(tab->ref.key) &&
 
4843
          !table->no_keyread)
 
4844
      {
 
4845
        table->key_read=1;
 
4846
        table->file->extra(HA_EXTRA_KEYREAD);
 
4847
      }
 
4848
      break;
 
4849
    case AM_EQ_REF:
 
4850
      table->status=STATUS_NO_RECORD;
 
4851
      if (tab->select)
 
4852
      {
 
4853
        delete tab->select->quick;
 
4854
        tab->select->quick=0;
 
4855
      }
 
4856
      delete tab->quick;
 
4857
      tab->quick=0;
 
4858
      tab->read_first_record= join_read_key;
 
4859
      tab->read_record.read_record= join_no_more_records;
 
4860
      if (table->covering_keys.test(tab->ref.key) && !table->no_keyread)
 
4861
      {
 
4862
        table->key_read=1;
 
4863
        table->file->extra(HA_EXTRA_KEYREAD);
 
4864
      }
 
4865
      break;
 
4866
    case AM_REF_OR_NULL:
 
4867
    case AM_REF:
 
4868
      table->status=STATUS_NO_RECORD;
 
4869
      if (tab->select)
 
4870
      {
 
4871
        delete tab->select->quick;
 
4872
        tab->select->quick=0;
 
4873
      }
 
4874
      delete tab->quick;
 
4875
      tab->quick=0;
 
4876
      if (table->covering_keys.test(tab->ref.key) && !table->no_keyread)
 
4877
      {
 
4878
        table->key_read=1;
 
4879
        table->file->extra(HA_EXTRA_KEYREAD);
 
4880
      }
 
4881
      if (tab->type == AM_REF)
 
4882
      {
 
4883
        tab->read_first_record= join_read_always_key;
 
4884
        tab->read_record.read_record= tab->insideout_match_tab?
 
4885
           join_read_next_same_diff : join_read_next_same;
 
4886
      }
 
4887
      else
 
4888
      {
 
4889
        tab->read_first_record= join_read_always_key_or_null;
 
4890
        tab->read_record.read_record= join_read_next_same_or_null;
 
4891
      }
 
4892
      break;
 
4893
    case AM_ALL:
 
4894
      /*
 
4895
        If previous table use cache
 
4896
        If the incoming data set is already sorted don't use cache.
 
4897
      */
 
4898
      table->status=STATUS_NO_RECORD;
 
4899
      using_join_cache= false;
 
4900
      if (i != join->const_tables && !(options & SELECT_NO_JOIN_CACHE) &&
 
4901
          tab->use_quick != 2 && !tab->first_inner && i <= no_jbuf_after &&
 
4902
          !tab->insideout_match_tab)
 
4903
      {
 
4904
        if ((options & SELECT_DESCRIBE) ||
 
4905
            !join_init_cache(join->session,join->join_tab+join->const_tables,
 
4906
                i-join->const_tables))
 
4907
        {
 
4908
                using_join_cache= true;
 
4909
          tab[-1].next_select=sub_select_cache; /* Patch previous */
 
4910
        }
 
4911
      }
 
4912
      /* These init changes read_record */
 
4913
      if (tab->use_quick == 2)
 
4914
      {
 
4915
        join->session->server_status|=SERVER_QUERY_NO_GOOD_INDEX_USED;
 
4916
        tab->read_first_record= join_init_quick_read_record;
 
4917
        if (statistics)
 
4918
          status_var_increment(join->session->status_var.select_range_check_count);
 
4919
      }
 
4920
      else
 
4921
      {
 
4922
        tab->read_first_record= join_init_read_record;
 
4923
        if (i == join->const_tables)
 
4924
        {
 
4925
          if (tab->select && tab->select->quick)
 
4926
          {
 
4927
            if (statistics)
 
4928
              status_var_increment(join->session->status_var.select_range_count);
 
4929
          }
 
4930
          else
 
4931
          {
 
4932
            join->session->server_status|=SERVER_QUERY_NO_INDEX_USED;
 
4933
            if (statistics)
 
4934
              status_var_increment(join->session->status_var.select_scan_count);
 
4935
          }
 
4936
        }
 
4937
        else
 
4938
        {
 
4939
          if (tab->select && tab->select->quick)
 
4940
          {
 
4941
            if (statistics)
 
4942
              status_var_increment(join->session->status_var.select_full_range_join_count);
 
4943
          }
 
4944
          else
 
4945
          {
 
4946
            join->session->server_status|=SERVER_QUERY_NO_INDEX_USED;
 
4947
            if (statistics)
 
4948
              status_var_increment(join->session->status_var.select_full_join_count);
 
4949
          }
 
4950
        }
 
4951
        if (!table->no_keyread)
 
4952
        {
 
4953
          if (tab->select && tab->select->quick &&
 
4954
                    tab->select->quick->index != MAX_KEY && //not index_merge
 
4955
              table->covering_keys.test(tab->select->quick->index))
 
4956
          {
 
4957
            table->key_read=1;
 
4958
            table->file->extra(HA_EXTRA_KEYREAD);
 
4959
          }
 
4960
          else if (!table->covering_keys.none() &&
 
4961
            !(tab->select && tab->select->quick))
 
4962
          {                                     // Only read index tree
 
4963
                  if (!tab->insideout_match_tab)
 
4964
                  {
 
4965
                    /*
 
4966
                      See bug #26447: "Using the clustered index for a table scan
 
4967
                      is always faster than using a secondary index".
 
4968
                    */
 
4969
                    if (table->s->primary_key != MAX_KEY &&
 
4970
                        table->file->primary_key_is_clustered())
 
4971
                      tab->index= table->s->primary_key;
 
4972
                    else
 
4973
                      tab->index= table->find_shortest_key(&table->covering_keys);
 
4974
                  }
 
4975
            tab->read_first_record= join_read_first;
 
4976
            tab->type= AM_NEXT;         // Read with index_first / index_next
 
4977
          }
 
4978
        }
 
4979
      }
 
4980
      break;
 
4981
    default:
 
4982
      break;                                    /* purecov: deadcode */
 
4983
    case AM_UNKNOWN:
 
4984
    case AM_MAYBE_REF:
 
4985
      abort();                                  /* purecov: deadcode */
5132
4986
    }
5133
 
 
5134
 
    access_method->getStats(table, tab);
5135
4987
  }
5136
 
 
5137
 
  join->join_tab[join->tables-1].next_select= NULL; /* Set by do_select */
5138
 
 
5139
 
  return false;
 
4988
  join->join_tab[join->tables-1].next_select=0; /* Set by do_select */
 
4989
  return(false);
5140
4990
}
5141
4991
 
5142
4992
/** Update the dependency map for the tables. */
5143
 
static void update_depend_map(Join *join)
 
4993
static void update_depend_map(JOIN *join)
5144
4994
{
5145
4995
  JoinTable *join_tab=join->join_tab, *end=join_tab+join->tables;
5146
4996
 
5163
5013
}
5164
5014
 
5165
5015
/** Update the dependency map for the sort order. */
5166
 
static void update_depend_map(Join *join, Order *order)
 
5016
static void update_depend_map(JOIN *join, order_st *order)
5167
5017
{
5168
5018
  for (; order ; order=order->next)
5169
5019
  {
5201
5051
  @return
5202
5052
    Returns new sort order
5203
5053
*/
5204
 
static Order *remove_constants(Join *join,Order *first_order, COND *cond, bool change_list, bool *simple_order)
 
5054
static order_st *remove_constants(JOIN *join,order_st *first_order, COND *cond, bool change_list, bool *simple_order)
5205
5055
{
5206
5056
  if (join->tables == join->const_tables)
5207
5057
    return change_list ? 0 : first_order;               // No need to sort
5208
5058
 
5209
 
  Order *order,**prev_ptr;
 
5059
  order_st *order,**prev_ptr;
5210
5060
  table_map first_table= join->join_tab[join->const_tables].table->map;
5211
5061
  table_map not_const_tables= ~join->const_table_map;
5212
5062
  table_map ref;
5261
5111
  return(first_order);
5262
5112
}
5263
5113
 
5264
 
static int return_zero_rows(Join *join,
 
5114
static int return_zero_rows(JOIN *join,
5265
5115
                            select_result *result,
5266
5116
                            TableList *tables,
5267
5117
                                        List<Item> &fields,
5272
5122
{
5273
5123
  if (select_options & SELECT_DESCRIBE)
5274
5124
  {
5275
 
    optimizer::ExplainPlan planner(join,
5276
 
                                   false,
5277
 
                                   false,
5278
 
                                   false,
5279
 
                                   info);
5280
 
    planner.printPlan();
5281
 
    return 0;
 
5125
    select_describe(join, false, false, false, info);
 
5126
    return(0);
5282
5127
  }
5283
5128
 
5284
5129
  join->join_free();
5427
5272
    - The new condition, if success
5428
5273
    - 0, otherwise
5429
5274
*/
5430
 
static COND *simplify_joins(Join *join, List<TableList> *join_list, COND *conds, bool top)
 
5275
static COND *simplify_joins(JOIN *join, List<TableList> *join_list, COND *conds, bool top)
5431
5276
{
5432
5277
  TableList *table;
5433
 
  NestedJoin *nested_join;
 
5278
  nested_join_st *nested_join;
5434
5279
  TableList *prev_table= 0;
5435
5280
  List_iterator<TableList> li(*join_list);
5436
5281
 
5443
5288
    table_map used_tables;
5444
5289
    table_map not_null_tables= (table_map) 0;
5445
5290
 
5446
 
    if ((nested_join= table->getNestedJoin()))
 
5291
    if ((nested_join= table->nested_join))
5447
5292
    {
5448
5293
      /*
5449
5294
         If the element of join_list is a nested join apply
5485
5330
        not_null_tables= conds->not_null_tables();
5486
5331
    }
5487
5332
 
5488
 
    if (table->getEmbedding())
 
5333
    if (table->embedding)
5489
5334
    {
5490
 
      table->getEmbedding()->getNestedJoin()->used_tables|= used_tables;
5491
 
      table->getEmbedding()->getNestedJoin()->not_null_tables|= not_null_tables;
 
5335
      table->embedding->nested_join->used_tables|= used_tables;
 
5336
      table->embedding->nested_join->not_null_tables|= not_null_tables;
5492
5337
    }
5493
5338
 
5494
5339
    if (!table->outer_join || (used_tables & not_null_tables))
5524
5369
    */
5525
5370
    if (table->on_expr)
5526
5371
    {
5527
 
      table->setDepTables(table->getDepTables() | table->on_expr->used_tables());
5528
 
      if (table->getEmbedding())
 
5372
      table->dep_tables|= table->on_expr->used_tables();
 
5373
      if (table->embedding)
5529
5374
      {
5530
 
        table->setDepTables(table->getDepTables() & ~table->getEmbedding()->getNestedJoin()->used_tables);
 
5375
        table->dep_tables&= ~table->embedding->nested_join->used_tables;
5531
5376
        /*
5532
5377
           Embedding table depends on tables used
5533
5378
           in embedded on expressions.
5534
5379
        */
5535
 
        table->getEmbedding()->setOnExprDepTables(table->getEmbedding()->getOnExprDepTables() & table->on_expr->used_tables());
 
5380
        table->embedding->on_expr_dep_tables|= table->on_expr->used_tables();
5536
5381
      }
5537
5382
      else
5538
 
        table->setDepTables(table->getDepTables() & ~table->table->map);
 
5383
        table->dep_tables&= ~table->table->map;
5539
5384
    }
5540
5385
 
5541
5386
    if (prev_table)
5542
5387
    {
5543
 
      //If this is straight join, set prev table to be dependent on all tables
5544
 
      //from this nested join, so that correct join order is selected.
5545
 
      if ((test(join->select_options & SELECT_STRAIGHT_JOIN)) ||
5546
 
          prev_table->straight)
5547
 
        prev_table->setDepTables(prev_table->getDepTables() | used_tables);
 
5388
      /* The order of tables is reverse: prev_table follows table */
 
5389
      if (prev_table->straight)
 
5390
        prev_table->dep_tables|= used_tables;
5548
5391
      if (prev_table->on_expr)
5549
5392
      {
5550
 
        prev_table->setDepTables(prev_table->getDepTables() | table->getOnExprDepTables());
5551
 
        table_map prev_used_tables= prev_table->getNestedJoin() ?
5552
 
                                    prev_table->getNestedJoin()->used_tables :
 
5393
        prev_table->dep_tables|= table->on_expr_dep_tables;
 
5394
        table_map prev_used_tables= prev_table->nested_join ?
 
5395
                                    prev_table->nested_join->used_tables :
5553
5396
                                    prev_table->table->map;
5554
5397
        /*
5555
5398
          If on expression contains only references to inner tables
5558
5401
          for them. Yet this is really a rare case.
5559
5402
              */
5560
5403
        if (!(prev_table->on_expr->used_tables() & ~prev_used_tables))
5561
 
          prev_table->setDepTables(prev_table->getDepTables() | used_tables);
 
5404
          prev_table->dep_tables|= used_tables;
5562
5405
      }
5563
5406
    }
5564
5407
    prev_table= table;
5571
5414
  li.rewind();
5572
5415
  while ((table= li++))
5573
5416
  {
5574
 
    nested_join= table->getNestedJoin();
 
5417
    nested_join= table->nested_join;
5575
5418
    if (nested_join && !table->on_expr)
5576
5419
    {
5577
5420
      TableList *tbl;
5578
5421
      List_iterator<TableList> it(nested_join->join_list);
5579
5422
      while ((tbl= it++))
5580
5423
      {
5581
 
        tbl->setEmbedding(table->getEmbedding());
5582
 
        tbl->setJoinList(table->getJoinList());
 
5424
        tbl->embedding= table->embedding;
 
5425
        tbl->join_list= table->join_list;
5583
5426
      }
5584
5427
      li.replace(nested_join->join_list);
5585
5428
    }
5587
5430
  return(conds);
5588
5431
}
5589
5432
 
5590
 
static int remove_duplicates(Join *join, Table *entry,List<Item> &fields, Item *having)
 
5433
static int remove_duplicates(JOIN *join, Table *entry,List<Item> &fields, Item *having)
5591
5434
{
5592
5435
  int error;
5593
5436
  uint32_t reclength,offset;
5611
5454
    join->unit->select_limit_cnt= 1;            // Only send first row
5612
5455
    return(0);
5613
5456
  }
5614
 
  Field **first_field=entry->getFields() + entry->getShare()->sizeFields() - field_count;
 
5457
  Field **first_field=entry->field+entry->s->fields - field_count;
5615
5458
  offset= (field_count ?
5616
 
           entry->getField(entry->getShare()->sizeFields() - field_count)->offset(entry->getInsertRecord()) : 0);
5617
 
  reclength= entry->getShare()->getRecordLength() - offset;
 
5459
           entry->field[entry->s->fields - field_count]->
 
5460
           offset(entry->record[0]) : 0);
 
5461
  reclength= entry->s->reclength-offset;
5618
5462
 
5619
5463
  entry->free_io_cache();                               // Safety
5620
 
  entry->cursor->info(HA_STATUS_VARIABLE);
5621
 
  if (entry->getShare()->db_type() == heap_engine ||
5622
 
      (!entry->getShare()->blob_fields &&
5623
 
       ((ALIGN_SIZE(reclength) + HASH_OVERHEAD) * entry->cursor->stats.records <
5624
 
        session->variables.sortbuff_size)))
5625
 
  {
 
5464
  entry->file->info(HA_STATUS_VARIABLE);
 
5465
  if (entry->s->db_type() == heap_engine ||
 
5466
      (!entry->s->blob_fields &&
 
5467
       ((ALIGN_SIZE(reclength) + HASH_OVERHEAD) * entry->file->stats.records <
 
5468
        session->variables.sortbuff_size)))
5626
5469
    error= remove_dup_with_hash_index(join->session, entry,
5627
 
                                      field_count, first_field,
5628
 
                                      reclength, having);
5629
 
  }
 
5470
                                     field_count, first_field,
 
5471
                                     reclength, having);
5630
5472
  else
5631
 
  {
5632
 
    error= remove_dup_with_compare(join->session, entry, first_field, offset, having);
5633
 
  }
 
5473
    error= remove_dup_with_compare(join->session, entry, first_field, offset,
 
5474
                                  having);
5634
5475
 
5635
5476
  free_blobs(first_field);
5636
 
 
5637
5477
  return(error);
5638
5478
}
5639
5479
 
5647
5487
                               List<Item> &fields,
5648
5488
                               List<Item> &all_fields,
5649
5489
                               COND **conds,
5650
 
                               Order *order,
5651
 
                               Order *group,
 
5490
                               order_st *order,
 
5491
                               order_st *group,
5652
5492
                               bool *hidden_group_fields)
5653
5493
{
5654
5494
  int res;
5675
5515
  @retval
5676
5516
    1   Fatal error
5677
5517
*/
5678
 
static bool make_join_statistics(Join *join, TableList *tables, COND *conds, DYNAMIC_ARRAY *keyuse_array)
 
5518
static bool make_join_statistics(JOIN *join, TableList *tables, COND *conds, DYNAMIC_ARRAY *keyuse_array)
5679
5519
{
5680
5520
  int error;
5681
5521
  Table *table;
5682
 
  uint32_t i;
5683
 
  uint32_t table_count;
5684
 
  uint32_t const_count;
5685
 
  uint32_t key;
5686
 
  table_map found_const_table_map;
5687
 
  table_map all_table_map;
5688
 
  table_map found_ref;
5689
 
  table_map refs;
5690
 
  key_map const_ref;
5691
 
  key_map eq_part;
5692
 
  Table **table_vector= NULL;
5693
 
  JoinTable *stat= NULL;
5694
 
  JoinTable *stat_end= NULL;
5695
 
  JoinTable *s= NULL;
5696
 
  JoinTable **stat_ref= NULL;
5697
 
  optimizer::KeyUse *keyuse= NULL;
5698
 
  optimizer::KeyUse *start_keyuse= NULL;
5699
 
  table_map outer_join= 0;
 
5522
  uint32_t i,table_count,const_count,key;
 
5523
  table_map found_const_table_map, all_table_map, found_ref, refs;
 
5524
  key_map const_ref, eq_part;
 
5525
  Table **table_vector;
 
5526
  JoinTable *stat,*stat_end,*s,**stat_ref;
 
5527
  optimizer::KeyUse *keyuse,*start_keyuse;
 
5528
  table_map outer_join=0;
5700
5529
  vector<optimizer::SargableParam> sargables;
5701
5530
  JoinTable *stat_vector[MAX_TABLES+1];
5702
5531
  optimizer::Position *partial_pos;
5703
5532
 
5704
 
  table_count= join->tables;
5705
 
  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));
 
5533
  table_count=join->tables;
 
5534
  stat=(JoinTable*) join->session->calloc(sizeof(JoinTable)*table_count);
 
5535
  stat_ref=(JoinTable**) join->session->alloc(sizeof(JoinTable*)*MAX_TABLES);
 
5536
  table_vector=(Table**) join->session->alloc(sizeof(Table*)*(table_count*2));
5708
5537
  if (! stat || ! stat_ref || ! table_vector)
5709
 
    return 1;
 
5538
    return 1;                           // Eom /* purecov: inspected */
5710
5539
 
5711
5540
  join->best_ref=stat_vector;
5712
5541
 
5718
5547
       tables;
5719
5548
       s++, tables= tables->next_leaf, i++)
5720
5549
  {
5721
 
    TableList *embedding= tables->getEmbedding();
 
5550
    TableList *embedding= tables->embedding;
5722
5551
    stat_vector[i]=s;
5723
5552
    s->keys.reset();
5724
5553
    s->const_keys.reset();
5726
5555
    s->needed_reg.reset();
5727
5556
    table_vector[i]=s->table=table=tables->table;
5728
5557
    table->pos_in_table_list= tables;
5729
 
    assert(table->cursor);
5730
 
    error= table->cursor->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
 
5558
    error= table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
5731
5559
    if (error)
5732
5560
    {
5733
 
        table->print_error(error, MYF(0));
 
5561
        table->file->print_error(error, MYF(0));
5734
5562
        return 1;
5735
5563
    }
5736
5564
    table->quick_keys.reset();
5737
5565
    table->reginfo.join_tab=s;
5738
5566
    table->reginfo.not_exists_optimize=0;
5739
5567
    memset(table->const_key_parts, 0,
5740
 
           sizeof(key_part_map)*table->getShare()->sizeKeys());
 
5568
           sizeof(key_part_map)*table->s->keys);
5741
5569
    all_table_map|= table->map;
5742
5570
    s->join=join;
5743
5571
    s->info=0;                                  // For describe
5744
5572
 
5745
 
    s->dependent= tables->getDepTables();
 
5573
    s->dependent= tables->dep_tables;
5746
5574
    s->key_dependent= 0;
5747
 
    table->quick_condition_rows= table->cursor->stats.records;
 
5575
    if (tables->schema_table)
 
5576
      table->file->stats.records= 2;
 
5577
    table->quick_condition_rows= table->file->stats.records;
5748
5578
 
5749
5579
    s->on_expr_ref= &tables->on_expr;
5750
5580
    if (*s->on_expr_ref)
5751
5581
    {
5752
5582
      /* s is the only inner table of an outer join */
5753
 
      if (!table->cursor->stats.records && !embedding)
 
5583
      if (!table->file->stats.records && !embedding)
5754
5584
      {                                         // Empty table
5755
5585
        s->dependent= 0;                        // Ignore LEFT JOIN depend.
5756
 
        set_position(join, const_count++, s, (optimizer::KeyUse*) 0);
 
5586
        set_position(join,const_count++,s,(optimizer::KeyUse*) 0);
5757
5587
        continue;
5758
5588
      }
5759
5589
      outer_join|= table->map;
5760
5590
      s->embedding_map.reset();
5761
 
      for (;embedding; embedding= embedding->getEmbedding())
5762
 
        s->embedding_map|= embedding->getNestedJoin()->nj_map;
 
5591
      for (;embedding; embedding= embedding->embedding)
 
5592
        s->embedding_map|= embedding->nested_join->nj_map;
5763
5593
      continue;
5764
5594
    }
5765
 
    if (embedding && !(false && ! embedding->getEmbedding()))
 
5595
    if (embedding && !(false && ! embedding->embedding))
5766
5596
    {
5767
5597
      /* s belongs to a nested join, maybe to several embedded joins */
5768
5598
      s->embedding_map.reset();
5769
5599
      do
5770
5600
      {
5771
 
        NestedJoin *nested_join= embedding->getNestedJoin();
 
5601
        nested_join_st *nested_join= embedding->nested_join;
5772
5602
        s->embedding_map|= nested_join->nj_map;
5773
 
        s->dependent|= embedding->getDepTables();
5774
 
        embedding= embedding->getEmbedding();
 
5603
        s->dependent|= embedding->dep_tables;
 
5604
        embedding= embedding->embedding;
5775
5605
        outer_join|= nested_join->used_tables;
5776
5606
      }
5777
5607
      while (embedding);
5778
5608
      continue;
5779
5609
    }
5780
 
    if ((table->cursor->stats.records <= 1) && !s->dependent &&
5781
 
              (table->cursor->getEngine()->check_flag(HTON_BIT_STATS_RECORDS_IS_EXACT)) &&
 
5610
    if ((table->file->stats.records <= 1) && !s->dependent &&
 
5611
              (table->file->ha_table_flags() & HA_STATS_RECORDS_IS_EXACT) && 
5782
5612
        !join->no_const_tables)
5783
5613
    {
5784
 
      set_position(join, const_count++, s, (optimizer::KeyUse*) 0);
 
5614
      set_position(join,const_count++,s,(optimizer::KeyUse*) 0);
5785
5615
    }
5786
5616
  }
5787
5617
  stat_vector[i]=0;
5797
5627
       As we use bitmaps to represent the relation the complexity
5798
5628
       of the algorithm is O((number of tables)^2).
5799
5629
    */
5800
 
    for (i= 0; i < table_count; i++)
 
5630
    for (i= 0, s= stat ; i < table_count ; i++, s++)
5801
5631
    {
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++)
 
5632
      for (uint32_t j= 0 ; j < table_count ; j++)
5809
5633
      {
 
5634
        table= stat[j].table;
5810
5635
        if (s->dependent & table->map)
5811
 
        {
5812
 
          table_map was_dependent= s->dependent;
5813
5636
          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
5637
      }
 
5638
      if (s->dependent)
 
5639
        s->table->maybe_null= 1;
5821
5640
    }
5822
5641
    /* Catch illegal cross references for outer joins */
5823
5642
    for (i= 0, s= stat ; i < table_count ; i++, s++)
5828
5647
        my_message(ER_WRONG_OUTER_JOIN, ER(ER_WRONG_OUTER_JOIN), MYF(0));
5829
5648
        return 1;
5830
5649
      }
5831
 
      if (outer_join & s->table->map)
5832
 
        s->table->maybe_null= 1;
5833
 
 
5834
5650
      s->key_dependent= s->dependent;
5835
5651
    }
5836
5652
  }
5852
5668
    s= p_pos->getJoinTable();
5853
5669
    s->type= AM_SYSTEM;
5854
5670
    join->const_table_map|=s->table->map;
5855
 
    if ((tmp= s->joinReadConstTable(p_pos)))
 
5671
    if ((tmp= join_read_const_table(s, p_pos)))
5856
5672
    {
5857
5673
      if (tmp > 0)
5858
5674
        return 1;                       // Fatal error
5875
5691
      set_position() will move all const_tables first in stat_vector
5876
5692
    */
5877
5693
 
5878
 
    for (JoinTable **pos= stat_vector+const_count; (s= *pos); pos++)
 
5694
    for (JoinTable **pos=stat_vector+const_count ; (s= *pos) ; pos++)
5879
5695
    {
5880
 
      table= s->table;
 
5696
      table=s->table;
5881
5697
 
5882
5698
      /*
5883
5699
        If equi-join condition by a key is null rejecting and after a
5896
5712
          TODO. Apply single row substitution to null complemented inner tables
5897
5713
          for nested outer join operations.
5898
5714
        */
5899
 
        while (keyuse->getTable() == table)
 
5715
        while (keyuse->table == table)
5900
5716
        {
5901
 
          if (! (keyuse->getVal()->used_tables() & ~join->const_table_map) &&
5902
 
              keyuse->getVal()->is_null() && keyuse->isNullRejected())
 
5717
          if (!(keyuse->val->used_tables() & ~join->const_table_map) &&
 
5718
              keyuse->val->is_null() && keyuse->null_rejecting)
5903
5719
          {
5904
5720
            s->type= AM_CONST;
5905
5721
            table->mark_as_null_row();
5906
5722
            found_const_table_map|= table->map;
5907
5723
            join->const_table_map|= table->map;
5908
 
            set_position(join, const_count++, s, (optimizer::KeyUse*) 0);
 
5724
            set_position(join,const_count++,s,(optimizer::KeyUse*) 0);
5909
5725
            goto more_const_tables_found;
5910
5726
           }
5911
5727
          keyuse++;
5917
5733
        // All dep. must be constants
5918
5734
        if (s->dependent & ~(found_const_table_map))
5919
5735
          continue;
5920
 
        if (table->cursor->stats.records <= 1L &&
5921
 
            (table->cursor->getEngine()->check_flag(HTON_BIT_STATS_RECORDS_IS_EXACT)) &&
5922
 
                  !table->pos_in_table_list->getEmbedding())
 
5736
        if (table->file->stats.records <= 1L &&
 
5737
            (table->file->ha_table_flags() & HA_STATS_RECORDS_IS_EXACT) &&
 
5738
                  !table->pos_in_table_list->embedding)
5923
5739
        {                                       // system table
5924
5740
          int tmp= 0;
5925
5741
          s->type= AM_SYSTEM;
5926
5742
          join->const_table_map|=table->map;
5927
 
          set_position(join, const_count++, s, (optimizer::KeyUse*) 0);
 
5743
          set_position(join,const_count++,s,(optimizer::KeyUse*) 0);
5928
5744
          partial_pos= join->getSpecificPosInPartialPlan(const_count - 1);
5929
 
          if ((tmp= s->joinReadConstTable(partial_pos)))
 
5745
          if ((tmp= join_read_const_table(s, partial_pos)))
5930
5746
          {
5931
5747
            if (tmp > 0)
5932
5748
              return 1;                 // Fatal error
5940
5756
      if ((keyuse=s->keyuse))
5941
5757
      {
5942
5758
        s->type= AM_REF;
5943
 
        while (keyuse->getTable() == table)
 
5759
        while (keyuse->table == table)
5944
5760
        {
5945
 
          start_keyuse= keyuse;
5946
 
          key= keyuse->getKey();
 
5761
          start_keyuse=keyuse;
 
5762
          key=keyuse->key;
5947
5763
          s->keys.set(key);               // QQ: remove this ?
5948
5764
 
5949
 
          refs= 0;
5950
 
          const_ref.reset();
 
5765
          refs=0;
 
5766
                const_ref.reset();
5951
5767
          eq_part.reset();
5952
5768
          do
5953
5769
          {
5954
 
            if (keyuse->getVal()->type() != Item::NULL_ITEM && 
5955
 
                ! keyuse->getOptimizeFlags())
 
5770
            if (keyuse->val->type() != Item::NULL_ITEM && !keyuse->optimize)
5956
5771
            {
5957
 
              if (! ((~found_const_table_map) & keyuse->getUsedTables()))
5958
 
                const_ref.set(keyuse->getKeypart());
 
5772
              if (!((~found_const_table_map) & keyuse->used_tables))
 
5773
                const_ref.set(keyuse->keypart);
5959
5774
              else
5960
 
                refs|= keyuse->getUsedTables();
5961
 
              eq_part.set(keyuse->getKeypart());
 
5775
                refs|=keyuse->used_tables;
 
5776
              eq_part.set(keyuse->keypart);
5962
5777
            }
5963
5778
            keyuse++;
5964
 
          } while (keyuse->getTable() == table && keyuse->getKey() == key);
 
5779
          } while (keyuse->table == table && keyuse->key == key);
5965
5780
 
5966
5781
          if (is_keymap_prefix(eq_part, table->key_info[key].key_parts) &&
5967
 
              ! table->pos_in_table_list->getEmbedding())
 
5782
              !table->pos_in_table_list->embedding)
5968
5783
          {
5969
5784
            if ((table->key_info[key].flags & (HA_NOSAME)) == HA_NOSAME)
5970
5785
            {
5974
5789
                ref_changed = 1;
5975
5790
                s->type= AM_CONST;
5976
5791
                join->const_table_map|= table->map;
5977
 
                set_position(join, const_count++, s, start_keyuse);
 
5792
                set_position(join,const_count++,s,start_keyuse);
5978
5793
                if (create_ref_for_key(join, s, start_keyuse, found_const_table_map))
5979
5794
                  return 1;
5980
5795
                partial_pos= join->getSpecificPosInPartialPlan(const_count - 1);
5981
 
                if ((tmp=s->joinReadConstTable(partial_pos)))
 
5796
                if ((tmp=join_read_const_table(s, partial_pos)))
5982
5797
                {
5983
5798
                  if (tmp > 0)
5984
5799
                    return 1;                   // Fatal error
6008
5823
    while (iter != sargables.end())
6009
5824
    {
6010
5825
      Field *field= (*iter).getField();
6011
 
      JoinTable *join_tab= field->getTable()->reginfo.join_tab;
 
5826
      JoinTable *join_tab= field->table->reginfo.join_tab;
6012
5827
      key_map possible_keys= field->key_start;
6013
 
      possible_keys&= field->getTable()->keys_in_use_for_query;
 
5828
      possible_keys&= field->table->keys_in_use_for_query;
6014
5829
      bool is_const= true;
6015
5830
      for (uint32_t j= 0; j < (*iter).getNumValues(); j++)
6016
5831
        is_const&= (*iter).isConstItem(j);
6031
5846
      continue;
6032
5847
    }
6033
5848
    /* Approximate found rows and time to read them */
6034
 
    s->found_records=s->records=s->table->cursor->stats.records;
6035
 
    s->read_time=(ha_rows) s->table->cursor->scan_time();
 
5849
    s->found_records=s->records=s->table->file->stats.records;
 
5850
    s->read_time=(ha_rows) s->table->file->scan_time();
6036
5851
 
6037
5852
    /*
6038
5853
      Set a max range of how many seeks we can expect when using keys
6051
5866
    add_group_and_distinct_keys(join, s);
6052
5867
 
6053
5868
    if (s->const_keys.any() &&
6054
 
        !s->table->pos_in_table_list->getEmbedding())
 
5869
        !s->table->pos_in_table_list->embedding)
6055
5870
    {
6056
5871
      ha_rows records;
6057
 
      optimizer::SqlSelect *select= NULL;
6058
 
      select= optimizer::make_select(s->table, found_const_table_map, found_const_table_map, *s->on_expr_ref ? *s->on_expr_ref : conds, 1, &error);
 
5872
      SQL_SELECT *select;
 
5873
      select= make_select(s->table, found_const_table_map, found_const_table_map, *s->on_expr_ref ? *s->on_expr_ref : conds, 1, &error);
6059
5874
      if (! select)
6060
5875
        return 1;
6061
5876
      records= get_quick_record_count(join->session, select, s->table, &s->const_keys, join->row_limit);
6062
5877
      s->quick=select->quick;
6063
5878
      s->needed_reg=select->needed_reg;
6064
5879
      select->quick=0;
6065
 
 
6066
5880
      if (records == 0 && s->table->reginfo.impossible_range)
6067
5881
      {
6068
5882
        /*
6072
5886
          caller to abort with a zero row result.
6073
5887
        */
6074
5888
        join->const_table_map|= s->table->map;
6075
 
        set_position(join, const_count++, s, (optimizer::KeyUse*) 0);
 
5889
        set_position(join,const_count++,s,(optimizer::KeyUse*) 0);
6076
5890
        s->type= AM_CONST;
6077
5891
        if (*s->on_expr_ref)
6078
5892
        {
6102
5916
  if (join->const_tables != join->tables)
6103
5917
  {
6104
5918
    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);
6108
 
    bool res= choose_plan(join, all_table_map & ~join->const_table_map);
6109
 
    DRIZZLE_QUERY_OPT_CHOOSE_PLAN_DONE(res ? 1 : 0);
6110
 
    if (res)
6111
 
      return true;
 
5919
    if (choose_plan(join, all_table_map & ~join->const_table_map))
 
5920
      return(true);
6112
5921
  }
6113
5922
  else
6114
5923
  {
6116
5925
    join->best_read= 1.0;
6117
5926
  }
6118
5927
  /* Generate an execution plan from the found optimal join order. */
6119
 
  return (join->session->getKilled() || get_best_combination(join));
 
5928
  return (join->session->killed || get_best_combination(join));
6120
5929
}
6121
5930
 
6122
5931
/**
6144
5953
  TableList *table;
6145
5954
  while ((table= li++))
6146
5955
  {
6147
 
    NestedJoin *nested_join;
6148
 
    if ((nested_join= table->getNestedJoin()))
 
5956
    nested_join_st *nested_join;
 
5957
    if ((nested_join= table->nested_join))
6149
5958
    {
6150
5959
      /*
6151
5960
        It is guaranteed by simplify_joins() function that a nested join
6176
5985
  Return table number if there is only one table in sort order
6177
5986
  and group and order is compatible, else return 0.
6178
5987
*/
6179
 
static Table *get_sort_by_table(Order *a, Order *b,TableList *tables)
 
5988
static Table *get_sort_by_table(order_st *a,order_st *b,TableList *tables)
6180
5989
{
6181
5990
  table_map map= (table_map) 0;
6182
5991
 
6201
6010
}
6202
6011
 
6203
6012
/**
6204
 
  Set NestedJoin::counter=0 in all nested joins in passed list.
 
6013
  Set nested_join_st::counter=0 in all nested joins in passed list.
6205
6014
 
6206
 
    Recursively set NestedJoin::counter=0 for all nested joins contained in
 
6015
    Recursively set nested_join_st::counter=0 for all nested joins contained in
6207
6016
    the passed join_list.
6208
6017
 
6209
6018
  @param join_list  List of nested joins to process. It may also contain base
6215
6024
  TableList *table;
6216
6025
  while ((table= li++))
6217
6026
  {
6218
 
    NestedJoin *nested_join;
6219
 
    if ((nested_join= table->getNestedJoin()))
 
6027
    nested_join_st *nested_join;
 
6028
    if ((nested_join= table->nested_join))
6220
6029
    {
6221
6030
      nested_join->counter_= 0;
6222
6031
      reset_nj_counters(&nested_join->join_list);
6231
6040
  If first parts has different direction, change it to second part
6232
6041
  (group is sorted like order)
6233
6042
*/
6234
 
static bool test_if_subpart(Order *a, Order *b)
 
6043
static bool test_if_subpart(order_st *a,order_st *b)
6235
6044
{
6236
6045
  for (; a && b; a=a->next,b=b->next)
6237
6046
  {
6246
6055
/**
6247
6056
  Nested joins perspective: Remove the last table from the join order.
6248
6057
 
6249
 
  The algorithm is the reciprocal of check_interleaving_with_nj(), hence
6250
 
  parent join nest nodes are updated only when the last table in its child
6251
 
  node is removed. The ASCII graphic below will clarify.
6252
 
 
6253
 
  %A table nesting such as <tt> t1 x [ ( t2 x t3 ) x ( t4 x t5 ) ] </tt>is
6254
 
  represented by the below join nest tree.
6255
 
 
6256
 
  @verbatim
6257
 
                     NJ1
6258
 
                  _/ /  \
6259
 
                _/  /    NJ2
6260
 
              _/   /     / \ 
6261
 
             /    /     /   \
6262
 
   t1 x [ (t2 x t3) x (t4 x t5) ]
6263
 
  @endverbatim
6264
 
 
6265
 
  At the point in time when check_interleaving_with_nj() adds the table t5 to
6266
 
  the query execution plan, QEP, it also directs the node named NJ2 to mark
6267
 
  the table as covered. NJ2 does so by incrementing its @c counter
6268
 
  member. Since all of NJ2's tables are now covered by the QEP, the algorithm
6269
 
  proceeds up the tree to NJ1, incrementing its counter as well. All join
6270
 
  nests are now completely covered by the QEP.
6271
 
 
6272
 
  restore_prev_nj_state() does the above in reverse. As seen above, the node
6273
 
  NJ1 contains the nodes t2, t3, and NJ2. Its counter being equal to 3 means
6274
 
  that the plan covers t2, t3, and NJ2, @e and that the sub-plan (t4 x t5)
6275
 
  completely covers NJ2. The removal of t5 from the partial plan will first
6276
 
  decrement NJ2's counter to 1. It will then detect that NJ2 went from being
6277
 
  completely to partially covered, and hence the algorithm must continue
6278
 
  upwards to NJ1 and decrement its counter to 2. %A subsequent removal of t4
6279
 
  will however not influence NJ1 since it did not un-cover the last table in
6280
 
  NJ2.
6281
 
 
6282
 
  SYNOPSIS
6283
 
    restore_prev_nj_state()
6284
 
      last  join table to remove, it is assumed to be the last in current 
6285
 
            partial join order.
6286
 
     
6287
 
  DESCRIPTION
6288
 
 
6289
6058
    Remove the last table from the partial join order and update the nested
6290
 
    joins counters and join->cur_embedding_map. It is ok to call this 
6291
 
    function for the first table in join order (for which 
 
6059
    joins counters and join->cur_embedding_map. It is ok to call this
 
6060
    function for the first table in join order (for which
6292
6061
    check_interleaving_with_nj has not been called)
6293
6062
 
6294
6063
  @param last  join table to remove, it is assumed to be the last in current
6295
6064
               partial join order.
6296
6065
*/
6297
 
 
6298
6066
static void restore_prev_nj_state(JoinTable *last)
6299
6067
{
6300
 
  TableList *last_emb= last->table->pos_in_table_list->getEmbedding();
6301
 
  Join *join= last->join;
6302
 
  for (;last_emb != NULL; last_emb= last_emb->getEmbedding())
6303
 
  {
6304
 
    NestedJoin *nest= last_emb->getNestedJoin();
6305
 
    
6306
 
    bool was_fully_covered= nest->is_fully_covered();
6307
 
    
6308
 
    if (--nest->counter_ == 0)
6309
 
      join->cur_embedding_map&= ~nest->nj_map;
6310
 
    
6311
 
    if (!was_fully_covered)
 
6068
  TableList *last_emb= last->table->pos_in_table_list->embedding;
 
6069
  JOIN *join= last->join;
 
6070
  while (last_emb)
 
6071
  {
 
6072
    if (last_emb->on_expr)
 
6073
    {
 
6074
      if (!(--last_emb->nested_join->counter_))
 
6075
        join->cur_embedding_map&= ~last_emb->nested_join->nj_map;
 
6076
      else if (last_emb->nested_join->join_list.elements-1 ==
 
6077
               last_emb->nested_join->counter_)
 
6078
        join->cur_embedding_map|= last_emb->nested_join->nj_map;
 
6079
      else
 
6080
        break;
 
6081
    }
 
6082
    last_emb= last_emb->embedding;
 
6083
  }
 
6084
}
 
6085
 
 
6086
/**
 
6087
  Determine if the set is already ordered for order_st BY, so it can
 
6088
  disable join cache because it will change the ordering of the results.
 
6089
  Code handles sort table that is at any location (not only first after
 
6090
  the const tables) despite the fact that it's currently prohibited.
 
6091
  We must disable join cache if the first non-const table alone is
 
6092
  ordered. If there is a temp table the ordering is done as a last
 
6093
  operation and doesn't prevent join cache usage.
 
6094
*/
 
6095
static uint32_t make_join_orderinfo(JOIN *join)
 
6096
{
 
6097
  uint32_t i;
 
6098
  if (join->need_tmp)
 
6099
    return join->tables;
 
6100
 
 
6101
  for (i=join->const_tables ; i < join->tables ; i++)
 
6102
  {
 
6103
    JoinTable *tab= join->join_tab+i;
 
6104
    Table *table= tab->table;
 
6105
    if ((table == join->sort_by_table &&
 
6106
        (!join->order || join->skip_sort_order)) ||
 
6107
        (join->sort_by_table == (Table *) 1 &&  i != join->const_tables))
 
6108
    {
6312
6109
      break;
6313
 
    
6314
 
    join->cur_embedding_map|= nest->nj_map;
 
6110
    }
6315
6111
  }
 
6112
  return i;
6316
6113
}
6317
6114
 
6318
6115
/**
6332
6129
 
6333
6130
  for (uint32_t i=0 ; i < join_tab->ref.key_parts ; i++)
6334
6131
  {
6335
 
    Field *field=table->getField(table->key_info[join_tab->ref.key].key_part[i].fieldnr - 1);
 
6132
    Field *field=table->field[table->key_info[join_tab->ref.key].key_part[i].
 
6133
                              fieldnr-1];
6336
6134
    Item *value=join_tab->ref.items[i];
6337
6135
    cond->add(new Item_func_equal(new Item_field(field), value));
6338
6136
  }
6346
6144
    error=(int) cond->add(join_tab->select->cond);
6347
6145
    join_tab->select_cond=join_tab->select->cond=cond;
6348
6146
  }
6349
 
  else if ((join_tab->select= optimizer::make_select(join_tab->table, 0, 0, cond, 0,
6350
 
                                                     &error)))
 
6147
  else if ((join_tab->select= make_select(join_tab->table, 0, 0, cond, 0,
 
6148
                                          &error)))
6351
6149
    join_tab->select_cond=cond;
6352
6150
 
6353
6151
  return(error ? true : false);
6365
6163
/**
6366
6164
  @} (end of group Query_Optimizer)
6367
6165
*/
6368
 
 
6369
 
} /* namespace drizzled */