~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/join.cc

Monty fixes pluss a few from me for charset.

Show diffs side-by-side

added added

removed removed

Lines of Context:
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"
45
42
#include "drizzled/join_cache.h"
46
43
#include "drizzled/show.h"
47
44
#include "drizzled/field/blob.h"
48
 
#include "drizzled/optimizer/position.h"
49
 
#include "drizzled/optimizer/sargable_param.h"
50
 
#include "drizzled/optimizer/key_use.h"
51
 
#include "drizzled/optimizer/range.h"
52
 
#include "drizzled/optimizer/sum.h"
53
 
#include "drizzled/optimizer/explain_plan.h"
54
 
#include "drizzled/optimizer/access_method_factory.h"
55
 
#include "drizzled/optimizer/access_method.h"
56
 
#include "drizzled/records.h"
57
 
#include "drizzled/probes.h"
58
 
#include "drizzled/internal/my_bit.h"
59
 
#include "drizzled/internal/my_sys.h"
60
 
#include "drizzled/internal/iocache.h"
 
45
#include "mysys/my_bit.h"
61
46
 
62
47
#include <algorithm>
63
48
 
64
49
using namespace std;
65
50
 
66
 
namespace drizzled
67
 
{
68
 
 
69
 
extern plugin::StorageEngine *heap_engine;
70
 
extern std::bitset<12> test_flags;
71
 
 
72
51
/** Declarations of static functions used in this source file. */
73
 
static bool make_group_fields(Join *main_join, Join *curr_join);
74
 
static void calc_group_buffer(Join *join, Order *group);
75
 
static bool alloc_group_fields(Join *join, Order *group);
76
 
static uint32_t cache_record_length(Join *join, uint32_t index);
77
 
static double prev_record_reads(Join *join, uint32_t idx, table_map found_ref);
78
 
static bool get_best_combination(Join *join);
79
 
static void set_position(Join *join,
80
 
                         uint32_t index,
81
 
                         JoinTable *table,
82
 
                         optimizer::KeyUse *key);
83
 
static bool choose_plan(Join *join,table_map join_tables);
84
 
static void best_access_path(Join *join, JoinTable *s,
 
52
static bool make_group_fields(JOIN *main_join, JOIN *curr_join);
 
53
static void calc_group_buffer(JOIN *join,order_st *group);
 
54
static bool alloc_group_fields(JOIN *join,order_st *group);
 
55
/*
 
56
  TODO: 'find_best' is here only temporarily until 'greedy_search' is
 
57
  tested and approved.
 
58
*/
 
59
static bool find_best(JOIN *join,table_map rest_tables,uint32_t index, double record_count,double read_time);
 
60
static uint32_t cache_record_length(JOIN *join, uint32_t index);
 
61
static double prev_record_reads(JOIN *join, uint32_t idx, table_map found_ref);
 
62
static bool get_best_combination(JOIN *join);
 
63
static void set_position(JOIN *join,uint32_t index,JoinTable *table,KeyUse *key);
 
64
static bool choose_plan(JOIN *join,table_map join_tables);
 
65
static void best_access_path(JOIN *join, JoinTable *s,
85
66
                             Session *session,
86
67
                             table_map remaining_tables,
87
68
                             uint32_t idx,
88
69
                             double record_count,
89
70
                             double read_time);
90
 
static void optimize_straight_join(Join *join, table_map join_tables);
91
 
static bool greedy_search(Join *join, table_map remaining_tables, uint32_t depth, uint32_t prune_level);
92
 
static bool best_extension_by_limited_search(Join *join,
 
71
static void optimize_straight_join(JOIN *join, table_map join_tables);
 
72
static bool greedy_search(JOIN *join, table_map remaining_tables, uint32_t depth, uint32_t prune_level);
 
73
static bool best_extension_by_limited_search(JOIN *join,
93
74
                                             table_map remaining_tables,
94
75
                                             uint32_t idx,
95
76
                                             double record_count,
96
77
                                             double read_time,
97
78
                                             uint32_t depth,
98
79
                                             uint32_t prune_level);
99
 
static uint32_t determine_search_depth(Join* join);
100
 
static bool make_simple_join(Join *join,Table *tmp_table);
101
 
static void make_outerjoin_info(Join *join);
102
 
static bool make_join_select(Join *join, optimizer::SqlSelect *select,COND *item);
103
 
static bool make_join_readinfo(Join *join);
104
 
static void update_depend_map(Join *join);
105
 
static void update_depend_map(Join *join, Order *order);
106
 
static Order *remove_constants(Join *join,Order *first_order,COND *cond, bool change_list, bool *simple_order);
107
 
static int return_zero_rows(Join *join,
 
80
static uint32_t determine_search_depth(JOIN* join);
 
81
static bool make_simple_join(JOIN *join,Table *tmp_table);
 
82
static void make_outerjoin_info(JOIN *join);
 
83
static bool make_join_select(JOIN *join,SQL_SELECT *select,COND *item);
 
84
static bool make_join_readinfo(JOIN *join, uint64_t options, uint32_t no_jbuf_after);
 
85
static void update_depend_map(JOIN *join);
 
86
static void update_depend_map(JOIN *join, order_st *order);
 
87
static order_st *remove_constants(JOIN *join,order_st *first_order,COND *cond, bool change_list, bool *simple_order);
 
88
static int return_zero_rows(JOIN *join,
108
89
                            select_result *res,
109
90
                            TableList *tables,
110
91
                            List<Item> &fields,
112
93
                            uint64_t select_options,
113
94
                            const char *info,
114
95
                            Item *having);
115
 
static COND *simplify_joins(Join *join, List<TableList> *join_list, COND *conds, bool top);
116
 
static int remove_duplicates(Join *join,Table *entry,List<Item> &fields, Item *having);
 
96
static COND *simplify_joins(JOIN *join, List<TableList> *join_list, COND *conds, bool top);
 
97
static int remove_duplicates(JOIN *join,Table *entry,List<Item> &fields, Item *having);
117
98
static int setup_without_group(Session *session, 
118
99
                               Item **ref_pointer_array,
119
100
                               TableList *tables,
121
102
                               List<Item> &fields,
122
103
                               List<Item> &all_fields,
123
104
                               COND **conds,
124
 
                               Order *order,
125
 
                               Order *group,
 
105
                               order_st *order,
 
106
                               order_st *group,
126
107
                               bool *hidden_group_fields);
127
 
static bool make_join_statistics(Join *join, TableList *leaves, COND *conds, DYNAMIC_ARRAY *keyuse);
 
108
static bool make_join_statistics(JOIN *join, TableList *leaves, COND *conds, DYNAMIC_ARRAY *keyuse);
128
109
static uint32_t build_bitmap_for_nested_joins(List<TableList> *join_list, uint32_t first_unused);
129
 
static Table *get_sort_by_table(Order *a, Order *b,TableList *tables);
 
110
static Table *get_sort_by_table(order_st *a,order_st *b,TableList *tables);
130
111
static void reset_nj_counters(List<TableList> *join_list);
131
 
static bool test_if_subpart(Order *a,Order *b);
 
112
static bool test_if_subpart(order_st *a,order_st *b);
132
113
static void restore_prev_nj_state(JoinTable *last);
 
114
static uint32_t make_join_orderinfo(JOIN *join);
133
115
static bool add_ref_to_table_cond(Session *session, JoinTable *join_tab);
134
116
static void free_blobs(Field **ptr); /* Rename this method...conflicts with another in global namespace... */
135
117
 
145
127
  @retval
146
128
    0   on success
147
129
*/
148
 
int Join::prepare(Item ***rref_pointer_array,
 
130
int JOIN::prepare(Item ***rref_pointer_array,
149
131
                  TableList *tables_init,
150
132
                  uint32_t wild_num,
151
133
                  COND *conds_init,
152
134
                  uint32_t og_num,
153
 
                  Order *order_init,
154
 
                  Order *group_init,
 
135
                  order_st *order_init,
 
136
                  order_st *group_init,
155
137
                  Item *having_init,
156
138
                  Select_Lex *select_lex_arg,
157
139
                  Select_Lex_Unit *unit_arg)
184
166
      setup_tables_and_check_access(session, &select_lex->context, join_list,
185
167
                                    tables_list, &select_lex->leaf_tables,
186
168
                                    false))
187
 
  {
188
169
      return(-1);
189
 
  }
190
170
 
191
171
  TableList *table_ptr;
192
172
  for (table_ptr= select_lex->leaf_tables;
193
173
       table_ptr;
194
174
       table_ptr= table_ptr->next_leaf)
195
 
  {
196
175
    tables++;
197
 
  }
198
 
 
199
176
 
200
177
  if (setup_wild(session, fields_list, &all_fields, wild_num) ||
201
178
      select_lex->setup_ref_array(session, og_num) ||
205
182
        select_lex->leaf_tables, fields_list,
206
183
        all_fields, &conds, order, group_list,
207
184
        &hidden_group_fields))
208
 
    return(-1);
 
185
    return(-1);       /* purecov: inspected */
209
186
 
210
187
  ref_pointer_array= *rref_pointer_array;
211
188
 
220
197
        having->check_cols(1)));
221
198
    select_lex->having_fix_field= 0;
222
199
    if (having_fix_rc || session->is_error())
223
 
      return(-1);
 
200
      return(-1);       /* purecov: inspected */
224
201
    session->lex->allow_sum_func= save_allow_sum_func;
225
202
  }
226
203
 
237
214
        in_subs= (Item_in_subselect*)subselect;
238
215
 
239
216
      {
240
 
        bool do_materialize= true;
 
217
        bool do_materialize= !test(session->variables.optimizer_switch &
 
218
                                   OPTIMIZER_SWITCH_NO_MATERIALIZATION);
241
219
        /*
242
220
          Check if the subquery predicate can be executed via materialization.
243
221
          The required conditions are:
255
233
             (Subquery is non-correlated ||
256
234
              Subquery is correlated to any query outer to IN predicate ||
257
235
              (Subquery is correlated to the immediate outer query &&
258
 
               Subquery !contains {GROUP BY, ORDER BY [LIMIT],
 
236
               Subquery !contains {GROUP BY, order_st BY [LIMIT],
259
237
               aggregate functions) && subquery predicate is not under "NOT IN"))
260
238
          6. No execution method was already chosen (by a prepared statement).
261
239
 
291
269
 
292
270
  if (order)
293
271
  {
294
 
    Order *ord;
 
272
    order_st *ord;
295
273
    for (ord= order; ord; ord= ord->next)
296
274
    {
297
275
      Item *item= *ord->item;
336
314
  {
337
315
    /* Caclulate the number of groups */
338
316
    send_group_parts= 0;
339
 
    for (Order *group_tmp= group_list ; group_tmp ; group_tmp= group_tmp->next)
 
317
    for (order_st *group_tmp= group_list ; group_tmp ; group_tmp= group_tmp->next)
340
318
      send_group_parts++;
341
319
  }
342
320
 
343
321
  if (error)
344
 
    return(-1);
 
322
    goto err;         /* purecov: inspected */
345
323
 
346
 
  /* 
347
 
   * The below will create the new table for
348
 
   * CREATE TABLE ... SELECT
349
 
   *
350
 
   * @see create_table_from_items() in drizzled/sql_insert.cc
351
 
   */
352
324
  if (result && result->prepare(fields_list, unit_arg))
353
 
    return(-1);
 
325
    goto err;         /* purecov: inspected */
354
326
 
355
327
  /* Init join struct */
356
328
  count_field_types(select_lex, &tmp_table_param, all_fields, 0);
362
334
  if (sum_func_count && !group_list && (func_count || field_count))
363
335
  {
364
336
    my_message(ER_WRONG_SUM_SELECT,ER(ER_WRONG_SUM_SELECT),MYF(0));
365
 
    return(-1);
 
337
    goto err;
366
338
  }
367
339
#endif
368
340
  if (select_lex->olap == ROLLUP_TYPE && rollup_init())
369
 
    return(-1);
370
 
 
 
341
    goto err;
371
342
  if (alloc_func_list())
372
 
    return(-1);
373
 
 
374
 
  return 0; // All OK
 
343
    goto err;
 
344
 
 
345
  return(0); // All OK
 
346
 
 
347
err:
 
348
  return(-1);       /* purecov: inspected */
375
349
}
376
350
 
377
351
/*
378
352
  Remove the predicates pushed down into the subquery
379
353
 
380
354
  SYNOPSIS
381
 
    Join::remove_subq_pushed_predicates()
 
355
    JOIN::remove_subq_pushed_predicates()
382
356
      where   IN  Must be NULL
383
357
              OUT The remaining WHERE condition, or NULL
384
358
 
403
377
    that is searched in a byte. But this requires homogenization of the return
404
378
    codes of all Field*::store() methods.
405
379
*/
406
 
void Join::remove_subq_pushed_predicates(Item **where)
 
