~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/join.cc

  • Committer: Monty Taylor
  • Date: 2009-09-22 23:50:12 UTC
  • mto: This revision was merged to the branch mainline in revision 1184.
  • Revision ID: mordred@inaugust.com-20090922235012-i0a3bs91f6krqduc
Fixed multi_malloc.h include guard.
Added include guard checking script.

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"
47
44
#include "drizzled/field/blob.h"
48
45
#include "drizzled/optimizer/position.h"
49
46
#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"
 
47
#include "mysys/my_bit.h"
61
48
 
62
49
#include <algorithm>
63
50
 
64
51
using namespace std;
65
 
 
66
 
namespace drizzled
67
 
{
68
 
 
69
 
extern plugin::StorageEngine *heap_engine;
70
 
extern std::bitset<12> test_flags;
 
52
using namespace drizzled;
71
53
 
72
54
/** 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,
 
55
static bool make_group_fields(JOIN *main_join, JOIN *curr_join);
 
56
static void calc_group_buffer(JOIN *join,order_st *group);
 
57
static bool alloc_group_fields(JOIN *join,order_st *group);
 
58
static uint32_t cache_record_length(JOIN *join, uint32_t index);
 
59
static double prev_record_reads(JOIN *join, uint32_t idx, table_map found_ref);
 
60
static bool get_best_combination(JOIN *join);
 
61
static void set_position(JOIN *join,uint32_t index,JoinTable *table,KeyUse *key);
 
62
static bool choose_plan(JOIN *join,table_map join_tables);
 
63
static void best_access_path(JOIN *join, JoinTable *s,
85
64
                             Session *session,
86
65
                             table_map remaining_tables,
87
66
                             uint32_t idx,
88
67
                             double record_count,
89
68
                             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,
 
69
static void optimize_straight_join(JOIN *join, table_map join_tables);
 
70
static bool greedy_search(JOIN *join, table_map remaining_tables, uint32_t depth, uint32_t prune_level);
 
71
static bool best_extension_by_limited_search(JOIN *join,
93
72
                                             table_map remaining_tables,
94
73
                                             uint32_t idx,
95
74
                                             double record_count,
96
75
                                             double read_time,
97
76
                                             uint32_t depth,
98
77
                                             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,
 
78
static uint32_t determine_search_depth(JOIN* join);
 
79
static bool make_simple_join(JOIN *join,Table *tmp_table);
 
80
static void make_outerjoin_info(JOIN *join);
 
81
static bool make_join_select(JOIN *join,SQL_SELECT *select,COND *item);
 
82
static bool make_join_readinfo(JOIN *join, uint64_t options, uint32_t no_jbuf_after);
 
83
static void update_depend_map(JOIN *join);
 
84
static void update_depend_map(JOIN *join, order_st *order);
 
85
static order_st *remove_constants(JOIN *join,order_st *first_order,COND *cond, bool change_list, bool *simple_order);
 
86
static int return_zero_rows(JOIN *join,
108
87
                            select_result *res,
109
88
                            TableList *tables,
110
89
                            List<Item> &fields,
112
91
                            uint64_t select_options,
113
92
                            const char *info,
114
93
                            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);
 
94
static COND *simplify_joins(JOIN *join, List<TableList> *join_list, COND *conds, bool top);
 
95
static int remove_duplicates(JOIN *join,Table *entry,List<Item> &fields, Item *having);
117
96
static int setup_without_group(Session *session, 
118
97
                               Item **ref_pointer_array,
119
98
                               TableList *tables,
121
100
                               List<Item> &fields,
122
101
                               List<Item> &all_fields,
123
102
                               COND **conds,
124
 
                               Order *order,
125
 
                               Order *group,
 
103
                               order_st *order,
 
104
                               order_st *group,
126
105
                               bool *hidden_group_fields);
127
 
static bool make_join_statistics(Join *join, TableList *leaves, COND *conds, DYNAMIC_ARRAY *keyuse);
 
106
static bool make_join_statistics(JOIN *join, TableList *leaves, COND *conds, DYNAMIC_ARRAY *keyuse);
128
107
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);
 
108
static Table *get_sort_by_table(order_st *a,order_st *b,TableList *tables);
130
109
static void reset_nj_counters(List<TableList> *join_list);
131
 
static bool test_if_subpart(Order *a,Order *b);
 
110
static bool test_if_subpart(order_st *a,order_st *b);
132
111
static void restore_prev_nj_state(JoinTable *last);
 
112
static uint32_t make_join_orderinfo(JOIN *join);
133
113
static bool add_ref_to_table_cond(Session *session, JoinTable *join_tab);
134
114
static void free_blobs(Field **ptr); /* Rename this method...conflicts with another in global namespace... */
135
115
 
145
125
  @retval
146
126
    0   on success
147
127
*/
148
 
int Join::prepare(Item ***rref_pointer_array,
 
128
int JOIN::prepare(Item ***rref_pointer_array,
149
129
                  TableList *tables_init,
150
130
                  uint32_t wild_num,
151
131
                  COND *conds_init,
152
132
                  uint32_t og_num,
153
 
                  Order *order_init,
154
 
                  Order *group_init,
 
133
                  order_st *order_init,
 
134
                  order_st *group_init,
155
135
                  Item *having_init,
156
136
                  Select_Lex *select_lex_arg,
157
137
                  Select_Lex_Unit *unit_arg)
184
164
      setup_tables_and_check_access(session, &select_lex->context, join_list,
185
165
                                    tables_list, &select_lex->leaf_tables,
186
166
                                    false))
187
 
  {
188
167
      return(-1);
189
 
  }
190
168
 
191
169
  TableList *table_ptr;
192
170
  for (table_ptr= select_lex->leaf_tables;
193
171
       table_ptr;
194
172
       table_ptr= table_ptr->next_leaf)
195
 
  {
196
173
    tables++;
197
 
  }
198
 
 
199
174
 
200
175
  if (setup_wild(session, fields_list, &all_fields, wild_num) ||
201
176
      select_lex->setup_ref_array(session, og_num) ||
205
180
        select_lex->leaf_tables, fields_list,
206
181
        all_fields, &conds, order, group_list,
207
182
        &hidden_group_fields))
208
 
    return(-1);
 
183
    return(-1);       /* purecov: inspected */
209
184
 
210
185
  ref_pointer_array= *rref_pointer_array;
211
186
 
220
195
        having->check_cols(1)));
221
196
    select_lex->having_fix_field= 0;
222
197
    if (having_fix_rc || session->is_error())
223
 
      return(-1);
 
198
      return(-1);       /* purecov: inspected */
224
199
    session->lex->allow_sum_func= save_allow_sum_func;
225
200
  }
226
201
 
237
212
        in_subs= (Item_in_subselect*)subselect;
238
213
 
239
214
      {
240
 
        bool do_materialize= true;
 
215
        bool do_materialize= !test(session->variables.optimizer_switch &
 
216
                                   OPTIMIZER_SWITCH_NO_MATERIALIZATION);
241
217
        /*
242
218
          Check if the subquery predicate can be executed via materialization.
243
219
          The required conditions are:
255
231
             (Subquery is non-correlated ||
256
232
              Subquery is correlated to any query outer to IN predicate ||
257
233
              (Subquery is correlated to the immediate outer query &&
258
 
               Subquery !contains {GROUP BY, ORDER BY [LIMIT],
 
234
               Subquery !contains {GROUP BY, order_st BY [LIMIT],
259
235
               aggregate functions) && subquery predicate is not under "NOT IN"))
260
236
          6. No execution method was already chosen (by a prepared statement).
261
237
 
291
267
 
292
268
  if (order)
293
269
  {
294
 
    Order *ord;
 
270
    order_st *ord;
295
271
    for (ord= order; ord; ord= ord->next)
296
272
    {
297
273
      Item *item= *ord->item;
336
312
  {
337
313
    /* Caclulate the number of groups */
338
314
    send_group_parts= 0;
339
 
    for (Order *group_tmp= group_list ; group_tmp ; group_tmp= group_tmp->next)
 
315
    for (order_st *group_tmp= group_list ; group_tmp ; group_tmp= group_tmp->next)
340
316
      send_group_parts++;
341
317
  }
342
318
 
343
319
  if (error)
344
 
    return(-1);
 
320
    goto err;         /* purecov: inspected */
345
321
 
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
322
  if (result && result->prepare(fields_list, unit_arg))
353
 
    return(-1);
 
323
    goto err;         /* purecov: inspected */
354
324
 
355
325
  /* Init join struct */
356
326
  count_field_types(select_lex, &tmp_table_param, all_fields, 0);
362
332
  if (sum_func_count && !group_list && (func_count || field_count))
363
333
  {
364
334
    my_message(ER_WRONG_SUM_SELECT,ER(ER_WRONG_SUM_SELECT),MYF(0));
365
 
    return(-1);
 
335
    goto err;
366
336
  }
367
337
#endif
368
338
  if (select_lex->olap == ROLLUP_TYPE && rollup_init())
369
 
    return(-1);
370
 
 
 
339
    goto err;
371
340
  if (alloc_func_list())
372
 
    return(-1);
373
 
 
374
 
  return 0; // All OK
 
341
    goto err;
 
342
 
 
343
  return(0); // All OK
 
344
 
 
345
err:
 
346
  return(-1);       /* purecov: inspected */
375
347
}
376
348
 
377
349
/*
378
350
  Remove the predicates pushed down into the subquery
379
351
 
380
352
  SYNOPSIS
381
 
    Join::remove_subq_pushed_predicates()
 
353
    JOIN::remove_subq_pushed_predicates()
382
354
      where   IN  Must be NULL
383
355
              OUT The remaining WHERE condition, or NULL
384
356
 
403
375
    that is searched in a byte. But this requires homogenization of the return
404
376
    codes of all Field*::store() methods.
405
377
*/
406
 
void Join::remove_subq_pushed_predicates(Item **where)
 
378
void JOIN::remove_subq_pushed_predicates(Item **where)
407
379
{
408
380
  if (conds->type() == Item::FUNC_ITEM &&
409
381
      ((Item_func *)this->conds)->functype() == Item_func::EQ_FUNC &&
428
400
  @retval
429
401
    1   error
430
402
*/
431
 
int Join::optimize()
 
403
int JOIN::optimize()
432
404
{
433
405
  // to prevent double initialization on EXPLAIN
434
406
  if (optimized)
435
 
    return 0;
 
407
    return(0);
436
408
  optimized= 1;
437
409
 
438
410
  session->set_proc_info("optimizing");
498
470
    {           /* Impossible cond */
499
471
      zero_result_cause=  having_value == Item::COND_FALSE ?
500
472
                           "Impossible HAVING" : "Impossible WHERE";
501
 
      tables = 0;
502
 
      goto setup_subq_exit;
 
473
      error= 0;
 
474
      return(0);
503
475
    }
504
476
  }
505
477
 
508
480
  {
509
481
    int res;
510
482
    /*
511
 
      optimizer::sum_query() returns HA_ERR_KEY_NOT_FOUND if no rows match
 
483
      opt_sum_query() returns HA_ERR_KEY_NOT_FOUND if no rows match
512
484
      to the WHERE conditions,
513
485
      or 1 if all items were resolved,
514
486
      or 0, or an error number HA_ERR_...
515
487
    */
516
 
    if ((res= optimizer::sum_query(select_lex->leaf_tables, all_fields, conds)))
 
488
    if ((res=opt_sum_query(select_lex->leaf_tables, all_fields, conds)))
517
489
    {
518
490
      if (res == HA_ERR_KEY_NOT_FOUND)
519
491
      {
520
492
        zero_result_cause= "No matching min/max row";
521
 
        tables = 0;
522
 
        goto setup_subq_exit;
 
493
        error=0;
 
494
        return(0);
523
495
      }
524
496
      if (res > 1)
525
497
      {
529
501
      if (res < 0)
530
502
      {
531
503
        zero_result_cause= "No matching min/max row";
532
 
        tables = 0;
533
 
        goto setup_subq_exit;
 
504
        error=0;
 
505
        return(0);
534
506
      }
535
507
      zero_result_cause= "Select tables optimized away";
536
508
      tables_list= 0;       // All tables resolved
537
 
      const_tables= tables;
538
509
      /*
539
510
        Extract all table-independent conditions and replace the WHERE
540
 
        clause with them. All other conditions were computed by optimizer::sum_query
 
511
        clause with them. All other conditions were computed by opt_sum_query
541
512
        and the MIN/MAX/COUNT function(s) have been replaced by constants,
542
513
        so there is no need to compute the whole WHERE clause again.
543
514
        Notice that make_cond_for_table() will always succeed to remove all
544
 
        computed conditions, because optimizer::sum_query() is applicable only to
 
515
        computed conditions, because opt_sum_query() is applicable only to
545
516
        conjunctions.
546
517
        Preserve conditions for EXPLAIN.
547
518
      */
550
521
        COND *table_independent_conds= make_cond_for_table(conds, PSEUDO_TABLE_BITS, 0, 0);
551
522
        conds= table_independent_conds;
552
523
      }
553
 
      goto setup_subq_exit;
554
524
    }
555
525
  }
556
526
  if (!tables_list)
583
553
       select_lex->master_unit() == &session->lex->unit)) // upper level SELECT
584
554
  {
585
555
    zero_result_cause= "no matching row in const table";
586
 
    goto setup_subq_exit;
 
556
    error= 0;
 
557
    return(0);
587
558
  }
588
559
  if (!(session->options & OPTION_BIG_SELECTS) &&
589
560
      best_read > (double) session->variables.max_join_size &&
590
561
      !(select_options & SELECT_DESCRIBE))
591
 
  {
 
562
  {           /* purecov: inspected */
592
563
    my_message(ER_TOO_BIG_SELECT, ER(ER_TOO_BIG_SELECT), MYF(0));
593
564
    error= -1;
594
565
    return 1;
595
566
  }
596
567
  if (const_tables && !(select_options & SELECT_NO_UNLOCK))
597
 
    session->unlockSomeTables(table, const_tables);
 
568
    mysql_unlock_some_tables(session, table, const_tables);
598
569
  if (!conds && outer_join)
599
570
  {
600
571
    /* Handle the case where we have an OUTER JOIN without a WHERE */
601
572
    conds=new Item_int((int64_t) 1,1);  // Always true
602
573
  }
603
 
  select= optimizer::make_select(*table, const_table_map,
604
 
                                 const_table_map, conds, 1, &error);
 
574
  select= make_select(*table, const_table_map,
 
575
                      const_table_map, conds, 1, &error);
605
576
  if (error)
606
 
  {
607
 
    error= -1;
 
577
  {           /* purecov: inspected */
 
578
    error= -1;          /* purecov: inspected */
608
579
    return 1;
609
580
  }
610
581
 
644
615
  {
645
616
    conds=new Item_int((int64_t) 0,1);  // Always false
646
617
  }
647
 
 
648
618
  if (make_join_select(this, select, conds))
649
619
  {
650
620
    zero_result_cause=
651
621
      "Impossible WHERE noticed after reading const tables";
652
 
    goto setup_subq_exit;
 
622
    return(0);        // error == 0
653
623
  }
654
624
 
655
625
  error= -1;          /* if goto err */
656
626
 
657
627
  /* Optimize distinct away if possible */
658
628
  {
659
 
    Order *org_order= order;
 
629
    order_st *org_order= order;
660
630
    order= remove_constants(this, order,conds,1, &simple_order);
661
631
    if (session->is_error())
662
632
    {
665
635
    }
666
636
 
667
637
    /*
668
 
      If we are using ORDER BY NULL or ORDER BY const_expression,
 
638
      If we are using order_st BY NULL or order_st BY const_expression,
669
639
      return result in any order (even if we are using a GROUP BY)
670
640
    */
671
641
    if (!order && org_order)
684
654
     The FROM clause must contain a single non-constant table.
685
655
  */
686
656
  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 ||
 
657
      !tmp_table_param.sum_func_count &&
 
658
      (!join_tab[const_tables].select ||
 
659
       !join_tab[const_tables].select->quick ||
690
660
       join_tab[const_tables].select->quick->get_type() !=
691
 
       optimizer::QuickSelectInterface::QS_TYPE_GROUP_MIN_MAX))
 
661
       QUICK_SELECT_I::QS_TYPE_GROUP_MIN_MAX))
692
662
  {
693
663
    if (group_list && list_contains_unique_index(join_tab[const_tables].table, find_field_in_order_list, (void *) group_list))
694
664
    {
696
666
        We have found that grouping can be removed since groups correspond to
697
667
        only one row anyway, but we still have to guarantee correct result
698
668
        order. The line below effectively rewrites the query from GROUP BY
699
 
        <fields> to ORDER BY <fields>. There are two exceptions:
 
669
        <fields> to order_st BY <fields>. There are two exceptions:
700
670
        - if skip_sort_order is set (see above), then we can simply skip
701
671
          GROUP BY;
702
 
        - we can only rewrite ORDER BY if the ORDER BY fields are 'compatible'
 
672
        - we can only rewrite order_st BY if the order_st BY fields are 'compatible'
703
673
          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
 
674
          We only check if the order_st BY is a prefix of GROUP BY. In this case
705
675
          test_if_subpart() copies the ASC/DESC attributes from the original
706
 
          ORDER BY fields.
 
676
          order_st BY fields.
707
677
          If GROUP BY is a prefix of order_st BY, then it is safe to leave
708
678
          'order' as is.
709
679
       */
710
 
      if (! order || test_if_subpart(group_list, order))
 
680
      if (!order || test_if_subpart(group_list, order))
711
681
          order= skip_sort_order ? 0 : group_list;
712
682
      /*
713
683
        If we have an IGNORE INDEX FOR GROUP BY(fields) clause, this must be
742
712
      - We are scanning the whole table without LIMIT
743
713
        This can happen if:
744
714
        - We are using CALC_FOUND_ROWS
745
 
        - We are using an ORDER BY that can't be optimized away.
 
715
        - We are using an order_st BY that can't be optimized away.
746
716
 
747
717
      We don't want to use this optimization when we are using LIMIT
748
718
      because in this case we can just create a temporary table that
774
744
          {
775
745
            /*
776
746
              Force MySQL to read the table in sorted order to get result in
777
 
              ORDER BY order.
 
747
              order_st BY order.
778
748
            */
779
749
            tmp_table_param.quick_group=0;
780
750
          }
790
760
  }
791
761
  simple_group= 0;
792
762
  {
793
 
    Order *old_group_list;
 
763
    order_st *old_group_list;
794
764
    group_list= remove_constants(this, (old_group_list= group_list), conds,
795
765
                                 rollup.state == ROLLUP::STATE_NONE,
796
766
                                 &simple_group);
831
801
    This has to be done if all tables are not already read (const tables)
832
802
    and one of the following conditions holds:
833
803
    - 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
 
804
    - We are using an order_st BY or GROUP BY on fields not in the first table
 
805
    - We are using different order_st BY and GROUP BY orders
836
806
    - The user wants us to buffer the result.
837
807
  */
838
808
  need_tmp= (const_tables != tables &&
840
810
        (group_list && order) ||
841
811
        test(select_options & OPTION_BUFFER_RESULT)));
842
812
 
 
813
  uint32_t no_jbuf_after= make_join_orderinfo(this);
 
814
  uint64_t select_opts_for_readinfo=
 
815
    (select_options & (SELECT_DESCRIBE | SELECT_NO_JOIN_CACHE)) | (0);
 
816
 
843
817
  // No cache for MATCH == 'Don't use join buffering when we use MATCH'.
844
 
  if (make_join_readinfo(this))
 
818
  if (make_join_readinfo(this, select_opts_for_readinfo, no_jbuf_after))
845
819
    return 1;
846
820
 
847
821
  /* Create all structures needed for materialized subquery execution. */
848
822
  if (setup_subquery_materialization())
849
823
    return 1;
850
824
 
851
 
  /* Cache constant expressions in WHERE, HAVING, ON clauses. */
852
 
  cache_const_exprs();
853
 
 
854
825
  /*
855
826
    is this simple IN subquery?
856
827
  */
868
839
        save_index_subquery_explain_info(join_tab, where);
869
840
        join_tab[0].type= AM_UNIQUE_SUBQUERY;
870
841
        error= 0;
871
 
        return(unit->item->change_engine(new subselect_uniquesubquery_engine(session, join_tab, unit->item, where)));
 
842
        return(unit->item->
 
843
                    change_engine(new
 
844
                                  subselect_uniquesubquery_engine(session,
 
845
                                                                  join_tab,
 
846
                                                                  unit->item,
 
847
                                                                  where)));
872
848
      }
873
849
      else if (join_tab[0].type == AM_REF &&
874
850
         join_tab[0].ref.items[0]->name == in_left_expr_name)
877
853
        save_index_subquery_explain_info(join_tab, where);
878
854
        join_tab[0].type= AM_INDEX_SUBQUERY;
879
855
        error= 0;
880
 
        return(unit->item->change_engine(new subselect_indexsubquery_engine(session, join_tab, unit->item, where, NULL, 0)));
 
856
        return(unit->item->
 
857
                    change_engine(new
 
858
                                  subselect_indexsubquery_engine(session,
 
859
                                                                 join_tab,
 
860
                                                                 unit->item,
 
861
                                                                 where,
 
862
                                                                 NULL,
 
863
                                                                 0)));
881
864
      }
882
865
    } 
883
866
    else if (join_tab[0].type == AM_REF_OR_NULL &&
888
871
      error= 0;
889
872
      conds= remove_additional_cond(conds);
890
873
      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)));
 
874
      return(unit->item->
 
875
      change_engine(new subselect_indexsubquery_engine(session,
 
876
                   join_tab,
 
877
                   unit->item,
 
878
                   conds,
 
879
                                                                   having,
 
880
                   1)));
892
881
    }
893
882
 
894
883
  }
940
929
        Force using of tmp table if sorting by a SP or UDF function due to
941
930
        their expensive and probably non-deterministic nature.
942
931
      */
943
 
      for (Order *tmp_order= order; tmp_order ; tmp_order=tmp_order->next)
 
932
      for (order_st *tmp_order= order; tmp_order ; tmp_order=tmp_order->next)