380
void JOIN::remove_subq_pushed_predicates(Item **where)
407
381
{
408
382
  if (conds->type() == Item::FUNC_ITEM &&
409
383
      ((Item_func *)this->conds)->functype() == Item_func::EQ_FUNC &&
428
402
  @retval
429
403
    1   error
430
404
*/
431
 
int Join::optimize()
 
405
int JOIN::optimize()
432
406
{
433
407
  // to prevent double initialization on EXPLAIN
434
408
  if (optimized)
435
 
    return 0;
 
409
    return(0);
436
410
  optimized= 1;
437
411
 
438
412
  session->set_proc_info("optimizing");
478
452
  if (session->is_error())
479
453
  {
480
454
    error= 1;
481
 
    return 1;
 
455
    return(1);
482
456
  }
483
457
 
484
458
  {
486
460
    if (session->is_error())
487
461
    {
488
462
      error= 1;
489
 
      return 1;
 
463
      return(1);
490
464
    }
491
465
    if (select_lex->where)
492
466
      select_lex->cond_value= cond_value;
498
472
    {           /* Impossible cond */
499
473
      zero_result_cause=  having_value == Item::COND_FALSE ?
500
474
                           "Impossible HAVING" : "Impossible WHERE";
501
 
      tables = 0;
502
 
      goto setup_subq_exit;
 
475
      error= 0;
 
476
      return(0);
503
477
    }
504
478
  }
505
479
 
508
482
  {
509
483
    int res;
510
484
    /*
511
 
      optimizer::sum_query() returns HA_ERR_KEY_NOT_FOUND if no rows match
 
485
      opt_sum_query() returns HA_ERR_KEY_NOT_FOUND if no rows match
512
486
      to the WHERE conditions,
513
487
      or 1 if all items were resolved,
514
488
      or 0, or an error number HA_ERR_...
515
489
    */
516
 
    if ((res= optimizer::sum_query(select_lex->leaf_tables, all_fields, conds)))
 
490
    if ((res=opt_sum_query(select_lex->leaf_tables, all_fields, conds)))
517
491
    {
518
492
      if (res == HA_ERR_KEY_NOT_FOUND)
519
493
      {
520
494
        zero_result_cause= "No matching min/max row";
521
 
        tables = 0;
522
 
        goto setup_subq_exit;
 
495
        error=0;
 
496
        return(0);
523
497
      }
524
498
      if (res > 1)
525
499
      {
526
500
        error= res;
527
 
        return 1;
 
501
        return(1);
528
502
      }
529
503
      if (res < 0)
530
504
      {
531
505
        zero_result_cause= "No matching min/max row";
532
 
        tables = 0;
533
 
        goto setup_subq_exit;
 
506
        error=0;
 
507
        return(0);
534
508
      }
535
509
      zero_result_cause= "Select tables optimized away";
536
510
      tables_list= 0;       // All tables resolved
537
 
      const_tables= tables;
538
511
      /*
539
512
        Extract all table-independent conditions and replace the WHERE
540
 
        clause with them. All other conditions were computed by optimizer::sum_query
 
513
        clause with them. All other conditions were computed by opt_sum_query
541
514
        and the MIN/MAX/COUNT function(s) have been replaced by constants,
542
515
        so there is no need to compute the whole WHERE clause again.
543
516
        Notice that make_cond_for_table() will always succeed to remove all
544
 
        computed conditions, because optimizer::sum_query() is applicable only to
 
517
        computed conditions, because opt_sum_query() is applicable only to
545
518
        conjunctions.
546
519
        Preserve conditions for EXPLAIN.
547
520
      */
550
523
        COND *table_independent_conds= make_cond_for_table(conds, PSEUDO_TABLE_BITS, 0, 0);
551
524
        conds= table_independent_conds;
552
525
      }
553
 
      goto setup_subq_exit;
554
526
    }
555
527
  }
556
528
  if (!tables_list)
566
538
  if (make_join_statistics(this, select_lex->leaf_tables, conds, &keyuse) ||
567
539
      session->is_fatal_error)
568
540
  {
569
 
    return 1;
 
541
    return(1);
570
542
  }
571
543
 
572
544
  /* Remove distinct if only const tables */
574
546
  session->set_proc_info("preparing");
575
547
  if (result->initialize_tables(this))
576
548
  {
577
 
    return 1;        // error == -1
 
549
    return(1);        // error == -1
578
550
  }
579
551
  if (const_table_map != found_const_table_map &&
580
552
      !(select_options & SELECT_DESCRIBE) &&
583
555
       select_lex->master_unit() == &session->lex->unit)) // upper level SELECT
584
556
  {
585
557
    zero_result_cause= "no matching row in const table";
586
 
    goto setup_subq_exit;
 
558
    error= 0;
 
559
    return(0);
587
560
  }
588
561
  if (!(session->options & OPTION_BIG_SELECTS) &&
589
562
      best_read > (double) session->variables.max_join_size &&
590
563
      !(select_options & SELECT_DESCRIBE))
591
 
  {
 
564
  {           /* purecov: inspected */
592
565
    my_message(ER_TOO_BIG_SELECT, ER(ER_TOO_BIG_SELECT), MYF(0));
593
566
    error= -1;
594
 
    return 1;
 
567
    return(1);
595
568
  }
596
569
  if (const_tables && !(select_options & SELECT_NO_UNLOCK))
597
 
    session->unlockSomeTables(table, const_tables);
 
570
    mysql_unlock_some_tables(session, table, const_tables);
598
571
  if (!conds && outer_join)
599
572
  {
600
573
    /* Handle the case where we have an OUTER JOIN without a WHERE */
601
574
    conds=new Item_int((int64_t) 1,1);  // Always true
602
575
  }
603
 
  select= optimizer::make_select(*table, const_table_map,
604
 
                                 const_table_map, conds, 1, &error);
 
576
  select= make_select(*table, const_table_map,
 
577
                      const_table_map, conds, 1, &error);
605
578
  if (error)
606
 
  {
607
 
    error= -1;
608
 
    return 1;
 
579
  {           /* purecov: inspected */
 
580
    error= -1;          /* purecov: inspected */
 
581
    return(1);
609
582
  }
610
583
 
611
584
  reset_nj_counters(join_list);
644
617
  {
645
618
    conds=new Item_int((int64_t) 0,1);  // Always false
646
619
  }
647
 
 
648
620
  if (make_join_select(this, select, conds))
649
621
  {
650
622
    zero_result_cause=
651
623
      "Impossible WHERE noticed after reading const tables";
652
 
    goto setup_subq_exit;
 
624
    return(0);        // error == 0
653
625
  }
654
626
 
655
627
  error= -1;          /* if goto err */
656
628
 
657
629
  /* Optimize distinct away if possible */
658
630
  {
659
 
    Order *org_order= order;
 
631
    order_st *org_order= order;
660
632
    order= remove_constants(this, order,conds,1, &simple_order);
661
633
    if (session->is_error())
662
634
    {
663
635
      error= 1;
664
 
      return 1;
 
636
      return(1);
665
637
    }
666
638
 
667
639
    /*
668
 
      If we are using ORDER BY NULL or ORDER BY const_expression,
 
640
      If we are using order_st BY NULL or order_st BY const_expression,
669
641
      return result in any order (even if we are using a GROUP BY)
670
642
    */
671
643
    if (!order && org_order)
684
656
     The FROM clause must contain a single non-constant table.
685
657
  */
686
658
  if (tables - const_tables == 1 && (group_list || select_distinct) &&
687
 
      ! tmp_table_param.sum_func_count &&
688
 
      (! join_tab[const_tables].select ||
689
 
       ! join_tab[const_tables].select->quick ||
 
659
      !tmp_table_param.sum_func_count &&
 
660
      (!join_tab[const_tables].select ||
 
661
       !join_tab[const_tables].select->quick ||
690
662
       join_tab[const_tables].select->quick->get_type() !=
691
 
       optimizer::QuickSelectInterface::QS_TYPE_GROUP_MIN_MAX))
 
663
       QUICK_SELECT_I::QS_TYPE_GROUP_MIN_MAX))
692
664
  {
693
665
    if (group_list && list_contains_unique_index(join_tab[const_tables].table, find_field_in_order_list, (void *) group_list))
694
666
    {
696
668
        We have found that grouping can be removed since groups correspond to
697
669
        only one row anyway, but we still have to guarantee correct result
698
670
        order. The line below effectively rewrites the query from GROUP BY
699
 
        <fields> to ORDER BY <fields>. There are two exceptions:
 
671
        <fields> to order_st BY <fields>. There are two exceptions:
700
672
        - if skip_sort_order is set (see above), then we can simply skip
701
673
          GROUP BY;
702
 
        - we can only rewrite ORDER BY if the ORDER BY fields are 'compatible'
 
674
        - we can only rewrite order_st BY if the order_st BY fields are 'compatible'
703
675
          with the GROUP BY ones, i.e. either one is a prefix of another.
704
 
          We only check if the ORDER BY is a prefix of GROUP BY. In this case
 
676
          We only check if the order_st BY is a prefix of GROUP BY. In this case
705
677
          test_if_subpart() copies the ASC/DESC attributes from the original
706
 
          ORDER BY fields.
 
678
          order_st BY fields.
707
679
          If GROUP BY is a prefix of order_st BY, then it is safe to leave
708
680
          'order' as is.
709
681
       */
710
 
      if (! order || test_if_subpart(group_list, order))
 
682
      if (!order || test_if_subpart(group_list, order))
711
683
          order= skip_sort_order ? 0 : group_list;
712
684
      /*
713
685
        If we have an IGNORE INDEX FOR GROUP BY(fields) clause, this must be
742
714
      - We are scanning the whole table without LIMIT
743
715
        This can happen if:
744
716
        - We are using CALC_FOUND_ROWS
745
 
        - We are using an ORDER BY that can't be optimized away.
 
717
        - We are using an order_st BY that can't be optimized away.
746
718
 
747
719
      We don't want to use this optimization when we are using LIMIT
748
720
      because in this case we can just create a temporary table that
774
746
          {
775
747
            /*
776
748
              Force MySQL to read the table in sorted order to get result in
777
 
              ORDER BY order.
 
749
              order_st BY order.
778
750
            */
779
751
            tmp_table_param.quick_group=0;
780
752
          }
786
758
        group_list= 0;
787
759
    }
788
760
    else if (session->is_fatal_error)     // End of memory
789
 
      return 1;
 
761
      return(1);
790
762
  }
791
763
  simple_group= 0;
792
764
  {
793
 
    Order *old_group_list;
 
765
    order_st *old_group_list;
794
766
    group_list= remove_constants(this, (old_group_list= group_list), conds,
795
767
                                 rollup.state == ROLLUP::STATE_NONE,
796
768
                                 &simple_group);
797
769
    if (session->is_error())
798
770
    {
799
771
      error= 1;
800
 
      return 1;
 
772
      return(1);
801
773
    }
802
774
    if (old_group_list && !group_list)
803
775
      select_distinct= 0;
831
803
    This has to be done if all tables are not already read (const tables)
832
804
    and one of the following conditions holds:
833
805
    - We are using DISTINCT (simple distinct's are already optimized away)
834
 
    - We are using an ORDER BY or GROUP BY on fields not in the first table
835
 
    - We are using different ORDER BY and GROUP BY orders
 
806
    - We are using an order_st BY or GROUP BY on fields not in the first table
 
807
    - We are using different order_st BY and GROUP BY orders
836
808
    - The user wants us to buffer the result.
837
809
  */
838
810
  need_tmp= (const_tables != tables &&
840
812
        (group_list && order) ||
841
813
        test(select_options & OPTION_BUFFER_RESULT)));
842
814
 
 
815
  uint32_t no_jbuf_after= make_join_orderinfo(this);
 
816
  uint64_t select_opts_for_readinfo=
 
817
    (select_options & (SELECT_DESCRIBE | SELECT_NO_JOIN_CACHE)) | (0);
 
818
 
843
819
  // No cache for MATCH == 'Don't use join buffering when we use MATCH'.
844
 
  if (make_join_readinfo(this))
845
 
    return 1;
 
820
  if (make_join_readinfo(this, select_opts_for_readinfo, no_jbuf_after))
 
821
    return(1);
846
822
 
847
823
  /* Create all structures needed for materialized subquery execution. */
848
824
  if (setup_subquery_materialization())
849
 
    return 1;
850
 
 
851
 
  /* Cache constant expressions in WHERE, HAVING, ON clauses. */
852
 
  cache_const_exprs();
 
825
    return(1);
853
826
 
854
827
  /*
855
828
    is this simple IN subquery?
862
835
    if (!having)
863
836
    {
864
837
      Item *where= conds;
865
 
      if (join_tab[0].type == AM_EQ_REF && join_tab[0].ref.items[0]->name == in_left_expr_name)
 
838
      if (join_tab[0].type == JT_EQ_REF && join_tab[0].ref.items[0]->name == in_left_expr_name)
866
839
      {
867
840
        remove_subq_pushed_predicates(&where);
868
841
        save_index_subquery_explain_info(join_tab, where);
869
 
        join_tab[0].type= AM_UNIQUE_SUBQUERY;
 
842
        join_tab[0].type= JT_UNIQUE_SUBQUERY;
870
843
        error= 0;
871
 
        return(unit->item->change_engine(new subselect_uniquesubquery_engine(session, join_tab, unit->item, where)));
 
844
        return(unit->item->
 
845
                    change_engine(new
 
846
                                  subselect_uniquesubquery_engine(session,
 
847
                                                                  join_tab,
 
848
                                                                  unit->item,
 
849
                                                                  where)));
872
850
      }
873
 
      else if (join_tab[0].type == AM_REF &&
 
851
      else if (join_tab[0].type == JT_REF &&
874
852
         join_tab[0].ref.items[0]->name == in_left_expr_name)
875
853
      {
876
854
        remove_subq_pushed_predicates(&where);
877
855
        save_index_subquery_explain_info(join_tab, where);
878
 
        join_tab[0].type= AM_INDEX_SUBQUERY;
 
856
        join_tab[0].type= JT_INDEX_SUBQUERY;
879
857
        error= 0;
880
 
        return(unit->item->change_engine(new subselect_indexsubquery_engine(session, join_tab, unit->item, where, NULL, 0)));
 
858
        return(unit->item->
 
859
                    change_engine(new
 
860
                                  subselect_indexsubquery_engine(session,
 
861
                                                                 join_tab,
 
862
                                                                 unit->item,
 
863
                                                                 where,
 
864
                                                                 NULL,
 
865
                                                                 0)));
881
866
      }
882
867
    } 
883
 
    else if (join_tab[0].type == AM_REF_OR_NULL &&
 
868
    else if (join_tab[0].type == JT_REF_OR_NULL &&
884
869
         join_tab[0].ref.items[0]->name == in_left_expr_name &&
885
870
               having->name == in_having_cond)
886
871
    {
887
 
      join_tab[0].type= AM_INDEX_SUBQUERY;
 
872
      join_tab[0].type= JT_INDEX_SUBQUERY;
888
873
      error= 0;
889
874
      conds= remove_additional_cond(conds);
890
875
      save_index_subquery_explain_info(join_tab, conds);
891
 
      return(unit->item->change_engine(new subselect_indexsubquery_engine(session, join_tab, unit->item, conds, having, 1)));
 
876
      return(unit->item->
 
877
      change_engine(new subselect_indexsubquery_engine(session,
 
878
                   join_tab,
 
879
                   unit->item,
 
880
                   conds,
 
881
                                                                   having,
 
882
                   1)));
892
883
    }
893
884
 
894
885
  }
913
904
      as in other cases the join is done before the sort.
914
905
    */
915
906
    if ((order || group_list) &&
916
 
        (join_tab[const_tables].type != AM_ALL) &&
917
 
        (join_tab[const_tables].type != AM_REF_OR_NULL) &&
 
907
        (join_tab[const_tables].type != JT_ALL) &&
 
908
        (join_tab[const_tables].type != JT_REF_OR_NULL) &&
918
909
        ((order && simple_order) || (group_list && simple_group)))
919
910
    {
920
911
      if (add_ref_to_table_cond(session,&join_tab[const_tables])) {
921
 
        return 1;
 
912
        return(1);
922
913
      }
923
914
    }
924
915
 
940
931
        Force using of tmp table if sorting by a SP or UDF function due to
941
932
        their expensive and probably non-deterministic nature.
942
933
      */
943
 
      for (Order *tmp_order= order; tmp_order ; tmp_order=tmp_order->next)
 
934
      for (order_st *tmp_order= order; tmp_order ; tmp_order=tmp_order->next)
944
935
      {
945
936
        Item *item= *tmp_order->item;
946
937
        if (item->is_expensive())
984
975
 
985
976
    tmp_table_param.hidden_field_count= (all_fields.elements -
986
977
           fields_list.elements);
987
 
    Order *tmp_group= ((!simple_group &&
 
978
    order_st *tmp_group= ((!simple_group && 
988
979
                           ! (test_flags.test(TEST_NO_KEY_GROUP))) ? group_list :
989
 
                                                                     (Order*) 0);
 
980
                                                                     (order_st*) 0);
990
981
    /*
991
982
      Pushing LIMIT to the temporary table creation is not applicable
992
 
      when there is ORDER BY or GROUP BY or there is no GROUP BY, but
 
983
      when there is order_st BY or GROUP BY or there is no GROUP BY, but
993
984
      there are aggregate functions, because in all these cases we need
994
985
      all result rows.
995
986
    */
999
990
                            select_limit : HA_POS_ERROR;
1000
991
 
1001
992
    if (!(exec_tmp_table1=
1002
 
          create_tmp_table(session, &tmp_table_param, all_fields,
 
993
    create_tmp_table(session, &tmp_table_param, all_fields,
1003
994
                           tmp_group,
1004
 
                           group_list ? 0 : select_distinct,
1005
 
                           group_list && simple_group,
1006
 
                           select_options,
 
995
         group_list ? 0 : select_distinct,
 
996
         group_list && simple_group,
 
997
         select_options,
1007
998
                           tmp_rows_limit,
1008
 
                           (char *) "")))
 
999
         (char *) "")))
1009
1000
    {
1010
 
      return 1;
 
1001
      return(1);
1011
1002
    }
1012
1003
 
1013
1004
    /*
1033
1024
          make_sum_func_list(all_fields, fields_list, 1) ||
1034
1025
          setup_sum_funcs(session, sum_funcs))
1035
1026
      {
1036
 
        return 1;
 
1027
        return(1);
1037
1028
      }
1038
1029
      group_list=0;
1039
1030
    }
1042
1033
      if (make_sum_func_list(all_fields, fields_list, 0) ||
1043
1034
          setup_sum_funcs(session, sum_funcs))
1044
1035
      {
1045
 
        return 1;
 
1036
        return(1);
1046
1037
      }
1047
1038
 
1048
1039
      if (!group_list && ! exec_tmp_table1->distinct && order && simple_order)
1051
1042
        if (create_sort_index(session, this, order,
1052
1043
                              HA_POS_ERROR, HA_POS_ERROR, true))
1053
1044
        {
1054
 
          return 1;
 
1045
          return(1);
1055
1046
        }
1056
1047
        order=0;
1057
1048
      }
1089
1080
      If this join belongs to an uncacheable subquery save
1090
1081
      the original join
1091
1082
    */
1092
 
    if (select_lex->uncacheable.any() && 
1093
 
        ! is_top_level_join() &&
 
1083
    if (select_lex->uncacheable && !is_top_level_join() &&
1094
1084
        init_save_join_tab())
1095
 
    {
1096
 
      return -1;
1097
 
    }
 
1085
      return(-1);                         /* purecov: inspected */
1098
1086
  }
1099
1087
 
1100
1088
  error= 0;
1101
 
  return 0;
1102
 
 
1103
 
setup_subq_exit:
1104
 
  /* Even with zero matching rows, subqueries in the HAVING clause
1105
 
     may need to be evaluated if there are aggregate functions in the query.
1106
 
  */
1107
 
  if (setup_subquery_materialization())
1108
 
    return 1;
1109
 
  error= 0;
1110
 
  return 0;
 
1089
  return(0);
1111
1090
}
1112
1091
 
1113
1092
/**
1114
1093
  Restore values in temporary join.
1115
1094
*/
1116
 
void Join::restore_tmp()
 
1095
void JOIN::restore_tmp()
1117
1096
{
1118
 
  memcpy(tmp_join, this, (size_t) sizeof(Join));
 
1097
  memcpy(tmp_join, this, (size_t) sizeof(JOIN));
1119
1098
}
1120
1099
 
1121
 
int Join::reinit()
 
1100
int JOIN::reinit()
1122
1101
{
1123
1102
  unit->offset_limit_cnt= (ha_rows)(select_lex->offset_limit ?
1124
1103
                                    select_lex->offset_limit->val_uint() :
1128
1107
 
1129
1108
  if (exec_tmp_table1)
1130
1109
  {
1131
 
    exec_tmp_table1->cursor->extra(HA_EXTRA_RESET_STATE);
1132
 
    exec_tmp_table1->cursor->ha_delete_all_rows();
1133
 
    exec_tmp_table1->free_io_cache();
1134
 
    exec_tmp_table1->filesort_free_buffers();
 
1110
    exec_tmp_table1->file->extra(HA_EXTRA_RESET_STATE);
 
1111
    exec_tmp_table1->file->ha_delete_all_rows();
 
1112
    free_io_cache(exec_tmp_table1);
 
1113
    filesort_free_buffers(exec_tmp_table1,0);
1135
1114
  }
1136
1115
  if (exec_tmp_table2)
1137
1116
  {
1138
 
    exec_tmp_table2->cursor->extra(HA_EXTRA_RESET_STATE);
1139
 
    exec_tmp_table2->cursor->ha_delete_all_rows();
1140
 
    exec_tmp_table2->free_io_cache();
1141
 
    exec_tmp_table2->filesort_free_buffers();
 
1117
    exec_tmp_table2->file->extra(HA_EXTRA_RESET_STATE);
 
1118
    exec_tmp_table2->file->ha_delete_all_rows();
 
1119
    free_io_cache(exec_tmp_table2);
 
1120
    filesort_free_buffers(exec_tmp_table2,0);
1142
1121
  }
1143
1122
  if (items0)
1144
1123
    set_items_ref_array(items0);
1170
1149
   @retval 0      success.
1171
1150
   @retval 1      error occurred.
1172
1151
*/
1173
 
bool Join::init_save_join_tab()
 
1152
bool JOIN::init_save_join_tab()
1174
1153
{
1175
 
  if (!(tmp_join= (Join*)session->alloc(sizeof(Join))))
1176
 
    return 1;
1177
 
 
 
1154
  if (!(tmp_join= (JOIN*)session->alloc(sizeof(JOIN))))
 
1155
    return 1;                                  /* purecov: inspected */
1178
1156
  error= 0;              // Ensure that tmp_join.error= 0
1179
1157
  restore_tmp();
1180
 
 
1181
1158
  return 0;
1182
1159
}
1183
1160
 
1184
 
bool Join::save_join_tab()
 
1161
bool JOIN::save_join_tab()
1185
1162
{
1186
 
  if (! join_tab_save && select_lex->master_unit()->uncacheable.any())
 
1163
  if (!join_tab_save && select_lex->master_unit()->uncacheable)
1187
1164
  {
1188
1165
    if (!(join_tab_save= (JoinTable*)session->memdup((unsigned char*) join_tab,
1189
1166
            sizeof(JoinTable) * tables)))
1203
1180
  @todo
1204
1181
    When can we have here session->net.report_error not zero?
1205
1182
*/
1206
 
void Join::exec()
 
1183
void JOIN::exec()
1207
1184
{
1208
1185
  List<Item> *columns_list= &fields_list;
1209
1186
  int      tmp_error;
1215
1192
  {                                           
1216
1193
    /* Only test of functions */
1217
1194
    if (select_options & SELECT_DESCRIBE)
1218
 
    {
1219
 
      optimizer::ExplainPlan planner(this, 
1220
 
                                     false,
1221
 
                                     false,
1222
 
                                     false,
1223
 
                                     (zero_result_cause ? zero_result_cause : "No tables used"));
1224
 
      planner.printPlan();
1225
 
    }
 
1195
      select_describe(this, false, false, false, (zero_result_cause?zero_result_cause:"No tables used"));
1226
1196
    else
1227
1197
    {
1228
 
      result->send_fields(*columns_list);
 
1198
      result->send_fields(*columns_list, Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF);
1229
1199
      /*
1230
1200
        We have to test for 'conds' here as the WHERE may not be constant
1231
1201
        even if we don't have any tables for prepared statements or if
1273
1243
    return;
1274
1244
  }
1275
1245
 
 
1246
  if ((this->select_lex->options & OPTION_SCHEMA_TABLE) && get_schema_tables_result(this, PROCESSED_BY_JOIN_EXEC))
 
1247
    return;
 
1248
 
1276
1249
  if (select_options & SELECT_DESCRIBE)
1277
1250
  {
1278
1251
    /*
1279
 
      Check if we managed to optimize ORDER BY away and don't use temporary
 
1252
      Check if we managed to optimize order_st BY away and don't use temporary
1280
1253
      table to resolve order_st BY: in that case, we only may need to do
1281
1254
      filesort for GROUP BY.
1282
1255
    */
1295
1268
      order= 0;
1296
1269
    }
1297
1270
    having= tmp_having;
1298
 
    optimizer::ExplainPlan planner(this,
1299
 
                                   need_tmp,
1300
 
                                   order != 0 && ! skip_sort_order,
1301
 
                                   select_distinct,
1302
 
                                   ! tables ? "No tables used" : NULL);
1303
 
    planner.printPlan();
 
1271
    select_describe(this, need_tmp, order != 0 && !skip_sort_order,  select_distinct, !tables ? "No tables used" : NULL);
1304
1272
    return;
1305
1273
  }
1306
1274
 
1307
 
  Join *curr_join= this;
 
1275
  JOIN *curr_join= this;
1308
1276
  List<Item> *curr_all_fields= &all_fields;
1309
1277
  List<Item> *curr_fields_list= &fields_list;
1310
1278
  Table *curr_tmp_table= 0;
1339
1307
      error= tmp_error;
1340
1308
      return;
1341
1309
    }
1342
 
    curr_tmp_table->cursor->info(HA_STATUS_VARIABLE);
 
1310
    curr_tmp_table->file->info(HA_STATUS_VARIABLE);
1343
1311
 
1344
1312
    if (curr_join->having)
1345
1313
      curr_join->having= curr_join->tmp_having= 0; // Allready done
1414
1382
                                                   - curr_join->tmp_fields_list1.elements;
1415
1383
 
1416
1384
      if (exec_tmp_table2)
1417
 
      {
1418
1385
        curr_tmp_table= exec_tmp_table2;
1419
 
      }
1420
1386
      else
1421
1387
      {
1422
1388
        /* group data to new table */
1424
1390
        /*
1425
1391
          If the access method is loose index scan then all MIN/MAX
1426
1392
          functions are precomputed, and should be treated as regular
1427
 
          functions. See extended comment in Join::exec.
 
1393
          functions. See extended comment in JOIN::exec.
1428
1394
        */
1429
1395
        if (curr_join->join_tab->is_using_loose_index_scan())
1430
1396
          curr_join->tmp_table_param.precomputed_group_by= true;
1433
1399
              exec_tmp_table2= create_tmp_table(session,
1434
1400
                                                &curr_join->tmp_table_param,
1435
1401
                                                *curr_all_fields,
1436
 
                                                (Order*) 0,
 
1402
                                                (order_st*) 0,
1437
1403
                                                curr_join->select_distinct &&
1438
1404
                                                !curr_join->group_list,
1439
1405
                                                1, curr_join->select_options,
1440
1406
                                                HA_POS_ERROR,
1441
1407
                                                (char *) "")))
1442
 
        {
1443
1408
          return;
1444
 
        }
1445
 
 
1446
1409
        curr_join->exec_tmp_table2= exec_tmp_table2;
1447
1410
      }
1448
1411
      if (curr_join->group_list)
1490
1453
        error= tmp_error;
1491
1454
        return;
1492
1455
      }
1493
 
      curr_join->join_tab->read_record.end_read_record();
 
1456
      end_read_record(&curr_join->join_tab->read_record);
1494
1457
      curr_join->const_tables= curr_join->tables; // Mark free for cleanup()
1495
1458
      curr_join->join_tab[0].table= 0;           // Table is freed
1496
1459
 
1587
1550
      if (sort_table_cond)
1588
1551
      {
1589
1552
        if (!curr_table->select)
1590
 
          if (!(curr_table->select= new optimizer::SqlSelect))
 
1553
          if (!(curr_table->select= new SQL_SELECT))
1591
1554
            return;
1592
1555
        if (!curr_table->select->cond)
1593
1556
          curr_table->select->cond= sort_table_cond;
1679
1642
  curr_join->fields= curr_fields_list;
1680
1643
 
1681
1644
  session->set_proc_info("Sending data");
1682
 
  result->send_fields(*curr_fields_list);
 
1645
  result->send_fields(*curr_fields_list,
 
1646
                      Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF);
1683
1647
  error= do_select(curr_join, curr_fields_list, NULL);
1684
1648
  session->limit_found_rows= curr_join->send_records;
1685
1649
 
1701
1665
  Clean up join.
1702
1666
 
1703
1667
  @return
1704
 
    Return error that hold Join.
 
1668
    Return error that hold JOIN.
1705
1669
*/
1706
 
int Join::destroy()
 
1670
int JOIN::destroy()
1707
1671
{
1708
1672
  select_lex->join= 0;
1709
1673
 
1722
1686
  cond_equal= 0;
1723
1687
 
1724
1688
  cleanup(1);
1725
 
  exec_tmp_table1= NULL;
1726
 
  exec_tmp_table2= NULL;
 
1689
  if (exec_tmp_table1)
 
1690
    exec_tmp_table1->free_tmp_table(session);
 
1691
  if (exec_tmp_table2)
 
1692
    exec_tmp_table2->free_tmp_table(session);
1727
1693
  delete select;
1728
1694
  delete_dynamic(&keyuse);
1729
 
 
1730
1695
  return(error);
1731
1696
}
1732
1697
 
1739
1704
  - try to initialize all data structures needed for the materialized execution
1740
1705
    of the IN predicate,
1741
1706
  - if this fails, then perform the IN=>EXISTS transformation which was
1742
 
    previously blocked during Join::prepare.
 
1707
    previously blocked during JOIN::prepare.
1743
1708
 
1744
1709
  This method is part of the "code generation" query processing phase.
1745
1710
 
1752
1717
  @retval false     success.
1753
1718
  @retval true      error occurred.
1754
1719
*/
1755
 
bool Join::setup_subquery_materialization()
 
1720
bool JOIN::setup_subquery_materialization()
1756
1721
{
1757
1722
  for (Select_Lex_Unit *un= select_lex->first_inner_unit(); un;
1758
1723
       un= un->next_unit())
1774
1739
}
1775
1740
 
1776
1741
/**
1777
 
  Partially cleanup Join after it has executed: close index or rnd read
 
1742
  Partially cleanup JOIN after it has executed: close index or rnd read
1778
1743
  (table cursors), free quick selects.
1779
1744
 
1780
 
    This function is called in the end of execution of a Join, before the used
 
1745
    This function is called in the end of execution of a JOIN, before the used
1781
1746
    tables are unlocked and closed.
1782
1747
 
1783
1748
    For a join that is resolved using a temporary table, the first sweep is
1791
1756
    is called after all rows are sent, but before EOF packet is sent.
1792
1757
 
1793
1758
    For a simple SELECT with no subqueries this function performs a full
1794
 
    cleanup of the Join and calls unlockReadTables to free used base
 
1759
    cleanup of the JOIN and calls mysql_unlock_read_tables to free used base
1795
1760
    tables.
1796
1761
 
1797
 
    If a Join is executed for a subquery or if it has a subquery, we can't
 
1762
    If a JOIN is executed for a subquery or if it has a subquery, we can't
1798
1763
    do the full cleanup and need to do a partial cleanup only.
1799
 
    - If a Join is not the top level join, we must not unlock the tables
 
1764
    - If a JOIN is not the top level join, we must not unlock the tables
1800
1765
    because the outer select may not have been evaluated yet, and we
1801
1766
    can't unlock only selected tables of a query.
1802
 
    - Additionally, if this Join corresponds to a correlated subquery, we
 
1767
    - Additionally, if this JOIN corresponds to a correlated subquery, we
1803
1768
    should not free quick selects and join buffers because they will be
1804
1769
    needed for the next execution of the correlated subquery.
1805
 
    - However, if this is a Join for a [sub]select, which is not
 
1770
    - However, if this is a JOIN for a [sub]select, which is not
1806
1771
    a correlated subquery itself, but has subqueries, we can free it
1807
 
    fully and also free Joins of all its subqueries. The exception
 
1772
    fully and also free JOINs of all its subqueries. The exception
1808
1773
    is a subquery in SELECT list, e.g: @n
1809
1774
    SELECT a, (select cmax(b) from t1) group by c @n
1810
1775
    This subquery will not be evaluated at first sweep and its value will
1815
1780
  @todo
1816
1781
    Unlock tables even if the join isn't top level select in the tree
1817
1782
*/
1818
 
void Join::join_free()
 
1783
void JOIN::join_free()
1819
1784
{
1820
1785
  Select_Lex_Unit *tmp_unit;
1821
1786
  Select_Lex *sl;
1822
1787
  /*
1823
 
    Optimization: if not EXPLAIN and we are done with the Join,
 
1788
    Optimization: if not EXPLAIN and we are done with the JOIN,
1824
1789
    free all tables.
1825
1790
  */
1826
 
  bool full= (select_lex->uncacheable.none() && ! session->lex->describe);
 
1791
  bool full= (!select_lex->uncacheable && !session->lex->describe);
1827
1792
  bool can_unlock= full;
1828
1793
 
1829
1794
  cleanup(full);
1845
1810
        but all table cursors must be closed before the unlock.
1846
1811
      */
1847
1812
      sl->cleanup_all_joins(full_local);
1848
 
      /* Can't unlock if at least one Join is still needed */
 
1813
      /* Can't unlock if at least one JOIN is still needed */
1849
1814
      can_unlock= can_unlock && full_local;
1850
1815
    }
1851
1816
 
1863
1828
      TODO: unlock tables even if the join isn't top level select in the
1864
1829
      tree.
1865
1830
    */
1866
 
    session->unlockReadTables(lock);           // Don't free join->lock
 
1831
    mysql_unlock_read_tables(session, lock);           // Don't free join->lock
1867
1832
    lock= 0;
1868
1833
  }
1869
1834
 
1882
1847
    With subquery this function definitely will be called several times,
1883
1848
    but even for simple query it can be called several times.
1884
1849
*/
1885
 
void Join::cleanup(bool full)
 
1850
void JOIN::cleanup(bool full)
1886
1851
{
1887
1852
  if (table)
1888
1853
  {
1893
1858
    */
1894
1859
    if (tables > const_tables) // Test for not-const tables
1895
1860
    {
1896
 
      table[const_tables]->free_io_cache();
1897
 
      table[const_tables]->filesort_free_buffers(full);
 
1861
      free_io_cache(table[const_tables]);
 
1862
      filesort_free_buffers(table[const_tables],full);
1898
1863
    }
1899
1864
 
1900
1865
    if (full)
1908
1873
      for (tab= join_tab, end= tab+tables; tab != end; tab++)
1909
1874
      {
1910
1875
        if (tab->table)
1911
 
          tab->table->cursor->ha_index_or_rnd_end();
 
1876
          tab->table->file->ha_index_or_rnd_end();
1912
1877
      }
1913
1878
    }
1914
1879
  }
1927
1892
    */
1928
1893
    tmp_table_param.copy_funcs.empty();
1929
1894
    /*
1930
 
      If we have tmp_join and 'this' Join is not tmp_join and
 
1895
      If we have tmp_join and 'this' JOIN is not tmp_join and
1931
1896
      tmp_table_param.copy_field's  of them are equal then we have to remove
1932
1897
      pointer to  tmp_table_param.copy_field from tmp_join, because it qill
1933
1898
      be removed in tmp_table_param.cleanup().
1946
1911
}
1947
1912
 
1948
1913
/*
1949
 
  used only in Join::clear
 
1914
  used only in JOIN::clear
1950
1915
*/
1951
 
static void clear_tables(Join *join)
 
1916
static void clear_tables(JOIN *join)
1952
1917
{
1953
1918
  /*
1954
1919
    must clear only the non-const tables, as const tables
1967
1932
  @retval
1968
1933
    1 Error
1969
1934
*/
1970
 
bool Join::alloc_func_list()
 
1935
bool JOIN::alloc_func_list()
1971
1936
{
1972
1937
  uint32_t func_count, group_parts;
1973
1938
 
1993
1958
    */
1994
1959
    if (order)
1995
1960
    {
1996
 
      Order *ord;
 
1961
      order_st *ord;
1997
1962
      for (ord= order; ord; ord= ord->next)
1998
1963
        group_parts++;
1999
1964
    }
2019
1984
  @retval
2020
1985
    1  error
2021
1986
*/
2022
 
bool Join::make_sum_func_list(List<Item> &field_list, 
 
1987
bool JOIN::make_sum_func_list(List<Item> &field_list, 
2023
1988
                              List<Item> &send_fields,
2024
1989
                              bool before_group_by, 
2025
1990
                              bool recompute)
2057
2022
}
2058
2023
 
2059
2024
/** Allocate memory needed for other rollup functions. */
2060
 
bool Join::rollup_init()
 
2025
bool JOIN::rollup_init()
2061
2026
{
2062
2027
  uint32_t i,j;
2063
2028
  Item **ref_array;
2103
2068
  Item *item;
2104
2069
  while ((item= it++))
2105
2070
  {
2106
 
    Order *group_tmp;
 
2071
    order_st *group_tmp;
2107
2072
    bool found_in_group= 0;
2108
2073
 
2109
2074
    for (group_tmp= group_list; group_tmp; group_tmp= group_tmp->next)
2132
2097
            return 1;
2133
2098
          new_item->fix_fields(session, (Item **) 0);
2134
2099
          session->change_item_tree(it.ref(), new_item);
2135
 
          for (Order *tmp= group_tmp; tmp; tmp= tmp->next)
 
2100
          for (order_st *tmp= group_tmp; tmp; tmp= tmp->next)
2136
2101
          {
2137
2102
            if (*tmp->item == item)
2138
2103
              session->change_item_tree(tmp->item, new_item);
2172
2137
  @retval
2173
2138
    1    on error
2174
2139
*/
2175
 
bool Join::rollup_make_fields(List<Item> &fields_arg, List<Item> &sel_fields, Item_sum ***func)
 
2140
bool JOIN::rollup_make_fields(List<Item> &fields_arg, List<Item> &sel_fields, Item_sum ***func)
2176
2141
{
2177
2142
  List_iterator_fast<Item> it(fields_arg);
2178
2143
  Item *first_field= sel_fields.head();
2207
2172
    Item *item;
2208
2173
    List_iterator<Item> new_it(rollup.fields[pos]);
2209
2174
    Item **ref_array_start= rollup.ref_pointer_arrays[pos];
2210
 
    Order *start_group;
 
2175
    order_st *start_group;
2211
2176
 
2212
2177
    /* Point to first hidden field */
2213
2178
    Item **ref_array= ref_array_start + fields_arg.elements-1;
2249
2214
      else
2250
2215
      {
2251
2216
        /* Check if this is something that is part of this group by */
2252
 
        Order *group_tmp;
 
2217
        order_st *group_tmp;
2253
2218
        for (group_tmp= start_group, i= pos ;
2254
2219
                  group_tmp ; group_tmp= group_tmp->next, i++)
2255
2220
        {
2302
2267
  @retval
2303
2268
    1   If send_data_failed()
2304
2269
*/
2305
 
int Join::rollup_send_data(uint32_t idx)
 
2270
int JOIN::rollup_send_data(uint32_t idx)
2306
2271
{
2307
2272
  uint32_t i;
2308
2273
  for (i= send_group_parts ; i-- > idx ; )
2342
2307
  @retval
2343
2308
    1   if write_data_failed()
2344
2309
*/
2345
 
int Join::rollup_write_data(uint32_t idx, Table *table_arg)
 
2310
int JOIN::rollup_write_data(uint32_t idx, Table *table_arg)
2346
2311
{
2347
2312
  uint32_t i;
2348
2313
  for (i= send_group_parts ; i-- > idx ; )
2349
2314
  {
2350
2315
    /* Get reference pointers to sum functions in place */
2351
2316
    memcpy(ref_pointer_array, rollup.ref_pointer_arrays[i],
2352
 
           ref_pointer_array_size);
 
2317
     ref_pointer_array_size);
2353
2318
    if ((!having || having->val_int()))
2354
2319
    {
2355
2320
      int write_error;
2361
2326
          item->save_in_result_field(1);
2362
2327
      }
2363
2328
      copy_sum_funcs(sum_funcs_end[i+1], sum_funcs_end[i]);
2364
 
      if ((write_error= table_arg->cursor->insertRecord(table_arg->getInsertRecord())))
 
2329
      if ((write_error= table_arg->file->ha_write_row(table_arg->record[0])))
2365
2330
      {
2366
 
        my_error(ER_USE_SQL_BIG_RESULT, MYF(0));
2367
 
        return 1;
 
2331
  if (create_myisam_from_heap(session, table_arg,
 
2332
                                    tmp_table_param.start_recinfo,
 
2333
                                    &tmp_table_param.recinfo,
 
2334
                                    write_error, 0))
 
2335
    return 1;
2368
2336
      }
2369
2337
    }
2370
2338
  }
2377
2345
  clear results if there are not rows found for group
2378
2346
  (end_send_group/end_write_group)
2379
2347
*/
2380
 
void Join::clear()
 
2348
void JOIN::clear()
2381
2349
{
2382
2350
  clear_tables(this);
2383
2351
  copy_fields(&tmp_table_param);
2391
2359
}
2392
2360
 
2393
2361
/**
2394
 
  change select_result object of Join.
 
2362
  change select_result object of JOIN.
2395
2363
 
2396
2364
  @param res    new select_result object
2397
2365
 
2400
2368
  @retval
2401
2369
    true    error
2402
2370
*/
2403
 
bool Join::change_result(select_result *res)
 
2371
bool JOIN::change_result(select_result *res)
2404
2372
{
2405
2373
  result= res;
2406
2374
  if (result->prepare(fields_list, select_lex->master_unit()))
2411
2379
}
2412
2380
 
2413
2381
/**
2414
 
  Cache constant expressions in WHERE, HAVING, ON conditions.
 
2382
  Give error if we some tables are done with a full join.
 
2383
 
 
2384
  This is used by multi_table_update and multi_table_delete when running
 
2385
  in safe mode.
 
2386
 
 
2387
  @param join           Join condition
 
2388
 
 
2389
  @retval
 
2390
    0   ok
 
2391
  @retval
 
2392
    1   Error (full join used)
2415
2393
*/
2416
 
 
2417
 
void Join::cache_const_exprs()
 
2394
bool error_if_full_join(JOIN *join)
2418
2395
{
2419
 
  bool cache_flag= false;
2420
 
  bool *analyzer_arg= &cache_flag;
2421
 
 
2422
 
  /* No need in cache if all tables are constant. */
2423
 
  if (const_tables == tables)
2424
 
    return;
2425
 
 
2426
 
  if (conds)
2427
 
    conds->compile(&Item::cache_const_expr_analyzer, (unsigned char **)&analyzer_arg,
2428
 
                  &Item::cache_const_expr_transformer, (unsigned char *)&cache_flag);
2429
 
  cache_flag= false;
2430
 
  if (having)
2431
 
    having->compile(&Item::cache_const_expr_analyzer, (unsigned char **)&analyzer_arg,
2432
 
                    &Item::cache_const_expr_transformer, (unsigned char *)&cache_flag);
2433
 
 
2434
 
  for (JoinTable *tab= join_tab + const_tables; tab < join_tab + tables ; tab++)
 
2396
  for (JoinTable *tab= join->join_tab, *end= join->join_tab+join->tables; tab < end; tab++)
2435
2397
  {
2436
 
    if (*tab->on_expr_ref)
 
2398
    if (tab->type == JT_ALL && (!tab->select || !tab->select->quick))
2437
2399
    {
2438
 
      cache_flag= false;
2439
 
      (*tab->on_expr_ref)->compile(&Item::cache_const_expr_analyzer,
2440
 
                                 (unsigned char **)&analyzer_arg,
2441
 
                                 &Item::cache_const_expr_transformer,
2442
 
                                 (unsigned char *)&cache_flag);
 
2400
      my_message(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE,
 
2401
                 ER(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE), MYF(0));
 
2402
      return(1);
2443
2403
    }
2444
2404
  }
 
2405
  return(0);
2445
2406
}
2446
2407
 
2447
2408
/**
2455
2416
  applicable to the partial record on hand and in case of success
2456
2417
  submit this record to the next level of the nested loop.
2457
2418
*/
2458
 
enum_nested_loop_state evaluate_join_record(Join *join, JoinTable *join_tab, int error)
 
2419
enum_nested_loop_state evaluate_join_record(JOIN *join, JoinTable *join_tab, int error)
2459
2420
{
2460
2421
  bool not_used_in_distinct= join_tab->not_used_in_distinct;
2461
2422
  ha_rows found_records= join->found_records;
2465
2426
    return NESTED_LOOP_ERROR;
2466
2427
  if (error < 0)
2467
2428
    return NESTED_LOOP_NO_MORE_ROWS;
2468
 
  if (join->session->getKilled())                       // Aborted by user
 
2429
  if (join->session->killed)                    // Aborted by user
2469
2430
  {
2470
2431
    join->session->send_kill_message();
2471
 
    return NESTED_LOOP_KILLED;
 
2432
    return NESTED_LOOP_KILLED;               /* purecov: inspected */
2472
2433
  }
2473
2434
  if (!select_cond || select_cond->val_int())
2474
2435
  {
2558
2519
        return NESTED_LOOP_NO_MORE_ROWS;
2559
2520
    }
2560
2521
    else
2561
 
      join_tab->read_record.cursor->unlock_row();
 
2522
      join_tab->read_record.file->unlock_row();
2562
2523
  }
2563
2524
  else
2564
2525
  {
2568
2529
    */
2569
2530
    join->examined_rows++;
2570
2531
    join->session->row_count++;
2571
 
    join_tab->read_record.cursor->unlock_row();
 
2532
    join_tab->read_record.file->unlock_row();
2572
2533
  }
2573
2534
  return NESTED_LOOP_OK;
2574
2535
}
2579
2540
    level of the nested loop. This function is used in case we have
2580
2541
    an OUTER join and no matching record was found.
2581
2542
*/
2582
 
enum_nested_loop_state evaluate_null_complemented_join_record(Join *join, JoinTable *join_tab)
 
2543
enum_nested_loop_state evaluate_null_complemented_join_record(JOIN *join, JoinTable *join_tab)
2583
2544
{
2584
2545
  /*
2585
2546
    The table join_tab is the first inner table of a outer join operation
2635
2596
  return (*join_tab->next_select)(join, join_tab+1, 0);
2636
2597
}
2637
2598
 
2638
 
enum_nested_loop_state flush_cached_records(Join *join, JoinTable *join_tab, bool skip_last)
 
2599
enum_nested_loop_state flush_cached_records(JOIN *join, JoinTable *join_tab, bool skip_last)
2639
2600
{
2640
2601
  enum_nested_loop_state rc= NESTED_LOOP_OK;
2641
2602
  int error;
2642
 
  ReadRecord *info;
 
2603
  READ_RECORD *info;
2643
2604
 
2644
2605
  join_tab->table->null_row= 0;
2645
2606
  if (!join_tab->cache.records)
2646
 
  {
2647
2607
    return NESTED_LOOP_OK;                      /* Nothing to do */
2648
 
  }
2649
 
 
2650
2608
  if (skip_last)
2651
 
  {
2652
 
    (void) join_tab->cache.store_record_in_cache(); // Must save this for later
2653
 
  }
2654
 
 
2655
 
 
 
2609
    (void) store_record_in_cache(&join_tab->cache); // Must save this for later
2656
2610
  if (join_tab->use_quick == 2)
2657
2611
  {
2658
2612
    if (join_tab->select->quick)
2664
2618
  /* read through all records */
2665
2619
  if ((error=join_init_read_record(join_tab)))
2666
2620
  {
2667
 
    join_tab->cache.reset_cache_write();
 
2621
    reset_cache_write(&join_tab->cache);
2668
2622
    return error < 0 ? NESTED_LOOP_NO_MORE_ROWS: NESTED_LOOP_ERROR;
2669
2623
  }
2670
2624
 
2677
2631
  info= &join_tab->read_record;
2678
2632
  do
2679
2633
  {
2680
 
    if (join->session->getKilled())
 
2634
    if (join->session->killed)
2681
2635
    {
2682
2636
      join->session->send_kill_message();
2683
 
      return NESTED_LOOP_KILLED;
 
2637
      return NESTED_LOOP_KILLED; // Aborted by user /* purecov: inspected */
2684
2638
    }
2685
 
    optimizer::SqlSelect *select= join_tab->select;
 
2639
    SQL_SELECT *select=join_tab->select;
2686
2640
    if (rc == NESTED_LOOP_OK &&
2687
2641
        (!join_tab->cache.select || !join_tab->cache.select->skip_record()))
2688
2642
    {
2689
2643
      uint32_t i;
2690
 
      join_tab->cache.reset_cache_read();
 
2644
      reset_cache_read(&join_tab->cache);
2691
2645
      for (i=(join_tab->cache.records- (skip_last ? 1 : 0)) ; i-- > 0 ;)
2692
2646
      {
2693
2647
              join_tab->readCachedRecord();
2698
2652
          rc= (join_tab->next_select)(join,join_tab+1,0);
2699
2653
          if (rc != NESTED_LOOP_OK && rc != NESTED_LOOP_NO_MORE_ROWS)
2700
2654
          {
2701
 
            join_tab->cache.reset_cache_write();
 
2655
            reset_cache_write(&join_tab->cache);
2702
2656
            return rc;
2703
2657
          }
2704
2658
 
2711
2665
 
2712
2666
  if (skip_last)
2713
2667
    join_tab->readCachedRecord();               // Restore current record
2714
 
  join_tab->cache.reset_cache_write();
 
2668
  reset_cache_write(&join_tab->cache);
2715
2669
  if (error > 0)                                // Fatal error
2716
 
    return NESTED_LOOP_ERROR;
 
2670
    return NESTED_LOOP_ERROR;                   /* purecov: inspected */
2717
2671
  for (JoinTable *tmp2=join->join_tab; tmp2 != join_tab ; tmp2++)
2718
2672
    tmp2->table->status=tmp2->status;
2719
2673
  return NESTED_LOOP_OK;
2743
2697
                               operation.
2744
2698
   All return values except NESTED_LOOP_OK abort the nested loop.
2745
2699
*****************************************************************************/
2746
 
enum_nested_loop_state end_send(Join *join, JoinTable *, bool end_of_records)
 
2700
enum_nested_loop_state end_send(JOIN *join, JoinTable *, bool end_of_records)
2747
2701
{
2748
2702
  if (! end_of_records)
2749
2703
  {
2754
2708
    if (join->do_send_rows)
2755
2709
      error=join->result->send_data(*join->fields);
2756
2710
    if (error)
2757
 
      return NESTED_LOOP_ERROR;
 
2711
      return NESTED_LOOP_ERROR; /* purecov: inspected */
2758
2712
    if (++join->send_records >= join->unit->select_limit_cnt && join->do_send_rows)
2759
2713
    {
2760
2714
      if (join->select_options & OPTION_FOUND_ROWS)
2763
2717
        if ((join->tables == 1) && !join->tmp_table && !join->sort_and_group
2764
2718
            && !join->send_group_parts && !join->having && !jt->select_cond &&
2765
2719
            !(jt->select && jt->select->quick) &&
2766
 
            (jt->table->cursor->getEngine()->check_flag(HTON_BIT_STATS_RECORDS_IS_EXACT)) &&
 
2720
            (jt->table->file->ha_table_flags() & HA_STATS_RECORDS_IS_EXACT) &&
2767
2721
                  (jt->ref.key < 0))
2768
2722
        {
2769
2723
          /* Join over all rows in table;  Return number of found rows */
2778
2732
          }
2779
2733
          else
2780
2734
          {
2781
 
            table->cursor->info(HA_STATUS_VARIABLE);
2782
 
            join->send_records= table->cursor->stats.records;
 
2735
            table->file->info(HA_STATUS_VARIABLE);
 
2736
            join->send_records= table->file->stats.records;
2783
2737
          }
2784
2738
        }
2785
2739
        else
2805
2759
  return NESTED_LOOP_OK;
2806
2760
}
2807
2761
 
2808
 
enum_nested_loop_state end_write(Join *join, JoinTable *, bool end_of_records)
 
2762
enum_nested_loop_state end_write(JOIN *join, JoinTable *, bool end_of_records)
2809
2763
{
2810
2764
  Table *table= join->tmp_table;
2811
2765
 
2812
 
  if (join->session->getKilled())                       // Aborted by user
 
2766
  if (join->session->killed)                    // Aborted by user
2813
2767
  {
2814
2768
    join->session->send_kill_message();
2815
 
    return NESTED_LOOP_KILLED;
 
2769
    return NESTED_LOOP_KILLED;             /* purecov: inspected */
2816
2770
  }
2817
2771
  if (!end_of_records)
2818
2772
  {
2819
2773
    copy_fields(&join->tmp_table_param);
2820
 
    if (copy_funcs(join->tmp_table_param.items_to_copy, join->session))
2821
 
      return NESTED_LOOP_ERROR;
 
2774
    copy_funcs(join->tmp_table_param.items_to_copy);
2822
2775
    if (!join->having || join->having->val_int())
2823
2776
    {
2824
2777
      int error;
2825
2778
      join->found_records++;
2826
 
      if ((error=table->cursor->insertRecord(table->getInsertRecord())))
 
2779
      if ((error=table->file->ha_write_row(table->record[0])))
2827
2780
      {
2828
 
        if (!table->cursor->is_fatal_error(error, HA_CHECK_DUP))
2829
 
        {
2830
 
          return NESTED_LOOP_OK;
2831
 
        }
2832
 
 
2833
 
        my_error(ER_USE_SQL_BIG_RESULT, MYF(0));
2834
 
        return NESTED_LOOP_ERROR;        // Table is_full error
 
2781
        if (!table->file->is_fatal_error(error, HA_CHECK_DUP))
 
2782
          goto end;
 
2783
        if (create_myisam_from_heap(join->session, table,
 
2784
                                          join->tmp_table_param.start_recinfo,
 
2785
                                          &join->tmp_table_param.recinfo,
 
2786
                  error, 1))
 
2787
          return NESTED_LOOP_ERROR;        // Not a table_is_full error
 
2788
        table->s->uniques= 0;                   // To ensure rows are the same
2835
2789
      }
2836
2790
      if (++join->send_records >= join->tmp_table_param.end_write_records && join->do_send_rows)
2837
2791
      {
2843
2797
      }
2844
2798
    }
2845
2799
  }
2846
 
 
 
2800
end:
2847
2801
  return NESTED_LOOP_OK;
2848
2802
}
2849
2803
 
2850
2804
/** Group by searching after group record and updating it if possible. */
2851
 
enum_nested_loop_state end_update(Join *join, JoinTable *, bool end_of_records)
 
2805
enum_nested_loop_state end_update(JOIN *join, JoinTable *, bool end_of_records)
2852
2806
{
2853
2807
  Table *table= join->tmp_table;
2854
 
  Order *group;
 
2808
  order_st *group;
2855
2809
  int   error;
2856
2810
 
2857
2811
  if (end_of_records)
2858
2812
    return NESTED_LOOP_OK;
2859
 
  if (join->session->getKilled())                       // Aborted by user
 
2813
  if (join->session->killed)                    // Aborted by user
2860
2814
  {
2861
2815
    join->session->send_kill_message();
2862
 
    return NESTED_LOOP_KILLED;
 
2816
    return NESTED_LOOP_KILLED;             /* purecov: inspected */
2863
2817
  }
2864
2818
 
2865
2819
  join->found_records++;
2873
2827
    if (item->maybe_null)
2874
2828
      group->buff[-1]= (char) group->field->is_null();
2875
2829
  }
2876
 
  if (!table->cursor->index_read_map(table->getUpdateRecord(),
 
2830
  if (!table->file->index_read_map(table->record[1],
2877
2831
                                   join->tmp_table_param.group_buff,
2878
2832
                                   HA_WHOLE_KEY,
2879
2833
                                   HA_READ_KEY_EXACT))
2880
2834
  {                                             /* Update old record */
2881
2835
    table->restoreRecord();
2882
2836
    update_tmptable_sum_func(join->sum_funcs,table);
2883
 
    if ((error= table->cursor->updateRecord(table->getUpdateRecord(),
2884
 
                                          table->getInsertRecord())))
 
2837
    if ((error= table->file->ha_update_row(table->record[1],
 
2838
                                          table->record[0])))
2885
2839
    {
2886
 
      table->print_error(error,MYF(0));
2887
 
      return NESTED_LOOP_ERROR;
 
2840
      table->file->print_error(error,MYF(0));   /* purecov: inspected */
 
2841
      return NESTED_LOOP_ERROR;            /* purecov: inspected */
2888
2842
    }
2889
2843
    return NESTED_LOOP_OK;
2890
2844
  }
2894
2848
    We can't copy all data as the key may have different format
2895
2849
    as the row data (for example as with VARCHAR keys)
2896
2850
  */
2897
 
  KeyPartInfo *key_part;
 
2851
  KEY_PART_INFO *key_part;
2898
2852
  for (group=table->group,key_part=table->key_info[0].key_part;
2899
2853
       group ;
2900
2854
       group=group->next,key_part++)
2901
2855
  {
2902
2856
    if (key_part->null_bit)
2903
 
      memcpy(table->getInsertRecord()+key_part->offset, group->buff, 1);
 
2857
      memcpy(table->record[0]+key_part->offset, group->buff, 1);
2904
2858
  }
2905
2859
  init_tmptable_sum_functions(join->sum_funcs);
2906
 
  if (copy_funcs(join->tmp_table_param.items_to_copy, join->session))
2907
 
    return NESTED_LOOP_ERROR;
2908
 
  if ((error=table->cursor->insertRecord(table->getInsertRecord())))
 
2860
  copy_funcs(join->tmp_table_param.items_to_copy);
 
2861
  if ((error=table->file->ha_write_row(table->record[0])))
2909
2862
  {
2910
 
    my_error(ER_USE_SQL_BIG_RESULT, MYF(0));
2911
 
    return NESTED_LOOP_ERROR;        // Table is_full error
 
2863
    if (create_myisam_from_heap(join->session, table,
 
2864
                                join->tmp_table_param.start_recinfo,
 
2865
                                &join->tmp_table_param.recinfo,
 
2866
                                error, 0))
 
2867
      return NESTED_LOOP_ERROR;            // Not a table_is_full error
 
2868
    /* Change method to update rows */
 
2869
    table->file->ha_index_init(0, 0);
 
2870
    join->join_tab[join->tables-1].next_select= end_unique_update;
2912
2871
  }
2913
2872
  join->send_records++;
2914
2873
  return NESTED_LOOP_OK;
2915
2874
}
2916
2875
 
2917
2876
/** Like end_update, but this is done with unique constraints instead of keys.  */
2918
 
enum_nested_loop_state end_unique_update(Join *join, JoinTable *, bool end_of_records)
 
2877
enum_nested_loop_state end_unique_update(JOIN *join, JoinTable *, bool end_of_records)
2919
2878
{
2920
2879
  Table *table= join->tmp_table;
2921
2880
  int   error;
2922
2881
 
2923
2882
  if (end_of_records)
2924
2883
    return NESTED_LOOP_OK;
2925
 
  if (join->session->getKilled())                       // Aborted by user
 
2884
  if (join->session->killed)                    // Aborted by user
2926
2885
  {
2927
2886
    join->session->send_kill_message();
2928
 
    return NESTED_LOOP_KILLED;
 
2887
    return NESTED_LOOP_KILLED;             /* purecov: inspected */
2929
2888
  }
2930
2889
 
2931
2890
  init_tmptable_sum_functions(join->sum_funcs);
2932
2891
  copy_fields(&join->tmp_table_param);          // Groups are copied twice.
2933
 
  if (copy_funcs(join->tmp_table_param.items_to_copy, join->session))
2934
 
    return NESTED_LOOP_ERROR;
 
2892
  copy_funcs(join->tmp_table_param.items_to_copy);
2935
2893
 
2936
 
  if (!(error= table->cursor->insertRecord(table->getInsertRecord())))
 
2894
  if (!(error= table->file->ha_write_row(table->record[0])))
2937
2895
    join->send_records++;                       // New group
2938
2896
  else
2939
2897
  {
2940
 
    if ((int) table->get_dup_key(error) < 0)
 
2898
    if ((int) table->file->get_dup_key(error) < 0)
2941
2899
    {
2942
 
      table->print_error(error,MYF(0));
2943
 
      return NESTED_LOOP_ERROR;
 
2900
      table->file->print_error(error,MYF(0));   /* purecov: inspected */
 
2901
      return NESTED_LOOP_ERROR;            /* purecov: inspected */
2944
2902
    }
2945
 
    if (table->cursor->rnd_pos(table->getUpdateRecord(),table->cursor->dup_ref))
 
2903
    if (table->file->rnd_pos(table->record[1],table->file->dup_ref))
2946
2904
    {
2947
 
      table->print_error(error,MYF(0));
2948
 
      return NESTED_LOOP_ERROR;
 
2905
      table->file->print_error(error,MYF(0));   /* purecov: inspected */
 
2906
      return NESTED_LOOP_ERROR;            /* purecov: inspected */
2949
2907
    }
2950
2908
    table->restoreRecord();
2951
2909
    update_tmptable_sum_func(join->sum_funcs,table);
2952
 
    if ((error= table->cursor->updateRecord(table->getUpdateRecord(),
2953
 
                                          table->getInsertRecord())))
 
2910
    if ((error= table->file->ha_update_row(table->record[1],
 
2911
                                          table->record[0])))
2954
2912
    {
2955
 
      table->print_error(error,MYF(0));
2956
 
      return NESTED_LOOP_ERROR;
 
2913
      table->file->print_error(error,MYF(0));   /* purecov: inspected */
 
2914
      return NESTED_LOOP_ERROR;            /* purecov: inspected */
2957
2915
    }
2958
2916
  }
2959
2917
  return NESTED_LOOP_OK;
2971
2929
  @retval
2972
2930
    1   failed
2973
2931
*/
2974
 
static bool make_group_fields(Join *main_join, Join *curr_join)
 
2932
static bool make_group_fields(JOIN *main_join, JOIN *curr_join)
2975
2933
{
2976
2934
  if (main_join->group_fields_cache.elements)
2977
2935
  {
2981
2939
  else
2982
2940
  {
2983
2941
    if (alloc_group_fields(curr_join, curr_join->group_list))
2984
 
      return 1;
 
2942
      return (1);
2985
2943
    main_join->group_fields_cache= curr_join->group_fields;
2986
2944
  }
2987
2945
  return (0);
2990
2948
/**
2991
2949
  calc how big buffer we need for comparing group entries.
2992
2950
*/
2993
 
static void calc_group_buffer(Join *join, Order *group)
 
2951
static void calc_group_buffer(JOIN *join,order_st *group)
2994
2952
{
2995
2953
  uint32_t key_length=0, parts=0, null_parts=0;
2996
2954
 
3016
2974
      case REAL_RESULT:
3017
2975
        key_length+= sizeof(double);
3018
2976
        break;
3019
 
 
3020
2977
      case INT_RESULT:
3021
2978
        key_length+= sizeof(int64_t);
3022
2979
        break;
3023
 
 
3024
2980
      case DECIMAL_RESULT:
3025
2981
        key_length+= my_decimal_get_binary_size(group_item->max_length -
3026
2982
                                                (group_item->decimals ? 1 : 0),
3027
2983
                                                group_item->decimals);
3028
2984
        break;
3029
 
 
3030
2985
      case STRING_RESULT:
3031
 
        {
3032
 
          enum enum_field_types type= group_item->field_type();
 
2986
      {
 
2987
        enum enum_field_types type= group_item->field_type();
 
2988
        /*
 
2989
          As items represented as DATE/TIME fields in the group buffer
 
2990
          have STRING_RESULT result type, we increase the length
 
2991
          by 8 as maximum pack length of such fields.
 
2992
        */
 
2993
        if (type == DRIZZLE_TYPE_DATE ||
 
2994
            type == DRIZZLE_TYPE_DATETIME ||
 
2995
            type == DRIZZLE_TYPE_TIMESTAMP)
 
2996
        {
 
2997
          key_length+= 8;
 
2998
        }
 
2999
        else
 
3000
        {
3033
3001
          /*
3034
 
            As items represented as DATE/TIME fields in the group buffer
3035
 
            have STRING_RESULT result type, we increase the length
3036
 
            by 8 as maximum pack length of such fields.
 
3002
            Group strings are taken as varstrings and require an length field.
 
3003
            A field is not yet created by create_tmp_field()
 
3004
            and the sizes should match up.
3037
3005
          */
3038
 
          if (type == DRIZZLE_TYPE_DATE ||
3039
 
              type == DRIZZLE_TYPE_DATETIME ||
3040
 
              type == DRIZZLE_TYPE_TIMESTAMP)
3041
 
          {
3042
 
            key_length+= 8;
3043
 
          }
3044
 
          else
3045
 
          {
3046
 
            /*
3047
 
              Group strings are taken as varstrings and require an length field.
3048
 
              A field is not yet created by create_tmp_field()
3049
 
              and the sizes should match up.
3050
 
            */
3051
 
            key_length+= group_item->max_length + HA_KEY_BLOB_LENGTH;
3052
 
          }
3053
 
          break;
 
3006
          key_length+= group_item->max_length + HA_KEY_BLOB_LENGTH;
3054
3007
        }
3055
 
 
3056
 
      case ROW_RESULT:
 
3008
        break;
 
3009
      }
 
3010
      default:
3057
3011
        /* This case should never be choosen */
3058
3012
        assert(0);
3059
3013
        my_error(ER_OUT_OF_RESOURCES, MYF(ME_FATALERROR));
3060
3014
      }
3061
3015
    }
3062
 
 
3063
3016
    parts++;
3064
 
 
3065
3017
    if (group_item->maybe_null)
3066
3018
      null_parts++;
3067
3019
  }
3068
 
 
3069
3020
  join->tmp_table_param.group_length=key_length+null_parts;
3070
3021
  join->tmp_table_param.group_parts=parts;
3071
3022
  join->tmp_table_param.group_null_parts=null_parts;
3076
3027
 
3077
3028
  Groups are saved in reverse order for easyer check loop.
3078
3029
*/
3079
 
static bool alloc_group_fields(Join *join, Order *group)
 
3030
static bool alloc_group_fields(JOIN *join,order_st *group)
3080
3031
{
3081
3032
  if (group)
3082
3033
  {
3083
3034
    for (; group ; group=group->next)
3084
3035
    {
3085
 
      Cached_item *tmp= new_Cached_item(join->session, *group->item);
 
3036
      Cached_item *tmp=new_Cached_item(join->session, *group->item, false);
3086
3037
      if (!tmp || join->group_fields.push_front(tmp))
3087
3038
        return true;
3088
3039
    }
3091
3042
  return false;
3092
3043
}
3093
3044
 
3094
 
static uint32_t cache_record_length(Join *join,uint32_t idx)
 
3045
/**
 
3046
  @todo
 
3047
  - TODO: this function is here only temporarily until 'greedy_search' is
 
3048
  tested and accepted.
 
3049
 
 
3050
  RETURN VALUES
 
3051
    false       ok
 
3052
    true        Fatal error
 
3053
*/
 
3054
static bool find_best(JOIN *join,table_map rest_tables,uint32_t idx,double record_count, double read_time)
 
3055
{
 
3056
  Session *session= join->session;
 
3057
  if (session->killed)
 
3058
    return(true);
 
3059
  if (!rest_tables)
 
3060
  {
 
3061
    read_time+=record_count/(double) TIME_FOR_COMPARE;
 
3062
    if (join->sort_by_table &&
 
3063
  join->sort_by_table !=
 
3064
  join->positions[join->const_tables].table->table)
 
3065
      read_time+=record_count;      // We have to make a temp table
 
3066
    if (read_time < join->best_read)
 
3067
    {
 
3068
      memcpy(join->best_positions, join->positions, sizeof(POSITION)*idx);
 
3069
      join->best_read= read_time - 0.001;
 
3070
    }
 
3071
    return(false);
 
3072
  }
 
3073
  if (read_time+record_count/(double) TIME_FOR_COMPARE >= join->best_read)
 
3074
    return(false);          /* Found better before */
 
3075
 
 
3076
  JoinTable *s;
 
3077
  double best_record_count=DBL_MAX,best_read_time=DBL_MAX;
 
3078
  for (JoinTable **pos=join->best_ref+idx ; (s=*pos) ; pos++)
 
3079
  {
 
3080
    table_map real_table_bit=s->table->map;
 
3081
    if ((rest_tables & real_table_bit) && !(rest_tables & s->dependent) &&
 
3082
        (!idx|| !check_interleaving_with_nj(join->positions[idx-1].table, s)))
 
3083
    {
 
3084
      double records, best;
 
3085
      best_access_path(join, s, session, rest_tables, idx, record_count,
 
3086
                       read_time);
 
3087
      records= join->positions[idx].records_read;
 
3088
      best= join->positions[idx].read_time;
 
3089
      /*
 
3090
  Go to the next level only if there hasn't been a better key on
 
3091
  this level! This will cut down the search for a lot simple cases!
 
3092
      */
 
3093
      double current_record_count=record_count*records;
 
3094
      double current_read_time=read_time+best;
 
3095
      if (best_record_count > current_record_count ||
 
3096
    best_read_time > current_read_time ||
 
3097
    (idx == join->const_tables && s->table == join->sort_by_table))
 
3098
      {
 
3099
  if (best_record_count >= current_record_count &&
 
3100
      best_read_time >= current_read_time &&
 
3101
      (!(s->key_dependent & rest_tables) || records < 2.0))
 
3102
  {
 
3103
    best_record_count=current_record_count;
 
3104
    best_read_time=current_read_time;
 
3105
  }
 
3106
        std::swap(join->best_ref[idx], *pos);
 
3107
  if (find_best(join,rest_tables & ~real_table_bit,idx+1,
 
3108
                      current_record_count,current_read_time))
 
3109
          return(true);
 
3110
        std::swap(join->best_ref[idx], *pos);
 
3111
      }
 
3112
      restore_prev_nj_state(s);
 
3113
      if (join->select_options & SELECT_STRAIGHT_JOIN)
 
3114
  break;        // Don't test all combinations
 
3115
    }
 
3116
  }
 
3117
  return(false);
 
3118
}
 
3119
 
 
3120
static uint32_t cache_record_length(JOIN *join,uint32_t idx)
3095
3121
{
3096
3122
  uint32_t length=0;
3097
3123
  JoinTable **pos,**end;
3159
3185
  RETURN
3160
3186
    Expected number of row combinations
3161
3187
*/
3162
 
static double prev_record_reads(Join *join, uint32_t idx, table_map found_ref)
 
3188
static double prev_record_reads(JOIN *join, uint32_t idx, table_map found_ref)
3163
3189
{
3164
3190
  double found=1.0;
3165
 
  optimizer::Position *pos_end= join->getSpecificPosInPartialPlan(-1);
3166
 
  for (optimizer::Position *pos= join->getSpecificPosInPartialPlan(idx - 1); 
3167
 
       pos != pos_end; 
3168
 
       pos--)
 
3191
  POSITION *pos_end= join->positions - 1;
 
3192
  for (POSITION *pos= join->positions + idx - 1; pos != pos_end; pos--)
3169
3193
  {
3170
 
    if (pos->examinePosition(found_ref))
 
3194
    if (pos->table->table->map & found_ref)
3171
3195
    {
3172
 
      found_ref|= pos->getRefDependMap();
 
3196
      found_ref|= pos->ref_depend_map;
3173
3197
      /*
3174
 
        For the case of "t1 LEFT Join t2 ON ..." where t2 is a const table
 
3198
        For the case of "t1 LEFT JOIN t2 ON ..." where t2 is a const table
3175
3199
        with no matching row we will get position[t2].records_read==0.
3176
3200
        Actually the size of output is one null-complemented row, therefore
3177
3201
        we will use value of 1 whenever we get records_read==0.
3186
3210
          is an inprecise estimate and adding 1 (or, in the worst case,
3187
3211
          #max_nested_outer_joins=64-1) will not make it any more precise.
3188
3212
      */
3189
 
      if (pos->getFanout() > DBL_EPSILON)
3190
 
        found*= pos->getFanout();
 
3213
      if (pos->records_read > DBL_EPSILON)
 
3214
        found*= pos->records_read;
3191
3215
    }
3192
3216
  }
3193
3217
  return found;
3196
3220
/**
3197
3221
  Set up join struct according to best position.
3198
3222
*/
3199
 
static bool get_best_combination(Join *join)
 
3223
static bool get_best_combination(JOIN *join)
3200
3224
{
3201
3225
  uint32_t i,tablenr;
3202
3226
  table_map used_tables;
3203
3227
  JoinTable *join_tab,*j;
3204
 
  optimizer::KeyUse *keyuse;
 
3228
  KeyUse *keyuse;
3205
3229
  uint32_t table_count;
3206
3230
  Session *session=join->session;
3207
 
  optimizer::Position cur_pos;
3208
3231
 
3209
3232
  table_count=join->tables;
3210
3233
  if (!(join->join_tab=join_tab=
3217
3240
  for (j=join_tab, tablenr=0 ; tablenr < table_count ; tablenr++,j++)
3218
3241
  {
3219
3242
    Table *form;
3220
 
    cur_pos= join->getPosFromOptimalPlan(tablenr);
3221
 
    *j= *cur_pos.getJoinTable();
 
3243
    *j= *join->best_positions[tablenr].table;
3222
3244
    form=join->table[tablenr]=j->table;
3223
3245
    used_tables|= form->map;
3224
3246
    form->reginfo.join_tab=j;
3225
3247
    if (!*j->on_expr_ref)
3226
 
      form->reginfo.not_exists_optimize=0;  // Only with LEFT Join
3227
 
    if (j->type == AM_CONST)
 
3248
      form->reginfo.not_exists_optimize=0;  // Only with LEFT JOIN
 
3249
    if (j->type == JT_CONST)
3228
3250
      continue;         // Handled in make_join_stat..
3229
3251
 
3230
3252
    j->ref.key = -1;
3231
3253
    j->ref.key_parts=0;
3232
3254
 
3233
 
    if (j->type == AM_SYSTEM)
 
3255
    if (j->type == JT_SYSTEM)
3234
3256
      continue;
3235
 
    if (j->keys.none() || ! (keyuse= cur_pos.getKeyUse()))
 
3257
    if (j->keys.none() || !(keyuse= join->best_positions[tablenr].key))
3236
3258
    {
3237
 
      j->type= AM_ALL;
 
3259
      j->type=JT_ALL;
3238
3260
      if (tablenr != join->const_tables)
3239
3261
        join->full_join=1;
3240
3262
    }
3249
3271
}
3250
3272
 
3251
3273
/** Save const tables first as used tables. */
3252
 
static void set_position(Join *join,
3253
 
                         uint32_t idx,
3254
 
                         JoinTable *table,
3255
 
                         optimizer::KeyUse *key)
 
3274
static void set_position(JOIN *join,uint32_t idx,JoinTable *table,KeyUse *key)
3256
3275
{
3257
 
  optimizer::Position tmp_pos(1.0, /* This is a const table */
3258
 
                              0.0,
3259
 
                              table,
3260
 
                              key,
3261
 
                              0);
3262
 
  join->setPosInPartialPlan(idx, tmp_pos);
 
3276
  join->positions[idx].table= table;
 
3277
  join->positions[idx].key=key;
 
3278
  join->positions[idx].records_read=1.0;  /* This is a const table */
 
3279
  join->positions[idx].ref_depend_map= 0;
3263
3280
 
3264
3281
  /* Move the const table as down as possible in best_ref */
3265
3282
  JoinTable **pos=join->best_ref+idx+1;
3286
3303
                      the query
3287
3304
  @param join_tables  set of the tables in the query
3288
3305
 
 
3306
  @todo
 
3307
    'MAX_TABLES+2' denotes the old implementation of find_best before
 
3308
    the greedy version. Will be removed when greedy_search is approved.
 
3309
 
3289
3310
  @retval
3290
3311
    false       ok
3291
3312
  @retval
3292
3313
    true        Fatal error
3293
3314
*/
3294
 
static bool choose_plan(Join *join, table_map join_tables)
 
3315
static bool choose_plan(JOIN *join, table_map join_tables)
3295
3316
{
3296
3317
  uint32_t search_depth= join->session->variables.optimizer_search_depth;
3297
3318
  uint32_t prune_level=  join->session->variables.optimizer_prune_level;
3298
3319
  bool straight_join= test(join->select_options & SELECT_STRAIGHT_JOIN);
3299
3320
 
3300
 
  join->cur_embedding_map.reset();
 
3321
  join->cur_embedding_map= 0;
3301
3322
  reset_nj_counters(join->join_list);
3302
3323
  /*
3303
3324
    if (SELECT_STRAIGHT_JOIN option is set)
3307
3328
      Apply heuristic: pre-sort all access plans with respect to the number of
3308
3329
      records accessed.
3309
3330
  */
3310
 
  internal::my_qsort(join->best_ref + join->const_tables,
3311
 
                     join->tables - join->const_tables, sizeof(JoinTable*),
3312
 
                     straight_join ? join_tab_cmp_straight : join_tab_cmp);
 
3331
  my_qsort(join->best_ref + join->const_tables,
 
3332
           join->tables - join->const_tables, sizeof(JoinTable*),
 
3333
           straight_join ? join_tab_cmp_straight : join_tab_cmp);
3313
3334
  if (straight_join)
3314
3335
  {
3315
3336
    optimize_straight_join(join, join_tables);
3316
3337
  }
3317
3338
  else
3318
3339
  {
3319
 
    if (search_depth == 0)
3320
 
      /* Automatically determine a reasonable value for 'search_depth' */
3321
 
      search_depth= determine_search_depth(join);
3322
 
    if (greedy_search(join, join_tables, search_depth, prune_level))
3323
 
      return true;
 
3340
    if (search_depth == MAX_TABLES+2)
 
3341
    { /*
 
3342
        TODO: 'MAX_TABLES+2' denotes the old implementation of find_best before
 
3343
        the greedy version. Will be removed when greedy_search is approved.
 
3344
      */
 
3345
      join->best_read= DBL_MAX;
 
3346
      if (find_best(join, join_tables, join->const_tables, 1.0, 0.0))
 
3347
        return(true);
 
3348
    }
 
3349
    else
 
3350
    {
 
3351
      if (search_depth == 0)
 
3352
        /* Automatically determine a reasonable value for 'search_depth' */
 
3353
        search_depth= determine_search_depth(join);
 
3354
      if (greedy_search(join, join_tables, search_depth, prune_level))
 
3355
        return(true);
 
3356
    }
3324
3357
  }
3325
3358
 
3326
3359
  /*
3358
3391
  @return
3359
3392
    None
3360
3393
*/
3361
 
static void best_access_path(Join *join,
 
3394
static void best_access_path(JOIN *join,
3362
3395
                             JoinTable *s,
3363
3396
                             Session *session,
3364
3397
                             table_map remaining_tables,
3366
3399
                             double record_count,
3367
3400
                             double)
3368
3401
{
3369
 
  optimizer::KeyUse *best_key= NULL;
3370
 
  uint32_t best_max_key_part= 0;
 
3402
  KeyUse *best_key=         0;
 
3403
  uint32_t best_max_key_part=   0;
3371
3404
  bool found_constraint= 0;
3372
 
  double best= DBL_MAX;
3373
 
  double best_time= DBL_MAX;
3374
 
  double records= DBL_MAX;
 
3405
  double best=              DBL_MAX;
 
3406
  double best_time=         DBL_MAX;
 
3407
  double records=           DBL_MAX;
3375
3408
  table_map best_ref_depends_map= 0;
3376
3409
  double tmp;
3377
3410
  ha_rows rec;
3379
3412
  if (s->keyuse)
3380
3413
  {                                            /* Use key if possible */
3381
3414
    Table *table= s->table;
3382
 
    optimizer::KeyUse *keyuse= NULL;
3383
 
    optimizer::KeyUse *start_key= NULL;
 
3415
    KeyUse *keyuse,*start_key=0;
3384
3416
    double best_records= DBL_MAX;
3385
3417
    uint32_t max_key_part=0;
3386
3418
 
3387
3419
    /* Test how we can use keys */
3388
3420
    rec= s->records/MATCHING_ROWS_IN_OTHER_TABLE;  // Assumed records/key
3389
 
    for (keyuse= s->keyuse; keyuse->getTable() == table; )
 
3421
    for (keyuse=s->keyuse ; keyuse->table == table ;)
3390
3422
    {
3391
3423
      key_part_map found_part= 0;
3392
3424
      table_map found_ref= 0;
3393
 
      uint32_t key= keyuse->getKey();
3394
 
      KeyInfo *keyinfo= table->key_info + key;
 
3425
      uint32_t key= keyuse->key;
 
3426
      KEY *keyinfo= table->key_info+key;
3395
3427
      /* Bitmap of keyparts where the ref access is over 'keypart=const': */
3396
3428
      key_part_map const_part= 0;
3397
3429
      /* The or-null keypart in ref-or-null access: */
3402
3434
 
3403
3435
      do /* For each keypart */
3404
3436
      {
3405
 
        uint32_t keypart= keyuse->getKeypart();
 
3437
        uint32_t keypart= keyuse->keypart;
3406
3438
        table_map best_part_found_ref= 0;
3407
3439
        double best_prev_record_reads= DBL_MAX;
3408
3440
 
3413
3445
            if 1. expression doesn't refer to forward tables
3414
3446
               2. we won't get two ref-or-null's
3415
3447
          */
3416
 
          if (! (remaining_tables & keyuse->getUsedTables()) &&
3417
 
              ! (ref_or_null_part && (keyuse->getOptimizeFlags() &
3418
 
                                      KEY_OPTIMIZE_REF_OR_NULL)))
 
3448
          if (!(remaining_tables & keyuse->used_tables) &&
 
3449
              !(ref_or_null_part && (keyuse->optimize &
 
3450
                                     KEY_OPTIMIZE_REF_OR_NULL)))
3419
3451
          {
3420
 
            found_part|= keyuse->getKeypartMap();
3421
 
            if (! (keyuse->getUsedTables() & ~join->const_table_map))
3422
 
              const_part|= keyuse->getKeypartMap();
 
3452
            found_part|= keyuse->keypart_map;
 
3453
            if (!(keyuse->used_tables & ~join->const_table_map))
 
3454
              const_part|= keyuse->keypart_map;
3423
3455
 
3424
3456
            double tmp2= prev_record_reads(join, idx, (found_ref |
3425
 
                                                       keyuse->getUsedTables()));
 
3457
                                                      keyuse->used_tables));
3426
3458
            if (tmp2 < best_prev_record_reads)
3427
3459
            {
3428
 
              best_part_found_ref= keyuse->getUsedTables() & ~join->const_table_map;
 
3460
              best_part_found_ref= keyuse->used_tables & ~join->const_table_map;
3429
3461
              best_prev_record_reads= tmp2;
3430
3462
            }
3431
 
            if (rec > keyuse->getTableRows())
3432
 
              rec= keyuse->getTableRows();
 
3463
            if (rec > keyuse->ref_table_rows)
 
3464
              rec= keyuse->ref_table_rows;
3433
3465
      /*
3434
3466
        If there is one 'key_column IS NULL' expression, we can
3435
3467
        use this ref_or_null optimisation of this field
3436
3468
      */
3437
 
            if (keyuse->getOptimizeFlags() & KEY_OPTIMIZE_REF_OR_NULL)
3438
 
              ref_or_null_part|= keyuse->getKeypartMap();
 
3469
            if (keyuse->optimize & KEY_OPTIMIZE_REF_OR_NULL)
 
3470
              ref_or_null_part |= keyuse->keypart_map;
3439
3471
          }
3440
3472
 
3441
3473
          keyuse++;
3442
 
        } while (keyuse->getTable() == table && keyuse->getKey() == key &&
3443
 
                 keyuse->getKeypart() == keypart);
3444
 
        found_ref|= best_part_found_ref;
3445
 
      } while (keyuse->getTable() == table && keyuse->getKey() == key);
 
3474
        } while (keyuse->table == table && keyuse->key == key &&
 
3475
                 keyuse->keypart == keypart);
 
3476
  found_ref|= best_part_found_ref;
 
3477
      } while (keyuse->table == table && keyuse->key == key);
3446
3478
 
3447
3479
      /*
3448
3480
        Assume that that each key matches a proportional part of table.
3504
3536
                records=
3505
3537
                  ((double) s->records / (double) rec *
3506
3538
                   (1.0 +
3507
 
                    ((double) (table->getShare()->max_key_length-keyinfo->key_length) /
3508
 
                     (double) table->getShare()->max_key_length)));
 
3539
                    ((double) (table->s->max_key_length-keyinfo->key_length) /
 
3540
                     (double) table->s->max_key_length)));
3509
3541
                if (records < 2.0)
3510
3542
                  records=2.0;               /* Can't be as good as a unique */
3511
3543
              }
3533
3565
            if (table->covering_keys.test(key))
3534
3566
            {
3535
3567
              /* we can use only index tree */
3536
 
              tmp= record_count * table->cursor->index_only_read_time(key, tmp);
 
3568
              tmp= record_count * table->file->index_only_read_time(key, tmp);
3537
3569
            }
3538
3570
            else
3539
3571
              tmp= record_count * min(tmp,s->worst_seeks);
3547
3579
            Set tmp to (previous record count) * (records / combination)
3548
3580
          */
3549
3581
          if ((found_part & 1) &&
3550
 
              (!(table->index_flags(key) & HA_ONLY_WHOLE_INDEX) ||
3551
 
               found_part == PREV_BITS(uint, keyinfo->key_parts)))
 
3582
              (!(table->file->index_flags(key, 0, 0) & HA_ONLY_WHOLE_INDEX) ||
 
3583
               found_part == PREV_BITS(uint,keyinfo->key_parts)))
3552
3584
          {
3553
3585
            max_key_part= max_part_bit(found_part);
3554
3586
            /*
3627
3659
              else
3628
3660
              {
3629
3661
                /*
3630
 
                  Assume that the first key part matches 1% of the cursor
 
3662
                  Assume that the first key part matches 1% of the file
3631
3663
                  and that the whole key matches 10 (duplicates) or 1
3632
3664
                  (unique) records.
3633
3665
                  Assume also that more key matches proportionally more
3698
3730
            if (table->covering_keys.test(key))
3699
3731
            {
3700
3732
              /* we can use only index tree */
3701
 
              tmp= record_count * table->cursor->index_only_read_time(key, tmp);
 
3733
              tmp= record_count * table->file->index_only_read_time(key, tmp);
3702
3734
            }
3703
3735
            else
3704
3736
              tmp= record_count * min(tmp,s->worst_seeks);
3750
3782
        scan.
3751
3783
  */
3752
3784
  if ((records >= s->found_records || best > s->read_time) &&            // (1)
3753
 
      ! (s->quick && best_key && s->quick->index == best_key->getKey() &&      // (2)
3754
 
        best_max_key_part >= s->table->quick_key_parts[best_key->getKey()]) &&// (2)
3755
 
      ! ((s->table->cursor->getEngine()->check_flag(HTON_BIT_TABLE_SCAN_ON_INDEX)) &&   // (3)
3756
 
        ! s->table->covering_keys.none() && best_key && !s->quick) && // (3)
3757
 
      ! (s->table->force_index && best_key && !s->quick))                 // (4)
 
3785
      !(s->quick && best_key && s->quick->index == best_key->key &&      // (2)
 
3786
        best_max_key_part >= s->table->quick_key_parts[best_key->key]) &&// (2)
 
3787
      !((s->table->file->ha_table_flags() & HA_TABLE_SCAN_ON_INDEX) &&   // (3)
 
3788
        ! s->table->covering_keys.none() && best_key && !s->quick) &&// (3)
 
3789
      !(s->table->force_index && best_key && !s->quick))                 // (4)
3758
3790
  {                                             // Check full join
3759
3791
    ha_rows rnd_records= s->found_records;
3760
3792
    /*
3799
3831
    else
3800
3832
    {
3801
3833
      /* Estimate cost of reading table. */
3802
 
      tmp= s->table->cursor->scan_time();
 
3834
      tmp= s->table->file->scan_time();
3803
3835
      if (s->table->map & join->outer_join)     // Can't use join cache
3804
3836
      {
3805
3837
        /*
3850
3882
  }
3851
3883
 
3852
3884
  /* Update the cost information for the current partial plan */
3853
 
  optimizer::Position tmp_pos(records,
3854
 
                              best,
3855
 
                              s,
3856
 
                              best_key,
3857
 
                              best_ref_depends_map);
3858
 
  join->setPosInPartialPlan(idx, tmp_pos);
 
3885
  join->positions[idx].records_read= records;
 
3886
  join->positions[idx].read_time=    best;
 
3887
  join->positions[idx].key=          best_key;
 
3888
  join->positions[idx].table=        s;
 
3889
  join->positions[idx].ref_depend_map= best_ref_depends_map;
3859
3890
 
3860
3891
  if (!best_key &&
3861
3892
      idx == join->const_tables &&
3888
3919
    Thus 'optimize_straight_join' can be used at any stage of the query
3889
3920
    optimization process to finalize a QEP as it is.
3890
3921
*/
3891
 
static void optimize_straight_join(Join *join, table_map join_tables)
 
3922
static void optimize_straight_join(JOIN *join, table_map join_tables)
3892
3923
{
3893
3924
  JoinTable *s;
3894
 
  optimizer::Position partial_pos;
3895
3925
  uint32_t idx= join->const_tables;
3896
3926
  double    record_count= 1.0;
3897
3927
  double    read_time=    0.0;
3902
3932
    best_access_path(join, s, join->session, join_tables, idx,
3903
3933
                     record_count, read_time);
3904
3934
    /* compute the cost of the new plan extended with 's' */
3905
 
    partial_pos= join->getPosFromPartialPlan(idx);
3906
 
    record_count*= partial_pos.getFanout();
3907
 
    read_time+=    partial_pos.getCost();
 
3935
    record_count*= join->positions[idx].records_read;
 
3936
    read_time+=    join->positions[idx].read_time;
3908
3937
    join_tables&= ~(s->table->map);
3909
3938
    ++idx;
3910
3939
  }
3911
3940
 
3912
3941
  read_time+= record_count / (double) TIME_FOR_COMPARE;
3913
 
  partial_pos= join->getPosFromPartialPlan(join->const_tables);
3914
3942
  if (join->sort_by_table &&
3915
 
      partial_pos.hasTableForSorting(join->sort_by_table))
 
3943
      join->sort_by_table != join->positions[join->const_tables].table->table)
3916
3944
    read_time+= record_count;  // We have to make a temp table
3917
 
  join->copyPartialPlanIntoOptimalPlan(idx);
 
3945
  memcpy(join->best_positions, join->positions, sizeof(POSITION)*idx);
3918
3946
  join->best_read= read_time;
3919
3947
}
3920
3948
 
3998
4026
  @retval
3999
4027
    true        Fatal error
4000
4028
*/
4001
 
static bool greedy_search(Join      *join,
 
4029
static bool greedy_search(JOIN      *join,
4002
4030
              table_map remaining_tables,
4003
4031
              uint32_t      search_depth,
4004
4032
              uint32_t      prune_level)
4008
4036
  uint32_t      idx= join->const_tables; // index into 'join->best_ref'
4009
4037
  uint32_t      best_idx;
4010
4038
  uint32_t      size_remain;    // cardinality of remaining_tables
4011
 
  optimizer::Position best_pos;
 
4039
  POSITION  best_pos;
4012
4040
  JoinTable  *best_table; // the next plan node to be added to the curr QEP
4013
4041
 
4014
4042
  /* number of tables that remain to be optimized */
4015
 
  size_remain= internal::my_count_bits(remaining_tables);
 
4043
  size_remain= my_count_bits(remaining_tables);
4016
4044
 
4017
4045
  do {
4018
4046
    /* Find the extension of the current QEP with the lowest cost */
4031
4059
    }
4032
4060
 
4033
4061
    /* select the first table in the optimal extension as most promising */
4034
 
    best_pos= join->getPosFromOptimalPlan(idx);
4035
 
    best_table= best_pos.getJoinTable();
 
4062
    best_pos= join->best_positions[idx];
 
4063
    best_table= best_pos.table;
4036
4064
    /*
4037
4065
      Each subsequent loop of 'best_extension_by_limited_search' uses
4038
4066
      'join->positions' for cost estimates, therefore we have to update its
4039
4067
      value.
4040
4068
    */
4041
 
    join->setPosInPartialPlan(idx, best_pos);
4042
 
 
4043
 
    /*
4044
 
      We need to make best_extension_by_limited_search aware of the fact
4045
 
      that it's not starting from top level, but from a rather specific
4046
 
      position in the list of nested joins.
4047
 
    */
4048
 
    check_interleaving_with_nj (best_table);
4049
 
    
4050
 
      
 
4069
    join->positions[idx]= best_pos;
4051
4070
 
4052
4071
    /* find the position of 'best_table' in 'join->best_ref' */
4053
4072
    best_idx= idx;
4059
4078
    std::swap(join->best_ref[idx], join->best_ref[best_idx]);
4060
4079
 
4061
4080
    /* compute the cost of the new plan extended with 'best_table' */
4062
 
    optimizer::Position partial_pos= join->getPosFromPartialPlan(idx);
4063
 
    record_count*= partial_pos.getFanout();
4064
 
    read_time+=    partial_pos.getCost();
 
4081
    record_count*= join->positions[idx].records_read;
 
4082
    read_time+=    join->positions[idx].read_time;
4065
4083
 
4066
4084
    remaining_tables&= ~(best_table->table->map);
4067
4085
    --size_remain;
4186
4204
  @retval
4187
4205
    true        Fatal error
4188
4206
*/
4189
 
static bool best_extension_by_limited_search(Join *join,
 
4207
static bool best_extension_by_limited_search(JOIN *join,
4190
4208
                                             table_map remaining_tables,
4191
4209
                                             uint32_t idx,
4192
4210
                                             double record_count,
4195
4213
                                             uint32_t prune_level)
4196
4214
{
4197
4215
  Session *session= join->session;
4198
 
  if (session->getKilled())  // Abort
 
4216
  if (session->killed)  // Abort
4199
4217
    return(true);
4200
4218
 
4201
4219
  /*
4205
4223
  JoinTable *s;
4206
4224
  double best_record_count= DBL_MAX;
4207
4225
  double best_read_time=    DBL_MAX;
4208
 
  optimizer::Position partial_pos;
4209
4226
 
4210
4227
  for (JoinTable **pos= join->best_ref + idx ; (s= *pos) ; pos++)
4211
4228
  {
4212
4229
    table_map real_table_bit= s->table->map;
4213
4230
    if ((remaining_tables & real_table_bit) &&
4214
 
        ! (remaining_tables & s->dependent) &&
4215
 
        (! idx || ! check_interleaving_with_nj(s)))
 
4231
        !(remaining_tables & s->dependent) &&
 
4232
        (!idx || !check_interleaving_with_nj(join->positions[idx-1].table, s)))
4216
4233
    {
4217
4234
      double current_record_count, current_read_time;
4218
4235
 
4227
4244
      best_access_path(join, s, session, remaining_tables, idx,
4228
4245
                       record_count, read_time);
4229
4246
      /* Compute the cost of extending the plan with 's' */
4230
 
      partial_pos= join->getPosFromPartialPlan(idx);
4231
 
      current_record_count= record_count * partial_pos.getFanout();
4232
 
      current_read_time=    read_time + partial_pos.getCost();
 
4247
      current_record_count= record_count * join->positions[idx].records_read;
 
4248
      current_read_time=    read_time + join->positions[idx].read_time;
4233
4249
 
4234
4250
      /* Expand only partial plans with lower cost than the best QEP so far */
4235
4251
      if ((current_read_time +
4252
4268
          if (best_record_count >= current_record_count &&
4253
4269
              best_read_time >= current_read_time &&
4254
4270
              /* TODO: What is the reasoning behind this condition? */
4255
 
              (! (s->key_dependent & remaining_tables) ||
4256
 
               partial_pos.isConstTable()))
 
4271
              (!(s->key_dependent & remaining_tables) ||
 
4272
               join->positions[idx].records_read < 2.0))
4257
4273
          {
4258
4274
            best_record_count= current_record_count;
4259
4275
            best_read_time=    current_read_time;
4284
4300
          'join' is either the best partial QEP with 'search_depth' relations,
4285
4301
          or the best complete QEP so far, whichever is smaller.
4286
4302
        */
4287
 
        partial_pos= join->getPosFromPartialPlan(join->const_tables);
4288
4303
        current_read_time+= current_record_count / (double) TIME_FOR_COMPARE;
4289
4304
        if (join->sort_by_table &&
4290
 
            partial_pos.hasTableForSorting(join->sort_by_table))
 
4305
            join->sort_by_table !=
 
4306
            join->positions[join->const_tables].table->table)
4291
4307
          /* We have to make a temp table */
4292
4308
          current_read_time+= current_record_count;
4293
4309
        if ((search_depth == 1) || (current_read_time < join->best_read))
4294
4310
        {
4295
 
          join->copyPartialPlanIntoOptimalPlan(idx + 1);
 
4311
          memcpy(join->best_positions, join->positions,
 
4312
                 sizeof(POSITION) * (idx + 1));
4296
4313
          join->best_read= current_read_time - 0.001;
4297
4314
        }
4298
4315
      }
4333
4350
    exhaustiveness) of the depth-first search algorithm used by
4334
4351
    'greedy_search'.
4335
4352
*/
4336
 
static uint32_t determine_search_depth(Join *join)
 
4353
static uint32_t determine_search_depth(JOIN *join)
4337
4354
{
4338
4355
  uint32_t table_count=  join->tables - join->const_tables;
4339
4356
  uint32_t search_depth;
4352
4369
  return search_depth;
4353
4370
}
4354
4371
 
4355
 
static bool make_simple_join(Join *join,Table *tmp_table)
 
4372
static bool make_simple_join(JOIN *join,Table *tmp_table)
4356
4373
{
4357
4374
  Table **tableptr;
4358
4375
  JoinTable *join_tab;
4359
4376
 
4360
4377
  /*
4361
4378
    Reuse Table * and JoinTable if already allocated by a previous call
4362
 
    to this function through Join::exec (may happen for sub-queries).
 
4379
    to this function through JOIN::exec (may happen for sub-queries).
4363
4380
  */
4364
4381
  if (!join->table_reexec)
4365
4382
  {
4366
4383
    if (!(join->table_reexec= (Table**) join->session->alloc(sizeof(Table*))))
4367
 
      return(true);
 
4384
      return(true);                        /* purecov: inspected */
4368
4385
    if (join->tmp_join)
4369
4386
      join->tmp_join->table_reexec= join->table_reexec;
4370
4387
  }
4372
4389
  {
4373
4390
    if (!(join->join_tab_reexec=
4374
4391
          (JoinTable*) join->session->alloc(sizeof(JoinTable))))
4375
 
      return(true);
 
4392
      return(true);                        /* purecov: inspected */
4376
4393
    if (join->tmp_join)
4377
4394
      join->tmp_join->join_tab_reexec= join->join_tab_reexec;
4378
4395
  }
4398
4415
  join_tab->select=0;
4399
4416
  join_tab->select_cond=0;
4400
4417
  join_tab->quick=0;
4401
 
  join_tab->type= AM_ALL;                       /* Map through all records */
 
4418
  join_tab->type= JT_ALL;                       /* Map through all records */
4402
4419
  join_tab->keys.set();                     /* test everything in quick */
4403
4420
  join_tab->info=0;
4404
4421
  join_tab->on_expr_ref=0;
4409
4426
  join_tab->read_first_record= join_init_read_record;
4410
4427
  join_tab->join=join;
4411
4428
  join_tab->ref.key_parts= 0;
4412
 
  join_tab->read_record.init();
 
4429
  memset(&join_tab->read_record, 0, sizeof(join_tab->read_record));
4413
4430
  tmp_table->status=0;
4414
4431
  tmp_table->null_row=0;
4415
 
 
4416
 
  return false;
 
4432
  return(false);
4417
4433
}
4418
4434
 
4419
4435
/**
4457
4473
    This function can be called only after the execution plan
4458
4474
    has been chosen.
4459
4475
*/
4460
 
static void make_outerjoin_info(Join *join)
 
4476
static void make_outerjoin_info(JOIN *join)
4461
4477
{
4462
4478
  for (uint32_t i=join->const_tables ; i < join->tables ; i++)
4463
4479
  {
4464
4480
    JoinTable *tab=join->join_tab+i;
4465
4481
    Table *table=tab->table;
4466
4482
    TableList *tbl= table->pos_in_table_list;
4467
 
    TableList *embedding= tbl->getEmbedding();
 
4483
    TableList *embedding= tbl->embedding;
4468
4484
 
4469
4485
    if (tbl->outer_join)
4470
4486
    {
4477
4493
      tab->on_expr_ref= &tbl->on_expr;
4478
4494
      tab->cond_equal= tbl->cond_equal;
4479
4495
      if (embedding)
4480
 
        tab->first_upper= embedding->getNestedJoin()->first_nested;
 
4496
        tab->first_upper= embedding->nested_join->first_nested;
4481
4497
    }
4482
 
    for ( ; embedding ; embedding= embedding->getEmbedding())
 
4498
    for ( ; embedding ; embedding= embedding->embedding)
4483
4499
    {
4484
4500
      /* Ignore sj-nests: */
4485
4501
      if (!embedding->on_expr)
4486
4502
        continue;
4487
 
      nested_join_st *nested_join= embedding->getNestedJoin();
 
4503
      nested_join_st *nested_join= embedding->nested_join;
4488
4504
      if (!nested_join->counter_)
4489
4505
      {
4490
4506
        /*
4494
4510
        nested_join->first_nested= tab;
4495
4511
        tab->on_expr_ref= &embedding->on_expr;
4496
4512
        tab->cond_equal= tbl->cond_equal;
4497
 
        if (embedding->getEmbedding())
4498
 
          tab->first_upper= embedding->getEmbedding()->getNestedJoin()->first_nested;
 
4513
        if (embedding->embedding)
 
4514
          tab->first_upper= embedding->embedding->nested_join->first_nested;
4499
4515
      }
4500
4516
      if (!tab->first_inner)
4501
4517
        tab->first_inner= nested_join->first_nested;
4508
4524
  return;
4509
4525
}
4510
4526
 
4511
 
static bool make_join_select(Join *join,
4512
 
                             optimizer::SqlSelect *select,
4513
 
                             COND *cond)
 
4527
static bool make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
4514
4528
{
4515
4529
  Session *session= join->session;
4516
 
  optimizer::Position cur_pos;
4517
4530
  if (select)
4518
4531
  {
4519
4532
    add_not_null_conds(join);
4523
4536
      if (join->tables > 1)
4524
4537
        cond->update_used_tables();             // Tablenr may have changed
4525
4538
      if (join->const_tables == join->tables &&
4526
 
          session->lex->current_select->master_unit() ==
4527
 
          &session->lex->unit)          // not upper level SELECT
 
4539
          session->lex->current_select->master_unit() ==
 
4540
          &session->lex->unit)          // not upper level SELECT
4528
4541
        join->const_table_map|=RAND_TABLE_BIT;
4529
4542
      {                                         // Check const tables
4530
4543
        COND *const_cond=
4531
 
          make_cond_for_table(cond,
4532
 
              join->const_table_map,
4533
 
              (table_map) 0, 1);
 
4544
          make_cond_for_table(cond,
 
4545
                              join->const_table_map,
 
4546
                              (table_map) 0, 1);
4534
4547
        for (JoinTable *tab= join->join_tab+join->const_tables;
4535
 
            tab < join->join_tab+join->tables ; tab++)
 
4548
             tab < join->join_tab+join->tables ; tab++)
4536
4549
        {
4537
4550
          if (*tab->on_expr_ref)
4538
4551
          {
4539
4552
            JoinTable *cond_tab= tab->first_inner;
4540
4553
            COND *tmp= make_cond_for_table(*tab->on_expr_ref,
4541
 
                join->const_table_map,
4542
 
                (  table_map) 0, 0);
 
4554
                                           join->const_table_map,
 
4555
                                           (  table_map) 0, 0);
4543
4556
            if (!tmp)
4544
4557
              continue;
4545
4558
            tmp= new Item_func_trig_cond(tmp, &cond_tab->not_null_compl);
4546
 
            if (! tmp)
4547
 
              return 1;
 
4559
            if (!tmp)
 
4560
              return(1);
4548
4561
            tmp->quick_fix_field();
4549
4562
            cond_tab->select_cond= !cond_tab->select_cond ? tmp :
4550
 
              new Item_cond_and(cond_tab->select_cond,
4551
 
                  tmp);
4552
 
            if (! cond_tab->select_cond)
4553
 
              return 1;
 
4563
                                    new Item_cond_and(cond_tab->select_cond,
 
4564
                                                      tmp);
 
4565
            if (!cond_tab->select_cond)
 
4566
              return(1);
4554
4567
            cond_tab->select_cond->quick_fix_field();
4555
4568
          }
4556
4569
        }
4557
 
        if (const_cond && ! const_cond->val_int())
 
4570
        if (const_cond && !const_cond->val_int())
4558
4571
        {
4559
 
          return 1;      // Impossible const condition
 
4572
          return(1);     // Impossible const condition
4560
4573
        }
4561
4574
      }
4562
4575
    }
4563
4576
    used_tables=((select->const_tables=join->const_table_map) |
4564
 
        OUTER_REF_TABLE_BIT | RAND_TABLE_BIT);
 
4577
                 OUTER_REF_TABLE_BIT | RAND_TABLE_BIT);
4565
4578
    for (uint32_t i=join->const_tables ; i < join->tables ; i++)
4566
4579
    {
4567
4580
      JoinTable *tab=join->join_tab+i;
4568
4581
      /*
4569
 
         first_inner is the X in queries like:
4570
 
         SELECT * FROM t1 LEFT OUTER JOIN (t2 JOIN t3) ON X
4571
 
       */
 
4582
        first_inner is the X in queries like:
 
4583
        SELECT * FROM t1 LEFT OUTER JOIN (t2 JOIN t3) ON X
 
4584
      */
4572
4585
      JoinTable *first_inner_tab= tab->first_inner;
4573
4586
      table_map current_map= tab->table->map;
4574
4587
      bool use_quick_range=0;
4575
4588
      COND *tmp;
4576
4589
 
4577
4590
      /*
4578
 
         Following force including random expression in last table condition.
4579
 
         It solve problem with select like SELECT * FROM t1 WHERE rand() > 0.5
4580
 
       */
 
4591
        Following force including random expression in last table condition.
 
4592
        It solve problem with select like SELECT * FROM t1 WHERE rand() > 0.5
 
4593
      */
4581
4594
      if (i == join->tables-1)
4582
 
        current_map|= OUTER_REF_TABLE_BIT | RAND_TABLE_BIT;
 
4595
        current_map|= OUTER_REF_TABLE_BIT | RAND_TABLE_BIT;
4583
4596
      used_tables|=current_map;
4584
4597
 
4585
 
      if (tab->type == AM_REF && tab->quick &&
4586
 
          (uint32_t) tab->ref.key == tab->quick->index &&
4587
 
          tab->ref.key_length < tab->quick->max_used_key_length)
 
4598
      if (tab->type == JT_REF && tab->quick &&
 
4599
          (uint32_t) tab->ref.key == tab->quick->index &&
 
4600
          tab->ref.key_length < tab->quick->max_used_key_length)
4588
4601
      {
4589
 
        /* Range uses longer key;  Use this instead of ref on key */
4590
 
        tab->type= AM_ALL;
4591
 
        use_quick_range= 1;
4592
 
        tab->use_quick= 1;
 
4602
        /* Range uses longer key;  Use this instead of ref on key */
 
4603
        tab->type=JT_ALL;
 
4604
        use_quick_range=1;
 
4605
        tab->use_quick=1;
4593
4606
        tab->ref.key= -1;
4594
 
        tab->ref.key_parts= 0;          // Don't use ref key.
4595
 
        cur_pos= join->getPosFromOptimalPlan(i);
4596
 
        cur_pos.setFanout(rows2double(tab->quick->records));
 
4607
        tab->ref.key_parts=0;           // Don't use ref key.
 
4608
        join->best_positions[i].records_read= rows2double(tab->quick->records);
4597
4609
        /*
4598
 
           We will use join cache here : prevent sorting of the first
4599
 
           table only and sort at the end.
4600
 
         */
 
4610
          We will use join cache here : prevent sorting of the first
 
4611
          table only and sort at the end.
 
4612
        */
4601
4613
        if (i != join->const_tables && join->tables > join->const_tables + 1)
4602
4614
          join->full_join= 1;
4603
4615
      }
4607
4619
        tmp= make_cond_for_table(cond,used_tables,current_map, 0);
4608
4620
      if (cond && !tmp && tab->quick)
4609
4621
      {                                         // Outer join
4610
 
        if (tab->type != AM_ALL)
 
4622
        if (tab->type != JT_ALL)
4611
4623
        {
4612
4624
          /*
4613
 
             Don't use the quick method
4614
 
             We come here in the case where we have 'key=constant' and
4615
 
             the test is removed by make_cond_for_table()
4616
 
           */
 
4625
            Don't use the quick method
 
4626
            We come here in the case where we have 'key=constant' and
 
4627
            the test is removed by make_cond_for_table()
 
4628
          */
4617
4629
          delete tab->quick;
4618
4630
          tab->quick= 0;
4619
4631
        }
4620
4632
        else
4621
4633
        {
4622
4634
          /*
4623
 
             Hack to handle the case where we only refer to a table
4624
 
             in the ON part of an OUTER JOIN. In this case we want the code
4625
 
             below to check if we should use 'quick' instead.
4626
 
           */
 
4635
            Hack to handle the case where we only refer to a table
 
4636
            in the ON part of an OUTER JOIN. In this case we want the code
 
4637
            below to check if we should use 'quick' instead.
 
4638
          */
4627
4639
          tmp= new Item_int((int64_t) 1,1);     // Always true
4628
4640
        }
4629
4641
 
4630
4642
      }
4631
 
      if (tmp || !cond || tab->type == AM_REF || tab->type == AM_REF_OR_NULL ||
4632
 
          tab->type == AM_EQ_REF)
 
4643
      if (tmp || !cond || tab->type == JT_REF || tab->type == JT_REF_OR_NULL ||
 
4644
          tab->type == JT_EQ_REF)
4633
4645
      {
4634
 
        optimizer::SqlSelect *sel= tab->select= ((optimizer::SqlSelect*)
4635
 
            session->memdup((unsigned char*) select,
4636
 
              sizeof(*select)));
4637
 
        if (! sel)
4638
 
          return 1;                     // End of memory
 
4646
        SQL_SELECT *sel= tab->select= ((SQL_SELECT*)
 
4647
                                       session->memdup((unsigned char*) select,
 
4648
                                                   sizeof(*select)));
 
4649
        if (!sel)
 
4650
          return(1);                    // End of memory
4639
4651
        /*
4640
 
           If tab is an inner table of an outer join operation,
4641
 
           add a match guard to the pushed down predicate.
4642
 
           The guard will turn the predicate on only after
4643
 
           the first match for outer tables is encountered.
4644
 
         */
 
4652
          If tab is an inner table of an outer join operation,
 
4653
          add a match guard to the pushed down predicate.
 
4654
          The guard will turn the predicate on only after
 
4655
          the first match for outer tables is encountered.
 
4656
        */
4645
4657
        if (cond && tmp)
4646
4658
        {
4647
4659
          /*
4648
 
             Because of QUICK_GROUP_MIN_MAX_SELECT there may be a select without
4649
 
             a cond, so neutralize the hack above.
4650
 
           */
4651
 
          if (! (tmp= add_found_match_trig_cond(first_inner_tab, tmp, 0)))
4652
 
            return 1;
 
4660
            Because of QUICK_GROUP_MIN_MAX_SELECT there may be a select without
 
4661
            a cond, so neutralize the hack above.
 
4662
          */
 
4663
          if (!(tmp= add_found_match_trig_cond(first_inner_tab, tmp, 0)))
 
4664
            return(1);
4653
4665
          tab->select_cond=sel->cond=tmp;
 
4666
          /* Push condition to storage engine if this is enabled
 
4667
             and the condition is not guarded */
 
4668
          tab->table->file->pushed_cond= NULL;
 
4669
          if (session->variables.engine_condition_pushdown)
 
4670
          {
 
4671
            COND *push_cond=
 
4672
              make_cond_for_table(tmp, current_map, current_map, 0);
 
4673
            if (push_cond)
 
4674
            {
 
4675
              /* Push condition to handler */
 
4676
              if (!tab->table->file->cond_push(push_cond))
 
4677
                tab->table->file->pushed_cond= push_cond;
 
4678
            }
 
4679
          }
4654
4680
        }
4655
4681
        else
4656
4682
          tab->select_cond= sel->cond= NULL;
4657
4683
 
4658
 
        sel->head=tab->table;
4659
 
        if (tab->quick)
4660
 
        {
4661
 
          /* Use quick key read if it's a constant and it's not used
4662
 
             with key reading */
4663
 
          if (tab->needed_reg.none() && tab->type != AM_EQ_REF
4664
 
              && (tab->type != AM_REF || (uint32_t) tab->ref.key == tab->quick->index))
4665
 
          {
4666
 
            sel->quick=tab->quick;              // Use value from get_quick_...
4667
 
            sel->quick_keys.reset();
4668
 
            sel->needed_reg.reset();
4669
 
          }
4670
 
          else
4671
 
          {
4672
 
            delete tab->quick;
4673
 
          }
4674
 
          tab->quick= 0;
4675
 
        }
4676
 
        uint32_t ref_key= static_cast<uint32_t>(sel->head->reginfo.join_tab->ref.key + 1);
4677
 
        if (i == join->const_tables && ref_key)
4678
 
        {
4679
 
          if (tab->const_keys.any() &&
4680
 
              tab->table->reginfo.impossible_range)
4681
 
            return 1;
4682
 
        }
4683
 
        else if (tab->type == AM_ALL && ! use_quick_range)
4684
 
        {
4685
 
          if (tab->const_keys.any() &&
4686
 
              tab->table->reginfo.impossible_range)
4687
 
            return 1;                           // Impossible range
4688
 
          /*
4689
 
             We plan to scan all rows.
4690
 
             Check again if we should use an index.
4691
 
             We could have used an column from a previous table in
4692
 
             the index if we are using limit and this is the first table
4693
 
           */
4694
 
 
4695
 
          cur_pos= join->getPosFromOptimalPlan(i);
4696
 
          if ((cond && (! ((tab->keys & tab->const_keys) == tab->keys) && i > 0)) ||
4697
 
              (! tab->const_keys.none() && (i == join->const_tables) &&
4698
 
              (join->unit->select_limit_cnt < cur_pos.getFanout()) && ((join->select_options & OPTION_FOUND_ROWS) == false)))
4699
 
          {
4700
 
            /* Join with outer join condition */
4701
 
            COND *orig_cond= sel->cond;
4702
 
            sel->cond= and_conds(sel->cond, *tab->on_expr_ref);
4703
 
 
4704
 
            /*
4705
 
               We can't call sel->cond->fix_fields,
4706
 
               as it will break tab->on_expr if it's AND condition
4707
 
               (fix_fields currently removes extra AND/OR levels).
4708
 
               Yet attributes of the just built condition are not needed.
4709
 
               Thus we call sel->cond->quick_fix_field for safety.
4710
 
             */
4711
 
            if (sel->cond && ! sel->cond->fixed)
4712
 
              sel->cond->quick_fix_field();
4713
 
 
4714
 
            if (sel->test_quick_select(session, tab->keys,
4715
 
                  used_tables & ~ current_map,
4716
 
                  (join->select_options &
4717
 
                   OPTION_FOUND_ROWS ?
4718
 
                   HA_POS_ERROR :
4719
 
                   join->unit->select_limit_cnt), 0,
4720
 
                  false) < 0)
 
4684
        sel->head=tab->table;
 
4685
        if (tab->quick)
 
4686
        {
 
4687
          /* Use quick key read if it's a constant and it's not used
 
4688
             with key reading */
 
4689
          if (tab->needed_reg.none() && tab->type != JT_EQ_REF
 
4690
              && (tab->type != JT_REF || (uint32_t) tab->ref.key == tab->quick->index))
 
4691
          {
 
4692
            sel->quick=tab->quick;              // Use value from get_quick_...
 
4693
            sel->quick_keys.reset();
 
4694
            sel->needed_reg.reset();
 
4695
          }
 
4696
          else
 
4697
          {
 
4698
            delete tab->quick;
 
4699
          }
 
4700
          tab->quick=0;
 
4701
        }
 
4702
        uint32_t ref_key=(uint32_t) sel->head->reginfo.join_tab->ref.key+1;
 
4703
        if (i == join->const_tables && ref_key)
 
4704
        {
 
4705
          if (tab->const_keys.any() &&
 
4706
              tab->table->reginfo.impossible_range)
 
4707
            return(1);
 
4708
        }
 
4709
        else if (tab->type == JT_ALL && ! use_quick_range)
 
4710
        {
 
4711
          if (tab->const_keys.any() &&
 
4712
              tab->table->reginfo.impossible_range)
 
4713
            return(1);                          // Impossible range
 
4714
          /*
 
4715
            We plan to scan all rows.
 
4716
            Check again if we should use an index.
 
4717
            We could have used an column from a previous table in
 
4718
            the index if we are using limit and this is the first table
 
4719
          */
 
4720
 
 
4721
          if ((cond && (!((tab->keys & tab->const_keys) == tab->keys) && i > 0)) ||
 
4722
              (!tab->const_keys.none() && (i == join->const_tables) && (join->unit->select_limit_cnt < join->best_positions[i].records_read) && ((join->select_options & OPTION_FOUND_ROWS) == false)))
 
4723
          {
 
4724
            /* Join with outer join condition */
 
4725
            COND *orig_cond=sel->cond;
 
4726
            sel->cond= and_conds(sel->cond, *tab->on_expr_ref);
 
4727
 
 
4728
            /*
 
4729
              We can't call sel->cond->fix_fields,
 
4730
              as it will break tab->on_expr if it's AND condition
 
4731
              (fix_fields currently removes extra AND/OR levels).
 
4732
              Yet attributes of the just built condition are not needed.
 
4733
              Thus we call sel->cond->quick_fix_field for safety.
 
4734
            */
 
4735
            if (sel->cond && !sel->cond->fixed)
 
4736
              sel->cond->quick_fix_field();
 
4737
 
 
4738
            if (sel->test_quick_select(session, tab->keys,
 
4739
                                       used_tables & ~ current_map,
 
4740
                                       (join->select_options &
 
4741
                                        OPTION_FOUND_ROWS ?
 
4742
                                        HA_POS_ERROR :
 
4743
                                        join->unit->select_limit_cnt), 0,
 
4744
                                        false) < 0)
4721
4745
            {
4722
 
              /*
4723
 
                 Before reporting "Impossible WHERE" for the whole query
4724
 
                 we have to check isn't it only "impossible ON" instead
4725
 
               */
 
4746
              /*
 
4747
                Before reporting "Impossible WHERE" for the whole query
 
4748
                we have to check isn't it only "impossible ON" instead
 
4749
              */
4726
4750
              sel->cond=orig_cond;
4727
 
              if (! *tab->on_expr_ref ||
 
4751
              if (!*tab->on_expr_ref ||
4728
4752
                  sel->test_quick_select(session, tab->keys,
4729
 
                    used_tables & ~ current_map,
4730
 
                    (join->select_options &
4731
 
                     OPTION_FOUND_ROWS ?
4732
 
                     HA_POS_ERROR :
4733
 
                     join->unit->select_limit_cnt),0,
4734
 
                    false) < 0)
4735
 
                return 1;                       // Impossible WHERE
 
4753
                                         used_tables & ~ current_map,
 
4754
                                         (join->select_options &
 
4755
                                          OPTION_FOUND_ROWS ?
 
4756
                                          HA_POS_ERROR :
 
4757
                                          join->unit->select_limit_cnt),0,
 
4758
                                          false) < 0)
 
4759
                return(1);                      // Impossible WHERE
4736
4760
            }
4737
4761
            else
4738
 
              sel->cond=orig_cond;
 
4762
              sel->cond=orig_cond;
4739
4763
 
4740
 
            /* Fix for EXPLAIN */
4741
 
            if (sel->quick)
4742
 
            {
4743
 
              cur_pos= join->getPosFromOptimalPlan(i);
4744
 
              cur_pos.setFanout(static_cast<double>(sel->quick->records));
4745
 
            }
4746
 
          }
4747
 
          else
4748
 
          {
4749
 
            sel->needed_reg= tab->needed_reg;
4750
 
            sel->quick_keys.reset();
4751
 
          }
 
4764
            /* Fix for EXPLAIN */
 
4765
            if (sel->quick)
 
4766
              join->best_positions[i].records_read= (double)sel->quick->records;
 
4767
          }
 
4768
          else
 
4769
          {
 
4770
            sel->needed_reg=tab->needed_reg;
 
4771
            sel->quick_keys.reset();
 
4772
          }
4752
4773
          if (!((tab->checked_keys & sel->quick_keys) == sel->quick_keys) ||
4753
4774
              !((tab->checked_keys & sel->needed_reg) == sel->needed_reg))
4754
 
          {
4755
 
            tab->keys= sel->quick_keys;
 
4775
          {
 
4776
            tab->keys= sel->quick_keys;
4756
4777
            tab->keys|= sel->needed_reg;
4757
 
            tab->use_quick= (!sel->needed_reg.none() &&
4758
 
                (select->quick_keys.none() ||
4759
 
                 (select->quick &&
4760
 
                  (select->quick->records >= 100L)))) ?
4761
 
              2 : 1;
4762
 
            sel->read_tables= used_tables & ~current_map;
4763
 
          }
4764
 
          if (i != join->const_tables && tab->use_quick != 2)
4765
 
          {                                     /* Read with cache */
4766
 
            if (cond &&
 
4778
            tab->use_quick= (!sel->needed_reg.none() &&
 
4779
                             (select->quick_keys.none() ||
 
4780
                              (select->quick &&
 
4781
                               (select->quick->records >= 100L)))) ?
 
4782
              2 : 1;
 
4783
            sel->read_tables= used_tables & ~current_map;
 
4784
          }
 
4785
          if (i != join->const_tables && tab->use_quick != 2)
 
4786
          {                                     /* Read with cache */
 
4787
            if (cond &&
4767
4788
                (tmp=make_cond_for_table(cond,
4768
 
                                         join->const_table_map |
4769
 
                                         current_map,
4770
 
                                         current_map, 0)))
4771
 
            {
4772
 
              tab->cache.select= (optimizer::SqlSelect*)
4773
 
                session->memdup((unsigned char*) sel, sizeof(optimizer::SqlSelect));
4774
 
              tab->cache.select->cond= tmp;
4775
 
              tab->cache.select->read_tables= join->const_table_map;
4776
 
            }
4777
 
          }
4778
 
        }
 
4789
                                         join->const_table_map |
 
4790
                                         current_map,
 
4791
                                         current_map, 0)))
 
4792
            {
 
4793
              tab->cache.select=(SQL_SELECT*)
 
4794
                session->memdup((unsigned char*) sel, sizeof(SQL_SELECT));
 
4795
              tab->cache.select->cond=tmp;
 
4796
              tab->cache.select->read_tables=join->const_table_map;
 
4797
            }
 
4798
          }
 
4799
        }
4779
4800
      }
4780
4801
 
4781
4802
      /*
4782
 
         Push down conditions from all on expressions.
4783
 
         Each of these conditions are guarded by a variable
4784
 
         that turns if off just before null complemented row for
4785
 
         outer joins is formed. Thus, the condition from an
4786
 
         'on expression' are guaranteed not to be checked for
4787
 
         the null complemented row.
4788
 
       */
 
4803
        Push down conditions from all on expressions.
 
4804
        Each of these conditions are guarded by a variable
 
4805
        that turns if off just before null complemented row for
 
4806
        outer joins is formed. Thus, the condition from an
 
4807
        'on expression' are guaranteed not to be checked for
 
4808
        the null complemented row.
 
4809
      */
4789
4810
 
4790
4811
      /* First push down constant conditions from on expressions */
4791
4812
      for (JoinTable *join_tab= join->join_tab+join->const_tables;
4792
 
          join_tab < join->join_tab+join->tables ; join_tab++)
 
4813
           join_tab < join->join_tab+join->tables ; join_tab++)
4793
4814
      {
4794
4815
        if (*join_tab->on_expr_ref)
4795
4816
        {
4796
4817
          JoinTable *cond_tab= join_tab->first_inner;
4797
4818
          tmp= make_cond_for_table(*join_tab->on_expr_ref,
4798
 
              join->const_table_map,
4799
 
              (table_map) 0, 0);
 
4819
                                   join->const_table_map,
 
4820
                                   (table_map) 0, 0);
4800
4821
          if (!tmp)
4801
4822
            continue;
4802
4823
          tmp= new Item_func_trig_cond(tmp, &cond_tab->not_null_compl);
4803
 
          if (! tmp)
4804
 
            return 1;
 
4824
          if (!tmp)
 
4825
            return(1);
4805
4826
          tmp->quick_fix_field();
4806
4827
          cond_tab->select_cond= !cond_tab->select_cond ? tmp :
4807
 
            new Item_cond_and(cond_tab->select_cond,tmp);
4808
 
          if (! cond_tab->select_cond)
4809
 
            return 1;
 
4828
                                    new Item_cond_and(cond_tab->select_cond,tmp);
 
4829
          if (!cond_tab->select_cond)
 
4830
            return(1);
4810
4831
          cond_tab->select_cond->quick_fix_field();
4811
4832
        }
4812
4833
      }
4816
4837
      while (first_inner_tab && first_inner_tab->last_inner == last_tab)
4817
4838
      {
4818
4839
        /*
4819
 
           Table tab is the last inner table of an outer join.
4820
 
           An on expression is always attached to it.
4821
 
         */
 
4840
          Table tab is the last inner table of an outer join.
 
4841
          An on expression is always attached to it.
 
4842
        */
4822
4843
        COND *on_expr= *first_inner_tab->on_expr_ref;
4823
4844
 
4824
4845
        table_map used_tables2= (join->const_table_map |
4825
 
            OUTER_REF_TABLE_BIT | RAND_TABLE_BIT);
4826
 
        for (tab= join->join_tab+join->const_tables; tab <= last_tab ; tab++)
 
4846
                                 OUTER_REF_TABLE_BIT | RAND_TABLE_BIT);
 
4847
        for (tab= join->join_tab+join->const_tables; tab <= last_tab ; tab++)
4827
4848
        {
4828
4849
          current_map= tab->table->map;
4829
4850
          used_tables2|= current_map;
4830
4851
          COND *tmp_cond= make_cond_for_table(on_expr, used_tables2,
4831
 
              current_map, 0);
 
4852
                                              current_map, 0);
4832
4853
          if (tmp_cond)
4833
4854
          {
4834
4855
            JoinTable *cond_tab= tab < first_inner_tab ? first_inner_tab : tab;
4835
4856
            /*
4836
 
               First add the guards for match variables of
4837
 
               all embedding outer join operations.
4838
 
             */
 
4857
              First add the guards for match variables of
 
4858
              all embedding outer join operations.
 
4859
            */
4839
4860
            if (!(tmp_cond= add_found_match_trig_cond(cond_tab->first_inner,
4840
 
                                                      tmp_cond,
4841
 
                                                      first_inner_tab)))
4842
 
              return 1;
 
4861
                                                     tmp_cond,
 
4862
                                                     first_inner_tab)))
 
4863
              return(1);
4843
4864
            /*
4844
 
               Now add the guard turning the predicate off for
4845
 
               the null complemented row.
4846
 
             */
 
4865
              Now add the guard turning the predicate off for
 
4866
              the null complemented row.
 
4867
            */
4847
4868
            tmp_cond= new Item_func_trig_cond(tmp_cond,
4848
 
                &first_inner_tab->
4849
 
                not_null_compl);
 
4869
                                              &first_inner_tab->
 
4870
                                              not_null_compl);
4850
4871
            if (tmp_cond)
4851
4872
              tmp_cond->quick_fix_field();
4852
 
            /* Add the predicate to other pushed down predicates */
 
4873
            /* Add the predicate to other pushed down predicates */
4853
4874
            cond_tab->select_cond= !cond_tab->select_cond ? tmp_cond :
4854
 
              new Item_cond_and(cond_tab->select_cond,
4855
 
                                tmp_cond);
4856
 
            if (! cond_tab->select_cond)
4857
 
              return 1;
 
4875
                                  new Item_cond_and(cond_tab->select_cond,
 
4876
                                                    tmp_cond);
 
4877
            if (!cond_tab->select_cond)
 
4878
              return(1);
4858
4879
            cond_tab->select_cond->quick_fix_field();
4859
4880
          }
4860
4881
        }
4886
4907
    false - OK
4887
4908
    true  - Out of memory
4888
4909
*/
4889
 
static bool make_join_readinfo(Join *join)
 
4910
static bool make_join_readinfo(JOIN *join, uint64_t options, uint32_t no_jbuf_after)
4890
4911
{
4891
 
  bool sorted= true;
 
4912
  uint32_t i;
 
4913
  bool statistics= test(!(join->select_options & SELECT_DESCRIBE));
 
4914
  bool sorted= 1;
4892
4915
 
4893
 
  for (uint32_t i= join->const_tables ; i < join->tables ; i++)
 
4916
  for (i=join->const_tables ; i < join->tables ; i++)
4894
4917
  {
4895
4918
    JoinTable *tab=join->join_tab+i;
4896
4919
    Table *table=tab->table;
 
4920
    bool using_join_cache;
4897
4921
    tab->read_record.table= table;
4898
 
    tab->read_record.cursor= table->cursor;
 
4922
    tab->read_record.file=table->file;
4899
4923
    tab->next_select=sub_select;                /* normal select */
4900
4924
    /*
4901
4925
      TODO: don't always instruct first table's ref/range access method to
4902
4926
      produce sorted output.
4903
4927
    */
4904
4928
    tab->sorted= sorted;
4905
 
    sorted= false; // only first must be sorted
4906
 
 
 
4929
    sorted= 0;                                  // only first must be sorted
4907
4930
    if (tab->insideout_match_tab)
4908
4931
    {
4909
 
      if (! (tab->insideout_buf= (unsigned char*) join->session->alloc(tab->table->key_info
4910
 
                                                                       [tab->index].
4911
 
                                                                       key_length)))
 
4932
      if (!(tab->insideout_buf= (unsigned char*)join->session->alloc(tab->table->key_info
 
4933
                                                         [tab->index].
 
4934
                                                         key_length)))
4912
4935
        return true;
4913
4936
    }
4914
 
 
4915
 
    optimizer::AccessMethodFactory &factory= optimizer::AccessMethodFactory::singleton();
4916
 
    boost::shared_ptr<optimizer::AccessMethod> access_method(factory.createAccessMethod(tab->type));
4917
 
 
4918
 
    if (! access_method)
4919
 
    {
4920
 
      /**
4921
 
       * @todo
4922
 
       * Is abort() the correct thing to call here? I call this here because it was what was called in
4923
 
       * the default case for the switch statement that used to be here.
4924
 
       */
4925
 
      abort();
 
4937
    switch (tab->type) {
 
4938
    case JT_SYSTEM:                             // Only happens with left join
 
4939
      table->status=STATUS_NO_RECORD;
 
4940
      tab->read_first_record= join_read_system;
 
4941
      tab->read_record.read_record= join_no_more_records;
 
4942
      break;
 
4943
    case JT_CONST:                              // Only happens with left join
 
4944
      table->status=STATUS_NO_RECORD;
 
4945
      tab->read_first_record= join_read_const;
 
4946
      tab->read_record.read_record= join_no_more_records;
 
4947
      if (table->covering_keys.test(tab->ref.key) &&
 
4948
          !table->no_keyread)
 
4949
      {
 
4950
        table->key_read=1;
 
4951
        table->file->extra(HA_EXTRA_KEYREAD);
 
4952
      }
 
4953
      break;
 
4954
    case JT_EQ_REF:
 
4955
      table->status=STATUS_NO_RECORD;
 
4956
      if (tab->select)
 
4957
      {
 
4958
        delete tab->select->quick;
 
4959
        tab->select->quick=0;
 
4960
      }
 
4961
      delete tab->quick;
 
4962
      tab->quick=0;
 
4963
      tab->read_first_record= join_read_key;
 
4964
      tab->read_record.read_record= join_no_more_records;
 
4965
      if (table->covering_keys.test(tab->ref.key) && !table->no_keyread)
 
4966
      {
 
4967
        table->key_read=1;
 
4968
        table->file->extra(HA_EXTRA_KEYREAD);
 
4969
      }
 
4970
      else
 
4971
        push_index_cond(tab, tab->ref.key, true);
 
4972
      break;
 
4973
    case JT_REF_OR_NULL:
 
4974
    case JT_REF:
 
4975
      table->status=STATUS_NO_RECORD;
 
4976
      if (tab->select)
 
4977
      {
 
4978
        delete tab->select->quick;
 
4979
        tab->select->quick=0;
 
4980
      }
 
4981
      delete tab->quick;
 
4982
      tab->quick=0;
 
4983
      if (table->covering_keys.test(tab->ref.key) && !table->no_keyread)
 
4984
      {
 
4985
        table->key_read=1;
 
4986
        table->file->extra(HA_EXTRA_KEYREAD);
 
4987
      }
 
4988
      else
 
4989
        push_index_cond(tab, tab->ref.key, true);
 
4990
      if (tab->type == JT_REF)
 
4991
      {
 
4992
        tab->read_first_record= join_read_always_key;
 
4993
        tab->read_record.read_record= tab->insideout_match_tab?
 
4994
           join_read_next_same_diff : join_read_next_same;
 
4995
      }
 
4996
      else
 
4997
      {
 
4998
        tab->read_first_record= join_read_always_key_or_null;
 
4999
        tab->read_record.read_record= join_read_next_same_or_null;
 
5000
      }
 
5001
      break;
 
5002
    case JT_ALL:
 
5003
      /*
 
5004
        If previous table use cache
 
5005
        If the incoming data set is already sorted don't use cache.
 
5006
      */
 
5007
      table->status=STATUS_NO_RECORD;
 
5008
      using_join_cache= false;
 
5009
      if (i != join->const_tables && !(options & SELECT_NO_JOIN_CACHE) &&
 
5010
          tab->use_quick != 2 && !tab->first_inner && i <= no_jbuf_after &&
 
5011
          !tab->insideout_match_tab)
 
5012
      {
 
5013
        if ((options & SELECT_DESCRIBE) ||
 
5014
            !join_init_cache(join->session,join->join_tab+join->const_tables,
 
5015
                i-join->const_tables))
 
5016
        {
 
5017
                using_join_cache= true;
 
5018
          tab[-1].next_select=sub_select_cache; /* Patch previous */
 
5019
        }
 
5020
      }
 
5021
      /* These init changes read_record */
 
5022
      if (tab->use_quick == 2)
 
5023
      {
 
5024
        join->session->server_status|=SERVER_QUERY_NO_GOOD_INDEX_USED;
 
5025
        tab->read_first_record= join_init_quick_read_record;
 
5026
        if (statistics)
 
5027
          status_var_increment(join->session->status_var.select_range_check_count);
 
5028
      }
 
5029
      else
 
5030
      {
 
5031
        tab->read_first_record= join_init_read_record;
 
5032
        if (i == join->const_tables)
 
5033
        {
 
5034
          if (tab->select && tab->select->quick)
 
5035
          {
 
5036
            if (statistics)
 
5037
              status_var_increment(join->session->status_var.select_range_count);
 
5038
          }
 
5039
          else
 
5040
          {
 
5041
            join->session->server_status|=SERVER_QUERY_NO_INDEX_USED;
 
5042
            if (statistics)
 
5043
              status_var_increment(join->session->status_var.select_scan_count);
 
5044
          }
 
5045
        }
 
5046
        else
 
5047
        {
 
5048
          if (tab->select && tab->select->quick)
 
5049
          {
 
5050
            if (statistics)
 
5051
              status_var_increment(join->session->status_var.select_full_range_join_count);
 
5052
          }
 
5053
          else
 
5054
          {
 
5055
            join->session->server_status|=SERVER_QUERY_NO_INDEX_USED;
 
5056
            if (statistics)
 
5057
              status_var_increment(join->session->status_var.select_full_join_count);
 
5058
          }
 
5059
        }
 
5060
        if (!table->no_keyread)
 
5061
        {
 
5062
          if (tab->select && tab->select->quick &&
 
5063
                    tab->select->quick->index != MAX_KEY && //not index_merge
 
5064
              table->covering_keys.test(tab->select->quick->index))
 
5065
          {
 
5066
            table->key_read=1;
 
5067
            table->file->extra(HA_EXTRA_KEYREAD);
 
5068
          }
 
5069
          else if (!table->covering_keys.none() &&
 
5070
            !(tab->select && tab->select->quick))
 
5071
          {                                     // Only read index tree
 
5072
                  if (!tab->insideout_match_tab)
 
5073
                  {
 
5074
                    /*
 
5075
                      See bug #26447: "Using the clustered index for a table scan
 
5076
                      is always faster than using a secondary index".
 
5077
                    */
 
5078
                    if (table->s->primary_key != MAX_KEY &&
 
5079
                        table->file->primary_key_is_clustered())
 
5080
                      tab->index= table->s->primary_key;
 
5081
                    else
 
5082
                      tab->index= table->find_shortest_key(&table->covering_keys);
 
5083
                  }
 
5084
            tab->read_first_record= join_read_first;
 
5085
            tab->type=JT_NEXT;          // Read with index_first / index_next
 
5086
          }
 
5087
        }
 
5088
        if (tab->select && tab->select->quick &&
 
5089
            tab->select->quick->index != MAX_KEY && ! tab->table->key_read)
 
5090
          push_index_cond(tab, tab->select->quick->index, !using_join_cache);
 
5091
      }
 
5092
      break;
 
5093
    default:
 
5094
      break;                                    /* purecov: deadcode */
 
5095
    case JT_UNKNOWN:
 
5096
    case JT_MAYBE_REF:
 
5097
      abort();                                  /* purecov: deadcode */
4926
5098
    }
4927
 
 
4928
 
    access_method->getStats(table, tab);
4929
5099
  }
4930
 
 
4931
 
  join->join_tab[join->tables-1].next_select= NULL; /* Set by do_select */
4932
 
 
4933
 
  return false;
 
5100
  join->join_tab[join->tables-1].next_select=0; /* Set by do_select */
 
5101
  return(false);
4934
5102
}
4935
5103
 
4936
5104
/** Update the dependency map for the tables. */
4937
 
static void update_depend_map(Join *join)
 
5105
static void update_depend_map(JOIN *join)
4938
5106
{
4939
5107
  JoinTable *join_tab=join->join_tab, *end=join_tab+join->tables;
4940
5108
 
4957
5125
}
4958
5126
 
4959
5127
/** Update the dependency map for the sort order. */
4960
 
static void update_depend_map(Join *join, Order *order)
 
5128
static void update_depend_map(JOIN *join, order_st *order)
4961
5129
{
4962
5130
  for (; order ; order=order->next)
4963
5131
  {
4995
5163
  @return
4996
5164
    Returns new sort order
4997
5165
*/
4998
 
static Order *remove_constants(Join *join,Order *first_order, COND *cond, bool change_list, bool *simple_order)
 
5166
static order_st *remove_constants(JOIN *join,order_st *first_order, COND *cond, bool change_list, bool *simple_order)
4999
5167
{
5000
5168
  if (join->tables == join->const_tables)
5001
5169
    return change_list ? 0 : first_order;               // No need to sort
5002
5170
 
5003
 
  Order *order,**prev_ptr;
 
5171
  order_st *order,**prev_ptr;
5004
5172
  table_map first_table= join->join_tab[join->const_tables].table->map;
5005
5173
  table_map not_const_tables= ~join->const_table_map;
5006
5174
  table_map ref;
5055
5223
  return(first_order);
5056
5224
}
5057
5225
 
5058
 
static int return_zero_rows(Join *join,
 
5226
static int return_zero_rows(JOIN *join,
5059
5227
                            select_result *result,
5060
5228
                            TableList *tables,
5061
5229
                                        List<Item> &fields,
5066
5234
{
5067
5235
  if (select_options & SELECT_DESCRIBE)
5068
5236
  {
5069
 
    optimizer::ExplainPlan planner(join,
5070
 
                                   false,
5071
 
                                   false,
5072
 
                                   false,
5073
 
                                   info);
5074
 
    planner.printPlan();
5075
 
    return 0;
 
5237
    select_describe(join, false, false, false, info);
 
5238
    return(0);
5076
5239
  }
5077
5240
 
5078
5241
  join->join_free();
5084
5247
    if (having && having->val_int() == 0)
5085
5248
      send_row=0;
5086
5249
  }
5087
 
  if (! (result->send_fields(fields)))
 
5250
  if (!(result->send_fields(fields, Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF)))
5088
5251
  {
5089
5252
    if (send_row)
5090
5253
    {
5221
5384
    - The new condition, if success
5222
5385
    - 0, otherwise
5223
5386
*/
5224
 
static COND *simplify_joins(Join *join, List<TableList> *join_list, COND *conds, bool top)
 
5387
static COND *simplify_joins(JOIN *join, List<TableList> *join_list, COND *conds, bool top)
5225
5388
{
5226
5389
  TableList *table;
5227
5390
  nested_join_st *nested_join;
5237
5400
    table_map used_tables;
5238
5401
    table_map not_null_tables= (table_map) 0;
5239
5402
 
5240
 
    if ((nested_join= table->getNestedJoin()))
 
5403
    if ((nested_join= table->nested_join))
5241
5404
    {
5242
5405
      /*
5243
5406
         If the element of join_list is a nested join apply
5279
5442
        not_null_tables= conds->not_null_tables();
5280
5443
    }
5281
5444
 
5282
 
    if (table->getEmbedding())
 
5445
    if (table->embedding)
5283
5446
    {
5284
 
      table->getEmbedding()->getNestedJoin()->used_tables|= used_tables;
5285
 
      table->getEmbedding()->getNestedJoin()->not_null_tables|= not_null_tables;
 
5447
      table->embedding->nested_join->used_tables|= used_tables;
 
5448
      table->embedding->nested_join->not_null_tables|= not_null_tables;
5286
5449
    }
5287
5450
 
5288
5451
    if (!table->outer_join || (used_tables & not_null_tables))
5318
5481
    */
5319
5482
    if (table->on_expr)
5320
5483
    {
5321
 
      table->setDepTables(table->getDepTables() | table->on_expr->used_tables());
5322
 
      if (table->getEmbedding())
 
5484
      table->dep_tables|= table->on_expr->used_tables();
 
5485
      if (table->embedding)
5323
5486
      {
5324
 
        table->setDepTables(table->getDepTables() & ~table->getEmbedding()->getNestedJoin()->used_tables);
 
5487
        table->dep_tables&= ~table->embedding->nested_join->used_tables;
5325
5488
        /*
5326
5489
           Embedding table depends on tables used
5327
5490
           in embedded on expressions.
5328
5491
        */
5329
 
        table->getEmbedding()->setOnExprDepTables(table->getEmbedding()->getOnExprDepTables() & table->on_expr->used_tables());
 
5492
        table->embedding->on_expr_dep_tables|= table->on_expr->used_tables();
5330
5493
      }
5331
5494
      else
5332
 
        table->setDepTables(table->getDepTables() & ~table->table->map);
 
5495
        table->dep_tables&= ~table->table->map;
5333
5496
    }
5334
5497
 
5335
5498
    if (prev_table)
5336
5499
    {
5337
 
      //If this is straight join, set prev table to be dependent on all tables
5338
 
      //from this nested join, so that correct join order is selected.
5339
 
      if ((test(join->select_options & SELECT_STRAIGHT_JOIN)) ||
5340
 
          prev_table->straight)
5341
 
        prev_table->setDepTables(prev_table->getDepTables() | used_tables);
 
5500
      /* The order of tables is reverse: prev_table follows table */
 
5501
      if (prev_table->straight)
 
5502
        prev_table->dep_tables|= used_tables;
5342
5503
      if (prev_table->on_expr)
5343
5504
      {
5344
 
        prev_table->setDepTables(prev_table->getDepTables() | table->getOnExprDepTables());
5345
 
        table_map prev_used_tables= prev_table->getNestedJoin() ?
5346
 
                                    prev_table->getNestedJoin()->used_tables :
 
5505
        prev_table->dep_tables|= table->on_expr_dep_tables;
 
5506
        table_map prev_used_tables= prev_table->nested_join ?
 
5507
                                    prev_table->nested_join->used_tables :
5347
5508
                                    prev_table->table->map;
5348
5509
        /*
5349
5510
          If on expression contains only references to inner tables
5352
5513
          for them. Yet this is really a rare case.
5353
5514
              */
5354
5515
        if (!(prev_table->on_expr->used_tables() & ~prev_used_tables))
5355
 
          prev_table->setDepTables(prev_table->getDepTables() | used_tables);
 
5516
          prev_table->dep_tables|= used_tables;
5356
5517
      }
5357
5518
    }
5358
5519
    prev_table= table;
5365
5526
  li.rewind();
5366
5527
  while ((table= li++))
5367
5528
  {
5368
 
    nested_join= table->getNestedJoin();
 
5529
    nested_join= table->nested_join;
5369
5530
    if (nested_join && !table->on_expr)
5370
5531
    {
5371
5532
      TableList *tbl;
5372
5533
      List_iterator<TableList> it(nested_join->join_list);
5373
5534
      while ((tbl= it++))
5374
5535
      {
5375
 
        tbl->setEmbedding(table->getEmbedding());
5376
 
        tbl->setJoinList(table->getJoinList());
 
5536
        tbl->embedding= table->embedding;
 
5537
        tbl->join_list= table->join_list;
5377
5538
      }
5378
5539
      li.replace(nested_join->join_list);
5379
5540
    }
5381
5542
  return(conds);
5382
5543
}
5383
5544
 
5384
 
static int remove_duplicates(Join *join, Table *entry,List<Item> &fields, Item *having)
 
5545
static int remove_duplicates(JOIN *join, Table *entry,List<Item> &fields, Item *having)
5385
5546
{
5386
5547
  int error;
5387
5548
  uint32_t reclength,offset;
5405
5566
    join->unit->select_limit_cnt= 1;            // Only send first row
5406
5567
    return(0);
5407
5568
  }
5408
 
  Field **first_field=entry->getFields() + entry->getShare()->sizeFields() - field_count;
 
5569
  Field **first_field=entry->field+entry->s->fields - field_count;
5409
5570
  offset= (field_count ?
5410
 
           entry->getField(entry->getShare()->sizeFields() - field_count)->offset(entry->getInsertRecord()) : 0);
5411
 
  reclength= entry->getShare()->getRecordLength() - offset;
 
5571
           entry->field[entry->s->fields - field_count]->
 
5572
           offset(entry->record[0]) : 0);
 
5573
  reclength= entry->s->reclength-offset;
5412
5574
 
5413
 
  entry->free_io_cache();                               // Safety
5414
 
  entry->cursor->info(HA_STATUS_VARIABLE);
5415
 
  if (entry->getShare()->db_type() == heap_engine ||
5416
 
      (!entry->getShare()->blob_fields &&
5417
 
       ((ALIGN_SIZE(reclength) + HASH_OVERHEAD) * entry->cursor->stats.records <
5418
 
        session->variables.sortbuff_size)))
5419
 
  {
 
5575
  free_io_cache(entry);                         // Safety
 
5576
  entry->file->info(HA_STATUS_VARIABLE);
 
5577
  if (entry->s->db_type() == heap_engine ||
 
5578
      (!entry->s->blob_fields &&
 
5579
       ((ALIGN_SIZE(reclength) + HASH_OVERHEAD) * entry->file->stats.records <
 
5580
        session->variables.sortbuff_size)))
5420
5581
    error= remove_dup_with_hash_index(join->session, entry,
5421
 
                                      field_count, first_field,
5422
 
                                      reclength, having);
5423
 
  }
 
5582
                                     field_count, first_field,
 
5583
                                     reclength, having);
5424
5584
  else
5425
 
  {
5426
 
    error= remove_dup_with_compare(join->session, entry, first_field, offset, having);
5427
 
  }
 
5585
    error= remove_dup_with_compare(join->session, entry, first_field, offset,
 
5586
                                  having);
5428
5587
 
5429
5588
  free_blobs(first_field);
5430
 
 
5431
5589
  return(error);
5432
5590
}
5433
5591
 
5441
5599
                               List<Item> &fields,
5442
5600
                               List<Item> &all_fields,
5443
5601
                               COND **conds,
5444
 
                               Order *order,
5445
 
                               Order *group,
 
5602
                               order_st *order,
 
5603
                               order_st *group,
5446
5604
                               bool *hidden_group_fields)
5447
5605
{
5448
5606
  int res;
5449
5607
  nesting_map save_allow_sum_func=session->lex->allow_sum_func ;
5450
5608
 
5451
5609
  session->lex->allow_sum_func&= ~(1 << session->lex->current_select->nest_level);
5452
 
  res= session->setup_conds(tables, conds);
 
5610
  res= setup_conds(session, tables, conds);
5453
5611
 
5454
5612
  session->lex->allow_sum_func|= 1 << session->lex->current_select->nest_level;
5455
5613
  res= res || setup_order(session, ref_pointer_array, tables, fields, all_fields,
5469
5627
  @retval
5470
5628
    1   Fatal error
5471
5629
*/
5472
 
static bool make_join_statistics(Join *join, TableList *tables, COND *conds, DYNAMIC_ARRAY *keyuse_array)
 
5630
static bool make_join_statistics(JOIN *join, TableList *tables, COND *conds, DYNAMIC_ARRAY *keyuse_array)
5473
5631
{
5474
5632
  int error;
5475
5633
  Table *table;
5476
 
  uint32_t i;
5477
 
  uint32_t table_count;
5478
 
  uint32_t const_count;
5479
 
  uint32_t key;
5480
 
  table_map found_const_table_map;
5481
 
  table_map all_table_map;
5482
 
  table_map found_ref;
5483
 
  table_map refs;
5484
 
  key_map const_ref;
5485
 
  key_map eq_part;
5486
 
  Table **table_vector= NULL;
5487
 
  JoinTable *stat= NULL;
5488
 
  JoinTable *stat_end= NULL;
5489
 
  JoinTable *s= NULL;
5490
 
  JoinTable **stat_ref= NULL;
5491
 
  optimizer::KeyUse *keyuse= NULL;
5492
 
  optimizer::KeyUse *start_keyuse= NULL;
5493
 
  table_map outer_join= 0;
5494
 
  vector<optimizer::SargableParam> sargables;
 
5634
  uint32_t i,table_count,const_count,key;
 
5635
  table_map found_const_table_map, all_table_map, found_ref, refs;
 
5636
  key_map const_ref, eq_part;
 
5637
  Table **table_vector;
 
5638
  JoinTable *stat,*stat_end,*s,**stat_ref;
 
5639
  KeyUse *keyuse,*start_keyuse;
 
5640
  table_map outer_join=0;
 
5641
  SARGABLE_PARAM *sargables= 0;
5495
5642
  JoinTable *stat_vector[MAX_TABLES+1];
5496
 
  optimizer::Position *partial_pos;
5497
5643
 
5498
 
  table_count= join->tables;
5499
 
  stat= (JoinTable*) join->session->calloc(sizeof(JoinTable)*table_count);
5500
 
  stat_ref= (JoinTable**) join->session->alloc(sizeof(JoinTable*)*MAX_TABLES);
5501
 
  table_vector= (Table**) join->session->alloc(sizeof(Table*)*(table_count*2));
5502
 
  if (! stat || ! stat_ref || ! table_vector)
5503
 
    return 1;
 
5644
  table_count=join->tables;
 
5645
  stat=(JoinTable*) join->session->calloc(sizeof(JoinTable)*table_count);
 
5646
  stat_ref=(JoinTable**) join->session->alloc(sizeof(JoinTable*)*MAX_TABLES);
 
5647
  table_vector=(Table**) join->session->alloc(sizeof(Table*)*(table_count*2));
 
5648
  if (!stat || !stat_ref || !table_vector)
 
5649
    return(1);                          // Eom /* purecov: inspected */
5504
5650
 
5505
5651
  join->best_ref=stat_vector;
5506
5652
 
5512
5658
       tables;
5513
5659
       s++, tables= tables->next_leaf, i++)
5514
5660
  {
5515
 
    TableList *embedding= tables->getEmbedding();
 
5661
    TableList *embedding= tables->embedding;
5516
5662
    stat_vector[i]=s;
5517
5663
    s->keys.reset();
5518
5664
    s->const_keys.reset();
5520
5666
    s->needed_reg.reset();
5521
5667
    table_vector[i]=s->table=table=tables->table;
5522
5668
    table->pos_in_table_list= tables;
5523
 
    assert(table->cursor);
5524
 
    error= table->cursor->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
5525
 
    if (error)
 
5669
    error= table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
 
5670
    if(error)
5526
5671
    {
5527
 
        table->print_error(error, MYF(0));
5528
 
        return 1;
 
5672
        table->file->print_error(error, MYF(0));
 
5673
        return(1);
5529
5674
    }
5530
5675
    table->quick_keys.reset();
5531
5676
    table->reginfo.join_tab=s;
5532
5677
    table->reginfo.not_exists_optimize=0;
5533
5678
    memset(table->const_key_parts, 0,
5534
 
           sizeof(key_part_map)*table->getShare()->sizeKeys());
 
5679
           sizeof(key_part_map)*table->s->keys);
5535
5680
    all_table_map|= table->map;
5536
5681
    s->join=join;
5537
5682
    s->info=0;                                  // For describe
5538
5683
 
5539
 
    s->dependent= tables->getDepTables();
 
5684
    s->dependent= tables->dep_tables;
5540
5685
    s->key_dependent= 0;
5541
 
    table->quick_condition_rows= table->cursor->stats.records;
 
5686
    if (tables->schema_table)
 
5687
      table->file->stats.records= 2;
 
5688
    table->quick_condition_rows= table->file->stats.records;
5542
5689
 
5543
5690
    s->on_expr_ref= &tables->on_expr;
5544
5691
    if (*s->on_expr_ref)
5545
5692
    {
5546
5693
      /* s is the only inner table of an outer join */
5547
 
      if (!table->cursor->stats.records && !embedding)
 
5694
      if (!table->file->stats.records && !embedding)
5548
5695
      {                                         // Empty table
5549
5696
        s->dependent= 0;                        // Ignore LEFT JOIN depend.
5550
 
        set_position(join, const_count++, s, (optimizer::KeyUse*) 0);
 
5697
        set_position(join,const_count++,s,(KeyUse*) 0);
5551
5698
        continue;
5552
5699
      }
5553
5700
      outer_join|= table->map;
5554
 
      s->embedding_map.reset();
5555
 
      for (;embedding; embedding= embedding->getEmbedding())
5556
 
        s->embedding_map|= embedding->getNestedJoin()->nj_map;
 
5701
      s->embedding_map= 0;
 
5702
      for (;embedding; embedding= embedding->embedding)
 
5703
        s->embedding_map|= embedding->nested_join->nj_map;
5557
5704
      continue;
5558
5705
    }
5559
 
    if (embedding && !(false && ! embedding->getEmbedding()))
 
5706
    if (embedding && !(false && ! embedding->embedding))
5560
5707
    {
5561
5708
      /* s belongs to a nested join, maybe to several embedded joins */
5562
 
      s->embedding_map.reset();
 
5709
      s->embedding_map= 0;
5563
5710
      do
5564
5711
      {
5565
 
        nested_join_st *nested_join= embedding->getNestedJoin();
5566
 
        s->embedding_map|= nested_join->nj_map;
5567
 
        s->dependent|= embedding->getDepTables();
5568
 
        embedding= embedding->getEmbedding();
 
5712
        nested_join_st *nested_join= embedding->nested_join;
 
5713
        s->embedding_map|=nested_join->nj_map;
 
5714
        s->dependent|= embedding->dep_tables;
 
5715
        embedding= embedding->embedding;
5569
5716
        outer_join|= nested_join->used_tables;
5570
5717
      }
5571
5718
      while (embedding);
5572
5719
      continue;
5573
5720
    }
5574
 
    if ((table->cursor->stats.records <= 1) && !s->dependent &&
5575
 
              (table->cursor->getEngine()->check_flag(HTON_BIT_STATS_RECORDS_IS_EXACT)) &&
 
5721
    if ((table->file->stats.records <= 1) && !s->dependent &&
 
5722
              (table->file->ha_table_flags() & HA_STATS_RECORDS_IS_EXACT) && 
5576
5723
        !join->no_const_tables)
5577
5724
    {
5578
 
      set_position(join, const_count++, s, (optimizer::KeyUse*) 0);
 
5725
      set_position(join,const_count++,s,(KeyUse*) 0);
5579
5726
    }
5580
5727
  }
5581
5728
  stat_vector[i]=0;
5609
5756
      {
5610
5757
        join->tables=0;                 // Don't use join->table
5611
5758
        my_message(ER_WRONG_OUTER_JOIN, ER(ER_WRONG_OUTER_JOIN), MYF(0));
5612
 
        return 1;
 
5759
        return(1);
5613
5760
      }
5614
5761
      s->key_dependent= s->dependent;
5615
5762
    }
5618
5765
  if (conds || outer_join)
5619
5766
    if (update_ref_and_keys(join->session, keyuse_array, stat, join->tables,
5620
5767
                            conds, join->cond_equal,
5621
 
                            ~outer_join, join->select_lex, sargables))
5622
 
      return 1;
 
5768
                            ~outer_join, join->select_lex, &sargables))
 
5769
      return(1);
5623
5770
 
5624
5771
  /* Read tables with 0 or 1 rows (system tables) */
5625
5772
  join->const_table_map= 0;
5626
5773
 
5627
 
  optimizer::Position *p_pos= join->getFirstPosInPartialPlan();
5628
 
  optimizer::Position *p_end= join->getSpecificPosInPartialPlan(const_count);
5629
 
  while (p_pos < p_end)
 
5774
  for (POSITION *p_pos=join->positions, *p_end=p_pos+const_count;
 
5775
       p_pos < p_end ;
 
5776
       p_pos++)
5630
5777
  {
5631
5778
    int tmp;
5632
 
    s= p_pos->getJoinTable();
5633
 
    s->type= AM_SYSTEM;
 
5779
    s= p_pos->table;
 
5780
    s->type=JT_SYSTEM;
5634
5781
    join->const_table_map|=s->table->map;
5635
 
    if ((tmp= join_read_const_table(s, p_pos)))
 
5782
    if ((tmp=join_read_const_table(s, p_pos)))
5636
5783
    {
5637
5784
      if (tmp > 0)
5638
 
        return 1;                       // Fatal error
 
5785
        return(1);                      // Fatal error
5639
5786
    }
5640
5787
    else
5641
5788
      found_const_table_map|= s->table->map;
5642
 
    p_pos++;
5643
5789
  }
5644
5790
 
5645
5791
  /* loop until no more const tables are found */
5655
5801
      set_position() will move all const_tables first in stat_vector
5656
5802
    */
5657
5803
 
5658
 
    for (JoinTable **pos= stat_vector+const_count; (s= *pos); pos++)
 
5804
    for (JoinTable **pos=stat_vector+const_count ; (s= *pos) ; pos++)
5659
5805
    {
5660
 
      table= s->table;
 
5806
      table=s->table;
5661
5807
 
5662
5808
      /*
5663
5809
        If equi-join condition by a key is null rejecting and after a
5664
5810
        substitution of a const table the key value happens to be null
5665
5811
        then we can state that there are no matches for this equi-join.
5666
5812
      */
5667
 
      if ((keyuse= s->keyuse) && *s->on_expr_ref && s->embedding_map.none())
 
5813
      if ((keyuse= s->keyuse) && *s->on_expr_ref && !s->embedding_map)
5668
5814
      {
5669
5815
        /*
5670
5816
          When performing an outer join operation if there are no matching rows
5676
5822
          TODO. Apply single row substitution to null complemented inner tables
5677
5823
          for nested outer join operations.
5678
5824
        */
5679
 
        while (keyuse->getTable() == table)
 
5825
        while (keyuse->table == table)
5680
5826
        {
5681
 
          if (! (keyuse->getVal()->used_tables() & ~join->const_table_map) &&
5682
 
              keyuse->getVal()->is_null() && keyuse->isNullRejected())
 
5827
          if (!(keyuse->val->used_tables() & ~join->const_table_map) &&
 
5828
              keyuse->val->is_null() && keyuse->null_rejecting)
5683
5829
          {
5684
 
            s->type= AM_CONST;
 
5830
            s->type= JT_CONST;
5685
5831
            table->mark_as_null_row();
5686
5832
            found_const_table_map|= table->map;
5687
5833
            join->const_table_map|= table->map;
5688
 
            set_position(join, const_count++, s, (optimizer::KeyUse*) 0);
 
5834
            set_position(join,const_count++,s,(KeyUse*) 0);
5689
5835
            goto more_const_tables_found;
5690
5836
           }
5691
5837
          keyuse++;
5697
5843
        // All dep. must be constants
5698
5844
        if (s->dependent & ~(found_const_table_map))
5699
5845
          continue;
5700
 
        if (table->cursor->stats.records <= 1L &&
5701
 
            (table->cursor->getEngine()->check_flag(HTON_BIT_STATS_RECORDS_IS_EXACT)) &&
5702
 
                  !table->pos_in_table_list->getEmbedding())
 
5846
        if (table->file->stats.records <= 1L &&
 
5847
            (table->file->ha_table_flags() & HA_STATS_RECORDS_IS_EXACT) &&
 
5848
                  !table->pos_in_table_list->embedding)
5703
5849
        {                                       // system table
5704
5850
          int tmp= 0;
5705
 
          s->type= AM_SYSTEM;
 
5851
          s->type=JT_SYSTEM;
5706
5852
          join->const_table_map|=table->map;
5707
 
          set_position(join, const_count++, s, (optimizer::KeyUse*) 0);
5708
 
          partial_pos= join->getSpecificPosInPartialPlan(const_count - 1);
5709
 
          if ((tmp= join_read_const_table(s, partial_pos)))
 
5853
          set_position(join,const_count++,s,(KeyUse*) 0);
 
5854
          if ((tmp= join_read_const_table(s, join->positions+const_count-1)))
5710
5855
          {
5711
5856
            if (tmp > 0)
5712
 
              return 1;                 // Fatal error
 
5857
              return(1);                        // Fatal error
5713
5858
          }
5714
5859
          else
5715
5860
            found_const_table_map|= table->map;
5719
5864
      /* check if table can be read by key or table only uses const refs */
5720
5865
      if ((keyuse=s->keyuse))
5721
5866
      {
5722
 
        s->type= AM_REF;
5723
 
        while (keyuse->getTable() == table)
 
5867
        s->type= JT_REF;
 
5868
        while (keyuse->table == table)
5724
5869
        {
5725
 
          start_keyuse= keyuse;
5726
 
          key= keyuse->getKey();
 
5870
          start_keyuse=keyuse;
 
5871
          key=keyuse->key;
5727
5872
          s->keys.set(key);               // QQ: remove this ?
5728
5873
 
5729
 
          refs= 0;
5730
 
          const_ref.reset();
 
5874
          refs=0;
 
5875
                const_ref.reset();
5731
5876
          eq_part.reset();
5732
5877
          do
5733
5878
          {
5734
 
            if (keyuse->getVal()->type() != Item::NULL_ITEM && 
5735
 
                ! keyuse->getOptimizeFlags())
 
5879
            if (keyuse->val->type() != Item::NULL_ITEM && !keyuse->optimize)
5736
5880
            {
5737
 
              if (! ((~found_const_table_map) & keyuse->getUsedTables()))
5738
 
                const_ref.set(keyuse->getKeypart());
 
5881
              if (!((~found_const_table_map) & keyuse->used_tables))
 
5882
                const_ref.set(keyuse->keypart);
5739
5883
              else
5740
 
                refs|= keyuse->getUsedTables();
5741
 
              eq_part.set(keyuse->getKeypart());
 
5884
                refs|=keyuse->used_tables;
 
5885
              eq_part.set(keyuse->keypart);
5742
5886
            }
5743
5887
            keyuse++;
5744
 
          } while (keyuse->getTable() == table && keyuse->getKey() == key);
 
5888
          } while (keyuse->table == table && keyuse->key == key);
5745
5889
 
5746
5890
          if (is_keymap_prefix(eq_part, table->key_info[key].key_parts) &&
5747
 
              ! table->pos_in_table_list->getEmbedding())
 
5891
              !table->pos_in_table_list->embedding)
5748
5892
          {
5749
5893
            if ((table->key_info[key].flags & (HA_NOSAME)) == HA_NOSAME)
5750
5894
            {
5752
5896
              {                                 // Found everything for ref.
5753
5897
                int tmp;
5754
5898
                ref_changed = 1;
5755
 
                s->type= AM_CONST;
 
5899
                s->type= JT_CONST;
5756
5900
                join->const_table_map|= table->map;
5757
 
                set_position(join, const_count++, s, start_keyuse);
 
5901
                set_position(join,const_count++,s,start_keyuse);
5758
5902
                if (create_ref_for_key(join, s, start_keyuse, found_const_table_map))
5759
 
                  return 1;
5760
 
                partial_pos= join->getSpecificPosInPartialPlan(const_count - 1);
5761
 
                if ((tmp=join_read_const_table(s, partial_pos)))
 
5903
                  return(1);
 
5904
                if ((tmp=join_read_const_table(s, join->positions+const_count-1)))
5762
5905
                {
5763
5906
                  if (tmp > 0)
5764
 
                    return 1;                   // Fatal error
 
5907
                    return(1);                  // Fatal error
5765
5908
                }
5766
5909
                else
5767
5910
                  found_const_table_map|= table->map;
5782
5925
    Update info on indexes that can be used for search lookups as
5783
5926
    reading const tables may has added new sargable predicates.
5784
5927
  */
5785
 
  if (const_count && ! sargables.empty())
 
5928
  if (const_count && sargables)
5786
5929
  {
5787
 
    vector<optimizer::SargableParam>::iterator iter= sargables.begin();
5788
 
    while (iter != sargables.end())
 
5930
    for( ; sargables->field ; sargables++)
5789
5931
    {
5790
 
      Field *field= (*iter).getField();
5791
 
      JoinTable *join_tab= field->getTable()->reginfo.join_tab;
 
5932
      Field *field= sargables->field;
 
5933
      JoinTable *join_tab= field->table->reginfo.join_tab;
5792
5934
      key_map possible_keys= field->key_start;
5793
 
      possible_keys&= field->getTable()->keys_in_use_for_query;
5794
 
      bool is_const= true;
5795
 
      for (uint32_t j= 0; j < (*iter).getNumValues(); j++)
5796
 
        is_const&= (*iter).isConstItem(j);
 
5935
      possible_keys&= field->table->keys_in_use_for_query;
 
5936
      bool is_const= 1;
 
5937
      for (uint32_t j=0; j < sargables->num_values; j++)
 
5938
        is_const&= sargables->arg_value[j]->const_item();
5797
5939
      if (is_const)
5798
5940
        join_tab[0].const_keys|= possible_keys;
5799
 
      ++iter;
5800
5941
    }
5801
5942
  }
5802
5943
 
5804
5945
 
5805
5946
  for (s=stat ; s < stat_end ; s++)
5806
5947
  {
5807
 
    if (s->type == AM_SYSTEM || s->type == AM_CONST)
 
5948
    if (s->type == JT_SYSTEM || s->type == JT_CONST)
5808
5949
    {
5809
5950
      /* Only one matching row */
5810
5951
      s->found_records=s->records=s->read_time=1; s->worst_seeks=1.0;
5811
5952
      continue;
5812
5953
    }
5813
5954
    /* Approximate found rows and time to read them */
5814
 
    s->found_records=s->records=s->table->cursor->stats.records;
5815
 
    s->read_time=(ha_rows) s->table->cursor->scan_time();
 
5955
    s->found_records=s->records=s->table->file->stats.records;
 
5956
    s->read_time=(ha_rows) s->table->file->scan_time();
5816
5957
 
5817
5958
    /*
5818
5959
      Set a max range of how many seeks we can expect when using keys
5831
5972
    add_group_and_distinct_keys(join, s);
5832
5973
 
5833
5974
    if (s->const_keys.any() &&
5834
 
        !s->table->pos_in_table_list->getEmbedding())
 
5975
        !s->table->pos_in_table_list->embedding)
5835
5976
    {
5836
5977
      ha_rows records;
5837
 
      optimizer::SqlSelect *select= NULL;
5838
 
      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);
 
5978
      SQL_SELECT *select;
 
5979
      select= make_select(s->table, found_const_table_map, found_const_table_map, *s->on_expr_ref ? *s->on_expr_ref : conds, 1, &error);
5839
5980
      if (! select)
5840
 
        return 1;
 
5981
        return(1);
5841
5982
      records= get_quick_record_count(join->session, select, s->table, &s->const_keys, join->row_limit);
5842
5983
      s->quick=select->quick;
5843
5984
      s->needed_reg=select->needed_reg;
5851
5992
          caller to abort with a zero row result.
5852
5993
        */
5853
5994
        join->const_table_map|= s->table->map;
5854
 
        set_position(join, const_count++, s, (optimizer::KeyUse*) 0);
5855
 
        s->type= AM_CONST;
 
5995
        set_position(join,const_count++,s,(KeyUse*) 0);
 
5996
        s->type= JT_CONST;
5856
5997
        if (*s->on_expr_ref)
5857
5998
        {
5858
5999
          /* Generate empty row */
5859
6000
          s->info= "Impossible ON condition";
5860
6001
          found_const_table_map|= s->table->map;
5861
 
          s->type= AM_CONST;
 
6002
          s->type= JT_CONST;
5862
6003
          s->table->mark_as_null_row();         // All fields are NULL
5863
6004
        }
5864
6005
      }
5881
6022
  if (join->const_tables != join->tables)
5882
6023
  {
5883
6024
    optimize_keyuse(join, keyuse_array);
5884
 
    // @note c_str() is not likely to be valid here if dtrace expects it to
5885
 
    // exist for any period of time.
5886
 
    DRIZZLE_QUERY_OPT_CHOOSE_PLAN_START(join->session->getQueryString()->c_str(), join->session->thread_id);
5887
 
    bool res= choose_plan(join, all_table_map & ~join->const_table_map);
5888
 
    DRIZZLE_QUERY_OPT_CHOOSE_PLAN_DONE(res ? 1 : 0);
5889
 
    if (res)
5890
 
      return true;
 
6025
    if (choose_plan(join, all_table_map & ~join->const_table_map))
 
6026
      return(true);
5891
6027
  }
5892
6028
  else
5893
6029
  {
5894
 
    join->copyPartialPlanIntoOptimalPlan(join->const_tables);
 
6030
    memcpy(join->best_positions, join->positions, sizeof(POSITION)*join->const_tables);
5895
6031
    join->best_read= 1.0;
5896
6032
  }
5897
6033
  /* Generate an execution plan from the found optimal join order. */
5898
 
  return (join->session->getKilled() || get_best_combination(join));
 
6034
  return (join->session->killed || get_best_combination(join));
5899
6035
}
5900
6036
 
5901
6037
/**
5902
 
  Assign each nested join structure a bit in the nested join bitset.
 
6038
  Assign each nested join structure a bit in nested_join_map.
5903
6039
 
5904
6040
    Assign each nested join structure (except "confluent" ones - those that
5905
 
    embed only one element) a bit in the nested join bitset.
 
6041
    embed only one element) a bit in nested_join_map.
5906
6042
 
5907
6043
  @param join          Join being processed
5908
6044
  @param join_list     List of tables
5909
 
  @param first_unused  Number of first unused bit in the nest joing bitset before the
 
6045
  @param first_unused  Number of first unused bit in nested_join_map before the
5910
6046
                       call
5911
6047
 
5912
6048
  @note
5913
6049
    This function is called after simplify_joins(), when there are no
5914
6050
    redundant nested joins, #non_confluent_nested_joins <= #tables_in_join so
5915
 
    we will not run out of bits in the nested join bitset.
 
6051
    we will not run out of bits in nested_join_map.
5916
6052
 
5917
6053
  @return
5918
 
    First unused bit in the nest join bitset after the call.
 
6054
    First unused bit in nested_join_map after the call.
5919
6055
*/
5920
6056
static uint32_t build_bitmap_for_nested_joins(List<TableList> *join_list, uint32_t first_unused)
5921
6057
{
5924
6060
  while ((table= li++))
5925
6061
  {
5926
6062
    nested_join_st *nested_join;
5927
 
    if ((nested_join= table->getNestedJoin()))
 
6063
    if ((nested_join= table->nested_join))
5928
6064
    {
5929
6065
      /*
5930
6066
        It is guaranteed by simplify_joins() function that a nested join
5935
6071
        We don't assign bits to such sj-nests because
5936
6072
        1. it is redundant (a "sequence" of one table cannot be interleaved
5937
6073
            with anything)
5938
 
        2. we could run out of bits in the nested join bitset otherwise.
 
6074
        2. we could run out bits in nested_join_map otherwise.
5939
6075
      */
5940
6076
      if (nested_join->join_list.elements != 1)
5941
6077
      {
5942
6078
        /* Don't assign bits to sj-nests */
5943
6079
        if (table->on_expr)
5944
 
          nested_join->nj_map.set(first_unused++);
 
6080
          nested_join->nj_map= (nested_join_map) 1 << first_unused++;
5945
6081
        first_unused= build_bitmap_for_nested_joins(&nested_join->join_list,
5946
6082
                                                    first_unused);
5947
6083
      }
5955
6091
  Return table number if there is only one table in sort order
5956
6092
  and group and order is compatible, else return 0.
5957
6093
*/
5958
 
static Table *get_sort_by_table(Order *a, Order *b,TableList *tables)
 
6094
static Table *get_sort_by_table(order_st *a,order_st *b,TableList *tables)
5959
6095
{
5960
6096
  table_map map= (table_map) 0;
5961
6097
 
5995
6131
  while ((table= li++))
5996
6132
  {
5997
6133
    nested_join_st *nested_join;
5998
 
    if ((nested_join= table->getNestedJoin()))
 
6134
    if ((nested_join= table->nested_join))
5999
6135
    {
6000
6136
      nested_join->counter_= 0;
6001
6137
      reset_nj_counters(&nested_join->join_list);
6010
6146
  If first parts has different direction, change it to second part
6011
6147
  (group is sorted like order)
6012
6148
*/
6013
 
static bool test_if_subpart(Order *a, Order *b)
 
6149
static bool test_if_subpart(order_st *a,order_st *b)
6014
6150
{
6015
6151
  for (; a && b; a=a->next,b=b->next)
6016
6152
  {
6025
6161
/**
6026
6162
  Nested joins perspective: Remove the last table from the join order.
6027
6163
 
6028
 
  The algorithm is the reciprocal of check_interleaving_with_nj(), hence
6029
 
  parent join nest nodes are updated only when the last table in its child
6030
 
  node is removed. The ASCII graphic below will clarify.
6031
 
 
6032
 
  %A table nesting such as <tt> t1 x [ ( t2 x t3 ) x ( t4 x t5 ) ] </tt>is
6033
 
  represented by the below join nest tree.
6034
 
 
6035
 
  @verbatim
6036
 
                     NJ1
6037
 
                  _/ /  \
6038
 
                _/  /    NJ2
6039
 
              _/   /     / \ 
6040
 
             /    /     /   \
6041
 
   t1 x [ (t2 x t3) x (t4 x t5) ]
6042
 
  @endverbatim
6043
 
 
6044
 
  At the point in time when check_interleaving_with_nj() adds the table t5 to
6045
 
  the query execution plan, QEP, it also directs the node named NJ2 to mark
6046
 
  the table as covered. NJ2 does so by incrementing its @c counter
6047
 
  member. Since all of NJ2's tables are now covered by the QEP, the algorithm
6048
 
  proceeds up the tree to NJ1, incrementing its counter as well. All join
6049
 
  nests are now completely covered by the QEP.
6050
 
 
6051
 
  restore_prev_nj_state() does the above in reverse. As seen above, the node
6052
 
  NJ1 contains the nodes t2, t3, and NJ2. Its counter being equal to 3 means
6053
 
  that the plan covers t2, t3, and NJ2, @e and that the sub-plan (t4 x t5)
6054
 
  completely covers NJ2. The removal of t5 from the partial plan will first
6055
 
  decrement NJ2's counter to 1. It will then detect that NJ2 went from being
6056
 
  completely to partially covered, and hence the algorithm must continue
6057
 
  upwards to NJ1 and decrement its counter to 2. %A subsequent removal of t4
6058
 
  will however not influence NJ1 since it did not un-cover the last table in
6059
 
  NJ2.
6060
 
 
6061
 
  SYNOPSIS
6062
 
    restore_prev_nj_state()
6063
 
      last  join table to remove, it is assumed to be the last in current 
6064
 
            partial join order.
6065
 
     
6066
 
  DESCRIPTION
6067
 
 
6068
6164
    Remove the last table from the partial join order and update the nested
6069
 
    joins counters and join->cur_embedding_map. It is ok to call this 
6070
 
    function for the first table in join order (for which 
 
6165
    joins counters and join->cur_embedding_map. It is ok to call this
 
6166
    function for the first table in join order (for which
6071
6167
    check_interleaving_with_nj has not been called)
6072
6168
 
6073
6169
  @param last  join table to remove, it is assumed to be the last in current
6074
6170
               partial join order.
6075
6171
*/
6076
 
 
6077
6172
static void restore_prev_nj_state(JoinTable *last)
6078
6173
{
6079
 
  TableList *last_emb= last->table->pos_in_table_list->getEmbedding();
6080
 
  Join *join= last->join;
6081
 
  for (;last_emb != NULL; last_emb= last_emb->getEmbedding())
6082
 
  {
6083
 
    nested_join_st *nest= last_emb->getNestedJoin();
6084
 
    
6085
 
    bool was_fully_covered= nest->is_fully_covered();
6086
 
    
6087
 
    if (--nest->counter_ == 0)
6088
 
      join->cur_embedding_map&= ~nest->nj_map;
6089
 
    
6090
 
    if (!was_fully_covered)
 
6174
  TableList *last_emb= last->table->pos_in_table_list->embedding;
 
6175
  JOIN *join= last->join;
 
6176
  while (last_emb)
 
6177
  {
 
6178
    if (last_emb->on_expr)
 
6179
    {
 
6180
      if (!(--last_emb->nested_join->counter_))
 
6181
        join->cur_embedding_map&= ~last_emb->nested_join->nj_map;
 
6182
      else if (last_emb->nested_join->join_list.elements-1 ==
 
6183
               last_emb->nested_join->counter_)
 
6184
        join->cur_embedding_map|= last_emb->nested_join->nj_map;
 
6185
      else
 
6186
        break;
 
6187
    }
 
6188
    last_emb= last_emb->embedding;
 
6189
  }
 
6190
}
 
6191
 
 
6192
/**
 
6193
  Determine if the set is already ordered for order_st BY, so it can
 
6194
  disable join cache because it will change the ordering of the results.
 
6195
  Code handles sort table that is at any location (not only first after
 
6196
  the const tables) despite the fact that it's currently prohibited.
 
6197
  We must disable join cache if the first non-const table alone is
 
6198
  ordered. If there is a temp table the ordering is done as a last
 
6199
  operation and doesn't prevent join cache usage.
 
6200
*/
 
6201
static uint32_t make_join_orderinfo(JOIN *join)
 
6202
{
 
6203
  uint32_t i;
 
6204
  if (join->need_tmp)
 
6205
    return join->tables;
 
6206
 
 
6207
  for (i=join->const_tables ; i < join->tables ; i++)
 
6208
  {
 
6209
    JoinTable *tab= join->join_tab+i;
 
6210
    Table *table= tab->table;
 
6211
    if ((table == join->sort_by_table &&
 
6212
        (!join->order || join->skip_sort_order)) ||
 
6213
        (join->sort_by_table == (Table *) 1 &&  i != join->const_tables))
 
6214
    {
6091
6215
      break;
6092
 
    
6093
 
    join->cur_embedding_map|= nest->nj_map;
 
6216
    }
6094
6217
  }
 
6218
  return i;
6095
6219
}
6096
6220
 
6097
6221
/**
6111
6235
 
6112
6236
  for (uint32_t i=0 ; i < join_tab->ref.key_parts ; i++)
6113
6237
  {
6114
 
    Field *field=table->getField(table->key_info[join_tab->ref.key].key_part[i].fieldnr - 1);
 
6238
    Field *field=table->field[table->key_info[join_tab->ref.key].key_part[i].
 
6239
                              fieldnr-1];
6115
6240
    Item *value=join_tab->ref.items[i];
6116
6241
    cond->add(new Item_func_equal(new Item_field(field), value));
6117
6242
  }
6125
6250
    error=(int) cond->add(join_tab->select->cond);
6126
6251
    join_tab->select_cond=join_tab->select->cond=cond;
6127
6252
  }
6128
 
  else if ((join_tab->select= optimizer::make_select(join_tab->table, 0, 0, cond, 0,
6129
 
                                                     &error)))
 
6253
  else if ((join_tab->select= make_select(join_tab->table, 0, 0, cond, 0,
 
6254
                                          &error)))
6130
6255
    join_tab->select_cond=cond;
6131
6256
 
6132
6257
  return(error ? true : false);
6144
6269
/**
6145
6270
  @} (end of group Query_Optimizer)
6146
6271
*/
6147
 
 
6148
 
} /* namespace drizzled */