944
933
      {
945
934
        Item *item= *tmp_order->item;
946
935
        if (item->is_expensive())
984
973
 
985
974
    tmp_table_param.hidden_field_count= (all_fields.elements -
986
975
           fields_list.elements);
987
 
    Order *tmp_group= ((!simple_group &&
 
976
    order_st *tmp_group= ((!simple_group && 
988
977
                           ! (test_flags.test(TEST_NO_KEY_GROUP))) ? group_list :
989
 
                                                                     (Order*) 0);
 
978
                                                                     (order_st*) 0);
990
979
    /*
991
980
      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
 
981
      when there is order_st BY or GROUP BY or there is no GROUP BY, but
993
982
      there are aggregate functions, because in all these cases we need
994
983
      all result rows.
995
984
    */
1089
1078
      If this join belongs to an uncacheable subquery save
1090
1079
      the original join
1091
1080
    */
1092
 
    if (select_lex->uncacheable.any() && 
1093
 
        ! is_top_level_join() &&
 
1081
    if (select_lex->uncacheable && !is_top_level_join() &&
1094
1082
        init_save_join_tab())
1095
 
    {
1096
 
      return -1;
1097
 
    }
 
1083
      return(-1);                         /* purecov: inspected */
1098
1084
  }
1099
1085
 
1100
1086
  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;
 
1087
  return(0);
1111
1088
}
1112
1089
 
1113
1090
/**
1114
1091
  Restore values in temporary join.
1115
1092
*/
1116
 
void Join::restore_tmp()
 
1093
void JOIN::restore_tmp()
1117
1094
{
1118
 
  memcpy(tmp_join, this, (size_t) sizeof(Join));
 
1095
  memcpy(tmp_join, this, (size_t) sizeof(JOIN));
1119
1096
}
1120
1097
 
1121
 
int Join::reinit()
 
1098
int JOIN::reinit()
1122
1099
{
1123
1100
  unit->offset_limit_cnt= (ha_rows)(select_lex->offset_limit ?
1124
1101
                                    select_lex->offset_limit->val_uint() :
1128
1105
 
1129
1106
  if (exec_tmp_table1)
1130
1107
  {
1131
 
    exec_tmp_table1->cursor->extra(HA_EXTRA_RESET_STATE);
1132
 
    exec_tmp_table1->cursor->ha_delete_all_rows();
 
1108
    exec_tmp_table1->file->extra(HA_EXTRA_RESET_STATE);
 
1109
    exec_tmp_table1->file->ha_delete_all_rows();
1133
1110
    exec_tmp_table1->free_io_cache();
1134
1111
    exec_tmp_table1->filesort_free_buffers();
1135
1112
  }
1136
1113
  if (exec_tmp_table2)
1137
1114
  {
1138
 
    exec_tmp_table2->cursor->extra(HA_EXTRA_RESET_STATE);
1139
 
    exec_tmp_table2->cursor->ha_delete_all_rows();
 
1115
    exec_tmp_table2->file->extra(HA_EXTRA_RESET_STATE);
 
1116
    exec_tmp_table2->file->ha_delete_all_rows();
1140
1117
    exec_tmp_table2->free_io_cache();
1141
1118
    exec_tmp_table2->filesort_free_buffers();
1142
1119
  }
1170
1147
   @retval 0      success.
1171
1148
   @retval 1      error occurred.
1172
1149
*/
1173
 
bool Join::init_save_join_tab()
 
1150
bool JOIN::init_save_join_tab()
1174
1151
{
1175
 
  if (!(tmp_join= (Join*)session->alloc(sizeof(Join))))
1176
 
    return 1;
1177
 
 
 
1152
  if (!(tmp_join= (JOIN*)session->alloc(sizeof(JOIN))))
 
1153
    return 1;                                  /* purecov: inspected */
1178
1154
  error= 0;              // Ensure that tmp_join.error= 0
1179
1155
  restore_tmp();
1180
 
 
1181
1156
  return 0;
1182
1157
}
1183
1158
 
1184
 
bool Join::save_join_tab()
 
1159
bool JOIN::save_join_tab()
1185
1160
{
1186
 
  if (! join_tab_save && select_lex->master_unit()->uncacheable.any())
 
1161
  if (!join_tab_save && select_lex->master_unit()->uncacheable)
1187
1162
  {
1188
1163
    if (!(join_tab_save= (JoinTable*)session->memdup((unsigned char*) join_tab,
1189
1164
            sizeof(JoinTable) * tables)))
1203
1178
  @todo
1204
1179
    When can we have here session->net.report_error not zero?
1205
1180
*/
1206
 
void Join::exec()
 
1181
void JOIN::exec()
1207
1182
{
1208
1183
  List<Item> *columns_list= &fields_list;
1209
1184
  int      tmp_error;
1215
1190
  {                                           
1216
1191
    /* Only test of functions */
1217
1192
    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
 
    }
 
1193
      select_describe(this, false, false, false, (zero_result_cause?zero_result_cause:"No tables used"));
1226
1194
    else
1227
1195
    {
1228
1196
      result->send_fields(*columns_list);
1273
1241
    return;
1274
1242
  }
1275
1243
 
 
1244
  if ((this->select_lex->options & OPTION_SCHEMA_TABLE) && get_schema_tables_result(this, PROCESSED_BY_JOIN_EXEC))
 
1245
    return;
 
1246
 
1276
1247
  if (select_options & SELECT_DESCRIBE)
1277
1248
  {
1278
1249
    /*
1279
 
      Check if we managed to optimize ORDER BY away and don't use temporary
 
1250
      Check if we managed to optimize order_st BY away and don't use temporary
1280
1251
      table to resolve order_st BY: in that case, we only may need to do
1281
1252
      filesort for GROUP BY.
1282
1253
    */
1295
1266
      order= 0;
1296
1267
    }
1297
1268
    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();
 
1269
    select_describe(this, need_tmp, order != 0 && !skip_sort_order,  select_distinct, !tables ? "No tables used" : NULL);
1304
1270
    return;
1305
1271
  }
1306
1272
 
1307
 
  Join *curr_join= this;
 
1273
  JOIN *curr_join= this;
1308
1274
  List<Item> *curr_all_fields= &all_fields;
1309
1275
  List<Item> *curr_fields_list= &fields_list;
1310
1276
  Table *curr_tmp_table= 0;
1339
1305
      error= tmp_error;
1340
1306
      return;
1341
1307
    }
1342
 
    curr_tmp_table->cursor->info(HA_STATUS_VARIABLE);
 
1308
    curr_tmp_table->file->info(HA_STATUS_VARIABLE);
1343
1309
 
1344
1310
    if (curr_join->having)
1345
1311
      curr_join->having= curr_join->tmp_having= 0; // Allready done
1414
1380
                                                   - curr_join->tmp_fields_list1.elements;
1415
1381
 
1416
1382
      if (exec_tmp_table2)
1417
 
      {
1418
1383
        curr_tmp_table= exec_tmp_table2;
1419
 
      }
1420
1384
      else
1421
1385
      {
1422
1386
        /* group data to new table */
1424
1388
        /*
1425
1389
          If the access method is loose index scan then all MIN/MAX
1426
1390
          functions are precomputed, and should be treated as regular
1427
 
          functions. See extended comment in Join::exec.
 
1391
          functions. See extended comment in JOIN::exec.
1428
1392
        */
1429
1393
        if (curr_join->join_tab->is_using_loose_index_scan())
1430
1394
          curr_join->tmp_table_param.precomputed_group_by= true;
1433
1397
              exec_tmp_table2= create_tmp_table(session,
1434
1398
                                                &curr_join->tmp_table_param,
1435
1399
                                                *curr_all_fields,
1436
 
                                                (Order*) 0,
 
1400
                                                (order_st*) 0,
1437
1401
                                                curr_join->select_distinct &&
1438
1402
                                                !curr_join->group_list,
1439
1403
                                                1, curr_join->select_options,
1440
1404
                                                HA_POS_ERROR,
1441
1405
                                                (char *) "")))
1442
 
        {
1443
1406
          return;
1444
 
        }
1445
 
 
1446
1407
        curr_join->exec_tmp_table2= exec_tmp_table2;
1447
1408
      }
1448
1409
      if (curr_join->group_list)
1490
1451
        error= tmp_error;
1491
1452
        return;
1492
1453
      }
1493
 
      curr_join->join_tab->read_record.end_read_record();
 
1454
      end_read_record(&curr_join->join_tab->read_record);
1494
1455
      curr_join->const_tables= curr_join->tables; // Mark free for cleanup()
1495
1456
      curr_join->join_tab[0].table= 0;           // Table is freed
1496
1457
 
1587
1548
      if (sort_table_cond)
1588
1549
      {
1589
1550
        if (!curr_table->select)
1590
 
          if (!(curr_table->select= new optimizer::SqlSelect))
 
1551
          if (!(curr_table->select= new SQL_SELECT))
1591
1552
            return;
1592
1553
        if (!curr_table->select->cond)
1593
1554
          curr_table->select->cond= sort_table_cond;
1701
1662
  Clean up join.
1702
1663
 
1703
1664
  @return
1704
 
    Return error that hold Join.
 
1665
    Return error that hold JOIN.
1705
1666
*/
1706
 
int Join::destroy()
 
1667
int JOIN::destroy()
1707
1668
{
1708
1669
  select_lex->join= 0;
1709
1670
 
1722
1683
  cond_equal= 0;
1723
1684
 
1724
1685
  cleanup(1);
1725
 
  exec_tmp_table1= NULL;
1726
 
  exec_tmp_table2= NULL;
 
1686
  if (exec_tmp_table1)
 
1687
    exec_tmp_table1->free_tmp_table(session);
 
1688
  if (exec_tmp_table2)
 
1689
    exec_tmp_table2->free_tmp_table(session);
1727
1690
  delete select;
1728
1691
  delete_dynamic(&keyuse);
1729
 
 
1730
1692
  return(error);
1731
1693
}
1732
1694
 
1739
1701
  - try to initialize all data structures needed for the materialized execution
1740
1702
    of the IN predicate,
1741
1703
  - if this fails, then perform the IN=>EXISTS transformation which was
1742
 
    previously blocked during Join::prepare.
 
1704
    previously blocked during JOIN::prepare.
1743
1705
 
1744
1706
  This method is part of the "code generation" query processing phase.
1745
1707
 
1752
1714
  @retval false     success.
1753
1715
  @retval true      error occurred.
1754
1716
*/
1755
 
bool Join::setup_subquery_materialization()
 
1717
bool JOIN::setup_subquery_materialization()
1756
1718
{
1757
1719
  for (Select_Lex_Unit *un= select_lex->first_inner_unit(); un;
1758
1720
       un= un->next_unit())
1774
1736
}
1775
1737
 
1776
1738
/**
1777
 
  Partially cleanup Join after it has executed: close index or rnd read
 
1739
  Partially cleanup JOIN after it has executed: close index or rnd read
1778
1740
  (table cursors), free quick selects.
1779
1741
 
1780
 
    This function is called in the end of execution of a Join, before the used
 
1742
    This function is called in the end of execution of a JOIN, before the used
1781
1743
    tables are unlocked and closed.
1782
1744
 
1783
1745
    For a join that is resolved using a temporary table, the first sweep is
1791
1753
    is called after all rows are sent, but before EOF packet is sent.
1792
1754
 
1793
1755
    For a simple SELECT with no subqueries this function performs a full
1794
 
    cleanup of the Join and calls unlockReadTables to free used base
 
1756
    cleanup of the JOIN and calls mysql_unlock_read_tables to free used base
1795
1757
    tables.
1796
1758
 
1797
 
    If a Join is executed for a subquery or if it has a subquery, we can't
 
1759
    If a JOIN is executed for a subquery or if it has a subquery, we can't
1798
1760
    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
 
1761
    - If a JOIN is not the top level join, we must not unlock the tables
1800
1762
    because the outer select may not have been evaluated yet, and we
1801
1763
    can't unlock only selected tables of a query.
1802
 
    - Additionally, if this Join corresponds to a correlated subquery, we
 
1764
    - Additionally, if this JOIN corresponds to a correlated subquery, we
1803
1765
    should not free quick selects and join buffers because they will be
1804
1766
    needed for the next execution of the correlated subquery.
1805
 
    - However, if this is a Join for a [sub]select, which is not
 
1767
    - However, if this is a JOIN for a [sub]select, which is not
1806
1768
    a correlated subquery itself, but has subqueries, we can free it
1807
 
    fully and also free Joins of all its subqueries. The exception
 
1769
    fully and also free JOINs of all its subqueries. The exception
1808
1770
    is a subquery in SELECT list, e.g: @n
1809
1771
    SELECT a, (select cmax(b) from t1) group by c @n
1810
1772
    This subquery will not be evaluated at first sweep and its value will
1815
1777
  @todo
1816
1778
    Unlock tables even if the join isn't top level select in the tree
1817
1779
*/
1818
 
void Join::join_free()
 
1780
void JOIN::join_free()
1819
1781
{
1820
1782
  Select_Lex_Unit *tmp_unit;
1821
1783
  Select_Lex *sl;
1822
1784
  /*
1823
 
    Optimization: if not EXPLAIN and we are done with the Join,
 
1785
    Optimization: if not EXPLAIN and we are done with the JOIN,
1824
1786
    free all tables.
1825
1787
  */
1826
 
  bool full= (select_lex->uncacheable.none() && ! session->lex->describe);
 
1788
  bool full= (!select_lex->uncacheable && !session->lex->describe);
1827
1789
  bool can_unlock= full;
1828
1790
 
1829
1791
  cleanup(full);
1845
1807
        but all table cursors must be closed before the unlock.
1846
1808
      */
1847
1809
      sl->cleanup_all_joins(full_local);
1848
 
      /* Can't unlock if at least one Join is still needed */
 
1810
      /* Can't unlock if at least one JOIN is still needed */
1849
1811
      can_unlock= can_unlock && full_local;
1850
1812
    }
1851
1813
 
1863
1825
      TODO: unlock tables even if the join isn't top level select in the
1864
1826
      tree.
1865
1827
    */
1866
 
    session->unlockReadTables(lock);           // Don't free join->lock
 
1828
    mysql_unlock_read_tables(session, lock);           // Don't free join->lock
1867
1829
    lock= 0;
1868
1830
  }
1869
1831
 
1882
1844
    With subquery this function definitely will be called several times,
1883
1845
    but even for simple query it can be called several times.
1884
1846
*/
1885
 
void Join::cleanup(bool full)
 
1847
void JOIN::cleanup(bool full)
1886
1848
{
1887
1849
  if (table)
1888
1850
  {
1908
1870
      for (tab= join_tab, end= tab+tables; tab != end; tab++)
1909
1871
      {
1910
1872
        if (tab->table)
1911
 
          tab->table->cursor->ha_index_or_rnd_end();
 
1873
          tab->table->file->ha_index_or_rnd_end();
1912
1874
      }
1913
1875
    }
1914
1876
  }
1927
1889
    */
1928
1890
    tmp_table_param.copy_funcs.empty();
1929
1891
    /*
1930
 
      If we have tmp_join and 'this' Join is not tmp_join and
 
1892
      If we have tmp_join and 'this' JOIN is not tmp_join and
1931
1893
      tmp_table_param.copy_field's  of them are equal then we have to remove
1932
1894
      pointer to  tmp_table_param.copy_field from tmp_join, because it qill
1933
1895
      be removed in tmp_table_param.cleanup().
1946
1908
}
1947
1909
 
1948
1910
/*
1949
 
  used only in Join::clear
 
1911
  used only in JOIN::clear
1950
1912
*/
1951
 
static void clear_tables(Join *join)
 
1913
static void clear_tables(JOIN *join)
1952
1914
{
1953
1915
  /*
1954
1916
    must clear only the non-const tables, as const tables
1967
1929
  @retval
1968
1930
    1 Error
1969
1931
*/
1970
 
bool Join::alloc_func_list()
 
1932
bool JOIN::alloc_func_list()
1971
1933
{
1972
1934
  uint32_t func_count, group_parts;
1973
1935
 
1993
1955
    */
1994
1956
    if (order)
1995
1957
    {
1996
 
      Order *ord;
 
1958
      order_st *ord;
1997
1959
      for (ord= order; ord; ord= ord->next)
1998
1960
        group_parts++;
1999
1961
    }
2019
1981
  @retval
2020
1982
    1  error
2021
1983
*/
2022
 
bool Join::make_sum_func_list(List<Item> &field_list, 
 
1984
bool JOIN::make_sum_func_list(List<Item> &field_list, 
2023
1985
                              List<Item> &send_fields,
2024
1986
                              bool before_group_by, 
2025
1987
                              bool recompute)
2057
2019
}
2058
2020
 
2059
2021
/** Allocate memory needed for other rollup functions. */
2060
 
bool Join::rollup_init()
 
2022
bool JOIN::rollup_init()
2061
2023
{
2062
2024
  uint32_t i,j;
2063
2025
  Item **ref_array;
2103
2065
  Item *item;
2104
2066
  while ((item= it++))
2105
2067
  {
2106
 
    Order *group_tmp;
 
2068
    order_st *group_tmp;
2107
2069
    bool found_in_group= 0;
2108
2070
 
2109
2071
    for (group_tmp= group_list; group_tmp; group_tmp= group_tmp->next)
2132
2094
            return 1;
2133
2095
          new_item->fix_fields(session, (Item **) 0);
2134
2096
          session->change_item_tree(it.ref(), new_item);
2135
 
          for (Order *tmp= group_tmp; tmp; tmp= tmp->next)
 
2097
          for (order_st *tmp= group_tmp; tmp; tmp= tmp->next)
2136
2098
          {
2137
2099
            if (*tmp->item == item)
2138
2100
              session->change_item_tree(tmp->item, new_item);
2172
2134
  @retval
2173
2135
    1    on error
2174
2136
*/
2175
 
bool Join::rollup_make_fields(List<Item> &fields_arg, List<Item> &sel_fields, Item_sum ***func)
 
2137
bool JOIN::rollup_make_fields(List<Item> &fields_arg, List<Item> &sel_fields, Item_sum ***func)
2176
2138
{
2177
2139
  List_iterator_fast<Item> it(fields_arg);
2178
2140
  Item *first_field= sel_fields.head();
2207
2169
    Item *item;
2208
2170
    List_iterator<Item> new_it(rollup.fields[pos]);
2209
2171
    Item **ref_array_start= rollup.ref_pointer_arrays[pos];
2210
 
    Order *start_group;
 
2172
    order_st *start_group;
2211
2173
 
2212
2174
    /* Point to first hidden field */
2213
2175
    Item **ref_array= ref_array_start + fields_arg.elements-1;
2249
2211
      else
2250
2212
      {
2251
2213
        /* Check if this is something that is part of this group by */
2252
 
        Order *group_tmp;
 
2214
        order_st *group_tmp;
2253
2215
        for (group_tmp= start_group, i= pos ;
2254
2216
                  group_tmp ; group_tmp= group_tmp->next, i++)
2255
2217
        {
2302
2264
  @retval
2303
2265
    1   If send_data_failed()
2304
2266
*/
2305
 
int Join::rollup_send_data(uint32_t idx)
 
2267
int JOIN::rollup_send_data(uint32_t idx)
2306
2268
{
2307
2269
  uint32_t i;
2308
2270
  for (i= send_group_parts ; i-- > idx ; )
2342
2304
  @retval
2343
2305
    1   if write_data_failed()
2344
2306
*/
2345
 
int Join::rollup_write_data(uint32_t idx, Table *table_arg)
 
2307
int JOIN::rollup_write_data(uint32_t idx, Table *table_arg)
2346
2308
{
2347
2309
  uint32_t i;
2348
2310
  for (i= send_group_parts ; i-- > idx ; )
2349
2311
  {
2350
2312
    /* Get reference pointers to sum functions in place */
2351
2313
    memcpy(ref_pointer_array, rollup.ref_pointer_arrays[i],
2352
 
           ref_pointer_array_size);
 
2314
     ref_pointer_array_size);
2353
2315
    if ((!having || having->val_int()))
2354
2316
    {
2355
2317
      int write_error;
2361
2323
          item->save_in_result_field(1);
2362
2324
      }
2363
2325
      copy_sum_funcs(sum_funcs_end[i+1], sum_funcs_end[i]);
2364
 
      if ((write_error= table_arg->cursor->insertRecord(table_arg->getInsertRecord())))
 
2326
      if ((write_error= table_arg->file->ha_write_row(table_arg->record[0])))
2365
2327
      {
2366
 
        my_error(ER_USE_SQL_BIG_RESULT, MYF(0));
2367
 
        return 1;
 
2328
  if (create_myisam_from_heap(session, table_arg,
 
2329
                                    tmp_table_param.start_recinfo,
 
2330
                                    &tmp_table_param.recinfo,
 
2331
                                    write_error, 0))
 
2332
    return 1;
2368
2333
      }
2369
2334
    }
2370
2335
  }
2377
2342
  clear results if there are not rows found for group
2378
2343
  (end_send_group/end_write_group)
2379
2344
*/
2380
 
void Join::clear()
 
2345
void JOIN::clear()
2381
2346
{
2382
2347
  clear_tables(this);
2383
2348
  copy_fields(&tmp_table_param);
2391
2356
}
2392
2357
 
2393
2358
/**
2394
 
  change select_result object of Join.
 
2359
  change select_result object of JOIN.
2395
2360
 
2396
2361
  @param res    new select_result object
2397
2362
 
2400
2365
  @retval
2401
2366
    true    error
2402
2367
*/
2403
 
bool Join::change_result(select_result *res)
 
2368
bool JOIN::change_result(select_result *res)
2404
2369
{
2405
2370
  result= res;
2406
2371
  if (result->prepare(fields_list, select_lex->master_unit()))
2411
2376
}
2412
2377
 
2413
2378
/**
2414
 
  Cache constant expressions in WHERE, HAVING, ON conditions.
2415
 
*/
2416
 
 
2417
 
void Join::cache_const_exprs()
2418
 
{
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++)
2435
 
  {
2436
 
    if (*tab->on_expr_ref)
2437
 
    {
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);
2443
 
    }
2444
 
  }
2445
 
}
2446
 
 
2447
 
/**
2448
2379
  @brief
2449
2380
  
2450
2381
  Process one record of the nested loop join.
2455
2386
  applicable to the partial record on hand and in case of success
2456
2387
  submit this record to the next level of the nested loop.
2457
2388
*/
2458
 
enum_nested_loop_state evaluate_join_record(Join *join, JoinTable *join_tab, int error)
 
2389
enum_nested_loop_state evaluate_join_record(JOIN *join, JoinTable *join_tab, int error)
2459
2390
{
2460
2391
  bool not_used_in_distinct= join_tab->not_used_in_distinct;
2461
2392
  ha_rows found_records= join->found_records;
2465
2396
    return NESTED_LOOP_ERROR;
2466
2397
  if (error < 0)
2467
2398
    return NESTED_LOOP_NO_MORE_ROWS;
2468
 
  if (join->session->getKilled())                       // Aborted by user
 
2399
  if (join->session->killed)                    // Aborted by user
2469
2400
  {
2470
2401
    join->session->send_kill_message();
2471
 
    return NESTED_LOOP_KILLED;
 
2402
    return NESTED_LOOP_KILLED;               /* purecov: inspected */
2472
2403
  }
2473
2404
  if (!select_cond || select_cond->val_int())
2474
2405
  {
2558
2489
        return NESTED_LOOP_NO_MORE_ROWS;
2559
2490
    }
2560
2491
    else
2561
 
      join_tab->read_record.cursor->unlock_row();
 
2492
      join_tab->read_record.file->unlock_row();
2562
2493
  }
2563
2494
  else
2564
2495
  {
2568
2499
    */
2569
2500
    join->examined_rows++;
2570
2501
    join->session->row_count++;
2571
 
    join_tab->read_record.cursor->unlock_row();
 
2502
    join_tab->read_record.file->unlock_row();
2572
2503
  }
2573
2504
  return NESTED_LOOP_OK;
2574
2505
}
2579
2510
    level of the nested loop. This function is used in case we have
2580
2511
    an OUTER join and no matching record was found.
2581
2512
*/
2582
 
enum_nested_loop_state evaluate_null_complemented_join_record(Join *join, JoinTable *join_tab)
 
2513
enum_nested_loop_state evaluate_null_complemented_join_record(JOIN *join, JoinTable *join_tab)
2583
2514
{
2584
2515
  /*
2585
2516
    The table join_tab is the first inner table of a outer join operation
2635
2566
  return (*join_tab->next_select)(join, join_tab+1, 0);
2636
2567
}
2637
2568
 
2638
 
enum_nested_loop_state flush_cached_records(Join *join, JoinTable *join_tab, bool skip_last)
 
2569
enum_nested_loop_state flush_cached_records(JOIN *join, JoinTable *join_tab, bool skip_last)
2639
2570
{
2640
2571
  enum_nested_loop_state rc= NESTED_LOOP_OK;
2641
2572
  int error;
2642
 
  ReadRecord *info;
 
2573
  READ_RECORD *info;
2643
2574
 
2644
2575
  join_tab->table->null_row= 0;
2645
2576
  if (!join_tab->cache.records)
2646
 
  {
2647
2577
    return NESTED_LOOP_OK;                      /* Nothing to do */
2648
 
  }
2649
 
 
2650
2578
  if (skip_last)
2651
 
  {
2652
 
    (void) join_tab->cache.store_record_in_cache(); // Must save this for later
2653
 
  }
2654
 
 
2655
 
 
 
2579
    (void) store_record_in_cache(&join_tab->cache); // Must save this for later
2656
2580
  if (join_tab->use_quick == 2)
2657
2581
  {
2658
2582
    if (join_tab->select->quick)
2664
2588
  /* read through all records */
2665
2589
  if ((error=join_init_read_record(join_tab)))
2666
2590
  {
2667
 
    join_tab->cache.reset_cache_write();
 
2591
    reset_cache_write(&join_tab->cache);
2668
2592
    return error < 0 ? NESTED_LOOP_NO_MORE_ROWS: NESTED_LOOP_ERROR;
2669
2593
  }
2670
2594
 
2677
2601
  info= &join_tab->read_record;
2678
2602
  do
2679
2603
  {
2680
 
    if (join->session->getKilled())
 
2604
    if (join->session->killed)
2681
2605
    {
2682
2606
      join->session->send_kill_message();
2683
 
      return NESTED_LOOP_KILLED;
 
2607
      return NESTED_LOOP_KILLED; // Aborted by user /* purecov: inspected */
2684
2608
    }
2685
 
    optimizer::SqlSelect *select= join_tab->select;
 
2609
    SQL_SELECT *select=join_tab->select;
2686
2610
    if (rc == NESTED_LOOP_OK &&
2687
2611
        (!join_tab->cache.select || !join_tab->cache.select->skip_record()))
2688
2612
    {
2689
2613
      uint32_t i;
2690
 
      join_tab->cache.reset_cache_read();
 
2614
      reset_cache_read(&join_tab->cache);
2691
2615
      for (i=(join_tab->cache.records- (skip_last ? 1 : 0)) ; i-- > 0 ;)
2692
2616
      {
2693
2617
              join_tab->readCachedRecord();
2698
2622
          rc= (join_tab->next_select)(join,join_tab+1,0);
2699
2623
          if (rc != NESTED_LOOP_OK && rc != NESTED_LOOP_NO_MORE_ROWS)
2700
2624
          {
2701
 
            join_tab->cache.reset_cache_write();
 
2625
            reset_cache_write(&join_tab->cache);
2702
2626
            return rc;
2703
2627
          }
2704
2628
 
2711
2635
 
2712
2636
  if (skip_last)
2713
2637
    join_tab->readCachedRecord();               // Restore current record
2714
 
  join_tab->cache.reset_cache_write();
 
2638
  reset_cache_write(&join_tab->cache);
2715
2639
  if (error > 0)                                // Fatal error
2716
 
    return NESTED_LOOP_ERROR;
 
2640
    return NESTED_LOOP_ERROR;                   /* purecov: inspected */
2717
2641
  for (JoinTable *tmp2=join->join_tab; tmp2 != join_tab ; tmp2++)
2718
2642
    tmp2->table->status=tmp2->status;
2719
2643
  return NESTED_LOOP_OK;
2743
2667
                               operation.
2744
2668
   All return values except NESTED_LOOP_OK abort the nested loop.
2745
2669
*****************************************************************************/
2746
 
enum_nested_loop_state end_send(Join *join, JoinTable *, bool end_of_records)
 
2670
enum_nested_loop_state end_send(JOIN *join, JoinTable *, bool end_of_records)
2747
2671
{
2748
2672
  if (! end_of_records)
2749
2673
  {
2754
2678
    if (join->do_send_rows)
2755
2679
      error=join->result->send_data(*join->fields);
2756
2680
    if (error)
2757
 
      return NESTED_LOOP_ERROR;
 
2681
      return NESTED_LOOP_ERROR; /* purecov: inspected */
2758
2682
    if (++join->send_records >= join->unit->select_limit_cnt && join->do_send_rows)
2759
2683
    {
2760
2684
      if (join->select_options & OPTION_FOUND_ROWS)
2763
2687
        if ((join->tables == 1) && !join->tmp_table && !join->sort_and_group
2764
2688
            && !join->send_group_parts && !join->having && !jt->select_cond &&
2765
2689
            !(jt->select && jt->select->quick) &&
2766
 
            (jt->table->cursor->getEngine()->check_flag(HTON_BIT_STATS_RECORDS_IS_EXACT)) &&
 
2690
            (jt->table->file->ha_table_flags() & HA_STATS_RECORDS_IS_EXACT) &&
2767
2691
                  (jt->ref.key < 0))
2768
2692
        {
2769
2693
          /* Join over all rows in table;  Return number of found rows */
2778
2702
          }
2779
2703
          else
2780
2704
          {
2781
 
            table->cursor->info(HA_STATUS_VARIABLE);
2782
 
            join->send_records= table->cursor->stats.records;
 
2705
            table->file->info(HA_STATUS_VARIABLE);
 
2706
            join->send_records= table->file->stats.records;
2783
2707
          }
2784
2708
        }
2785
2709
        else
2805
2729
  return NESTED_LOOP_OK;
2806
2730
}
2807
2731
 
2808
 
enum_nested_loop_state end_write(Join *join, JoinTable *, bool end_of_records)
 
2732
enum_nested_loop_state end_write(JOIN *join, JoinTable *, bool end_of_records)
2809
2733
{
2810
2734
  Table *table= join->tmp_table;
2811
2735
 
2812
 
  if (join->session->getKilled())                       // Aborted by user
 
2736
  if (join->session->killed)                    // Aborted by user
2813
2737
  {
2814
2738
    join->session->send_kill_message();
2815
 
    return NESTED_LOOP_KILLED;
 
2739
    return NESTED_LOOP_KILLED;             /* purecov: inspected */
2816
2740
  }
2817
2741
  if (!end_of_records)
2818
2742
  {
2819
2743
    copy_fields(&join->tmp_table_param);
2820
 
    if (copy_funcs(join->tmp_table_param.items_to_copy, join->session))
2821
 
      return NESTED_LOOP_ERROR;
 
2744
    copy_funcs(join->tmp_table_param.items_to_copy);
2822
2745
    if (!join->having || join->having->val_int())
2823
2746
    {
2824
2747
      int error;
2825
2748
      join->found_records++;
2826
 
      if ((error=table->cursor->insertRecord(table->getInsertRecord())))
 
2749
      if ((error=table->file->ha_write_row(table->record[0])))
2827
2750
      {
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
 
2751
        if (!table->file->is_fatal_error(error, HA_CHECK_DUP))
 
2752
          goto end;
 
2753
        if (create_myisam_from_heap(join->session, table,
 
2754
                                          join->tmp_table_param.start_recinfo,
 
2755
                                          &join->tmp_table_param.recinfo,
 
2756
                  error, 1))
 
2757
          return NESTED_LOOP_ERROR;        // Not a table_is_full error
 
2758
        table->s->uniques= 0;                   // To ensure rows are the same
2835
2759
      }
2836
2760
      if (++join->send_records >= join->tmp_table_param.end_write_records && join->do_send_rows)
2837
2761
      {
2843
2767
      }
2844
2768
    }
2845
2769
  }
2846
 
 
 
2770
end:
2847
2771
  return NESTED_LOOP_OK;
2848
2772
}
2849
2773
 
2850
2774
/** 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)
 
2775
enum_nested_loop_state end_update(JOIN *join, JoinTable *, bool end_of_records)
2852
2776
{
2853
2777
  Table *table= join->tmp_table;
2854
 
  Order *group;
 
2778
  order_st *group;
2855
2779
  int   error;
2856
2780
 
2857
2781
  if (end_of_records)
2858
2782
    return NESTED_LOOP_OK;
2859
 
  if (join->session->getKilled())                       // Aborted by user
 
2783
  if (join->session->killed)                    // Aborted by user
2860
2784
  {
2861
2785
    join->session->send_kill_message();
2862
 
    return NESTED_LOOP_KILLED;
 
2786
    return NESTED_LOOP_KILLED;             /* purecov: inspected */
2863
2787
  }
2864
2788
 
2865
2789
  join->found_records++;
2873
2797
    if (item->maybe_null)
2874
2798
      group->buff[-1]= (char) group->field->is_null();
2875
2799
  }
2876
 
  if (!table->cursor->index_read_map(table->getUpdateRecord(),
 
2800
  if (!table->file->index_read_map(table->record[1],
2877
2801
                                   join->tmp_table_param.group_buff,
2878
2802
                                   HA_WHOLE_KEY,
2879
2803
                                   HA_READ_KEY_EXACT))
2880
2804
  {                                             /* Update old record */
2881
2805
    table->restoreRecord();
2882
2806
    update_tmptable_sum_func(join->sum_funcs,table);
2883
 
    if ((error= table->cursor->updateRecord(table->getUpdateRecord(),
2884
 
                                          table->getInsertRecord())))
 
2807
    if ((error= table->file->ha_update_row(table->record[1],
 
2808
                                          table->record[0])))
2885
2809
    {
2886
 
      table->print_error(error,MYF(0));
2887
 
      return NESTED_LOOP_ERROR;
 
2810
      table->file->print_error(error,MYF(0));   /* purecov: inspected */
 
2811
      return NESTED_LOOP_ERROR;            /* purecov: inspected */
2888
2812
    }
2889
2813
    return NESTED_LOOP_OK;
2890
2814
  }
2894
2818
    We can't copy all data as the key may have different format
2895
2819
    as the row data (for example as with VARCHAR keys)
2896
2820
  */
2897
 
  KeyPartInfo *key_part;
 
2821
  KEY_PART_INFO *key_part;
2898
2822
  for (group=table->group,key_part=table->key_info[0].key_part;
2899
2823
       group ;
2900
2824
       group=group->next,key_part++)
2901
2825
  {
2902
2826
    if (key_part->null_bit)
2903
 
      memcpy(table->getInsertRecord()+key_part->offset, group->buff, 1);
 
2827
      memcpy(table->record[0]+key_part->offset, group->buff, 1);
2904
2828
  }
2905
2829
  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())))
 
2830
  copy_funcs(join->tmp_table_param.items_to_copy);
 
2831
  if ((error=table->file->ha_write_row(table->record[0])))
2909
2832
  {
2910
 
    my_error(ER_USE_SQL_BIG_RESULT, MYF(0));
2911
 
    return NESTED_LOOP_ERROR;        // Table is_full error
 
2833
    if (create_myisam_from_heap(join->session, table,
 
2834
                                join->tmp_table_param.start_recinfo,
 
2835
                                &join->tmp_table_param.recinfo,
 
2836
                                error, 0))
 
2837
      return NESTED_LOOP_ERROR;            // Not a table_is_full error
 
2838
    /* Change method to update rows */
 
2839
    table->file->ha_index_init(0, 0);
 
2840
    join->join_tab[join->tables-1].next_select= end_unique_update;
2912
2841
  }
2913
2842
  join->send_records++;
2914
2843
  return NESTED_LOOP_OK;
2915
2844
}
2916
2845
 
2917
2846
/** 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)
 
2847
enum_nested_loop_state end_unique_update(JOIN *join, JoinTable *, bool end_of_records)
2919
2848
{
2920
2849
  Table *table= join->tmp_table;
2921
2850
  int   error;
2922
2851
 
2923
2852
  if (end_of_records)
2924
2853
    return NESTED_LOOP_OK;
2925
 
  if (join->session->getKilled())                       // Aborted by user
 
2854
  if (join->session->killed)                    // Aborted by user
2926
2855
  {
2927
2856
    join->session->send_kill_message();
2928
 
    return NESTED_LOOP_KILLED;
 
2857
    return NESTED_LOOP_KILLED;             /* purecov: inspected */
2929
2858
  }
2930
2859
 
2931
2860
  init_tmptable_sum_functions(join->sum_funcs);
2932
2861
  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;
 
2862
  copy_funcs(join->tmp_table_param.items_to_copy);
2935
2863
 
2936
 
  if (!(error= table->cursor->insertRecord(table->getInsertRecord())))
 
2864
  if (!(error= table->file->ha_write_row(table->record[0])))
2937
2865
    join->send_records++;                       // New group
2938
2866
  else
2939
2867
  {
2940
 
    if ((int) table->get_dup_key(error) < 0)
 
2868
    if ((int) table->file->get_dup_key(error) < 0)
2941
2869
    {
2942
 
      table->print_error(error,MYF(0));
2943
 
      return NESTED_LOOP_ERROR;
 
2870
      table->file->print_error(error,MYF(0));   /* purecov: inspected */
 
2871
      return NESTED_LOOP_ERROR;            /* purecov: inspected */
2944
2872
    }
2945
 
    if (table->cursor->rnd_pos(table->getUpdateRecord(),table->cursor->dup_ref))
 
2873
    if (table->file->rnd_pos(table->record[1],table->file->dup_ref))
2946
2874
    {
2947
 
      table->print_error(error,MYF(0));
2948
 
      return NESTED_LOOP_ERROR;
 
2875
      table->file->print_error(error,MYF(0));   /* purecov: inspected */
 
2876
      return NESTED_LOOP_ERROR;            /* purecov: inspected */
2949
2877
    }
2950
2878
    table->restoreRecord();
2951
2879
    update_tmptable_sum_func(join->sum_funcs,table);
2952
 
    if ((error= table->cursor->updateRecord(table->getUpdateRecord(),
2953
 
                                          table->getInsertRecord())))
 
2880
    if ((error= table->file->ha_update_row(table->record[1],
 
2881
                                          table->record[0])))
2954
2882
    {
2955
 
      table->print_error(error,MYF(0));
2956
 
      return NESTED_LOOP_ERROR;
 
2883
      table->file->print_error(error,MYF(0));   /* purecov: inspected */
 
2884
      return NESTED_LOOP_ERROR;            /* purecov: inspected */
2957
2885
    }
2958
2886
  }
2959
2887
  return NESTED_LOOP_OK;
2971
2899
  @retval
2972
2900
    1   failed
2973
2901
*/
2974
 
static bool make_group_fields(Join *main_join, Join *curr_join)
 
2902
static bool make_group_fields(JOIN *main_join, JOIN *curr_join)
2975
2903
{
2976
2904
  if (main_join->group_fields_cache.elements)
2977
2905
  {
2990
2918
/**
2991
2919
  calc how big buffer we need for comparing group entries.
2992
2920
*/
2993
 
static void calc_group_buffer(Join *join, Order *group)
 
2921
static void calc_group_buffer(JOIN *join,order_st *group)
2994
2922
{
2995
2923
  uint32_t key_length=0, parts=0, null_parts=0;
2996
2924
 
3016
2944
      case REAL_RESULT:
3017
2945
        key_length+= sizeof(double);
3018
2946
        break;
3019
 
 
3020
2947
      case INT_RESULT:
3021
2948
        key_length+= sizeof(int64_t);
3022
2949
        break;
3023
 
 
3024
2950
      case DECIMAL_RESULT:
3025
2951
        key_length+= my_decimal_get_binary_size(group_item->max_length -
3026
2952
                                                (group_item->decimals ? 1 : 0),
3027
2953
                                                group_item->decimals);
3028
2954
        break;
3029
 
 
3030
2955
      case STRING_RESULT:
3031
 
        {
3032
 
          enum enum_field_types type= group_item->field_type();
 
2956
      {
 
2957
        enum enum_field_types type= group_item->field_type();
 
2958
        /*
 
2959
          As items represented as DATE/TIME fields in the group buffer
 
2960
          have STRING_RESULT result type, we increase the length
 
2961
          by 8 as maximum pack length of such fields.
 
2962
        */
 
2963
        if (type == DRIZZLE_TYPE_DATE ||
 
2964
            type == DRIZZLE_TYPE_DATETIME ||
 
2965
            type == DRIZZLE_TYPE_TIMESTAMP)
 
2966
        {
 
2967
          key_length+= 8;
 
2968
        }
 
2969
        else
 
2970
        {
3033
2971
          /*
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.
 
2972
            Group strings are taken as varstrings and require an length field.
 
2973
            A field is not yet created by create_tmp_field()
 
2974
            and the sizes should match up.
3037
2975
          */
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;
 
2976
          key_length+= group_item->max_length + HA_KEY_BLOB_LENGTH;
3054
2977
        }
3055
 
 
3056
 
      case ROW_RESULT:
 
2978
        break;
 
2979
      }
 
2980
      default:
3057
2981
        /* This case should never be choosen */
3058
2982
        assert(0);
3059
2983
        my_error(ER_OUT_OF_RESOURCES, MYF(ME_FATALERROR));
3060
2984
      }
3061
2985
    }
3062
 
 
3063
2986
    parts++;
3064
 
 
3065
2987
    if (group_item->maybe_null)
3066
2988
      null_parts++;
3067
2989
  }
3068
 
 
3069
2990
  join->tmp_table_param.group_length=key_length+null_parts;
3070
2991
  join->tmp_table_param.group_parts=parts;
3071
2992
  join->tmp_table_param.group_null_parts=null_parts;
3076
2997
 
3077
2998
  Groups are saved in reverse order for easyer check loop.
3078
2999
*/
3079
 
static bool alloc_group_fields(Join *join, Order *group)
 
3000
static bool alloc_group_fields(JOIN *join,order_st *group)
3080
3001
{
3081
3002
  if (group)
3082
3003
  {
3083
3004
    for (; group ; group=group->next)
3084
3005
    {
3085
 
      Cached_item *tmp= new_Cached_item(join->session, *group->item);
 
3006
      Cached_item *tmp=new_Cached_item(join->session, *group->item, false);
3086
3007
      if (!tmp || join->group_fields.push_front(tmp))
3087
3008
        return true;
3088
3009
    }
3091
3012
  return false;
3092
3013
}
3093
3014
 
3094
 
static uint32_t cache_record_length(Join *join,uint32_t idx)
 
3015
static uint32_t cache_record_length(JOIN *join,uint32_t idx)
3095
3016
{
3096
3017
  uint32_t length=0;
3097
3018
  JoinTable **pos,**end;
3159
3080
  RETURN
3160
3081
    Expected number of row combinations
3161
3082
*/
3162
 
static double prev_record_reads(Join *join, uint32_t idx, table_map found_ref)
 
3083
static double prev_record_reads(JOIN *join, uint32_t idx, table_map found_ref)
3163
3084
{
3164
3085
  double found=1.0;
3165
3086
  optimizer::Position *pos_end= join->getSpecificPosInPartialPlan(-1);
3171
3092
    {
3172
3093
      found_ref|= pos->getRefDependMap();
3173
3094
      /*
3174
 
        For the case of "t1 LEFT Join t2 ON ..." where t2 is a const table
 
3095
        For the case of "t1 LEFT JOIN t2 ON ..." where t2 is a const table
3175
3096
        with no matching row we will get position[t2].records_read==0.
3176
3097
        Actually the size of output is one null-complemented row, therefore
3177
3098
        we will use value of 1 whenever we get records_read==0.
3196
3117
/**
3197
3118
  Set up join struct according to best position.
3198
3119
*/
3199
 
static bool get_best_combination(Join *join)
 
3120
static bool get_best_combination(JOIN *join)
3200
3121
{
3201
3122
  uint32_t i,tablenr;
3202
3123
  table_map used_tables;
3203
3124
  JoinTable *join_tab,*j;
3204
 
  optimizer::KeyUse *keyuse;
 
3125
  KeyUse *keyuse;
3205
3126
  uint32_t table_count;
3206
3127
  Session *session=join->session;
3207
3128
  optimizer::Position cur_pos;
3223
3144
    used_tables|= form->map;
3224
3145
    form->reginfo.join_tab=j;
3225
3146
    if (!*j->on_expr_ref)
3226
 
      form->reginfo.not_exists_optimize=0;  // Only with LEFT Join
 
3147
      form->reginfo.not_exists_optimize=0;  // Only with LEFT JOIN
3227
3148
    if (j->type == AM_CONST)
3228
3149
      continue;         // Handled in make_join_stat..
3229
3150
 
3249
3170
}
3250
3171
 
3251
3172
/** 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)
 
3173
static void set_position(JOIN *join,uint32_t idx,JoinTable *table,KeyUse *key)
3256
3174
{
3257
3175
  optimizer::Position tmp_pos(1.0, /* This is a const table */
3258
3176
                              0.0,
3291
3209
  @retval
3292
3210
    true        Fatal error
3293
3211
*/
3294
 
static bool choose_plan(Join *join, table_map join_tables)
 
3212
static bool choose_plan(JOIN *join, table_map join_tables)
3295
3213
{
3296
3214
  uint32_t search_depth= join->session->variables.optimizer_search_depth;
3297
3215
  uint32_t prune_level=  join->session->variables.optimizer_prune_level;
3307
3225
      Apply heuristic: pre-sort all access plans with respect to the number of
3308
3226
      records accessed.
3309
3227
  */
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);
 
3228
  my_qsort(join->best_ref + join->const_tables,
 
3229
           join->tables - join->const_tables, sizeof(JoinTable*),
 
3230
           straight_join ? join_tab_cmp_straight : join_tab_cmp);
3313
3231
  if (straight_join)
3314
3232
  {
3315
3233
    optimize_straight_join(join, join_tables);
3358
3276
  @return
3359
3277
    None
3360
3278
*/
3361
 
static void best_access_path(Join *join,
 
3279
static void best_access_path(JOIN *join,
3362
3280
                             JoinTable *s,
3363
3281
                             Session *session,
3364
3282
                             table_map remaining_tables,
3366
3284
                             double record_count,
3367
3285
                             double)
3368
3286
{
3369
 
  optimizer::KeyUse *best_key= NULL;
3370
 
  uint32_t best_max_key_part= 0;
 
3287
  KeyUse *best_key=         0;
 
3288
  uint32_t best_max_key_part=   0;
3371
3289
  bool found_constraint= 0;
3372
 
  double best= DBL_MAX;
3373
 
  double best_time= DBL_MAX;
3374
 
  double records= DBL_MAX;
 
3290
  double best=              DBL_MAX;
 
3291
  double best_time=         DBL_MAX;
 
3292
  double records=           DBL_MAX;
3375
3293
  table_map best_ref_depends_map= 0;
3376
3294
  double tmp;
3377
3295
  ha_rows rec;
3379
3297
  if (s->keyuse)
3380
3298
  {                                            /* Use key if possible */
3381
3299
    Table *table= s->table;
3382
 
    optimizer::KeyUse *keyuse= NULL;
3383
 
    optimizer::KeyUse *start_key= NULL;
 
3300
    KeyUse *keyuse,*start_key=0;
3384
3301
    double best_records= DBL_MAX;
3385
3302
    uint32_t max_key_part=0;
3386
3303
 
3387
3304
    /* Test how we can use keys */
3388
3305
    rec= s->records/MATCHING_ROWS_IN_OTHER_TABLE;  // Assumed records/key
3389
 
    for (keyuse= s->keyuse; keyuse->getTable() == table; )
 
3306
    for (keyuse=s->keyuse ; keyuse->table == table ;)
3390
3307
    {
3391
3308
      key_part_map found_part= 0;
3392
3309
      table_map found_ref= 0;
3393
 
      uint32_t key= keyuse->getKey();
3394
 
      KeyInfo *keyinfo= table->key_info + key;
 
3310
      uint32_t key= keyuse->key;
 
3311
      KEY *keyinfo= table->key_info+key;
3395
3312
      /* Bitmap of keyparts where the ref access is over 'keypart=const': */
3396
3313
      key_part_map const_part= 0;
3397
3314
      /* The or-null keypart in ref-or-null access: */
3402
3319
 
3403
3320
      do /* For each keypart */
3404
3321
      {
3405
 
        uint32_t keypart= keyuse->getKeypart();
 
3322
        uint32_t keypart= keyuse->keypart;
3406
3323
        table_map best_part_found_ref= 0;
3407
3324
        double best_prev_record_reads= DBL_MAX;
3408
3325
 
3413
3330
            if 1. expression doesn't refer to forward tables
3414
3331
               2. we won't get two ref-or-null's
3415
3332
          */
3416
 
          if (! (remaining_tables & keyuse->getUsedTables()) &&
3417
 
              ! (ref_or_null_part && (keyuse->getOptimizeFlags() &
3418
 
                                      KEY_OPTIMIZE_REF_OR_NULL)))
 
3333
          if (!(remaining_tables & keyuse->used_tables) &&
 
3334
              !(ref_or_null_part && (keyuse->optimize &
 
3335
                                     KEY_OPTIMIZE_REF_OR_NULL)))
3419
3336
          {
3420
 
            found_part|= keyuse->getKeypartMap();
3421
 
            if (! (keyuse->getUsedTables() & ~join->const_table_map))
3422
 
              const_part|= keyuse->getKeypartMap();
 
3337
            found_part|= keyuse->keypart_map;
 
3338
            if (!(keyuse->used_tables & ~join->const_table_map))
 
3339
              const_part|= keyuse->keypart_map;
3423
3340
 
3424
3341
            double tmp2= prev_record_reads(join, idx, (found_ref |
3425
 
                                                       keyuse->getUsedTables()));
 
3342
                                                      keyuse->used_tables));
3426
3343
            if (tmp2 < best_prev_record_reads)
3427
3344
            {
3428
 
              best_part_found_ref= keyuse->getUsedTables() & ~join->const_table_map;
 
3345
              best_part_found_ref= keyuse->used_tables & ~join->const_table_map;
3429
3346
              best_prev_record_reads= tmp2;
3430
3347
            }
3431
 
            if (rec > keyuse->getTableRows())
3432
 
              rec= keyuse->getTableRows();
 
3348
            if (rec > keyuse->ref_table_rows)
 
3349
              rec= keyuse->ref_table_rows;
3433
3350
      /*
3434
3351
        If there is one 'key_column IS NULL' expression, we can
3435
3352
        use this ref_or_null optimisation of this field
3436
3353
      */
3437
 
            if (keyuse->getOptimizeFlags() & KEY_OPTIMIZE_REF_OR_NULL)
3438
 
              ref_or_null_part|= keyuse->getKeypartMap();
 
3354
            if (keyuse->optimize & KEY_OPTIMIZE_REF_OR_NULL)
 
3355
              ref_or_null_part |= keyuse->keypart_map;
3439
3356
          }
3440
3357
 
3441
3358
          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);
 
3359
        } while (keyuse->table == table && keyuse->key == key &&
 
3360
                 keyuse->keypart == keypart);
 
3361
  found_ref|= best_part_found_ref;
 
3362
      } while (keyuse->table == table && keyuse->key == key);
3446
3363
 
3447
3364
      /*
3448
3365
        Assume that that each key matches a proportional part of table.
3504
3421
                records=
3505
3422
                  ((double) s->records / (double) rec *
3506
3423
                   (1.0 +
3507
 
                    ((double) (table->getShare()->max_key_length-keyinfo->key_length) /
3508
 
                     (double) table->getShare()->max_key_length)));
 
3424
                    ((double) (table->s->max_key_length-keyinfo->key_length) /
 
3425
                     (double) table->s->max_key_length)));
3509
3426
                if (records < 2.0)
3510
3427
                  records=2.0;               /* Can't be as good as a unique */
3511
3428
              }
3533
3450
            if (table->covering_keys.test(key))
3534
3451
            {
3535
3452
              /* we can use only index tree */
3536
 
              tmp= record_count * table->cursor->index_only_read_time(key, tmp);
 
3453
              tmp= record_count * table->file->index_only_read_time(key, tmp);
3537
3454
            }
3538
3455
            else
3539
3456
              tmp= record_count * min(tmp,s->worst_seeks);
3547
3464
            Set tmp to (previous record count) * (records / combination)
3548
3465
          */
3549
3466
          if ((found_part & 1) &&
3550
 
              (!(table->index_flags(key) & HA_ONLY_WHOLE_INDEX) ||
3551
 
               found_part == PREV_BITS(uint, keyinfo->key_parts)))
 
3467
              (!(table->file->index_flags(key, 0, 0) & HA_ONLY_WHOLE_INDEX) ||
 
3468
               found_part == PREV_BITS(uint,keyinfo->key_parts)))
3552
3469
          {
3553
3470
            max_key_part= max_part_bit(found_part);
3554
3471
            /*
3627
3544
              else
3628
3545
              {
3629
3546
                /*
3630
 
                  Assume that the first key part matches 1% of the cursor
 
3547
                  Assume that the first key part matches 1% of the file
3631
3548
                  and that the whole key matches 10 (duplicates) or 1
3632
3549
                  (unique) records.
3633
3550
                  Assume also that more key matches proportionally more
3698
3615
            if (table->covering_keys.test(key))
3699
3616
            {
3700
3617
              /* we can use only index tree */
3701
 
              tmp= record_count * table->cursor->index_only_read_time(key, tmp);
 
3618
              tmp= record_count * table->file->index_only_read_time(key, tmp);
3702
3619
            }
3703
3620
            else
3704
3621
              tmp= record_count * min(tmp,s->worst_seeks);
3750
3667
        scan.
3751
3668
  */
3752
3669
  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)
 
3670
      !(s->quick && best_key && s->quick->index == best_key->key &&      // (2)
 
3671
        best_max_key_part >= s->table->quick_key_parts[best_key->key]) &&// (2)
 
3672
      !((s->table->file->ha_table_flags() & HA_TABLE_SCAN_ON_INDEX) &&   // (3)
 
3673
        ! s->table->covering_keys.none() && best_key && !s->quick) &&// (3)
 
3674
      !(s->table->force_index && best_key && !s->quick))                 // (4)
3758
3675
  {                                             // Check full join
3759
3676
    ha_rows rnd_records= s->found_records;
3760
3677
    /*
3799
3716
    else
3800
3717
    {
3801
3718
      /* Estimate cost of reading table. */
3802
 
      tmp= s->table->cursor->scan_time();
 
3719
      tmp= s->table->file->scan_time();
3803
3720
      if (s->table->map & join->outer_join)     // Can't use join cache
3804
3721
      {
3805
3722
        /*
3888
3805
    Thus 'optimize_straight_join' can be used at any stage of the query
3889
3806
    optimization process to finalize a QEP as it is.
3890
3807
*/
3891
 
static void optimize_straight_join(Join *join, table_map join_tables)
 
3808
static void optimize_straight_join(JOIN *join, table_map join_tables)
3892
3809
{
3893
3810
  JoinTable *s;
3894
3811
  optimizer::Position partial_pos;
3998
3915
  @retval
3999
3916
    true        Fatal error
4000
3917
*/
4001
 
static bool greedy_search(Join      *join,
 
3918
static bool greedy_search(JOIN      *join,
4002
3919
              table_map remaining_tables,
4003
3920
              uint32_t      search_depth,
4004
3921
              uint32_t      prune_level)
4012
3929
  JoinTable  *best_table; // the next plan node to be added to the curr QEP
4013
3930
 
4014
3931
  /* number of tables that remain to be optimized */
4015
 
  size_remain= internal::my_count_bits(remaining_tables);
 
3932
  size_remain= my_count_bits(remaining_tables);
4016
3933
 
4017
3934
  do {
4018
3935
    /* Find the extension of the current QEP with the lowest cost */
4040
3957
    */
4041
3958
    join->setPosInPartialPlan(idx, best_pos);
4042
3959
 
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
 
      
4051
 
 
4052
3960
    /* find the position of 'best_table' in 'join->best_ref' */
4053
3961
    best_idx= idx;
4054
3962
    JoinTable *pos= join->best_ref[best_idx];
4186
4094
  @retval
4187
4095
    true        Fatal error
4188
4096
*/
4189
 
static bool best_extension_by_limited_search(Join *join,
 
4097
static bool best_extension_by_limited_search(JOIN *join,
4190
4098
                                             table_map remaining_tables,
4191
4099
                                             uint32_t idx,
4192
4100
                                             double record_count,
4195
4103
                                             uint32_t prune_level)
4196
4104
{
4197
4105
  Session *session= join->session;
4198
 
  if (session->getKilled())  // Abort
 
4106
  if (session->killed)  // Abort
4199
4107
    return(true);
4200
4108
 
4201
4109
  /*
4210
4118
  for (JoinTable **pos= join->best_ref + idx ; (s= *pos) ; pos++)
4211
4119
  {
4212
4120
    table_map real_table_bit= s->table->map;
 
4121
    if (idx)
 
4122
    {
 
4123
      partial_pos= join->getPosFromPartialPlan(idx - 1);
 
4124
    }
4213
4125
    if ((remaining_tables & real_table_bit) &&
4214
4126
        ! (remaining_tables & s->dependent) &&
4215
 
        (! idx || ! check_interleaving_with_nj(s)))
 
4127
        (! idx || ! check_interleaving_with_nj(partial_pos.getJoinTable(), s)))
4216
4128
    {
4217
4129
      double current_record_count, current_read_time;
4218
4130
 
4333
4245
    exhaustiveness) of the depth-first search algorithm used by
4334
4246
    'greedy_search'.
4335
4247
*/
4336
 
static uint32_t determine_search_depth(Join *join)
 
4248
static uint32_t determine_search_depth(JOIN *join)
4337
4249
{
4338
4250
  uint32_t table_count=  join->tables - join->const_tables;
4339
4251
  uint32_t search_depth;
4352
4264
  return search_depth;
4353
4265
}
4354
4266
 
4355
 
static bool make_simple_join(Join *join,Table *tmp_table)
 
4267
static bool make_simple_join(JOIN *join,Table *tmp_table)
4356
4268
{
4357
4269
  Table **tableptr;
4358
4270
  JoinTable *join_tab;
4359
4271
 
4360
4272
  /*
4361
4273
    Reuse Table * and JoinTable if already allocated by a previous call
4362
 
    to this function through Join::exec (may happen for sub-queries).
 
4274
    to this function through JOIN::exec (may happen for sub-queries).
4363
4275
  */
4364
4276
  if (!join->table_reexec)
4365
4277
  {
4366
4278
    if (!(join->table_reexec= (Table**) join->session->alloc(sizeof(Table*))))
4367
 
      return(true);
 
4279
      return(true);                        /* purecov: inspected */
4368
4280
    if (join->tmp_join)
4369
4281
      join->tmp_join->table_reexec= join->table_reexec;
4370
4282
  }
4372
4284
  {
4373
4285
    if (!(join->join_tab_reexec=
4374
4286
          (JoinTable*) join->session->alloc(sizeof(JoinTable))))
4375
 
      return(true);
 
4287
      return(true);                        /* purecov: inspected */
4376
4288
    if (join->tmp_join)
4377
4289
      join->tmp_join->join_tab_reexec= join->join_tab_reexec;
4378
4290
  }
4409
4321
  join_tab->read_first_record= join_init_read_record;
4410
4322
  join_tab->join=join;
4411
4323
  join_tab->ref.key_parts= 0;
4412
 
  join_tab->read_record.init();
 
4324
  memset(&join_tab->read_record, 0, sizeof(join_tab->read_record));
4413
4325
  tmp_table->status=0;
4414
4326
  tmp_table->null_row=0;
4415
 
 
4416
 
  return false;
 
4327
  return(false);
4417
4328
}
4418
4329
 
4419
4330
/**
4457
4368
    This function can be called only after the execution plan
4458
4369
    has been chosen.
4459
4370
*/
4460
 
static void make_outerjoin_info(Join *join)
 
4371
static void make_outerjoin_info(JOIN *join)
4461
4372
{
4462
4373
  for (uint32_t i=join->const_tables ; i < join->tables ; i++)
4463
4374
  {
4464
4375
    JoinTable *tab=join->join_tab+i;
4465
4376
    Table *table=tab->table;
4466
4377
    TableList *tbl= table->pos_in_table_list;
4467
 
    TableList *embedding= tbl->getEmbedding();
 
4378
    TableList *embedding= tbl->embedding;
4468
4379
 
4469
4380
    if (tbl->outer_join)
4470
4381
    {
4477
4388
      tab->on_expr_ref= &tbl->on_expr;
4478
4389
      tab->cond_equal= tbl->cond_equal;
4479
4390
      if (embedding)
4480
 
        tab->first_upper= embedding->getNestedJoin()->first_nested;
 
4391
        tab->first_upper= embedding->nested_join->first_nested;
4481
4392
    }
4482
 
    for ( ; embedding ; embedding= embedding->getEmbedding())
 
4393
    for ( ; embedding ; embedding= embedding->embedding)
4483
4394
    {
4484
4395
      /* Ignore sj-nests: */
4485
4396
      if (!embedding->on_expr)
4486
4397
        continue;
4487
 
      nested_join_st *nested_join= embedding->getNestedJoin();
 
4398
      nested_join_st *nested_join= embedding->nested_join;
4488
4399
      if (!nested_join->counter_)
4489
4400
      {
4490
4401
        /*
4494
4405
        nested_join->first_nested= tab;
4495
4406
        tab->on_expr_ref= &embedding->on_expr;
4496
4407
        tab->cond_equal= tbl->cond_equal;
4497
 
        if (embedding->getEmbedding())
4498
 
          tab->first_upper= embedding->getEmbedding()->getNestedJoin()->first_nested;
 
4408
        if (embedding->embedding)
 
4409
          tab->first_upper= embedding->embedding->nested_join->first_nested;
4499
4410
      }
4500
4411
      if (!tab->first_inner)
4501
4412
        tab->first_inner= nested_join->first_nested;
4508
4419
  return;
4509
4420
}
4510
4421
 
4511
 
static bool make_join_select(Join *join,
4512
 
                             optimizer::SqlSelect *select,
4513
 
                             COND *cond)
 
4422
static bool make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
4514
4423
{
4515
4424
  Session *session= join->session;
4516
4425
  optimizer::Position cur_pos;
4631
4540
      if (tmp || !cond || tab->type == AM_REF || tab->type == AM_REF_OR_NULL ||
4632
4541
          tab->type == AM_EQ_REF)
4633
4542
      {
4634
 
        optimizer::SqlSelect *sel= tab->select= ((optimizer::SqlSelect*)
 
4543
        SQL_SELECT *sel= tab->select= ((SQL_SELECT*)
4635
4544
            session->memdup((unsigned char*) select,
4636
4545
              sizeof(*select)));
4637
4546
        if (! sel)
4769
4678
                                         current_map,
4770
4679
                                         current_map, 0)))
4771
4680
            {
4772
 
              tab->cache.select= (optimizer::SqlSelect*)
4773
 
                session->memdup((unsigned char*) sel, sizeof(optimizer::SqlSelect));
 
4681
              tab->cache.select= (SQL_SELECT*)
 
4682
                session->memdup((unsigned char*) sel, sizeof(SQL_SELECT));
4774
4683
              tab->cache.select->cond= tmp;
4775
4684
              tab->cache.select->read_tables= join->const_table_map;
4776
4685
            }
4886
4795
    false - OK
4887
4796
    true  - Out of memory
4888
4797
*/
4889
 
static bool make_join_readinfo(Join *join)
 
4798
static bool make_join_readinfo(JOIN *join, uint64_t options, uint32_t no_jbuf_after)
4890
4799
{
4891
 
  bool sorted= true;
 
4800
  uint32_t i;
 
4801
  bool statistics= test(!(join->select_options & SELECT_DESCRIBE));
 
4802
  bool sorted= 1;
4892
4803
 
4893
 
  for (uint32_t i= join->const_tables ; i < join->tables ; i++)
 
4804
  for (i=join->const_tables ; i < join->tables ; i++)
4894
4805
  {
4895
4806
    JoinTable *tab=join->join_tab+i;
4896
4807
    Table *table=tab->table;
 
4808
    bool using_join_cache;
4897
4809
    tab->read_record.table= table;
4898
 
    tab->read_record.cursor= table->cursor;
 
4810
    tab->read_record.file=table->file;
4899
4811
    tab->next_select=sub_select;                /* normal select */
4900
4812
    /*
4901
4813
      TODO: don't always instruct first table's ref/range access method to
4902
4814
      produce sorted output.
4903
4815
    */
4904
4816
    tab->sorted= sorted;
4905
 
    sorted= false; // only first must be sorted
4906
 
 
 
4817
    sorted= 0;                                  // only first must be sorted
4907
4818
    if (tab->insideout_match_tab)
4908
4819
    {
4909
 
      if (! (tab->insideout_buf= (unsigned char*) join->session->alloc(tab->table->key_info
4910
 
                                                                       [tab->index].
4911
 
                                                                       key_length)))
 
4820
      if (!(tab->insideout_buf= (unsigned char*)join->session->alloc(tab->table->key_info
 
4821
                                                         [tab->index].
 
4822
                                                         key_length)))
4912
4823
        return true;
4913
4824
    }
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();
 
4825
    switch (tab->type) {
 
4826
    case AM_SYSTEM:                             // Only happens with left join
 
4827
      table->status=STATUS_NO_RECORD;
 
4828
      tab->read_first_record= join_read_system;
 
4829
      tab->read_record.read_record= join_no_more_records;
 
4830
      break;
 
4831
    case AM_CONST:                              // Only happens with left join
 
4832
      table->status=STATUS_NO_RECORD;
 
4833
      tab->read_first_record= join_read_const;
 
4834
      tab->read_record.read_record= join_no_more_records;
 
4835
      if (table->covering_keys.test(tab->ref.key) &&
 
4836
          !table->no_keyread)
 
4837
      {
 
4838
        table->key_read=1;
 
4839
        table->file->extra(HA_EXTRA_KEYREAD);
 
4840
      }
 
4841
      break;
 
4842
    case AM_EQ_REF:
 
4843
      table->status=STATUS_NO_RECORD;
 
4844
      if (tab->select)
 
4845
      {
 
4846
        delete tab->select->quick;
 
4847
        tab->select->quick=0;
 
4848
      }
 
4849
      delete tab->quick;
 
4850
      tab->quick=0;
 
4851
      tab->read_first_record= join_read_key;
 
4852
      tab->read_record.read_record= join_no_more_records;
 
4853
      if (table->covering_keys.test(tab->ref.key) && !table->no_keyread)
 
4854
      {
 
4855
        table->key_read=1;
 
4856
        table->file->extra(HA_EXTRA_KEYREAD);
 
4857
      }
 
4858
      break;
 
4859
    case AM_REF_OR_NULL:
 
4860
    case AM_REF:
 
4861
      table->status=STATUS_NO_RECORD;
 
4862
      if (tab->select)
 
4863
      {
 
4864
        delete tab->select->quick;
 
4865
        tab->select->quick=0;
 
4866
      }
 
4867
      delete tab->quick;
 
4868
      tab->quick=0;
 
4869
      if (table->covering_keys.test(tab->ref.key) && !table->no_keyread)
 
4870
      {
 
4871
        table->key_read=1;
 
4872
        table->file->extra(HA_EXTRA_KEYREAD);
 
4873
      }
 
4874
      if (tab->type == AM_REF)
 
4875
      {
 
4876
        tab->read_first_record= join_read_always_key;
 
4877
        tab->read_record.read_record= tab->insideout_match_tab?
 
4878
           join_read_next_same_diff : join_read_next_same;
 
4879
      }
 
4880
      else
 
4881
      {
 
4882
        tab->read_first_record= join_read_always_key_or_null;
 
4883
        tab->read_record.read_record= join_read_next_same_or_null;
 
4884
      }
 
4885
      break;
 
4886
    case AM_ALL:
 
4887
      /*
 
4888
        If previous table use cache
 
4889
        If the incoming data set is already sorted don't use cache.
 
4890
      */
 
4891
      table->status=STATUS_NO_RECORD;
 
4892
      using_join_cache= false;
 
4893
      if (i != join->const_tables && !(options & SELECT_NO_JOIN_CACHE) &&
 
4894
          tab->use_quick != 2 && !tab->first_inner && i <= no_jbuf_after &&
 
4895
          !tab->insideout_match_tab)
 
4896
      {
 
4897
        if ((options & SELECT_DESCRIBE) ||
 
4898
            !join_init_cache(join->session,join->join_tab+join->const_tables,
 
4899
                i-join->const_tables))
 
4900
        {
 
4901
                using_join_cache= true;
 
4902
          tab[-1].next_select=sub_select_cache; /* Patch previous */
 
4903
        }
 
4904
      }
 
4905
      /* These init changes read_record */
 
4906
      if (tab->use_quick == 2)
 
4907
      {
 
4908
        join->session->server_status|=SERVER_QUERY_NO_GOOD_INDEX_USED;
 
4909
        tab->read_first_record= join_init_quick_read_record;
 
4910
        if (statistics)
 
4911
          status_var_increment(join->session->status_var.select_range_check_count);
 
4912
      }
 
4913
      else
 
4914
      {
 
4915
        tab->read_first_record= join_init_read_record;
 
4916
        if (i == join->const_tables)
 
4917
        {
 
4918
          if (tab->select && tab->select->quick)
 
4919
          {
 
4920
            if (statistics)
 
4921
              status_var_increment(join->session->status_var.select_range_count);
 
4922
          }
 
4923
          else
 
4924
          {
 
4925
            join->session->server_status|=SERVER_QUERY_NO_INDEX_USED;
 
4926
            if (statistics)
 
4927
              status_var_increment(join->session->status_var.select_scan_count);
 
4928
          }
 
4929
        }
 
4930
        else
 
4931
        {
 
4932
          if (tab->select && tab->select->quick)
 
4933
          {
 
4934
            if (statistics)
 
4935
              status_var_increment(join->session->status_var.select_full_range_join_count);
 
4936
          }
 
4937
          else
 
4938
          {
 
4939
            join->session->server_status|=SERVER_QUERY_NO_INDEX_USED;
 
4940
            if (statistics)
 
4941
              status_var_increment(join->session->status_var.select_full_join_count);
 
4942
          }
 
4943
        }
 
4944
        if (!table->no_keyread)
 
4945
        {
 
4946
          if (tab->select && tab->select->quick &&
 
4947
                    tab->select->quick->index != MAX_KEY && //not index_merge
 
4948
              table->covering_keys.test(tab->select->quick->index))
 
4949
          {
 
4950
            table->key_read=1;
 
4951
            table->file->extra(HA_EXTRA_KEYREAD);
 
4952
          }
 
4953
          else if (!table->covering_keys.none() &&
 
4954
            !(tab->select && tab->select->quick))
 
4955
          {                                     // Only read index tree
 
4956
                  if (!tab->insideout_match_tab)
 
4957
                  {
 
4958
                    /*
 
4959
                      See bug #26447: "Using the clustered index for a table scan
 
4960
                      is always faster than using a secondary index".
 
4961
                    */
 
4962
                    if (table->s->primary_key != MAX_KEY &&
 
4963
                        table->file->primary_key_is_clustered())
 
4964
                      tab->index= table->s->primary_key;
 
4965
                    else
 
4966
                      tab->index= table->find_shortest_key(&table->covering_keys);
 
4967
                  }
 
4968
            tab->read_first_record= join_read_first;
 
4969
            tab->type= AM_NEXT;         // Read with index_first / index_next
 
4970
          }
 
4971
        }
 
4972
      }
 
4973
      break;
 
4974
    default:
 
4975
      break;                                    /* purecov: deadcode */
 
4976
    case AM_UNKNOWN:
 
4977
    case AM_MAYBE_REF:
 
4978
      abort();                                  /* purecov: deadcode */
4926
4979
    }
4927
 
 
4928
 
    access_method->getStats(table, tab);
4929
4980
  }
4930
 
 
4931
 
  join->join_tab[join->tables-1].next_select= NULL; /* Set by do_select */
4932
 
 
4933
 
  return false;
 
4981
  join->join_tab[join->tables-1].next_select=0; /* Set by do_select */
 
4982
  return(false);
4934
4983
}
4935
4984
 
4936
4985
/** Update the dependency map for the tables. */
4937
 
static void update_depend_map(Join *join)
 
4986
static void update_depend_map(JOIN *join)
4938
4987
{
4939
4988
  JoinTable *join_tab=join->join_tab, *end=join_tab+join->tables;
4940
4989
 
4957
5006
}
4958
5007
 
4959
5008
/** Update the dependency map for the sort order. */
4960
 
static void update_depend_map(Join *join, Order *order)
 
5009
static void update_depend_map(JOIN *join, order_st *order)
4961
5010
{
4962
5011
  for (; order ; order=order->next)
4963
5012
  {
4995
5044
  @return
4996
5045
    Returns new sort order
4997
5046
*/
4998
 
static Order *remove_constants(Join *join,Order *first_order, COND *cond, bool change_list, bool *simple_order)
 
5047
static order_st *remove_constants(JOIN *join,order_st *first_order, COND *cond, bool change_list, bool *simple_order)
4999
5048
{
5000
5049
  if (join->tables == join->const_tables)
5001
5050
    return change_list ? 0 : first_order;               // No need to sort
5002
5051
 
5003
 
  Order *order,**prev_ptr;
 
5052
  order_st *order,**prev_ptr;
5004
5053
  table_map first_table= join->join_tab[join->const_tables].table->map;
5005
5054
  table_map not_const_tables= ~join->const_table_map;
5006
5055
  table_map ref;
5055
5104
  return(first_order);
5056
5105
}
5057
5106
 
5058
 
static int return_zero_rows(Join *join,
 
5107
static int return_zero_rows(JOIN *join,
5059
5108
                            select_result *result,
5060
5109
                            TableList *tables,
5061
5110
                                        List<Item> &fields,
5066
5115
{
5067
5116
  if (select_options & SELECT_DESCRIBE)
5068
5117
  {
5069
 
    optimizer::ExplainPlan planner(join,
5070
 
                                   false,
5071
 
                                   false,
5072
 
                                   false,
5073
 
                                   info);
5074
 
    planner.printPlan();
5075
 
    return 0;
 
5118
    select_describe(join, false, false, false, info);
 
5119
    return(0);
5076
5120
  }
5077
5121
 
5078
5122
  join->join_free();
5221
5265
    - The new condition, if success
5222
5266
    - 0, otherwise
5223
5267
*/
5224
 
static COND *simplify_joins(Join *join, List<TableList> *join_list, COND *conds, bool top)
 
5268
static COND *simplify_joins(JOIN *join, List<TableList> *join_list, COND *conds, bool top)
5225
5269
{
5226
5270
  TableList *table;
5227
5271
  nested_join_st *nested_join;
5237
5281
    table_map used_tables;
5238
5282
    table_map not_null_tables= (table_map) 0;
5239
5283
 
5240
 
    if ((nested_join= table->getNestedJoin()))
 
5284
    if ((nested_join= table->nested_join))
5241
5285
    {
5242
5286
      /*
5243
5287
         If the element of join_list is a nested join apply
5279
5323
        not_null_tables= conds->not_null_tables();
5280
5324
    }
5281
5325
 
5282
 
    if (table->getEmbedding())
 
5326
    if (table->embedding)
5283
5327
    {
5284
 
      table->getEmbedding()->getNestedJoin()->used_tables|= used_tables;
5285
 
      table->getEmbedding()->getNestedJoin()->not_null_tables|= not_null_tables;
 
5328
      table->embedding->nested_join->used_tables|= used_tables;
 
5329
      table->embedding->nested_join->not_null_tables|= not_null_tables;
5286
5330
    }
5287
5331
 
5288
5332
    if (!table->outer_join || (used_tables & not_null_tables))
5318
5362
    */
5319
5363
    if (table->on_expr)
5320
5364
    {
5321
 
      table->setDepTables(table->getDepTables() | table->on_expr->used_tables());
5322
 
      if (table->getEmbedding())
 
5365
      table->dep_tables|= table->on_expr->used_tables();
 
5366
      if (table->embedding)
5323
5367
      {
5324
 
        table->setDepTables(table->getDepTables() & ~table->getEmbedding()->getNestedJoin()->used_tables);
 
5368
        table->dep_tables&= ~table->embedding->nested_join->used_tables;
5325
5369
        /*
5326
5370
           Embedding table depends on tables used
5327
5371
           in embedded on expressions.
5328
5372
        */
5329
 
        table->getEmbedding()->setOnExprDepTables(table->getEmbedding()->getOnExprDepTables() & table->on_expr->used_tables());
 
5373
        table->embedding->on_expr_dep_tables|= table->on_expr->used_tables();
5330
5374
      }
5331
5375
      else
5332
 
        table->setDepTables(table->getDepTables() & ~table->table->map);
 
5376
        table->dep_tables&= ~table->table->map;
5333
5377
    }
5334
5378
 
5335
5379
    if (prev_table)
5336
5380
    {
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);
 
5381
      /* The order of tables is reverse: prev_table follows table */
 
5382
      if (prev_table->straight)
 
5383
        prev_table->dep_tables|= used_tables;
5342
5384
      if (prev_table->on_expr)
5343
5385
      {
5344
 
        prev_table->setDepTables(prev_table->getDepTables() | table->getOnExprDepTables());
5345
 
        table_map prev_used_tables= prev_table->getNestedJoin() ?
5346
 
                                    prev_table->getNestedJoin()->used_tables :
 
5386
        prev_table->dep_tables|= table->on_expr_dep_tables;
 
5387
        table_map prev_used_tables= prev_table->nested_join ?
 
5388
                                    prev_table->nested_join->used_tables :
5347
5389
                                    prev_table->table->map;
5348
5390
        /*
5349
5391
          If on expression contains only references to inner tables
5352
5394
          for them. Yet this is really a rare case.
5353
5395
              */
5354
5396
        if (!(prev_table->on_expr->used_tables() & ~prev_used_tables))
5355
 
          prev_table->setDepTables(prev_table->getDepTables() | used_tables);
 
5397
          prev_table->dep_tables|= used_tables;
5356
5398
      }
5357
5399
    }
5358
5400
    prev_table= table;
5365
5407
  li.rewind();
5366
5408
  while ((table= li++))
5367
5409
  {
5368
 
    nested_join= table->getNestedJoin();
 
5410
    nested_join= table->nested_join;
5369
5411
    if (nested_join && !table->on_expr)
5370
5412
    {
5371
5413
      TableList *tbl;
5372
5414
      List_iterator<TableList> it(nested_join->join_list);
5373
5415
      while ((tbl= it++))
5374
5416
      {
5375
 
        tbl->setEmbedding(table->getEmbedding());
5376
 
        tbl->setJoinList(table->getJoinList());
 
5417
        tbl->embedding= table->embedding;
 
5418
        tbl->join_list= table->join_list;
5377
5419
      }
5378
5420
      li.replace(nested_join->join_list);
5379
5421
    }
5381
5423
  return(conds);
5382
5424
}
5383
5425
 
5384
 
static int remove_duplicates(Join *join, Table *entry,List<Item> &fields, Item *having)
 
5426
static int remove_duplicates(JOIN *join, Table *entry,List<Item> &fields, Item *having)
5385
5427
{
5386
5428
  int error;
5387
5429
  uint32_t reclength,offset;
5405
5447
    join->unit->select_limit_cnt= 1;            // Only send first row
5406
5448
    return(0);
5407
5449
  }
5408
 
  Field **first_field=entry->getFields() + entry->getShare()->sizeFields() - field_count;
 
5450
  Field **first_field=entry->field+entry->s->fields - field_count;
5409
5451
  offset= (field_count ?
5410
 
           entry->getField(entry->getShare()->sizeFields() - field_count)->offset(entry->getInsertRecord()) : 0);
5411
 
  reclength= entry->getShare()->getRecordLength() - offset;
 
5452
           entry->field[entry->s->fields - field_count]->
 
5453
           offset(entry->record[0]) : 0);
 
5454
  reclength= entry->s->reclength-offset;
5412
5455
 
5413
5456
  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
 
  {
 
5457
  entry->file->info(HA_STATUS_VARIABLE);
 
5458
  if (entry->s->db_type() == heap_engine ||
 
5459
      (!entry->s->blob_fields &&
 
5460
       ((ALIGN_SIZE(reclength) + HASH_OVERHEAD) * entry->file->stats.records <
 
5461
        session->variables.sortbuff_size)))
5420
5462
    error= remove_dup_with_hash_index(join->session, entry,
5421
 
                                      field_count, first_field,
5422
 
                                      reclength, having);
5423
 
  }
 
5463
                                     field_count, first_field,
 
5464
                                     reclength, having);
5424
5465
  else
5425
 
  {
5426
 
    error= remove_dup_with_compare(join->session, entry, first_field, offset, having);
5427
 
  }
 
5466
    error= remove_dup_with_compare(join->session, entry, first_field, offset,
 
5467
                                  having);
5428
5468
 
5429
5469
  free_blobs(first_field);
5430
 
 
5431
5470
  return(error);
5432
5471
}
5433
5472
 
5441
5480
                               List<Item> &fields,
5442
5481
                               List<Item> &all_fields,
5443
5482
                               COND **conds,
5444
 
                               Order *order,
5445
 
                               Order *group,
 
5483
                               order_st *order,
 
5484
                               order_st *group,
5446
5485
                               bool *hidden_group_fields)
5447
5486
{
5448
5487
  int res;
5469
5508
  @retval
5470
5509
    1   Fatal error
5471
5510
*/
5472
 
static bool make_join_statistics(Join *join, TableList *tables, COND *conds, DYNAMIC_ARRAY *keyuse_array)
 
5511
static bool make_join_statistics(JOIN *join, TableList *tables, COND *conds, DYNAMIC_ARRAY *keyuse_array)
5473
5512
{
5474
5513
  int error;
5475
5514
  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;
 
5515
  uint32_t i,table_count,const_count,key;
 
5516
  table_map found_const_table_map, all_table_map, found_ref, refs;
 
5517
  key_map const_ref, eq_part;
 
5518
  Table **table_vector;
 
5519
  JoinTable *stat,*stat_end,*s,**stat_ref;
 
5520
  KeyUse *keyuse,*start_keyuse;
 
5521
  table_map outer_join=0;
5494
5522
  vector<optimizer::SargableParam> sargables;
5495
5523
  JoinTable *stat_vector[MAX_TABLES+1];
5496
5524
  optimizer::Position *partial_pos;
5497
5525
 
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));
 
5526
  table_count=join->tables;
 
5527
  stat=(JoinTable*) join->session->calloc(sizeof(JoinTable)*table_count);
 
5528
  stat_ref=(JoinTable**) join->session->alloc(sizeof(JoinTable*)*MAX_TABLES);
 
5529
  table_vector=(Table**) join->session->alloc(sizeof(Table*)*(table_count*2));
5502
5530
  if (! stat || ! stat_ref || ! table_vector)
5503
 
    return 1;
 
5531
    return 1;                           // Eom /* purecov: inspected */
5504
5532
 
5505
5533
  join->best_ref=stat_vector;
5506
5534
 
5512
5540
       tables;
5513
5541
       s++, tables= tables->next_leaf, i++)
5514
5542
  {
5515
 
    TableList *embedding= tables->getEmbedding();
 
5543
    TableList *embedding= tables->embedding;
5516
5544
    stat_vector[i]=s;
5517
5545
    s->keys.reset();
5518
5546
    s->const_keys.reset();
5520
5548
    s->needed_reg.reset();
5521
5549
    table_vector[i]=s->table=table=tables->table;
5522
5550
    table->pos_in_table_list= tables;
5523
 
    assert(table->cursor);
5524
 
    error= table->cursor->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
 
5551
    error= table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
5525
5552
    if (error)
5526
5553
    {
5527
 
        table->print_error(error, MYF(0));
 
5554
        table->file->print_error(error, MYF(0));
5528
5555
        return 1;
5529
5556
    }
5530
5557
    table->quick_keys.reset();
5531
5558
    table->reginfo.join_tab=s;
5532
5559
    table->reginfo.not_exists_optimize=0;
5533
5560
    memset(table->const_key_parts, 0,
5534
 
           sizeof(key_part_map)*table->getShare()->sizeKeys());
 
5561
           sizeof(key_part_map)*table->s->keys);
5535
5562
    all_table_map|= table->map;
5536
5563
    s->join=join;
5537
5564
    s->info=0;                                  // For describe
5538
5565
 
5539
 
    s->dependent= tables->getDepTables();
 
5566
    s->dependent= tables->dep_tables;
5540
5567
    s->key_dependent= 0;
5541
 
    table->quick_condition_rows= table->cursor->stats.records;
 
5568
    if (tables->schema_table)
 
5569
      table->file->stats.records= 2;
 
5570
    table->quick_condition_rows= table->file->stats.records;
5542
5571
 
5543
5572
    s->on_expr_ref= &tables->on_expr;
5544
5573
    if (*s->on_expr_ref)
5545
5574
    {
5546
5575
      /* s is the only inner table of an outer join */
5547
 
      if (!table->cursor->stats.records && !embedding)
 
5576
      if (!table->file->stats.records && !embedding)
5548
5577
      {                                         // Empty table
5549
5578
        s->dependent= 0;                        // Ignore LEFT JOIN depend.
5550
 
        set_position(join, const_count++, s, (optimizer::KeyUse*) 0);
 
5579
        set_position(join,const_count++,s,(KeyUse*) 0);
5551
5580
        continue;
5552
5581
      }
5553
5582
      outer_join|= table->map;
5554
5583
      s->embedding_map.reset();
5555
 
      for (;embedding; embedding= embedding->getEmbedding())
5556
 
        s->embedding_map|= embedding->getNestedJoin()->nj_map;
 
5584
      for (;embedding; embedding= embedding->embedding)
 
5585
        s->embedding_map|= embedding->nested_join->nj_map;
5557
5586
      continue;
5558
5587
    }
5559
 
    if (embedding && !(false && ! embedding->getEmbedding()))
 
5588
    if (embedding && !(false && ! embedding->embedding))
5560
5589
    {
5561
5590
      /* s belongs to a nested join, maybe to several embedded joins */
5562
5591
      s->embedding_map.reset();
5563
5592
      do
5564
5593
      {
5565
 
        nested_join_st *nested_join= embedding->getNestedJoin();
 
5594
        nested_join_st *nested_join= embedding->nested_join;
5566
5595
        s->embedding_map|= nested_join->nj_map;
5567
 
        s->dependent|= embedding->getDepTables();
5568
 
        embedding= embedding->getEmbedding();
 
5596
        s->dependent|= embedding->dep_tables;
 
5597
        embedding= embedding->embedding;
5569
5598
        outer_join|= nested_join->used_tables;
5570
5599
      }
5571
5600
      while (embedding);
5572
5601
      continue;
5573
5602
    }
5574
 
    if ((table->cursor->stats.records <= 1) && !s->dependent &&
5575
 
              (table->cursor->getEngine()->check_flag(HTON_BIT_STATS_RECORDS_IS_EXACT)) &&
 
5603
    if ((table->file->stats.records <= 1) && !s->dependent &&
 
5604
              (table->file->ha_table_flags() & HA_STATS_RECORDS_IS_EXACT) && 
5576
5605
        !join->no_const_tables)
5577
5606
    {
5578
 
      set_position(join, const_count++, s, (optimizer::KeyUse*) 0);
 
5607
      set_position(join,const_count++,s,(KeyUse*) 0);
5579
5608
    }
5580
5609
  }
5581
5610
  stat_vector[i]=0;
5655
5684
      set_position() will move all const_tables first in stat_vector
5656
5685
    */
5657
5686
 
5658
 
    for (JoinTable **pos= stat_vector+const_count; (s= *pos); pos++)
 
5687
    for (JoinTable **pos=stat_vector+const_count ; (s= *pos) ; pos++)
5659
5688
    {
5660
 
      table= s->table;
 
5689
      table=s->table;
5661
5690
 
5662
5691
      /*
5663
5692
        If equi-join condition by a key is null rejecting and after a
5676
5705
          TODO. Apply single row substitution to null complemented inner tables
5677
5706
          for nested outer join operations.
5678
5707
        */
5679
 
        while (keyuse->getTable() == table)
 
5708
        while (keyuse->table == table)
5680
5709
        {
5681
 
          if (! (keyuse->getVal()->used_tables() & ~join->const_table_map) &&
5682
 
              keyuse->getVal()->is_null() && keyuse->isNullRejected())
 
5710
          if (!(keyuse->val->used_tables() & ~join->const_table_map) &&
 
5711
              keyuse->val->is_null() && keyuse->null_rejecting)
5683
5712
          {
5684
5713
            s->type= AM_CONST;
5685
5714
            table->mark_as_null_row();
5686
5715
            found_const_table_map|= table->map;
5687
5716
            join->const_table_map|= table->map;
5688
 
            set_position(join, const_count++, s, (optimizer::KeyUse*) 0);
 
5717
            set_position(join,const_count++,s,(KeyUse*) 0);
5689
5718
            goto more_const_tables_found;
5690
5719
           }
5691
5720
          keyuse++;
5697
5726
        // All dep. must be constants
5698
5727
        if (s->dependent & ~(found_const_table_map))
5699
5728
          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())
 
5729
        if (table->file->stats.records <= 1L &&
 
5730
            (table->file->ha_table_flags() & HA_STATS_RECORDS_IS_EXACT) &&
 
5731
                  !table->pos_in_table_list->embedding)
5703
5732
        {                                       // system table
5704
5733
          int tmp= 0;
5705
5734
          s->type= AM_SYSTEM;
5706
5735
          join->const_table_map|=table->map;
5707
 
          set_position(join, const_count++, s, (optimizer::KeyUse*) 0);
 
5736
          set_position(join,const_count++,s,(KeyUse*) 0);
5708
5737
          partial_pos= join->getSpecificPosInPartialPlan(const_count - 1);
5709
5738
          if ((tmp= join_read_const_table(s, partial_pos)))
5710
5739
          {
5720
5749
      if ((keyuse=s->keyuse))
5721
5750
      {
5722
5751
        s->type= AM_REF;
5723
 
        while (keyuse->getTable() == table)
 
5752
        while (keyuse->table == table)
5724
5753
        {
5725
 
          start_keyuse= keyuse;
5726
 
          key= keyuse->getKey();
 
5754
          start_keyuse=keyuse;
 
5755
          key=keyuse->key;
5727
5756
          s->keys.set(key);               // QQ: remove this ?
5728
5757
 
5729
 
          refs= 0;
5730
 
          const_ref.reset();
 
5758
          refs=0;
 
5759
                const_ref.reset();
5731
5760
          eq_part.reset();
5732
5761
          do
5733
5762
          {
5734
 
            if (keyuse->getVal()->type() != Item::NULL_ITEM && 
5735
 
                ! keyuse->getOptimizeFlags())
 
5763
            if (keyuse->val->type() != Item::NULL_ITEM && !keyuse->optimize)
5736
5764
            {
5737
 
              if (! ((~found_const_table_map) & keyuse->getUsedTables()))
5738
 
                const_ref.set(keyuse->getKeypart());
 
5765
              if (!((~found_const_table_map) & keyuse->used_tables))
 
5766
                const_ref.set(keyuse->keypart);
5739
5767
              else
5740
 
                refs|= keyuse->getUsedTables();
5741
 
              eq_part.set(keyuse->getKeypart());
 
5768
                refs|=keyuse->used_tables;
 
5769
              eq_part.set(keyuse->keypart);
5742
5770
            }
5743
5771
            keyuse++;
5744
 
          } while (keyuse->getTable() == table && keyuse->getKey() == key);
 
5772
          } while (keyuse->table == table && keyuse->key == key);
5745
5773
 
5746
5774
          if (is_keymap_prefix(eq_part, table->key_info[key].key_parts) &&
5747
 
              ! table->pos_in_table_list->getEmbedding())
 
5775
              !table->pos_in_table_list->embedding)
5748
5776
          {
5749
5777
            if ((table->key_info[key].flags & (HA_NOSAME)) == HA_NOSAME)
5750
5778
            {
5754
5782
                ref_changed = 1;
5755
5783
                s->type= AM_CONST;
5756
5784
                join->const_table_map|= table->map;
5757
 
                set_position(join, const_count++, s, start_keyuse);
 
5785
                set_position(join,const_count++,s,start_keyuse);
5758
5786
                if (create_ref_for_key(join, s, start_keyuse, found_const_table_map))
5759
5787
                  return 1;
5760
5788
                partial_pos= join->getSpecificPosInPartialPlan(const_count - 1);
5788
5816
    while (iter != sargables.end())
5789
5817
    {
5790
5818
      Field *field= (*iter).getField();
5791
 
      JoinTable *join_tab= field->getTable()->reginfo.join_tab;
 
5819
      JoinTable *join_tab= field->table->reginfo.join_tab;
5792
5820
      key_map possible_keys= field->key_start;
5793
 
      possible_keys&= field->getTable()->keys_in_use_for_query;
 
5821
      possible_keys&= field->table->keys_in_use_for_query;
5794
5822
      bool is_const= true;
5795
5823
      for (uint32_t j= 0; j < (*iter).getNumValues(); j++)
5796
5824
        is_const&= (*iter).isConstItem(j);
5811
5839
      continue;
5812
5840
    }
5813
5841
    /* 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();
 
5842
    s->found_records=s->records=s->table->file->stats.records;
 
5843
    s->read_time=(ha_rows) s->table->file->scan_time();
5816
5844
 
5817
5845
    /*
5818
5846
      Set a max range of how many seeks we can expect when using keys
5831
5859
    add_group_and_distinct_keys(join, s);
5832
5860
 
5833
5861
    if (s->const_keys.any() &&
5834
 
        !s->table->pos_in_table_list->getEmbedding())
 
5862
        !s->table->pos_in_table_list->embedding)
5835
5863
    {
5836
5864
      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);
 
5865
      SQL_SELECT *select;
 
5866
      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
5867
      if (! select)
5840
5868
        return 1;
5841
5869
      records= get_quick_record_count(join->session, select, s->table, &s->const_keys, join->row_limit);
5851
5879
          caller to abort with a zero row result.
5852
5880
        */
5853
5881
        join->const_table_map|= s->table->map;
5854
 
        set_position(join, const_count++, s, (optimizer::KeyUse*) 0);
 
5882
        set_position(join,const_count++,s,(KeyUse*) 0);
5855
5883
        s->type= AM_CONST;
5856
5884
        if (*s->on_expr_ref)
5857
5885
        {
5881
5909
  if (join->const_tables != join->tables)
5882
5910
  {
5883
5911
    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;
 
5912
    if (choose_plan(join, all_table_map & ~join->const_table_map))
 
5913
      return(true);
5891
5914
  }
5892
5915
  else
5893
5916
  {
5895
5918
    join->best_read= 1.0;
5896
5919
  }
5897
5920
  /* Generate an execution plan from the found optimal join order. */
5898
 
  return (join->session->getKilled() || get_best_combination(join));
 
5921
  return (join->session->killed || get_best_combination(join));
5899
5922
}
5900
5923
 
5901
5924
/**
5924
5947
  while ((table= li++))
5925
5948
  {
5926
5949
    nested_join_st *nested_join;
5927
 
    if ((nested_join= table->getNestedJoin()))
 
5950
    if ((nested_join= table->nested_join))
5928
5951
    {
5929
5952
      /*
5930
5953
        It is guaranteed by simplify_joins() function that a nested join
5955
5978
  Return table number if there is only one table in sort order
5956
5979
  and group and order is compatible, else return 0.
5957
5980
*/
5958
 
static Table *get_sort_by_table(Order *a, Order *b,TableList *tables)
 
5981
static Table *get_sort_by_table(order_st *a,order_st *b,TableList *tables)
5959
5982
{
5960
5983
  table_map map= (table_map) 0;
5961
5984
 
5995
6018
  while ((table= li++))
5996
6019
  {
5997
6020
    nested_join_st *nested_join;
5998
 
    if ((nested_join= table->getNestedJoin()))
 
6021
    if ((nested_join= table->nested_join))
5999
6022
    {
6000
6023
      nested_join->counter_= 0;
6001
6024
      reset_nj_counters(&nested_join->join_list);
6010
6033
  If first parts has different direction, change it to second part
6011
6034
  (group is sorted like order)
6012
6035
*/
6013
 
static bool test_if_subpart(Order *a, Order *b)
 
6036
static bool test_if_subpart(order_st *a,order_st *b)
6014
6037
{
6015
6038
  for (; a && b; a=a->next,b=b->next)
6016
6039
  {
6025
6048
/**
6026
6049
  Nested joins perspective: Remove the last table from the join order.
6027
6050
 
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
6051
    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 
 
6052
    joins counters and join->cur_embedding_map. It is ok to call this
 
6053
    function for the first table in join order (for which
6071
6054
    check_interleaving_with_nj has not been called)
6072
6055
 
6073
6056
  @param last  join table to remove, it is assumed to be the last in current
6074
6057
               partial join order.
6075
6058
*/
6076
 
 
6077
6059
static void restore_prev_nj_state(JoinTable *last)
6078
6060
{
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)
 
6061
  TableList *last_emb= last->table->pos_in_table_list->embedding;
 
6062
  JOIN *join= last->join;
 
6063
  while (last_emb)
 
6064
  {
 
6065
    if (last_emb->on_expr)
 
6066
    {
 
6067
      if (!(--last_emb->nested_join->counter_))
 
6068
        join->cur_embedding_map&= ~last_emb->nested_join->nj_map;
 
6069
      else if (last_emb->nested_join->join_list.elements-1 ==
 
6070
               last_emb->nested_join->counter_)
 
6071
        join->cur_embedding_map|= last_emb->nested_join->nj_map;
 
6072
      else
 
6073
        break;
 
6074
    }
 
6075
    last_emb= last_emb->embedding;
 
6076
  }
 
6077
}
 
6078
 
 
6079
/**
 
6080
  Determine if the set is already ordered for order_st BY, so it can
 
6081
  disable join cache because it will change the ordering of the results.
 
6082
  Code handles sort table that is at any location (not only first after
 
6083
  the const tables) despite the fact that it's currently prohibited.
 
6084
  We must disable join cache if the first non-const table alone is
 
6085
  ordered. If there is a temp table the ordering is done as a last
 
6086
  operation and doesn't prevent join cache usage.
 
6087
*/
 
6088
static uint32_t make_join_orderinfo(JOIN *join)
 
6089
{
 
6090
  uint32_t i;
 
6091
  if (join->need_tmp)
 
6092
    return join->tables;
 
6093
 
 
6094
  for (i=join->const_tables ; i < join->tables ; i++)
 
6095
  {
 
6096
    JoinTable *tab= join->join_tab+i;
 
6097
    Table *table= tab->table;
 
6098
    if ((table == join->sort_by_table &&
 
6099
        (!join->order || join->skip_sort_order)) ||
 
6100
        (join->sort_by_table == (Table *) 1 &&  i != join->const_tables))
 
6101
    {
6091
6102
      break;
6092
 
    
6093
 
    join->cur_embedding_map|= nest->nj_map;
 
6103
    }
6094
6104
  }
 
6105
  return i;
6095
6106
}
6096
6107
 
6097
6108
/**
6111
6122
 
6112
6123
  for (uint32_t i=0 ; i < join_tab->ref.key_parts ; i++)
6113
6124
  {
6114
 
    Field *field=table->getField(table->key_info[join_tab->ref.key].key_part[i].fieldnr - 1);
 
6125
    Field *field=table->field[table->key_info[join_tab->ref.key].key_part[i].
 
6126
                              fieldnr-1];
6115
6127
    Item *value=join_tab->ref.items[i];
6116
6128
    cond->add(new Item_func_equal(new Item_field(field), value));
6117
6129
  }
6125
6137
    error=(int) cond->add(join_tab->select->cond);
6126
6138
    join_tab->select_cond=join_tab->select->cond=cond;
6127
6139
  }
6128
 
  else if ((join_tab->select= optimizer::make_select(join_tab->table, 0, 0, cond, 0,
6129
 
                                                     &error)))
 
6140
  else if ((join_tab->select= make_select(join_tab->table, 0, 0, cond, 0,
 
6141
                                          &error)))
6130
6142
    join_tab->select_cond=cond;
6131
6143
 
6132
6144
  return(error ? true : false);
6144
6156
/**
6145
6157
  @} (end of group Query_Optimizer)
6146
6158
*/
6147
 
 
6148
 
} /* namespace drizzled */