~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/join.cc

New merge for TableShare

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"
48
45
#include "drizzled/optimizer/position.h"
49
46
#include "drizzled/optimizer/sargable_param.h"
50
47
#include "drizzled/optimizer/key_use.h"
51
 
#include "drizzled/optimizer/range.h"
52
 
#include "drizzled/optimizer/sum.h"
53
 
#include "drizzled/optimizer/explain_plan.h"
54
 
#include "drizzled/optimizer/access_method_factory.h"
55
 
#include "drizzled/optimizer/access_method.h"
56
 
#include "drizzled/records.h"
57
 
#include "drizzled/probes.h"
58
 
#include "drizzled/internal/my_bit.h"
59
 
#include "drizzled/internal/my_sys.h"
60
 
#include "drizzled/internal/iocache.h"
 
48
#include "mysys/my_bit.h"
61
49
 
62
50
#include <algorithm>
63
51
 
64
52
using namespace std;
65
 
 
66
 
namespace drizzled
67
 
{
68
 
 
69
 
extern plugin::StorageEngine *heap_engine;
70
 
extern std::bitset<12> test_flags;
 
53
using namespace drizzled;
71
54
 
72
55
/** 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,
 
56
static bool make_group_fields(JOIN *main_join, JOIN *curr_join);
 
57
static void calc_group_buffer(JOIN *join,order_st *group);
 
58
static bool alloc_group_fields(JOIN *join,order_st *group);
 
59
static uint32_t cache_record_length(JOIN *join, uint32_t index);
 
60
static double prev_record_reads(JOIN *join, uint32_t idx, table_map found_ref);
 
61
static bool get_best_combination(JOIN *join);
 
62
static void set_position(JOIN *join,
80
63
                         uint32_t index,
81
64
                         JoinTable *table,
82
65
                         optimizer::KeyUse *key);
83
 
static bool choose_plan(Join *join,table_map join_tables);
84
 
static void best_access_path(Join *join, JoinTable *s,
 
66
static bool choose_plan(JOIN *join,table_map join_tables);
 
67
static void best_access_path(JOIN *join, JoinTable *s,
85
68
                             Session *session,
86
69
                             table_map remaining_tables,
87
70
                             uint32_t idx,
88
71
                             double record_count,
89
72
                             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,
 
73
static void optimize_straight_join(JOIN *join, table_map join_tables);
 
74
static bool greedy_search(JOIN *join, table_map remaining_tables, uint32_t depth, uint32_t prune_level);
 
75
static bool best_extension_by_limited_search(JOIN *join,
93
76
                                             table_map remaining_tables,
94
77
                                             uint32_t idx,
95
78
                                             double record_count,
96
79
                                             double read_time,
97
80
                                             uint32_t depth,
98
81
                                             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,
 
82
static uint32_t determine_search_depth(JOIN* join);
 
83
static bool make_simple_join(JOIN *join,Table *tmp_table);
 
84
static void make_outerjoin_info(JOIN *join);
 
85
static bool make_join_select(JOIN *join,SQL_SELECT *select,COND *item);
 
86
static bool make_join_readinfo(JOIN *join, uint64_t options, uint32_t no_jbuf_after);
 
87
static void update_depend_map(JOIN *join);
 
88
static void update_depend_map(JOIN *join, order_st *order);
 
89
static order_st *remove_constants(JOIN *join,order_st *first_order,COND *cond, bool change_list, bool *simple_order);
 
90
static int return_zero_rows(JOIN *join,
108
91
                            select_result *res,
109
92
                            TableList *tables,
110
93
                            List<Item> &fields,
112
95
                            uint64_t select_options,
113
96
                            const char *info,
114
97
                            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);
 
98
static COND *simplify_joins(JOIN *join, List<TableList> *join_list, COND *conds, bool top);
 
99
static int remove_duplicates(JOIN *join,Table *entry,List<Item> &fields, Item *having);
117
100
static int setup_without_group(Session *session, 
118
101
                               Item **ref_pointer_array,
119
102
                               TableList *tables,
121
104
                               List<Item> &fields,
122
105
                               List<Item> &all_fields,
123
106
                               COND **conds,
124
 
                               Order *order,
125
 
                               Order *group,
 
107
                               order_st *order,
 
108
                               order_st *group,
126
109
                               bool *hidden_group_fields);
127
 
static bool make_join_statistics(Join *join, TableList *leaves, COND *conds, DYNAMIC_ARRAY *keyuse);
 
110
static bool make_join_statistics(JOIN *join, TableList *leaves, COND *conds, DYNAMIC_ARRAY *keyuse);
128
111
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);
 
112
static Table *get_sort_by_table(order_st *a,order_st *b,TableList *tables);
130
113
static void reset_nj_counters(List<TableList> *join_list);
131
 
static bool test_if_subpart(Order *a,Order *b);
 
114
static bool test_if_subpart(order_st *a,order_st *b);
132
115
static void restore_prev_nj_state(JoinTable *last);
 
116
static uint32_t make_join_orderinfo(JOIN *join);
133
117
static bool add_ref_to_table_cond(Session *session, JoinTable *join_tab);
134
118
static void free_blobs(Field **ptr); /* Rename this method...conflicts with another in global namespace... */
135
119
 
145
129
  @retval
146
130
    0   on success
147
131
*/
148
 
int Join::prepare(Item ***rref_pointer_array,
 
132
int JOIN::prepare(Item ***rref_pointer_array,
149
133
                  TableList *tables_init,
150
134
                  uint32_t wild_num,
151
135
                  COND *conds_init,
152
136
                  uint32_t og_num,
153
 
                  Order *order_init,
154
 
                  Order *group_init,
 
137
                  order_st *order_init,
 
138
                  order_st *group_init,
155
139
                  Item *having_init,
156
140
                  Select_Lex *select_lex_arg,
157
141
                  Select_Lex_Unit *unit_arg)
184
168
      setup_tables_and_check_access(session, &select_lex->context, join_list,
185
169
                                    tables_list, &select_lex->leaf_tables,
186
170
                                    false))
187
 
  {
188
171
      return(-1);
189
 
  }
190
172
 
191
173
  TableList *table_ptr;
192
174
  for (table_ptr= select_lex->leaf_tables;
193
175
       table_ptr;
194
176
       table_ptr= table_ptr->next_leaf)
195
 
  {
196
177
    tables++;
197
 
  }
198
 
 
199
178
 
200
179
  if (setup_wild(session, fields_list, &all_fields, wild_num) ||
201
180
      select_lex->setup_ref_array(session, og_num) ||
237
216
        in_subs= (Item_in_subselect*)subselect;
238
217
 
239
218
      {
240
 
        bool do_materialize= true;
 
219
        bool do_materialize= !test(session->variables.optimizer_switch &
 
220
                                   OPTIMIZER_SWITCH_NO_MATERIALIZATION);
241
221
        /*
242
222
          Check if the subquery predicate can be executed via materialization.
243
223
          The required conditions are:
255
235
             (Subquery is non-correlated ||
256
236
              Subquery is correlated to any query outer to IN predicate ||
257
237
              (Subquery is correlated to the immediate outer query &&
258
 
               Subquery !contains {GROUP BY, ORDER BY [LIMIT],
 
238
               Subquery !contains {GROUP BY, order_st BY [LIMIT],
259
239
               aggregate functions) && subquery predicate is not under "NOT IN"))
260
240
          6. No execution method was already chosen (by a prepared statement).
261
241
 
291
271
 
292
272
  if (order)
293
273
  {
294
 
    Order *ord;
 
274
    order_st *ord;
295
275
    for (ord= order; ord; ord= ord->next)
296
276
    {
297
277
      Item *item= *ord->item;
336
316
  {
337
317
    /* Caclulate the number of groups */
338
318
    send_group_parts= 0;
339
 
    for (Order *group_tmp= group_list ; group_tmp ; group_tmp= group_tmp->next)
 
319
    for (order_st *group_tmp= group_list ; group_tmp ; group_tmp= group_tmp->next)
340
320
      send_group_parts++;
341
321
  }
342
322
 
343
323
  if (error)
344
 
    return(-1);
 
324
    goto err;
345
325
 
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
326
  if (result && result->prepare(fields_list, unit_arg))
353
 
    return(-1);
 
327
    goto err;
354
328
 
355
329
  /* Init join struct */
356
330
  count_field_types(select_lex, &tmp_table_param, all_fields, 0);
362
336
  if (sum_func_count && !group_list && (func_count || field_count))
363
337
  {
364
338
    my_message(ER_WRONG_SUM_SELECT,ER(ER_WRONG_SUM_SELECT),MYF(0));
365
 
    return(-1);
 
339
    goto err;
366
340
  }
367
341
#endif
368
342
  if (select_lex->olap == ROLLUP_TYPE && rollup_init())
369
 
    return(-1);
370
 
 
 
343
    goto err;
371
344
  if (alloc_func_list())
372
 
    return(-1);
373
 
 
374
 
  return 0; // All OK
 
345
    goto err;
 
346
 
 
347
  return(0); // All OK
 
348
 
 
349
err:
 
350
  return(-1);
375
351
}
376
352
 
377
353
/*
378
354
  Remove the predicates pushed down into the subquery
379
355
 
380
356
  SYNOPSIS
381
 
    Join::remove_subq_pushed_predicates()
 
357
    JOIN::remove_subq_pushed_predicates()
382
358
      where   IN  Must be NULL
383
359
              OUT The remaining WHERE condition, or NULL
384
360
 
403
379
    that is searched in a byte. But this requires homogenization of the return
404
380
    codes of all Field*::store() methods.
405
381
*/
406
 
void Join::remove_subq_pushed_predicates(Item **where)
 
382
void JOIN::remove_subq_pushed_predicates(Item **where)
407
383
{
408
384
  if (conds->type() == Item::FUNC_ITEM &&
409
385
      ((Item_func *)this->conds)->functype() == Item_func::EQ_FUNC &&
428
404
  @retval
429
405
    1   error
430
406
*/
431
 
int Join::optimize()
 
407
int JOIN::optimize()
432
408
{
433
409
  // to prevent double initialization on EXPLAIN
434
410
  if (optimized)
498
474
    {           /* Impossible cond */
499
475
      zero_result_cause=  having_value == Item::COND_FALSE ?
500
476
                           "Impossible HAVING" : "Impossible WHERE";
501
 
      tables = 0;
502
 
      goto setup_subq_exit;
 
477
      error= 0;
 
478
      return(0);
503
479
    }
504
480
  }
505
481
 
508
484
  {
509
485
    int res;
510
486
    /*
511
 
      optimizer::sum_query() returns HA_ERR_KEY_NOT_FOUND if no rows match
 
487
      opt_sum_query() returns HA_ERR_KEY_NOT_FOUND if no rows match
512
488
      to the WHERE conditions,
513
489
      or 1 if all items were resolved,
514
490
      or 0, or an error number HA_ERR_...
515
491
    */
516
 
    if ((res= optimizer::sum_query(select_lex->leaf_tables, all_fields, conds)))
 
492
    if ((res=opt_sum_query(select_lex->leaf_tables, all_fields, conds)))
517
493
    {
518
494
      if (res == HA_ERR_KEY_NOT_FOUND)
519
495
      {
520
496
        zero_result_cause= "No matching min/max row";
521
 
        tables = 0;
522
 
        goto setup_subq_exit;
 
497
        error=0;
 
498
        return(0);
523
499
      }
524
500
      if (res > 1)
525
501
      {
529
505
      if (res < 0)
530
506
      {
531
507
        zero_result_cause= "No matching min/max row";
532
 
        tables = 0;
533
 
        goto setup_subq_exit;
 
508
        error=0;
 
509
        return(0);
534
510
      }
535
511
      zero_result_cause= "Select tables optimized away";
536
512
      tables_list= 0;       // All tables resolved
537
 
      const_tables= tables;
538
513
      /*
539
514
        Extract all table-independent conditions and replace the WHERE
540
 
        clause with them. All other conditions were computed by optimizer::sum_query
 
515
        clause with them. All other conditions were computed by opt_sum_query
541
516
        and the MIN/MAX/COUNT function(s) have been replaced by constants,
542
517
        so there is no need to compute the whole WHERE clause again.
543
518
        Notice that make_cond_for_table() will always succeed to remove all
544
 
        computed conditions, because optimizer::sum_query() is applicable only to
 
519
        computed conditions, because opt_sum_query() is applicable only to
545
520
        conjunctions.
546
521
        Preserve conditions for EXPLAIN.
547
522
      */
550
525
        COND *table_independent_conds= make_cond_for_table(conds, PSEUDO_TABLE_BITS, 0, 0);
551
526
        conds= table_independent_conds;
552
527
      }
553
 
      goto setup_subq_exit;
554
528
    }
555
529
  }
556
530
  if (!tables_list)
583
557
       select_lex->master_unit() == &session->lex->unit)) // upper level SELECT
584
558
  {
585
559
    zero_result_cause= "no matching row in const table";
586
 
    goto setup_subq_exit;
 
560
    error= 0;
 
561
    return(0);
587
562
  }
588
563
  if (!(session->options & OPTION_BIG_SELECTS) &&
589
564
      best_read > (double) session->variables.max_join_size &&
594
569
    return 1;
595
570
  }
596
571
  if (const_tables && !(select_options & SELECT_NO_UNLOCK))
597
 
    session->unlockSomeTables(table, const_tables);
 
572
    mysql_unlock_some_tables(session, table, const_tables);
598
573
  if (!conds && outer_join)
599
574
  {
600
575
    /* Handle the case where we have an OUTER JOIN without a WHERE */
601
576
    conds=new Item_int((int64_t) 1,1);  // Always true
602
577
  }
603
 
  select= optimizer::make_select(*table, const_table_map,
604
 
                                 const_table_map, conds, 1, &error);
 
578
  select= make_select(*table, const_table_map,
 
579
                      const_table_map, conds, 1, &error);
605
580
  if (error)
606
581
  {
607
582
    error= -1;
644
619
  {
645
620
    conds=new Item_int((int64_t) 0,1);  // Always false
646
621
  }
647
 
 
648
622
  if (make_join_select(this, select, conds))
649
623
  {
650
624
    zero_result_cause=
651
625
      "Impossible WHERE noticed after reading const tables";
652
 
    goto setup_subq_exit;
 
626
    return(0);        // error == 0
653
627
  }
654
628
 
655
629
  error= -1;          /* if goto err */
656
630
 
657
631
  /* Optimize distinct away if possible */
658
632
  {
659
 
    Order *org_order= order;
 
633
    order_st *org_order= order;
660
634
    order= remove_constants(this, order,conds,1, &simple_order);
661
635
    if (session->is_error())
662
636
    {
665
639
    }
666
640
 
667
641
    /*
668
 
      If we are using ORDER BY NULL or ORDER BY const_expression,
 
642
      If we are using order_st BY NULL or order_st BY const_expression,
669
643
      return result in any order (even if we are using a GROUP BY)
670
644
    */
671
645
    if (!order && org_order)
684
658
     The FROM clause must contain a single non-constant table.
685
659
  */
686
660
  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 ||
 
661
      !tmp_table_param.sum_func_count &&
 
662
      (!join_tab[const_tables].select ||
 
663
       !join_tab[const_tables].select->quick ||
690
664
       join_tab[const_tables].select->quick->get_type() !=
691
 
       optimizer::QuickSelectInterface::QS_TYPE_GROUP_MIN_MAX))
 
665
       QUICK_SELECT_I::QS_TYPE_GROUP_MIN_MAX))
692
666
  {
693
667
    if (group_list && list_contains_unique_index(join_tab[const_tables].table, find_field_in_order_list, (void *) group_list))
694
668
    {
696
670
        We have found that grouping can be removed since groups correspond to
697
671
        only one row anyway, but we still have to guarantee correct result
698
672
        order. The line below effectively rewrites the query from GROUP BY
699
 
        <fields> to ORDER BY <fields>. There are two exceptions:
 
673
        <fields> to order_st BY <fields>. There are two exceptions:
700
674
        - if skip_sort_order is set (see above), then we can simply skip
701
675
          GROUP BY;
702
 
        - we can only rewrite ORDER BY if the ORDER BY fields are 'compatible'
 
676
        - we can only rewrite order_st BY if the order_st BY fields are 'compatible'
703
677
          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
 
678
          We only check if the order_st BY is a prefix of GROUP BY. In this case
705
679
          test_if_subpart() copies the ASC/DESC attributes from the original
706
 
          ORDER BY fields.
 
680
          order_st BY fields.
707
681
          If GROUP BY is a prefix of order_st BY, then it is safe to leave
708
682
          'order' as is.
709
683
       */
710
 
      if (! order || test_if_subpart(group_list, order))
 
684
      if (!order || test_if_subpart(group_list, order))
711
685
          order= skip_sort_order ? 0 : group_list;
712
686
      /*
713
687
        If we have an IGNORE INDEX FOR GROUP BY(fields) clause, this must be
742
716
      - We are scanning the whole table without LIMIT
743
717
        This can happen if:
744
718
        - We are using CALC_FOUND_ROWS
745
 
        - We are using an ORDER BY that can't be optimized away.
 
719
        - We are using an order_st BY that can't be optimized away.
746
720
 
747
721
      We don't want to use this optimization when we are using LIMIT
748
722
      because in this case we can just create a temporary table that
774
748
          {
775
749
            /*
776
750
              Force MySQL to read the table in sorted order to get result in
777
 
              ORDER BY order.
 
751
              order_st BY order.
778
752
            */
779
753
            tmp_table_param.quick_group=0;
780
754
          }
790
764
  }
791
765
  simple_group= 0;
792
766
  {
793
 
    Order *old_group_list;
 
767
    order_st *old_group_list;
794
768
    group_list= remove_constants(this, (old_group_list= group_list), conds,
795
769
                                 rollup.state == ROLLUP::STATE_NONE,
796
770
                                 &simple_group);
831
805
    This has to be done if all tables are not already read (const tables)
832
806
    and one of the following conditions holds:
833
807
    - 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
 
808
    - We are using an order_st BY or GROUP BY on fields not in the first table
 
809
    - We are using different order_st BY and GROUP BY orders
836
810
    - The user wants us to buffer the result.
837
811
  */
838
812
  need_tmp= (const_tables != tables &&
840
814
        (group_list && order) ||
841
815
        test(select_options & OPTION_BUFFER_RESULT)));
842
816
 
 
817
  uint32_t no_jbuf_after= make_join_orderinfo(this);
 
818
  uint64_t select_opts_for_readinfo=
 
819
    (select_options & (SELECT_DESCRIBE | SELECT_NO_JOIN_CACHE)) | (0);
 
820
 
843
821
  // No cache for MATCH == 'Don't use join buffering when we use MATCH'.
844
 
  if (make_join_readinfo(this))
 
822
  if (make_join_readinfo(this, select_opts_for_readinfo, no_jbuf_after))
845
823
    return 1;
846
824
 
847
825
  /* Create all structures needed for materialized subquery execution. */
848
826
  if (setup_subquery_materialization())
849
827
    return 1;
850
828
 
851
 
  /* Cache constant expressions in WHERE, HAVING, ON clauses. */
852
 
  cache_const_exprs();
853
 
 
854
829
  /*
855
830
    is this simple IN subquery?
856
831
  */
868
843
        save_index_subquery_explain_info(join_tab, where);
869
844
        join_tab[0].type= AM_UNIQUE_SUBQUERY;
870
845
        error= 0;
871
 
        return(unit->item->change_engine(new subselect_uniquesubquery_engine(session, join_tab, unit->item, where)));
 
846
        return(unit->item->
 
847
                    change_engine(new
 
848
                                  subselect_uniquesubquery_engine(session,
 
849
                                                                  join_tab,
 
850
                                                                  unit->item,
 
851
                                                                  where)));
872
852
      }
873
853
      else if (join_tab[0].type == AM_REF &&
874
854
         join_tab[0].ref.items[0]->name == in_left_expr_name)
877
857
        save_index_subquery_explain_info(join_tab, where);
878
858
        join_tab[0].type= AM_INDEX_SUBQUERY;
879
859
        error= 0;
880
 
        return(unit->item->change_engine(new subselect_indexsubquery_engine(session, join_tab, unit->item, where, NULL, 0)));
 
860
        return(unit->item->
 
861
                    change_engine(new
 
862
                                  subselect_indexsubquery_engine(session,
 
863
                                                                 join_tab,
 
864
                                                                 unit->item,
 
865
                                                                 where,
 
866
                                                                 NULL,
 
867
                                                                 0)));
881
868
      }
882
869
    } 
883
870
    else if (join_tab[0].type == AM_REF_OR_NULL &&
888
875
      error= 0;
889
876
      conds= remove_additional_cond(conds);
890
877
      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)));
 
878
      return(unit->item->
 
879
      change_engine(new subselect_indexsubquery_engine(session,
 
880
                   join_tab,
 
881
                   unit->item,
 
882
                   conds,
 
883
                                                                   having,
 
884
                   1)));
892
885
    }
893
886
 
894
887
  }
940
933
        Force using of tmp table if sorting by a SP or UDF function due to
941
934
        their expensive and probably non-deterministic nature.
942
935
      */
943
 
      for (Order *tmp_order= order; tmp_order ; tmp_order=tmp_order->next)
 
936
      for (order_st *tmp_order= order; tmp_order ; tmp_order=tmp_order->next)
944
937
      {
945
938
        Item *item= *tmp_order->item;
946
939
        if (item->is_expensive())
984
977
 
985
978
    tmp_table_param.hidden_field_count= (all_fields.elements -
986
979
           fields_list.elements);
987
 
    Order *tmp_group= ((!simple_group &&
 
980
    order_st *tmp_group= ((!simple_group && 
988
981
                           ! (test_flags.test(TEST_NO_KEY_GROUP))) ? group_list :
989
 
                                                                     (Order*) 0);
 
982
                                                                     (order_st*) 0);
990
983
    /*
991
984
      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
 
985
      when there is order_st BY or GROUP BY or there is no GROUP BY, but
993
986
      there are aggregate functions, because in all these cases we need
994
987
      all result rows.
995
988
    */
1089
1082
      If this join belongs to an uncacheable subquery save
1090
1083
      the original join
1091
1084
    */
1092
 
    if (select_lex->uncacheable.any() && 
1093
 
        ! is_top_level_join() &&
 
1085
    if (select_lex->uncacheable && !is_top_level_join() &&
1094
1086
        init_save_join_tab())
1095
 
    {
1096
 
      return -1;
1097
 
    }
 
1087
      return(-1);
1098
1088
  }
1099
1089
 
1100
1090
  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;
 
1091
  return(0);
1111
1092
}
1112
1093
 
1113
1094
/**
1114
1095
  Restore values in temporary join.
1115
1096
*/
1116
 
void Join::restore_tmp()
 
1097
void JOIN::restore_tmp()
1117
1098
{
1118
 
  memcpy(tmp_join, this, (size_t) sizeof(Join));
 
1099
  memcpy(tmp_join, this, (size_t) sizeof(JOIN));
1119
1100
}
1120
1101
 
1121
 
int Join::reinit()
 
1102
int JOIN::reinit()
1122
1103
{
1123
1104
  unit->offset_limit_cnt= (ha_rows)(select_lex->offset_limit ?
1124
1105
                                    select_lex->offset_limit->val_uint() :
1170
1151
   @retval 0      success.
1171
1152
   @retval 1      error occurred.
1172
1153
*/
1173
 
bool Join::init_save_join_tab()
 
1154
bool JOIN::init_save_join_tab()
1174
1155
{
1175
 
  if (!(tmp_join= (Join*)session->alloc(sizeof(Join))))
 
1156
  if (!(tmp_join= (JOIN*)session->alloc(sizeof(JOIN))))
1176
1157
    return 1;
1177
 
 
1178
1158
  error= 0;              // Ensure that tmp_join.error= 0
1179
1159
  restore_tmp();
1180
 
 
1181
1160
  return 0;
1182
1161
}
1183
1162
 
1184
 
bool Join::save_join_tab()
 
1163
bool JOIN::save_join_tab()
1185
1164
{
1186
 
  if (! join_tab_save && select_lex->master_unit()->uncacheable.any())
 
1165
  if (!join_tab_save && select_lex->master_unit()->uncacheable)
1187
1166
  {
1188
1167
    if (!(join_tab_save= (JoinTable*)session->memdup((unsigned char*) join_tab,
1189
1168
            sizeof(JoinTable) * tables)))
1203
1182
  @todo
1204
1183
    When can we have here session->net.report_error not zero?
1205
1184
*/
1206
 
void Join::exec()
 
1185
void JOIN::exec()
1207
1186
{
1208
1187
  List<Item> *columns_list= &fields_list;
1209
1188
  int      tmp_error;
1215
1194
  {                                           
1216
1195
    /* Only test of functions */
1217
1196
    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
 
    }
 
1197
      select_describe(this, false, false, false, (zero_result_cause?zero_result_cause:"No tables used"));
1226
1198
    else
1227
1199
    {
1228
1200
      result->send_fields(*columns_list);
1273
1245
    return;
1274
1246
  }
1275
1247
 
 
1248
  if ((this->select_lex->options & OPTION_SCHEMA_TABLE) && get_schema_tables_result(this, PROCESSED_BY_JOIN_EXEC))
 
1249
    return;
 
1250
 
1276
1251
  if (select_options & SELECT_DESCRIBE)
1277
1252
  {
1278
1253
    /*
1279
 
      Check if we managed to optimize ORDER BY away and don't use temporary
 
1254
      Check if we managed to optimize order_st BY away and don't use temporary
1280
1255
      table to resolve order_st BY: in that case, we only may need to do
1281
1256
      filesort for GROUP BY.
1282
1257
    */
1295
1270
      order= 0;
1296
1271
    }
1297
1272
    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();
 
1273
    select_describe(this, need_tmp, order != 0 && !skip_sort_order,  select_distinct, !tables ? "No tables used" : NULL);
1304
1274
    return;
1305
1275
  }
1306
1276
 
1307
 
  Join *curr_join= this;
 
1277
  JOIN *curr_join= this;
1308
1278
  List<Item> *curr_all_fields= &all_fields;
1309
1279
  List<Item> *curr_fields_list= &fields_list;
1310
1280
  Table *curr_tmp_table= 0;
1414
1384
                                                   - curr_join->tmp_fields_list1.elements;
1415
1385
 
1416
1386
      if (exec_tmp_table2)
1417
 
      {
1418
1387
        curr_tmp_table= exec_tmp_table2;
1419
 
      }
1420
1388
      else
1421
1389
      {
1422
1390
        /* group data to new table */
1424
1392
        /*
1425
1393
          If the access method is loose index scan then all MIN/MAX
1426
1394
          functions are precomputed, and should be treated as regular
1427
 
          functions. See extended comment in Join::exec.
 
1395
          functions. See extended comment in JOIN::exec.
1428
1396
        */
1429
1397
        if (curr_join->join_tab->is_using_loose_index_scan())
1430
1398
          curr_join->tmp_table_param.precomputed_group_by= true;
1433
1401
              exec_tmp_table2= create_tmp_table(session,
1434
1402
                                                &curr_join->tmp_table_param,
1435
1403
                                                *curr_all_fields,
1436
 
                                                (Order*) 0,
 
1404
                                                (order_st*) 0,
1437
1405
                                                curr_join->select_distinct &&
1438
1406
                                                !curr_join->group_list,
1439
1407
                                                1, curr_join->select_options,
1440
1408
                                                HA_POS_ERROR,
1441
1409
                                                (char *) "")))
1442
 
        {
1443
1410
          return;
1444
 
        }
1445
 
 
1446
1411
        curr_join->exec_tmp_table2= exec_tmp_table2;
1447
1412
      }
1448
1413
      if (curr_join->group_list)
1490
1455
        error= tmp_error;
1491
1456
        return;
1492
1457
      }
1493
 
      curr_join->join_tab->read_record.end_read_record();
 
1458
      end_read_record(&curr_join->join_tab->read_record);
1494
1459
      curr_join->const_tables= curr_join->tables; // Mark free for cleanup()
1495
1460
      curr_join->join_tab[0].table= 0;           // Table is freed
1496
1461
 
1587
1552
      if (sort_table_cond)
1588
1553
      {
1589
1554
        if (!curr_table->select)
1590
 
          if (!(curr_table->select= new optimizer::SqlSelect))
 
1555
          if (!(curr_table->select= new SQL_SELECT))
1591
1556
            return;
1592
1557
        if (!curr_table->select->cond)
1593
1558
          curr_table->select->cond= sort_table_cond;
1701
1666
  Clean up join.
1702
1667
 
1703
1668
  @return
1704
 
    Return error that hold Join.
 
1669
    Return error that hold JOIN.
1705
1670
*/
1706
 
int Join::destroy()
 
1671
int JOIN::destroy()
1707
1672
{
1708
1673
  select_lex->join= 0;
1709
1674
 
1722
1687
  cond_equal= 0;
1723
1688
 
1724
1689
  cleanup(1);
1725
 
  exec_tmp_table1= NULL;
1726
 
  exec_tmp_table2= NULL;
 
1690
  if (exec_tmp_table1)
 
1691
    exec_tmp_table1->free_tmp_table(session);
 
1692
  if (exec_tmp_table2)
 
1693
    exec_tmp_table2->free_tmp_table(session);
1727
1694
  delete select;
1728
1695
  delete_dynamic(&keyuse);
1729
 
 
1730
1696
  return(error);
1731
1697
}
1732
1698
 
1739
1705
  - try to initialize all data structures needed for the materialized execution
1740
1706
    of the IN predicate,
1741
1707
  - if this fails, then perform the IN=>EXISTS transformation which was
1742
 
    previously blocked during Join::prepare.
 
1708
    previously blocked during JOIN::prepare.
1743
1709
 
1744
1710
  This method is part of the "code generation" query processing phase.
1745
1711
 
1752
1718
  @retval false     success.
1753
1719
  @retval true      error occurred.
1754
1720
*/
1755
 
bool Join::setup_subquery_materialization()
 
1721
bool JOIN::setup_subquery_materialization()
1756
1722
{
1757
1723
  for (Select_Lex_Unit *un= select_lex->first_inner_unit(); un;
1758
1724
       un= un->next_unit())
1774
1740
}
1775
1741
 
1776
1742
/**
1777
 
  Partially cleanup Join after it has executed: close index or rnd read
 
1743
  Partially cleanup JOIN after it has executed: close index or rnd read
1778
1744
  (table cursors), free quick selects.
1779
1745
 
1780
 
    This function is called in the end of execution of a Join, before the used
 
1746
    This function is called in the end of execution of a JOIN, before the used
1781
1747
    tables are unlocked and closed.
1782
1748
 
1783
1749
    For a join that is resolved using a temporary table, the first sweep is
1791
1757
    is called after all rows are sent, but before EOF packet is sent.
1792
1758
 
1793
1759
    For a simple SELECT with no subqueries this function performs a full
1794
 
    cleanup of the Join and calls unlockReadTables to free used base
 
1760
    cleanup of the JOIN and calls mysql_unlock_read_tables to free used base
1795
1761
    tables.
1796
1762
 
1797
 
    If a Join is executed for a subquery or if it has a subquery, we can't
 
1763
    If a JOIN is executed for a subquery or if it has a subquery, we can't
1798
1764
    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
 
1765
    - If a JOIN is not the top level join, we must not unlock the tables
1800
1766
    because the outer select may not have been evaluated yet, and we
1801
1767
    can't unlock only selected tables of a query.
1802
 
    - Additionally, if this Join corresponds to a correlated subquery, we
 
1768
    - Additionally, if this JOIN corresponds to a correlated subquery, we
1803
1769
    should not free quick selects and join buffers because they will be
1804
1770
    needed for the next execution of the correlated subquery.
1805
 
    - However, if this is a Join for a [sub]select, which is not
 
1771
    - However, if this is a JOIN for a [sub]select, which is not
1806
1772
    a correlated subquery itself, but has subqueries, we can free it
1807
 
    fully and also free Joins of all its subqueries. The exception
 
1773
    fully and also free JOINs of all its subqueries. The exception
1808
1774
    is a subquery in SELECT list, e.g: @n
1809
1775
    SELECT a, (select cmax(b) from t1) group by c @n
1810
1776
    This subquery will not be evaluated at first sweep and its value will
1815
1781
  @todo
1816
1782
    Unlock tables even if the join isn't top level select in the tree
1817
1783
*/
1818
 
void Join::join_free()
 
1784
void JOIN::join_free()
1819
1785
{
1820
1786
  Select_Lex_Unit *tmp_unit;
1821
1787
  Select_Lex *sl;
1822
1788
  /*
1823
 
    Optimization: if not EXPLAIN and we are done with the Join,
 
1789
    Optimization: if not EXPLAIN and we are done with the JOIN,
1824
1790
    free all tables.
1825
1791
  */
1826
 
  bool full= (select_lex->uncacheable.none() && ! session->lex->describe);
 
1792
  bool full= (!select_lex->uncacheable && !session->lex->describe);
1827
1793
  bool can_unlock= full;
1828
1794
 
1829
1795
  cleanup(full);
1845
1811
        but all table cursors must be closed before the unlock.
1846
1812
      */
1847
1813
      sl->cleanup_all_joins(full_local);
1848
 
      /* Can't unlock if at least one Join is still needed */
 
1814
      /* Can't unlock if at least one JOIN is still needed */
1849
1815
      can_unlock= can_unlock && full_local;
1850
1816
    }
1851
1817
 
1863
1829
      TODO: unlock tables even if the join isn't top level select in the
1864
1830
      tree.
1865
1831
    */
1866
 
    session->unlockReadTables(lock);           // Don't free join->lock
 
1832
    mysql_unlock_read_tables(session, lock);           // Don't free join->lock
1867
1833
    lock= 0;
1868
1834
  }
1869
1835
 
1882
1848
    With subquery this function definitely will be called several times,
1883
1849
    but even for simple query it can be called several times.
1884
1850
*/
1885
 
void Join::cleanup(bool full)
 
1851
void JOIN::cleanup(bool full)
1886
1852
{
1887
1853
  if (table)
1888
1854
  {
1927
1893
    */
1928
1894
    tmp_table_param.copy_funcs.empty();
1929
1895
    /*
1930
 
      If we have tmp_join and 'this' Join is not tmp_join and
 
1896
      If we have tmp_join and 'this' JOIN is not tmp_join and
1931
1897
      tmp_table_param.copy_field's  of them are equal then we have to remove
1932
1898
      pointer to  tmp_table_param.copy_field from tmp_join, because it qill
1933
1899
      be removed in tmp_table_param.cleanup().
1946
1912
}
1947
1913
 
1948
1914
/*
1949
 
  used only in Join::clear
 
1915
  used only in JOIN::clear
1950
1916
*/
1951
 
static void clear_tables(Join *join)
 
1917
static void clear_tables(JOIN *join)
1952
1918
{
1953
1919
  /*
1954
1920
    must clear only the non-const tables, as const tables
1967
1933
  @retval
1968
1934
    1 Error
1969
1935
*/
1970
 
bool Join::alloc_func_list()
 
1936
bool JOIN::alloc_func_list()
1971
1937
{
1972
1938
  uint32_t func_count, group_parts;
1973
1939
 
1993
1959
    */
1994
1960
    if (order)
1995
1961
    {
1996
 
      Order *ord;
 
1962
      order_st *ord;
1997
1963
      for (ord= order; ord; ord= ord->next)
1998
1964
        group_parts++;
1999
1965
    }
2019
1985
  @retval
2020
1986
    1  error
2021
1987
*/
2022
 
bool Join::make_sum_func_list(List<Item> &field_list, 
 
1988
bool JOIN::make_sum_func_list(List<Item> &field_list, 
2023
1989
                              List<Item> &send_fields,
2024
1990
                              bool before_group_by, 
2025
1991
                              bool recompute)
2057
2023
}
2058
2024
 
2059
2025
/** Allocate memory needed for other rollup functions. */
2060
 
bool Join::rollup_init()
 
2026
bool JOIN::rollup_init()
2061
2027
{
2062
2028
  uint32_t i,j;
2063
2029
  Item **ref_array;
2103
2069
  Item *item;
2104
2070
  while ((item= it++))
2105
2071
  {
2106
 
    Order *group_tmp;
 
2072
    order_st *group_tmp;
2107
2073
    bool found_in_group= 0;
2108
2074
 
2109
2075
    for (group_tmp= group_list; group_tmp; group_tmp= group_tmp->next)
2132
2098
            return 1;
2133
2099
          new_item->fix_fields(session, (Item **) 0);
2134
2100
          session->change_item_tree(it.ref(), new_item);
2135
 
          for (Order *tmp= group_tmp; tmp; tmp= tmp->next)
 
2101
          for (order_st *tmp= group_tmp; tmp; tmp= tmp->next)
2136
2102
          {
2137
2103
            if (*tmp->item == item)
2138
2104
              session->change_item_tree(tmp->item, new_item);
2172
2138
  @retval
2173
2139
    1    on error
2174
2140
*/
2175
 
bool Join::rollup_make_fields(List<Item> &fields_arg, List<Item> &sel_fields, Item_sum ***func)
 
2141
bool JOIN::rollup_make_fields(List<Item> &fields_arg, List<Item> &sel_fields, Item_sum ***func)
2176
2142
{
2177
2143
  List_iterator_fast<Item> it(fields_arg);
2178
2144
  Item *first_field= sel_fields.head();
2207
2173
    Item *item;
2208
2174
    List_iterator<Item> new_it(rollup.fields[pos]);
2209
2175
    Item **ref_array_start= rollup.ref_pointer_arrays[pos];
2210
 
    Order *start_group;
 
2176
    order_st *start_group;
2211
2177
 
2212
2178
    /* Point to first hidden field */
2213
2179
    Item **ref_array= ref_array_start + fields_arg.elements-1;
2249
2215
      else
2250
2216
      {
2251
2217
        /* Check if this is something that is part of this group by */
2252
 
        Order *group_tmp;
 
2218
        order_st *group_tmp;
2253
2219
        for (group_tmp= start_group, i= pos ;
2254
2220
                  group_tmp ; group_tmp= group_tmp->next, i++)
2255
2221
        {
2302
2268
  @retval
2303
2269
    1   If send_data_failed()
2304
2270
*/
2305
 
int Join::rollup_send_data(uint32_t idx)
 
2271
int JOIN::rollup_send_data(uint32_t idx)
2306
2272
{
2307
2273
  uint32_t i;
2308
2274
  for (i= send_group_parts ; i-- > idx ; )
2342
2308
  @retval
2343
2309
    1   if write_data_failed()
2344
2310
*/
2345
 
int Join::rollup_write_data(uint32_t idx, Table *table_arg)
 
2311
int JOIN::rollup_write_data(uint32_t idx, Table *table_arg)
2346
2312
{
2347
2313
  uint32_t i;
2348
2314
  for (i= send_group_parts ; i-- > idx ; )
2349
2315
  {
2350
2316
    /* Get reference pointers to sum functions in place */
2351
2317
    memcpy(ref_pointer_array, rollup.ref_pointer_arrays[i],
2352
 
           ref_pointer_array_size);
 
2318
     ref_pointer_array_size);
2353
2319
    if ((!having || having->val_int()))
2354
2320
    {
2355
2321
      int write_error;
2361
2327
          item->save_in_result_field(1);
2362
2328
      }
2363
2329
      copy_sum_funcs(sum_funcs_end[i+1], sum_funcs_end[i]);
2364
 
      if ((write_error= table_arg->cursor->insertRecord(table_arg->getInsertRecord())))
 
2330
      if ((write_error= table_arg->cursor->ha_write_row(table_arg->record[0])))
2365
2331
      {
2366
 
        my_error(ER_USE_SQL_BIG_RESULT, MYF(0));
2367
 
        return 1;
 
2332
  if (create_myisam_from_heap(session, table_arg,
 
2333
                                    tmp_table_param.start_recinfo,
 
2334
                                    &tmp_table_param.recinfo,
 
2335
                                    write_error, 0))
 
2336
    return 1;
2368
2337
      }
2369
2338
    }
2370
2339
  }
2377
2346
  clear results if there are not rows found for group
2378
2347
  (end_send_group/end_write_group)
2379
2348
*/
2380
 
void Join::clear()
 
2349
void JOIN::clear()
2381
2350
{
2382
2351
  clear_tables(this);
2383
2352
  copy_fields(&tmp_table_param);
2391
2360
}
2392
2361
 
2393
2362
/**
2394
 
  change select_result object of Join.
 
2363
  change select_result object of JOIN.
2395
2364
 
2396
2365
  @param res    new select_result object
2397
2366
 
2400
2369
  @retval
2401
2370
    true    error
2402
2371
*/
2403
 
bool Join::change_result(select_result *res)
 
2372
bool JOIN::change_result(select_result *res)
2404
2373
{
2405
2374
  result= res;
2406
2375
  if (result->prepare(fields_list, select_lex->master_unit()))
2411
2380
}
2412
2381
 
2413
2382
/**
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
2383
  @brief
2449
2384
  
2450
2385
  Process one record of the nested loop join.
2455
2390
  applicable to the partial record on hand and in case of success
2456
2391
  submit this record to the next level of the nested loop.
2457
2392
*/
2458
 
enum_nested_loop_state evaluate_join_record(Join *join, JoinTable *join_tab, int error)
 
2393
enum_nested_loop_state evaluate_join_record(JOIN *join, JoinTable *join_tab, int error)
2459
2394
{
2460
2395
  bool not_used_in_distinct= join_tab->not_used_in_distinct;
2461
2396
  ha_rows found_records= join->found_records;
2465
2400
    return NESTED_LOOP_ERROR;
2466
2401
  if (error < 0)
2467
2402
    return NESTED_LOOP_NO_MORE_ROWS;
2468
 
  if (join->session->getKilled())                       // Aborted by user
 
2403
  if (join->session->killed)                    // Aborted by user
2469
2404
  {
2470
2405
    join->session->send_kill_message();
2471
2406
    return NESTED_LOOP_KILLED;
2579
2514
    level of the nested loop. This function is used in case we have
2580
2515
    an OUTER join and no matching record was found.
2581
2516
*/
2582
 
enum_nested_loop_state evaluate_null_complemented_join_record(Join *join, JoinTable *join_tab)
 
2517
enum_nested_loop_state evaluate_null_complemented_join_record(JOIN *join, JoinTable *join_tab)
2583
2518
{
2584
2519
  /*
2585
2520
    The table join_tab is the first inner table of a outer join operation
2635
2570
  return (*join_tab->next_select)(join, join_tab+1, 0);
2636
2571
}
2637
2572
 
2638
 
enum_nested_loop_state flush_cached_records(Join *join, JoinTable *join_tab, bool skip_last)
 
2573
enum_nested_loop_state flush_cached_records(JOIN *join, JoinTable *join_tab, bool skip_last)
2639
2574
{
2640
2575
  enum_nested_loop_state rc= NESTED_LOOP_OK;
2641
2576
  int error;
2642
 
  ReadRecord *info;
 
2577
  READ_RECORD *info;
2643
2578
 
2644
2579
  join_tab->table->null_row= 0;
2645
2580
  if (!join_tab->cache.records)
2646
 
  {
2647
2581
    return NESTED_LOOP_OK;                      /* Nothing to do */
2648
 
  }
2649
 
 
2650
2582
  if (skip_last)
2651
 
  {
2652
 
    (void) join_tab->cache.store_record_in_cache(); // Must save this for later
2653
 
  }
2654
 
 
2655
 
 
 
2583
    (void) store_record_in_cache(&join_tab->cache); // Must save this for later
2656
2584
  if (join_tab->use_quick == 2)
2657
2585
  {
2658
2586
    if (join_tab->select->quick)
2664
2592
  /* read through all records */
2665
2593
  if ((error=join_init_read_record(join_tab)))
2666
2594
  {
2667
 
    join_tab->cache.reset_cache_write();
 
2595
    reset_cache_write(&join_tab->cache);
2668
2596
    return error < 0 ? NESTED_LOOP_NO_MORE_ROWS: NESTED_LOOP_ERROR;
2669
2597
  }
2670
2598
 
2677
2605
  info= &join_tab->read_record;
2678
2606
  do
2679
2607
  {
2680
 
    if (join->session->getKilled())
 
2608
    if (join->session->killed)
2681
2609
    {
2682
2610
      join->session->send_kill_message();
2683
2611
      return NESTED_LOOP_KILLED;
2684
2612
    }
2685
 
    optimizer::SqlSelect *select= join_tab->select;
 
2613
    SQL_SELECT *select=join_tab->select;
2686
2614
    if (rc == NESTED_LOOP_OK &&
2687
2615
        (!join_tab->cache.select || !join_tab->cache.select->skip_record()))
2688
2616
    {
2689
2617
      uint32_t i;
2690
 
      join_tab->cache.reset_cache_read();
 
2618
      reset_cache_read(&join_tab->cache);
2691
2619
      for (i=(join_tab->cache.records- (skip_last ? 1 : 0)) ; i-- > 0 ;)
2692
2620
      {
2693
2621
              join_tab->readCachedRecord();
2698
2626
          rc= (join_tab->next_select)(join,join_tab+1,0);
2699
2627
          if (rc != NESTED_LOOP_OK && rc != NESTED_LOOP_NO_MORE_ROWS)
2700
2628
          {
2701
 
            join_tab->cache.reset_cache_write();
 
2629
            reset_cache_write(&join_tab->cache);
2702
2630
            return rc;
2703
2631
          }
2704
2632
 
2711
2639
 
2712
2640
  if (skip_last)
2713
2641
    join_tab->readCachedRecord();               // Restore current record
2714
 
  join_tab->cache.reset_cache_write();
 
2642
  reset_cache_write(&join_tab->cache);
2715
2643
  if (error > 0)                                // Fatal error
2716
2644
    return NESTED_LOOP_ERROR;
2717
2645
  for (JoinTable *tmp2=join->join_tab; tmp2 != join_tab ; tmp2++)
2743
2671
                               operation.
2744
2672
   All return values except NESTED_LOOP_OK abort the nested loop.
2745
2673
*****************************************************************************/
2746
 
enum_nested_loop_state end_send(Join *join, JoinTable *, bool end_of_records)
 
2674
enum_nested_loop_state end_send(JOIN *join, JoinTable *, bool end_of_records)
2747
2675
{
2748
2676
  if (! end_of_records)
2749
2677
  {
2763
2691
        if ((join->tables == 1) && !join->tmp_table && !join->sort_and_group
2764
2692
            && !join->send_group_parts && !join->having && !jt->select_cond &&
2765
2693
            !(jt->select && jt->select->quick) &&
2766
 
            (jt->table->cursor->getEngine()->check_flag(HTON_BIT_STATS_RECORDS_IS_EXACT)) &&
 
2694
            (jt->table->cursor->ha_table_flags() & HA_STATS_RECORDS_IS_EXACT) &&
2767
2695
                  (jt->ref.key < 0))
2768
2696
        {
2769
2697
          /* Join over all rows in table;  Return number of found rows */
2805
2733
  return NESTED_LOOP_OK;
2806
2734
}
2807
2735
 
2808
 
enum_nested_loop_state end_write(Join *join, JoinTable *, bool end_of_records)
 
2736
enum_nested_loop_state end_write(JOIN *join, JoinTable *, bool end_of_records)
2809
2737
{
2810
2738
  Table *table= join->tmp_table;
2811
2739
 
2812
 
  if (join->session->getKilled())                       // Aborted by user
 
2740
  if (join->session->killed)                    // Aborted by user
2813
2741
  {
2814
2742
    join->session->send_kill_message();
2815
2743
    return NESTED_LOOP_KILLED;
2817
2745
  if (!end_of_records)
2818
2746
  {
2819
2747
    copy_fields(&join->tmp_table_param);
2820
 
    if (copy_funcs(join->tmp_table_param.items_to_copy, join->session))
2821
 
      return NESTED_LOOP_ERROR;
 
2748
    copy_funcs(join->tmp_table_param.items_to_copy);
2822
2749
    if (!join->having || join->having->val_int())
2823
2750
    {
2824
2751
      int error;
2825
2752
      join->found_records++;
2826
 
      if ((error=table->cursor->insertRecord(table->getInsertRecord())))
 
2753
      if ((error=table->cursor->ha_write_row(table->record[0])))
2827
2754
      {
2828
2755
        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
 
2756
          goto end;
 
2757
        if (create_myisam_from_heap(join->session, table,
 
2758
                                          join->tmp_table_param.start_recinfo,
 
2759
                                          &join->tmp_table_param.recinfo,
 
2760
                  error, 1))
 
2761
          return NESTED_LOOP_ERROR;        // Not a table_is_full error
 
2762
        table->s->uniques= 0;                   // To ensure rows are the same
2835
2763
      }
2836
2764
      if (++join->send_records >= join->tmp_table_param.end_write_records && join->do_send_rows)
2837
2765
      {
2843
2771
      }
2844
2772
    }
2845
2773
  }
2846
 
 
 
2774
end:
2847
2775
  return NESTED_LOOP_OK;
2848
2776
}
2849
2777
 
2850
2778
/** 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)
 
2779
enum_nested_loop_state end_update(JOIN *join, JoinTable *, bool end_of_records)
2852
2780
{
2853
2781
  Table *table= join->tmp_table;
2854
 
  Order *group;
 
2782
  order_st *group;
2855
2783
  int   error;
2856
2784
 
2857
2785
  if (end_of_records)
2858
2786
    return NESTED_LOOP_OK;
2859
 
  if (join->session->getKilled())                       // Aborted by user
 
2787
  if (join->session->killed)                    // Aborted by user
2860
2788
  {
2861
2789
    join->session->send_kill_message();
2862
2790
    return NESTED_LOOP_KILLED;
2873
2801
    if (item->maybe_null)
2874
2802
      group->buff[-1]= (char) group->field->is_null();
2875
2803
  }
2876
 
  if (!table->cursor->index_read_map(table->getUpdateRecord(),
 
2804
  if (!table->cursor->index_read_map(table->record[1],
2877
2805
                                   join->tmp_table_param.group_buff,
2878
2806
                                   HA_WHOLE_KEY,
2879
2807
                                   HA_READ_KEY_EXACT))
2880
2808
  {                                             /* Update old record */
2881
2809
    table->restoreRecord();
2882
2810
    update_tmptable_sum_func(join->sum_funcs,table);
2883
 
    if ((error= table->cursor->updateRecord(table->getUpdateRecord(),
2884
 
                                          table->getInsertRecord())))
 
2811
    if ((error= table->cursor->ha_update_row(table->record[1],
 
2812
                                          table->record[0])))
2885
2813
    {
2886
2814
      table->print_error(error,MYF(0));
2887
2815
      return NESTED_LOOP_ERROR;
2894
2822
    We can't copy all data as the key may have different format
2895
2823
    as the row data (for example as with VARCHAR keys)
2896
2824
  */
2897
 
  KeyPartInfo *key_part;
 
2825
  KEY_PART_INFO *key_part;
2898
2826
  for (group=table->group,key_part=table->key_info[0].key_part;
2899
2827
       group ;
2900
2828
       group=group->next,key_part++)
2901
2829
  {
2902
2830
    if (key_part->null_bit)
2903
 
      memcpy(table->getInsertRecord()+key_part->offset, group->buff, 1);
 
2831
      memcpy(table->record[0]+key_part->offset, group->buff, 1);
2904
2832
  }
2905
2833
  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())))
 
2834
  copy_funcs(join->tmp_table_param.items_to_copy);
 
2835
  if ((error=table->cursor->ha_write_row(table->record[0])))
2909
2836
  {
2910
 
    my_error(ER_USE_SQL_BIG_RESULT, MYF(0));
2911
 
    return NESTED_LOOP_ERROR;        // Table is_full error
 
2837
    if (create_myisam_from_heap(join->session, table,
 
2838
                                join->tmp_table_param.start_recinfo,
 
2839
                                &join->tmp_table_param.recinfo,
 
2840
                                error, 0))
 
2841
      return NESTED_LOOP_ERROR;            // Not a table_is_full error
 
2842
    /* Change method to update rows */
 
2843
    table->cursor->ha_index_init(0, 0);
 
2844
    join->join_tab[join->tables-1].next_select= end_unique_update;
2912
2845
  }
2913
2846
  join->send_records++;
2914
2847
  return NESTED_LOOP_OK;
2915
2848
}
2916
2849
 
2917
2850
/** 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)
 
2851
enum_nested_loop_state end_unique_update(JOIN *join, JoinTable *, bool end_of_records)
2919
2852
{
2920
2853
  Table *table= join->tmp_table;
2921
2854
  int   error;
2922
2855
 
2923
2856
  if (end_of_records)
2924
2857
    return NESTED_LOOP_OK;
2925
 
  if (join->session->getKilled())                       // Aborted by user
 
2858
  if (join->session->killed)                    // Aborted by user
2926
2859
  {
2927
2860
    join->session->send_kill_message();
2928
2861
    return NESTED_LOOP_KILLED;
2930
2863
 
2931
2864
  init_tmptable_sum_functions(join->sum_funcs);
2932
2865
  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;
 
2866
  copy_funcs(join->tmp_table_param.items_to_copy);
2935
2867
 
2936
 
  if (!(error= table->cursor->insertRecord(table->getInsertRecord())))
 
2868
  if (!(error= table->cursor->ha_write_row(table->record[0])))
2937
2869
    join->send_records++;                       // New group
2938
2870
  else
2939
2871
  {
2942
2874
      table->print_error(error,MYF(0));
2943
2875
      return NESTED_LOOP_ERROR;
2944
2876
    }
2945
 
    if (table->cursor->rnd_pos(table->getUpdateRecord(),table->cursor->dup_ref))
 
2877
    if (table->cursor->rnd_pos(table->record[1],table->cursor->dup_ref))
2946
2878
    {
2947
2879
      table->print_error(error,MYF(0));
2948
2880
      return NESTED_LOOP_ERROR;
2949
2881
    }
2950
2882
    table->restoreRecord();
2951
2883
    update_tmptable_sum_func(join->sum_funcs,table);
2952
 
    if ((error= table->cursor->updateRecord(table->getUpdateRecord(),
2953
 
                                          table->getInsertRecord())))
 
2884
    if ((error= table->cursor->ha_update_row(table->record[1],
 
2885
                                          table->record[0])))
2954
2886
    {
2955
2887
      table->print_error(error,MYF(0));
2956
2888
      return NESTED_LOOP_ERROR;
2971
2903
  @retval
2972
2904
    1   failed
2973
2905
*/
2974
 
static bool make_group_fields(Join *main_join, Join *curr_join)
 
2906
static bool make_group_fields(JOIN *main_join, JOIN *curr_join)
2975
2907
{
2976
2908
  if (main_join->group_fields_cache.elements)
2977
2909
  {
2990
2922
/**
2991
2923
  calc how big buffer we need for comparing group entries.
2992
2924
*/
2993
 
static void calc_group_buffer(Join *join, Order *group)
 
2925
static void calc_group_buffer(JOIN *join,order_st *group)
2994
2926
{
2995
2927
  uint32_t key_length=0, parts=0, null_parts=0;
2996
2928
 
3016
2948
      case REAL_RESULT:
3017
2949
        key_length+= sizeof(double);
3018
2950
        break;
3019
 
 
3020
2951
      case INT_RESULT:
3021
2952
        key_length+= sizeof(int64_t);
3022
2953
        break;
3023
 
 
3024
2954
      case DECIMAL_RESULT:
3025
2955
        key_length+= my_decimal_get_binary_size(group_item->max_length -
3026
2956
                                                (group_item->decimals ? 1 : 0),
3027
2957
                                                group_item->decimals);
3028
2958
        break;
3029
 
 
3030
2959
      case STRING_RESULT:
3031
 
        {
3032
 
          enum enum_field_types type= group_item->field_type();
 
2960
      {
 
2961
        enum enum_field_types type= group_item->field_type();
 
2962
        /*
 
2963
          As items represented as DATE/TIME fields in the group buffer
 
2964
          have STRING_RESULT result type, we increase the length
 
2965
          by 8 as maximum pack length of such fields.
 
2966
        */
 
2967
        if (type == DRIZZLE_TYPE_DATE ||
 
2968
            type == DRIZZLE_TYPE_DATETIME ||
 
2969
            type == DRIZZLE_TYPE_TIMESTAMP)
 
2970
        {
 
2971
          key_length+= 8;
 
2972
        }
 
2973
        else
 
2974
        {
3033
2975
          /*
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.
 
2976
            Group strings are taken as varstrings and require an length field.
 
2977
            A field is not yet created by create_tmp_field()
 
2978
            and the sizes should match up.
3037
2979
          */
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;
 
2980
          key_length+= group_item->max_length + HA_KEY_BLOB_LENGTH;
3054
2981
        }
3055
 
 
3056
 
      case ROW_RESULT:
 
2982
        break;
 
2983
      }
 
2984
      default:
3057
2985
        /* This case should never be choosen */
3058
2986
        assert(0);
3059
2987
        my_error(ER_OUT_OF_RESOURCES, MYF(ME_FATALERROR));
3060
2988
      }
3061
2989
    }
3062
 
 
3063
2990
    parts++;
3064
 
 
3065
2991
    if (group_item->maybe_null)
3066
2992
      null_parts++;
3067
2993
  }
3068
 
 
3069
2994
  join->tmp_table_param.group_length=key_length+null_parts;
3070
2995
  join->tmp_table_param.group_parts=parts;
3071
2996
  join->tmp_table_param.group_null_parts=null_parts;
3076
3001
 
3077
3002
  Groups are saved in reverse order for easyer check loop.
3078
3003
*/
3079
 
static bool alloc_group_fields(Join *join, Order *group)
 
3004
static bool alloc_group_fields(JOIN *join,order_st *group)
3080
3005
{
3081
3006
  if (group)
3082
3007
  {
3091
3016
  return false;
3092
3017
}
3093
3018
 
3094
 
static uint32_t cache_record_length(Join *join,uint32_t idx)
 
3019
static uint32_t cache_record_length(JOIN *join,uint32_t idx)
3095
3020
{
3096
3021
  uint32_t length=0;
3097
3022
  JoinTable **pos,**end;
3159
3084
  RETURN
3160
3085
    Expected number of row combinations
3161
3086
*/
3162
 
static double prev_record_reads(Join *join, uint32_t idx, table_map found_ref)
 
3087
static double prev_record_reads(JOIN *join, uint32_t idx, table_map found_ref)
3163
3088
{
3164
3089
  double found=1.0;
3165
3090
  optimizer::Position *pos_end= join->getSpecificPosInPartialPlan(-1);
3171
3096
    {
3172
3097
      found_ref|= pos->getRefDependMap();
3173
3098
      /*
3174
 
        For the case of "t1 LEFT Join t2 ON ..." where t2 is a const table
 
3099
        For the case of "t1 LEFT JOIN t2 ON ..." where t2 is a const table
3175
3100
        with no matching row we will get position[t2].records_read==0.
3176
3101
        Actually the size of output is one null-complemented row, therefore
3177
3102
        we will use value of 1 whenever we get records_read==0.
3196
3121
/**
3197
3122
  Set up join struct according to best position.
3198
3123
*/
3199
 
static bool get_best_combination(Join *join)
 
3124
static bool get_best_combination(JOIN *join)
3200
3125
{
3201
3126
  uint32_t i,tablenr;
3202
3127
  table_map used_tables;
3223
3148
    used_tables|= form->map;
3224
3149
    form->reginfo.join_tab=j;
3225
3150
    if (!*j->on_expr_ref)
3226
 
      form->reginfo.not_exists_optimize=0;  // Only with LEFT Join
 
3151
      form->reginfo.not_exists_optimize=0;  // Only with LEFT JOIN
3227
3152
    if (j->type == AM_CONST)
3228
3153
      continue;         // Handled in make_join_stat..
3229
3154
 
3249
3174
}
3250
3175
 
3251
3176
/** Save const tables first as used tables. */
3252
 
static void set_position(Join *join,
 
3177
static void set_position(JOIN *join,
3253
3178
                         uint32_t idx,
3254
3179
                         JoinTable *table,
3255
3180
                         optimizer::KeyUse *key)
3291
3216
  @retval
3292
3217
    true        Fatal error
3293
3218
*/
3294
 
static bool choose_plan(Join *join, table_map join_tables)
 
3219
static bool choose_plan(JOIN *join, table_map join_tables)
3295
3220
{
3296
3221
  uint32_t search_depth= join->session->variables.optimizer_search_depth;
3297
3222
  uint32_t prune_level=  join->session->variables.optimizer_prune_level;
3307
3232
      Apply heuristic: pre-sort all access plans with respect to the number of
3308
3233
      records accessed.
3309
3234
  */
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);
 
3235
  my_qsort(join->best_ref + join->const_tables,
 
3236
           join->tables - join->const_tables, sizeof(JoinTable*),
 
3237
           straight_join ? join_tab_cmp_straight : join_tab_cmp);
3313
3238
  if (straight_join)
3314
3239
  {
3315
3240
    optimize_straight_join(join, join_tables);
3358
3283
  @return
3359
3284
    None
3360
3285
*/
3361
 
static void best_access_path(Join *join,
 
3286
static void best_access_path(JOIN *join,
3362
3287
                             JoinTable *s,
3363
3288
                             Session *session,
3364
3289
                             table_map remaining_tables,
3391
3316
      key_part_map found_part= 0;
3392
3317
      table_map found_ref= 0;
3393
3318
      uint32_t key= keyuse->getKey();
3394
 
      KeyInfo *keyinfo= table->key_info + key;
 
3319
      KEY *keyinfo= table->key_info + key;
3395
3320
      /* Bitmap of keyparts where the ref access is over 'keypart=const': */
3396
3321
      key_part_map const_part= 0;
3397
3322
      /* The or-null keypart in ref-or-null access: */
3504
3429
                records=
3505
3430
                  ((double) s->records / (double) rec *
3506
3431
                   (1.0 +
3507
 
                    ((double) (table->getShare()->max_key_length-keyinfo->key_length) /
3508
 
                     (double) table->getShare()->max_key_length)));
 
3432
                    ((double) (table->s->max_key_length-keyinfo->key_length) /
 
3433
                     (double) table->s->max_key_length)));
3509
3434
                if (records < 2.0)
3510
3435
                  records=2.0;               /* Can't be as good as a unique */
3511
3436
              }
3547
3472
            Set tmp to (previous record count) * (records / combination)
3548
3473
          */
3549
3474
          if ((found_part & 1) &&
3550
 
              (!(table->index_flags(key) & HA_ONLY_WHOLE_INDEX) ||
3551
 
               found_part == PREV_BITS(uint, keyinfo->key_parts)))
 
3475
              (!(table->cursor->index_flags(key, 0, 0) & HA_ONLY_WHOLE_INDEX) ||
 
3476
               found_part == PREV_BITS(uint,keyinfo->key_parts)))
3552
3477
          {
3553
3478
            max_key_part= max_part_bit(found_part);
3554
3479
            /*
3752
3677
  if ((records >= s->found_records || best > s->read_time) &&            // (1)
3753
3678
      ! (s->quick && best_key && s->quick->index == best_key->getKey() &&      // (2)
3754
3679
        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)
 
3680
      ! ((s->table->cursor->ha_table_flags() & HA_TABLE_SCAN_ON_INDEX) &&   // (3)
3756
3681
        ! s->table->covering_keys.none() && best_key && !s->quick) && // (3)
3757
3682
      ! (s->table->force_index && best_key && !s->quick))                 // (4)
3758
3683
  {                                             // Check full join
3888
3813
    Thus 'optimize_straight_join' can be used at any stage of the query
3889
3814
    optimization process to finalize a QEP as it is.
3890
3815
*/
3891
 
static void optimize_straight_join(Join *join, table_map join_tables)
 
3816
static void optimize_straight_join(JOIN *join, table_map join_tables)
3892
3817
{
3893
3818
  JoinTable *s;
3894
3819
  optimizer::Position partial_pos;
3998
3923
  @retval
3999
3924
    true        Fatal error
4000
3925
*/
4001
 
static bool greedy_search(Join      *join,
 
3926
static bool greedy_search(JOIN      *join,
4002
3927
              table_map remaining_tables,
4003
3928
              uint32_t      search_depth,
4004
3929
              uint32_t      prune_level)
4012
3937
  JoinTable  *best_table; // the next plan node to be added to the curr QEP
4013
3938
 
4014
3939
  /* number of tables that remain to be optimized */
4015
 
  size_remain= internal::my_count_bits(remaining_tables);
 
3940
  size_remain= my_count_bits(remaining_tables);
4016
3941
 
4017
3942
  do {
4018
3943
    /* Find the extension of the current QEP with the lowest cost */
4040
3965
    */
4041
3966
    join->setPosInPartialPlan(idx, best_pos);
4042
3967
 
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
3968
    /* find the position of 'best_table' in 'join->best_ref' */
4053
3969
    best_idx= idx;
4054
3970
    JoinTable *pos= join->best_ref[best_idx];
4186
4102
  @retval
4187
4103
    true        Fatal error
4188
4104
*/
4189
 
static bool best_extension_by_limited_search(Join *join,
 
4105
static bool best_extension_by_limited_search(JOIN *join,
4190
4106
                                             table_map remaining_tables,
4191
4107
                                             uint32_t idx,
4192
4108
                                             double record_count,
4195
4111
                                             uint32_t prune_level)
4196
4112
{
4197
4113
  Session *session= join->session;
4198
 
  if (session->getKilled())  // Abort
 
4114
  if (session->killed)  // Abort
4199
4115
    return(true);
4200
4116
 
4201
4117
  /*
4210
4126
  for (JoinTable **pos= join->best_ref + idx ; (s= *pos) ; pos++)
4211
4127
  {
4212
4128
    table_map real_table_bit= s->table->map;
 
4129
    if (idx)
 
4130
    {
 
4131
      partial_pos= join->getPosFromPartialPlan(idx - 1);
 
4132
    }
4213
4133
    if ((remaining_tables & real_table_bit) &&
4214
4134
        ! (remaining_tables & s->dependent) &&
4215
 
        (! idx || ! check_interleaving_with_nj(s)))
 
4135
        (! idx || ! check_interleaving_with_nj(partial_pos.getJoinTable(), s)))
4216
4136
    {
4217
4137
      double current_record_count, current_read_time;
4218
4138
 
4333
4253
    exhaustiveness) of the depth-first search algorithm used by
4334
4254
    'greedy_search'.
4335
4255
*/
4336
 
static uint32_t determine_search_depth(Join *join)
 
4256
static uint32_t determine_search_depth(JOIN *join)
4337
4257
{
4338
4258
  uint32_t table_count=  join->tables - join->const_tables;
4339
4259
  uint32_t search_depth;
4352
4272
  return search_depth;
4353
4273
}
4354
4274
 
4355
 
static bool make_simple_join(Join *join,Table *tmp_table)
 
4275
static bool make_simple_join(JOIN *join,Table *tmp_table)
4356
4276
{
4357
4277
  Table **tableptr;
4358
4278
  JoinTable *join_tab;
4359
4279
 
4360
4280
  /*
4361
4281
    Reuse Table * and JoinTable if already allocated by a previous call
4362
 
    to this function through Join::exec (may happen for sub-queries).
 
4282
    to this function through JOIN::exec (may happen for sub-queries).
4363
4283
  */
4364
4284
  if (!join->table_reexec)
4365
4285
  {
4409
4329
  join_tab->read_first_record= join_init_read_record;
4410
4330
  join_tab->join=join;
4411
4331
  join_tab->ref.key_parts= 0;
4412
 
  join_tab->read_record.init();
 
4332
  memset(&join_tab->read_record, 0, sizeof(join_tab->read_record));
4413
4333
  tmp_table->status=0;
4414
4334
  tmp_table->null_row=0;
4415
 
 
4416
 
  return false;
 
4335
  return(false);
4417
4336
}
4418
4337
 
4419
4338
/**
4457
4376
    This function can be called only after the execution plan
4458
4377
    has been chosen.
4459
4378
*/
4460
 
static void make_outerjoin_info(Join *join)
 
4379
static void make_outerjoin_info(JOIN *join)
4461
4380
{
4462
4381
  for (uint32_t i=join->const_tables ; i < join->tables ; i++)
4463
4382
  {
4464
4383
    JoinTable *tab=join->join_tab+i;
4465
4384
    Table *table=tab->table;
4466
4385
    TableList *tbl= table->pos_in_table_list;
4467
 
    TableList *embedding= tbl->getEmbedding();
 
4386
    TableList *embedding= tbl->embedding;
4468
4387
 
4469
4388
    if (tbl->outer_join)
4470
4389
    {
4477
4396
      tab->on_expr_ref= &tbl->on_expr;
4478
4397
      tab->cond_equal= tbl->cond_equal;
4479
4398
      if (embedding)
4480
 
        tab->first_upper= embedding->getNestedJoin()->first_nested;
 
4399
        tab->first_upper= embedding->nested_join->first_nested;
4481
4400
    }
4482
 
    for ( ; embedding ; embedding= embedding->getEmbedding())
 
4401
    for ( ; embedding ; embedding= embedding->embedding)
4483
4402
    {
4484
4403
      /* Ignore sj-nests: */
4485
4404
      if (!embedding->on_expr)
4486
4405
        continue;
4487
 
      nested_join_st *nested_join= embedding->getNestedJoin();
 
4406
      nested_join_st *nested_join= embedding->nested_join;
4488
4407
      if (!nested_join->counter_)
4489
4408
      {
4490
4409
        /*
4494
4413
        nested_join->first_nested= tab;
4495
4414
        tab->on_expr_ref= &embedding->on_expr;
4496
4415
        tab->cond_equal= tbl->cond_equal;
4497
 
        if (embedding->getEmbedding())
4498
 
          tab->first_upper= embedding->getEmbedding()->getNestedJoin()->first_nested;
 
4416
        if (embedding->embedding)
 
4417
          tab->first_upper= embedding->embedding->nested_join->first_nested;
4499
4418
      }
4500
4419
      if (!tab->first_inner)
4501
4420
        tab->first_inner= nested_join->first_nested;
4508
4427
  return;
4509
4428
}
4510
4429
 
4511
 
static bool make_join_select(Join *join,
4512
 
                             optimizer::SqlSelect *select,
4513
 
                             COND *cond)
 
4430
static bool make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
4514
4431
{
4515
4432
  Session *session= join->session;
4516
4433
  optimizer::Position cur_pos;
4631
4548
      if (tmp || !cond || tab->type == AM_REF || tab->type == AM_REF_OR_NULL ||
4632
4549
          tab->type == AM_EQ_REF)
4633
4550
      {
4634
 
        optimizer::SqlSelect *sel= tab->select= ((optimizer::SqlSelect*)
 
4551
        SQL_SELECT *sel= tab->select= ((SQL_SELECT*)
4635
4552
            session->memdup((unsigned char*) select,
4636
4553
              sizeof(*select)));
4637
4554
        if (! sel)
4769
4686
                                         current_map,
4770
4687
                                         current_map, 0)))
4771
4688
            {
4772
 
              tab->cache.select= (optimizer::SqlSelect*)
4773
 
                session->memdup((unsigned char*) sel, sizeof(optimizer::SqlSelect));
 
4689
              tab->cache.select= (SQL_SELECT*)
 
4690
                session->memdup((unsigned char*) sel, sizeof(SQL_SELECT));
4774
4691
              tab->cache.select->cond= tmp;
4775
4692
              tab->cache.select->read_tables= join->const_table_map;
4776
4693
            }
4886
4803
    false - OK
4887
4804
    true  - Out of memory
4888
4805
*/
4889
 
static bool make_join_readinfo(Join *join)
 
4806
static bool make_join_readinfo(JOIN *join, uint64_t options, uint32_t no_jbuf_after)
4890
4807
{
4891
 
  bool sorted= true;
 
4808
  uint32_t i;
 
4809
  bool statistics= test(!(join->select_options & SELECT_DESCRIBE));
 
4810
  bool sorted= 1;
4892
4811
 
4893
 
  for (uint32_t i= join->const_tables ; i < join->tables ; i++)
 
4812
  for (i=join->const_tables ; i < join->tables ; i++)
4894
4813
  {
4895
4814
    JoinTable *tab=join->join_tab+i;
4896
4815
    Table *table=tab->table;
 
4816
    bool using_join_cache;
4897
4817
    tab->read_record.table= table;
4898
4818
    tab->read_record.cursor= table->cursor;
4899
4819
    tab->next_select=sub_select;                /* normal select */
4902
4822
      produce sorted output.
4903
4823
    */
4904
4824
    tab->sorted= sorted;
4905
 
    sorted= false; // only first must be sorted
4906
 
 
 
4825
    sorted= 0;                                  // only first must be sorted
4907
4826
    if (tab->insideout_match_tab)
4908
4827
    {
4909
 
      if (! (tab->insideout_buf= (unsigned char*) join->session->alloc(tab->table->key_info
4910
 
                                                                       [tab->index].
4911
 
                                                                       key_length)))
 
4828
      if (!(tab->insideout_buf= (unsigned char*)join->session->alloc(tab->table->key_info
 
4829
                                                         [tab->index].
 
4830
                                                         key_length)))
4912
4831
        return true;
4913
4832
    }
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
 
       */
 
4833
    switch (tab->type) {
 
4834
    case AM_SYSTEM:                             // Only happens with left join
 
4835
      table->status=STATUS_NO_RECORD;
 
4836
      tab->read_first_record= join_read_system;
 
4837
      tab->read_record.read_record= join_no_more_records;
 
4838
      break;
 
4839
    case AM_CONST:                              // Only happens with left join
 
4840
      table->status=STATUS_NO_RECORD;
 
4841
      tab->read_first_record= join_read_const;
 
4842
      tab->read_record.read_record= join_no_more_records;
 
4843
      if (table->covering_keys.test(tab->ref.key) &&
 
4844
          !table->no_keyread)
 
4845
      {
 
4846
        table->key_read=1;
 
4847
        table->cursor->extra(HA_EXTRA_KEYREAD);
 
4848
      }
 
4849
      break;
 
4850
    case AM_EQ_REF:
 
4851
      table->status=STATUS_NO_RECORD;
 
4852
      if (tab->select)
 
4853
      {
 
4854
        delete tab->select->quick;
 
4855
        tab->select->quick=0;
 
4856
      }
 
4857
      delete tab->quick;
 
4858
      tab->quick=0;
 
4859
      tab->read_first_record= join_read_key;
 
4860
      tab->read_record.read_record= join_no_more_records;
 
4861
      if (table->covering_keys.test(tab->ref.key) && !table->no_keyread)
 
4862
      {
 
4863
        table->key_read=1;
 
4864
        table->cursor->extra(HA_EXTRA_KEYREAD);
 
4865
      }
 
4866
      break;
 
4867
    case AM_REF_OR_NULL:
 
4868
    case AM_REF:
 
4869
      table->status=STATUS_NO_RECORD;
 
4870
      if (tab->select)
 
4871
      {
 
4872
        delete tab->select->quick;
 
4873
        tab->select->quick=0;
 
4874
      }
 
4875
      delete tab->quick;
 
4876
      tab->quick=0;
 
4877
      if (table->covering_keys.test(tab->ref.key) && !table->no_keyread)
 
4878
      {
 
4879
        table->key_read=1;
 
4880
        table->cursor->extra(HA_EXTRA_KEYREAD);
 
4881
      }
 
4882
      if (tab->type == AM_REF)
 
4883
      {
 
4884
        tab->read_first_record= join_read_always_key;
 
4885
        tab->read_record.read_record= tab->insideout_match_tab?
 
4886
           join_read_next_same_diff : join_read_next_same;
 
4887
      }
 
4888
      else
 
4889
      {
 
4890
        tab->read_first_record= join_read_always_key_or_null;
 
4891
        tab->read_record.read_record= join_read_next_same_or_null;
 
4892
      }
 
4893
      break;
 
4894
    case AM_ALL:
 
4895
      /*
 
4896
        If previous table use cache
 
4897
        If the incoming data set is already sorted don't use cache.
 
4898
      */
 
4899
      table->status=STATUS_NO_RECORD;
 
4900
      using_join_cache= false;
 
4901
      if (i != join->const_tables && !(options & SELECT_NO_JOIN_CACHE) &&
 
4902
          tab->use_quick != 2 && !tab->first_inner && i <= no_jbuf_after &&
 
4903
          !tab->insideout_match_tab)
 
4904
      {
 
4905
        if ((options & SELECT_DESCRIBE) ||
 
4906
            !join_init_cache(join->session,join->join_tab+join->const_tables,
 
4907
                i-join->const_tables))
 
4908
        {
 
4909
                using_join_cache= true;
 
4910
          tab[-1].next_select=sub_select_cache; /* Patch previous */
 
4911
        }
 
4912
      }
 
4913
      /* These init changes read_record */
 
4914
      if (tab->use_quick == 2)
 
4915
      {
 
4916
        join->session->server_status|=SERVER_QUERY_NO_GOOD_INDEX_USED;
 
4917
        tab->read_first_record= join_init_quick_read_record;
 
4918
        if (statistics)
 
4919
          status_var_increment(join->session->status_var.select_range_check_count);
 
4920
      }
 
4921
      else
 
4922
      {
 
4923
        tab->read_first_record= join_init_read_record;
 
4924
        if (i == join->const_tables)
 
4925
        {
 
4926
          if (tab->select && tab->select->quick)
 
4927
          {
 
4928
            if (statistics)
 
4929
              status_var_increment(join->session->status_var.select_range_count);
 
4930
          }
 
4931
          else
 
4932
          {
 
4933
            join->session->server_status|=SERVER_QUERY_NO_INDEX_USED;
 
4934
            if (statistics)
 
4935
              status_var_increment(join->session->status_var.select_scan_count);
 
4936
          }
 
4937
        }
 
4938
        else
 
4939
        {
 
4940
          if (tab->select && tab->select->quick)
 
4941
          {
 
4942
            if (statistics)
 
4943
              status_var_increment(join->session->status_var.select_full_range_join_count);
 
4944
          }
 
4945
          else
 
4946
          {
 
4947
            join->session->server_status|=SERVER_QUERY_NO_INDEX_USED;
 
4948
            if (statistics)
 
4949
              status_var_increment(join->session->status_var.select_full_join_count);
 
4950
          }
 
4951
        }
 
4952
        if (!table->no_keyread)
 
4953
        {
 
4954
          if (tab->select && tab->select->quick &&
 
4955
                    tab->select->quick->index != MAX_KEY && //not index_merge
 
4956
              table->covering_keys.test(tab->select->quick->index))
 
4957
          {
 
4958
            table->key_read=1;
 
4959
            table->cursor->extra(HA_EXTRA_KEYREAD);
 
4960
          }
 
4961
          else if (!table->covering_keys.none() &&
 
4962
            !(tab->select && tab->select->quick))
 
4963
          {                                     // Only read index tree
 
4964
                  if (!tab->insideout_match_tab)
 
4965
                  {
 
4966
                    /*
 
4967
                      See bug #26447: "Using the clustered index for a table scan
 
4968
                      is always faster than using a secondary index".
 
4969
                    */
 
4970
                    if (table->s->primary_key != MAX_KEY &&
 
4971
                        table->cursor->primary_key_is_clustered())
 
4972
                      tab->index= table->s->primary_key;
 
4973
                    else
 
4974
                      tab->index= table->find_shortest_key(&table->covering_keys);
 
4975
                  }
 
4976
            tab->read_first_record= join_read_first;
 
4977
            tab->type= AM_NEXT;         // Read with index_first / index_next
 
4978
          }
 
4979
        }
 
4980
      }
 
4981
      break;
 
4982
    default:
 
4983
      break;
 
4984
    case AM_UNKNOWN:
 
4985
    case AM_MAYBE_REF:
4925
4986
      abort();
4926
4987
    }
4927
 
 
4928
 
    access_method->getStats(table, tab);
4929
4988
  }
4930
 
 
4931
 
  join->join_tab[join->tables-1].next_select= NULL; /* Set by do_select */
4932
 
 
4933
 
  return false;
 
4989
  join->join_tab[join->tables-1].next_select=0; /* Set by do_select */
 
4990
  return(false);
4934
4991
}
4935
4992
 
4936
4993
/** Update the dependency map for the tables. */
4937
 
static void update_depend_map(Join *join)
 
4994
static void update_depend_map(JOIN *join)
4938
4995
{
4939
4996
  JoinTable *join_tab=join->join_tab, *end=join_tab+join->tables;
4940
4997
 
4957
5014
}
4958
5015
 
4959
5016
/** Update the dependency map for the sort order. */
4960
 
static void update_depend_map(Join *join, Order *order)
 
5017
static void update_depend_map(JOIN *join, order_st *order)
4961
5018
{
4962
5019
  for (; order ; order=order->next)
4963
5020
  {
4995
5052
  @return
4996
5053
    Returns new sort order
4997
5054
*/
4998
 
static Order *remove_constants(Join *join,Order *first_order, COND *cond, bool change_list, bool *simple_order)
 
5055
static order_st *remove_constants(JOIN *join,order_st *first_order, COND *cond, bool change_list, bool *simple_order)
4999
5056
{
5000
5057
  if (join->tables == join->const_tables)
5001
5058
    return change_list ? 0 : first_order;               // No need to sort
5002
5059
 
5003
 
  Order *order,**prev_ptr;
 
5060
  order_st *order,**prev_ptr;
5004
5061
  table_map first_table= join->join_tab[join->const_tables].table->map;
5005
5062
  table_map not_const_tables= ~join->const_table_map;
5006
5063
  table_map ref;
5055
5112
  return(first_order);
5056
5113
}
5057
5114
 
5058
 
static int return_zero_rows(Join *join,
 
5115
static int return_zero_rows(JOIN *join,
5059
5116
                            select_result *result,
5060
5117
                            TableList *tables,
5061
5118
                                        List<Item> &fields,
5066
5123
{
5067
5124
  if (select_options & SELECT_DESCRIBE)
5068
5125
  {
5069
 
    optimizer::ExplainPlan planner(join,
5070
 
                                   false,
5071
 
                                   false,
5072
 
                                   false,
5073
 
                                   info);
5074
 
    planner.printPlan();
5075
 
    return 0;
 
5126
    select_describe(join, false, false, false, info);
 
5127
    return(0);
5076
5128
  }
5077
5129
 
5078
5130
  join->join_free();
5221
5273
    - The new condition, if success
5222
5274
    - 0, otherwise
5223
5275
*/
5224
 
static COND *simplify_joins(Join *join, List<TableList> *join_list, COND *conds, bool top)
 
5276
static COND *simplify_joins(JOIN *join, List<TableList> *join_list, COND *conds, bool top)
5225
5277
{
5226
5278
  TableList *table;
5227
5279
  nested_join_st *nested_join;
5237
5289
    table_map used_tables;
5238
5290
    table_map not_null_tables= (table_map) 0;
5239
5291
 
5240
 
    if ((nested_join= table->getNestedJoin()))
 
5292
    if ((nested_join= table->nested_join))
5241
5293
    {
5242
5294
      /*
5243
5295
         If the element of join_list is a nested join apply
5279
5331
        not_null_tables= conds->not_null_tables();
5280
5332
    }
5281
5333
 
5282
 
    if (table->getEmbedding())
 
5334
    if (table->embedding)
5283
5335
    {
5284
 
      table->getEmbedding()->getNestedJoin()->used_tables|= used_tables;
5285
 
      table->getEmbedding()->getNestedJoin()->not_null_tables|= not_null_tables;
 
5336
      table->embedding->nested_join->used_tables|= used_tables;
 
5337
      table->embedding->nested_join->not_null_tables|= not_null_tables;
5286
5338
    }
5287
5339
 
5288
5340
    if (!table->outer_join || (used_tables & not_null_tables))
5318
5370
    */
5319
5371
    if (table->on_expr)
5320
5372
    {
5321
 
      table->setDepTables(table->getDepTables() | table->on_expr->used_tables());
5322
 
      if (table->getEmbedding())
 
5373
      table->dep_tables|= table->on_expr->used_tables();
 
5374
      if (table->embedding)
5323
5375
      {
5324
 
        table->setDepTables(table->getDepTables() & ~table->getEmbedding()->getNestedJoin()->used_tables);
 
5376
        table->dep_tables&= ~table->embedding->nested_join->used_tables;
5325
5377
        /*
5326
5378
           Embedding table depends on tables used
5327
5379
           in embedded on expressions.
5328
5380
        */
5329
 
        table->getEmbedding()->setOnExprDepTables(table->getEmbedding()->getOnExprDepTables() & table->on_expr->used_tables());
 
5381
        table->embedding->on_expr_dep_tables|= table->on_expr->used_tables();
5330
5382
      }
5331
5383
      else
5332
 
        table->setDepTables(table->getDepTables() & ~table->table->map);
 
5384
        table->dep_tables&= ~table->table->map;
5333
5385
    }
5334
5386
 
5335
5387
    if (prev_table)
5336
5388
    {
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);
 
5389
      /* The order of tables is reverse: prev_table follows table */
 
5390
      if (prev_table->straight)
 
5391
        prev_table->dep_tables|= used_tables;
5342
5392
      if (prev_table->on_expr)
5343
5393
      {
5344
 
        prev_table->setDepTables(prev_table->getDepTables() | table->getOnExprDepTables());
5345
 
        table_map prev_used_tables= prev_table->getNestedJoin() ?
5346
 
                                    prev_table->getNestedJoin()->used_tables :
 
5394
        prev_table->dep_tables|= table->on_expr_dep_tables;
 
5395
        table_map prev_used_tables= prev_table->nested_join ?
 
5396
                                    prev_table->nested_join->used_tables :
5347
5397
                                    prev_table->table->map;
5348
5398
        /*
5349
5399
          If on expression contains only references to inner tables
5352
5402
          for them. Yet this is really a rare case.
5353
5403
              */
5354
5404
        if (!(prev_table->on_expr->used_tables() & ~prev_used_tables))
5355
 
          prev_table->setDepTables(prev_table->getDepTables() | used_tables);
 
5405
          prev_table->dep_tables|= used_tables;
5356
5406
      }
5357
5407
    }
5358
5408
    prev_table= table;
5365
5415
  li.rewind();
5366
5416
  while ((table= li++))
5367
5417
  {
5368
 
    nested_join= table->getNestedJoin();
 
5418
    nested_join= table->nested_join;
5369
5419
    if (nested_join && !table->on_expr)
5370
5420
    {
5371
5421
      TableList *tbl;
5372
5422
      List_iterator<TableList> it(nested_join->join_list);
5373
5423
      while ((tbl= it++))
5374
5424
      {
5375
 
        tbl->setEmbedding(table->getEmbedding());
5376
 
        tbl->setJoinList(table->getJoinList());
 
5425
        tbl->embedding= table->embedding;
 
5426
        tbl->join_list= table->join_list;
5377
5427
      }
5378
5428
      li.replace(nested_join->join_list);
5379
5429
    }
5381
5431
  return(conds);
5382
5432
}
5383
5433
 
5384
 
static int remove_duplicates(Join *join, Table *entry,List<Item> &fields, Item *having)
 
5434
static int remove_duplicates(JOIN *join, Table *entry,List<Item> &fields, Item *having)
5385
5435
{
5386
5436
  int error;
5387
5437
  uint32_t reclength,offset;
5405
5455
    join->unit->select_limit_cnt= 1;            // Only send first row
5406
5456
    return(0);
5407
5457
  }
5408
 
  Field **first_field=entry->getFields() + entry->getShare()->sizeFields() - field_count;
 
5458
  Field **first_field=entry->field+entry->s->fields - field_count;
5409
5459
  offset= (field_count ?
5410
 
           entry->getField(entry->getShare()->sizeFields() - field_count)->offset(entry->getInsertRecord()) : 0);
5411
 
  reclength= entry->getShare()->getRecordLength() - offset;
 
5460
           entry->field[entry->s->fields - field_count]->
 
5461
           offset(entry->record[0]) : 0);
 
5462
  reclength= entry->s->reclength-offset;
5412
5463
 
5413
5464
  entry->free_io_cache();                               // Safety
5414
5465
  entry->cursor->info(HA_STATUS_VARIABLE);
5415
 
  if (entry->getShare()->db_type() == heap_engine ||
5416
 
      (!entry->getShare()->blob_fields &&
 
5466
  if (entry->s->db_type() == heap_engine ||
 
5467
      (!entry->s->blob_fields &&
5417
5468
       ((ALIGN_SIZE(reclength) + HASH_OVERHEAD) * entry->cursor->stats.records <
5418
 
        session->variables.sortbuff_size)))
5419
 
  {
 
5469
        session->variables.sortbuff_size)))
5420
5470
    error= remove_dup_with_hash_index(join->session, entry,
5421
 
                                      field_count, first_field,
5422
 
                                      reclength, having);
5423
 
  }
 
5471
                                     field_count, first_field,
 
5472
                                     reclength, having);
5424
5473
  else
5425
 
  {
5426
 
    error= remove_dup_with_compare(join->session, entry, first_field, offset, having);
5427
 
  }
 
5474
    error= remove_dup_with_compare(join->session, entry, first_field, offset,
 
5475
                                  having);
5428
5476
 
5429
5477
  free_blobs(first_field);
5430
 
 
5431
5478
  return(error);
5432
5479
}
5433
5480
 
5441
5488
                               List<Item> &fields,
5442
5489
                               List<Item> &all_fields,
5443
5490
                               COND **conds,
5444
 
                               Order *order,
5445
 
                               Order *group,
 
5491
                               order_st *order,
 
5492
                               order_st *group,
5446
5493
                               bool *hidden_group_fields)
5447
5494
{
5448
5495
  int res;
5469
5516
  @retval
5470
5517
    1   Fatal error
5471
5518
*/
5472
 
static bool make_join_statistics(Join *join, TableList *tables, COND *conds, DYNAMIC_ARRAY *keyuse_array)
 
5519
static bool make_join_statistics(JOIN *join, TableList *tables, COND *conds, DYNAMIC_ARRAY *keyuse_array)
5473
5520
{
5474
5521
  int error;
5475
5522
  Table *table;
5512
5559
       tables;
5513
5560
       s++, tables= tables->next_leaf, i++)
5514
5561
  {
5515
 
    TableList *embedding= tables->getEmbedding();
 
5562
    TableList *embedding= tables->embedding;
5516
5563
    stat_vector[i]=s;
5517
5564
    s->keys.reset();
5518
5565
    s->const_keys.reset();
5520
5567
    s->needed_reg.reset();
5521
5568
    table_vector[i]=s->table=table=tables->table;
5522
5569
    table->pos_in_table_list= tables;
5523
 
    assert(table->cursor);
5524
5570
    error= table->cursor->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
5525
5571
    if (error)
5526
5572
    {
5531
5577
    table->reginfo.join_tab=s;
5532
5578
    table->reginfo.not_exists_optimize=0;
5533
5579
    memset(table->const_key_parts, 0,
5534
 
           sizeof(key_part_map)*table->getShare()->sizeKeys());
 
5580
           sizeof(key_part_map)*table->s->keys);
5535
5581
    all_table_map|= table->map;
5536
5582
    s->join=join;
5537
5583
    s->info=0;                                  // For describe
5538
5584
 
5539
 
    s->dependent= tables->getDepTables();
 
5585
    s->dependent= tables->dep_tables;
5540
5586
    s->key_dependent= 0;
 
5587
    if (tables->schema_table)
 
5588
      table->cursor->stats.records= 2;
5541
5589
    table->quick_condition_rows= table->cursor->stats.records;
5542
5590
 
5543
5591
    s->on_expr_ref= &tables->on_expr;
5552
5600
      }
5553
5601
      outer_join|= table->map;
5554
5602
      s->embedding_map.reset();
5555
 
      for (;embedding; embedding= embedding->getEmbedding())
5556
 
        s->embedding_map|= embedding->getNestedJoin()->nj_map;
 
5603
      for (;embedding; embedding= embedding->embedding)
 
5604
        s->embedding_map|= embedding->nested_join->nj_map;
5557
5605
      continue;
5558
5606
    }
5559
 
    if (embedding && !(false && ! embedding->getEmbedding()))
 
5607
    if (embedding && !(false && ! embedding->embedding))
5560
5608
    {
5561
5609
      /* s belongs to a nested join, maybe to several embedded joins */
5562
5610
      s->embedding_map.reset();
5563
5611
      do
5564
5612
      {
5565
 
        nested_join_st *nested_join= embedding->getNestedJoin();
 
5613
        nested_join_st *nested_join= embedding->nested_join;
5566
5614
        s->embedding_map|= nested_join->nj_map;
5567
 
        s->dependent|= embedding->getDepTables();
5568
 
        embedding= embedding->getEmbedding();
 
5615
        s->dependent|= embedding->dep_tables;
 
5616
        embedding= embedding->embedding;
5569
5617
        outer_join|= nested_join->used_tables;
5570
5618
      }
5571
5619
      while (embedding);
5572
5620
      continue;
5573
5621
    }
5574
5622
    if ((table->cursor->stats.records <= 1) && !s->dependent &&
5575
 
              (table->cursor->getEngine()->check_flag(HTON_BIT_STATS_RECORDS_IS_EXACT)) &&
 
5623
              (table->cursor->ha_table_flags() & HA_STATS_RECORDS_IS_EXACT) && 
5576
5624
        !join->no_const_tables)
5577
5625
    {
5578
5626
      set_position(join, const_count++, s, (optimizer::KeyUse*) 0);
5698
5746
        if (s->dependent & ~(found_const_table_map))
5699
5747
          continue;
5700
5748
        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())
 
5749
            (table->cursor->ha_table_flags() & HA_STATS_RECORDS_IS_EXACT) &&
 
5750
                  !table->pos_in_table_list->embedding)
5703
5751
        {                                       // system table
5704
5752
          int tmp= 0;
5705
5753
          s->type= AM_SYSTEM;
5744
5792
          } while (keyuse->getTable() == table && keyuse->getKey() == key);
5745
5793
 
5746
5794
          if (is_keymap_prefix(eq_part, table->key_info[key].key_parts) &&
5747
 
              ! table->pos_in_table_list->getEmbedding())
 
5795
              ! table->pos_in_table_list->embedding)
5748
5796
          {
5749
5797
            if ((table->key_info[key].flags & (HA_NOSAME)) == HA_NOSAME)
5750
5798
            {
5788
5836
    while (iter != sargables.end())
5789
5837
    {
5790
5838
      Field *field= (*iter).getField();
5791
 
      JoinTable *join_tab= field->getTable()->reginfo.join_tab;
 
5839
      JoinTable *join_tab= field->table->reginfo.join_tab;
5792
5840
      key_map possible_keys= field->key_start;
5793
 
      possible_keys&= field->getTable()->keys_in_use_for_query;
 
5841
      possible_keys&= field->table->keys_in_use_for_query;
5794
5842
      bool is_const= true;
5795
5843
      for (uint32_t j= 0; j < (*iter).getNumValues(); j++)
5796
5844
        is_const&= (*iter).isConstItem(j);
5831
5879
    add_group_and_distinct_keys(join, s);
5832
5880
 
5833
5881
    if (s->const_keys.any() &&
5834
 
        !s->table->pos_in_table_list->getEmbedding())
 
5882
        !s->table->pos_in_table_list->embedding)
5835
5883
    {
5836
5884
      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);
 
5885
      SQL_SELECT *select;
 
5886
      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
5887
      if (! select)
5840
5888
        return 1;
5841
5889
      records= get_quick_record_count(join->session, select, s->table, &s->const_keys, join->row_limit);
5881
5929
  if (join->const_tables != join->tables)
5882
5930
  {
5883
5931
    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;
 
5932
    if (choose_plan(join, all_table_map & ~join->const_table_map))
 
5933
      return(true);
5891
5934
  }
5892
5935
  else
5893
5936
  {
5895
5938
    join->best_read= 1.0;
5896
5939
  }
5897
5940
  /* Generate an execution plan from the found optimal join order. */
5898
 
  return (join->session->getKilled() || get_best_combination(join));
 
5941
  return (join->session->killed || get_best_combination(join));
5899
5942
}
5900
5943
 
5901
5944
/**
5924
5967
  while ((table= li++))
5925
5968
  {
5926
5969
    nested_join_st *nested_join;
5927
 
    if ((nested_join= table->getNestedJoin()))
 
5970
    if ((nested_join= table->nested_join))
5928
5971
    {
5929
5972
      /*
5930
5973
        It is guaranteed by simplify_joins() function that a nested join
5955
5998
  Return table number if there is only one table in sort order
5956
5999
  and group and order is compatible, else return 0.
5957
6000
*/
5958
 
static Table *get_sort_by_table(Order *a, Order *b,TableList *tables)
 
6001
static Table *get_sort_by_table(order_st *a,order_st *b,TableList *tables)
5959
6002
{
5960
6003
  table_map map= (table_map) 0;
5961
6004
 
5995
6038
  while ((table= li++))
5996
6039
  {
5997
6040
    nested_join_st *nested_join;
5998
 
    if ((nested_join= table->getNestedJoin()))
 
6041
    if ((nested_join= table->nested_join))
5999
6042
    {
6000
6043
      nested_join->counter_= 0;
6001
6044
      reset_nj_counters(&nested_join->join_list);
6010
6053
  If first parts has different direction, change it to second part
6011
6054
  (group is sorted like order)
6012
6055
*/
6013
 
static bool test_if_subpart(Order *a, Order *b)
 
6056
static bool test_if_subpart(order_st *a,order_st *b)
6014
6057
{
6015
6058
  for (; a && b; a=a->next,b=b->next)
6016
6059
  {
6025
6068
/**
6026
6069
  Nested joins perspective: Remove the last table from the join order.
6027
6070
 
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
6071
    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 
 
6072
    joins counters and join->cur_embedding_map. It is ok to call this
 
6073
    function for the first table in join order (for which
6071
6074
    check_interleaving_with_nj has not been called)
6072
6075
 
6073
6076
  @param last  join table to remove, it is assumed to be the last in current
6074
6077
               partial join order.
6075
6078
*/
6076
 
 
6077
6079
static void restore_prev_nj_state(JoinTable *last)
6078
6080
{
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)
 
6081
  TableList *last_emb= last->table->pos_in_table_list->embedding;
 
6082
  JOIN *join= last->join;
 
6083
  while (last_emb)
 
6084
  {
 
6085
    if (last_emb->on_expr)
 
6086
    {
 
6087
      if (!(--last_emb->nested_join->counter_))
 
6088
        join->cur_embedding_map&= ~last_emb->nested_join->nj_map;
 
6089
      else if (last_emb->nested_join->join_list.elements-1 ==
 
6090
               last_emb->nested_join->counter_)
 
6091
        join->cur_embedding_map|= last_emb->nested_join->nj_map;
 
6092
      else
 
6093
        break;
 
6094
    }
 
6095
    last_emb= last_emb->embedding;
 
6096
  }
 
6097
}
 
6098
 
 
6099
/**
 
6100
  Determine if the set is already ordered for order_st BY, so it can
 
6101
  disable join cache because it will change the ordering of the results.
 
6102
  Code handles sort table that is at any location (not only first after
 
6103
  the const tables) despite the fact that it's currently prohibited.
 
6104
  We must disable join cache if the first non-const table alone is
 
6105
  ordered. If there is a temp table the ordering is done as a last
 
6106
  operation and doesn't prevent join cache usage.
 
6107
*/
 
6108
static uint32_t make_join_orderinfo(JOIN *join)
 
6109
{
 
6110
  uint32_t i;
 
6111
  if (join->need_tmp)
 
6112
    return join->tables;
 
6113
 
 
6114
  for (i=join->const_tables ; i < join->tables ; i++)
 
6115
  {
 
6116
    JoinTable *tab= join->join_tab+i;
 
6117
    Table *table= tab->table;
 
6118
    if ((table == join->sort_by_table &&
 
6119
        (!join->order || join->skip_sort_order)) ||
 
6120
        (join->sort_by_table == (Table *) 1 &&  i != join->const_tables))
 
6121
    {
6091
6122
      break;
6092
 
    
6093
 
    join->cur_embedding_map|= nest->nj_map;
 
6123
    }
6094
6124
  }
 
6125
  return i;
6095
6126
}
6096
6127
 
6097
6128
/**
6111
6142
 
6112
6143
  for (uint32_t i=0 ; i < join_tab->ref.key_parts ; i++)
6113
6144
  {
6114
 
    Field *field=table->getField(table->key_info[join_tab->ref.key].key_part[i].fieldnr - 1);
 
6145
    Field *field=table->field[table->key_info[join_tab->ref.key].key_part[i].
 
6146
                              fieldnr-1];
6115
6147
    Item *value=join_tab->ref.items[i];
6116
6148
    cond->add(new Item_func_equal(new Item_field(field), value));
6117
6149
  }
6125
6157
    error=(int) cond->add(join_tab->select->cond);
6126
6158
    join_tab->select_cond=join_tab->select->cond=cond;
6127
6159
  }
6128
 
  else if ((join_tab->select= optimizer::make_select(join_tab->table, 0, 0, cond, 0,
6129
 
                                                     &error)))
 
6160
  else if ((join_tab->select= make_select(join_tab->table, 0, 0, cond, 0,
 
6161
                                          &error)))
6130
6162
    join_tab->select_cond=cond;
6131
6163
 
6132
6164
  return(error ? true : false);
6144
6176
/**
6145
6177
  @} (end of group Query_Optimizer)
6146
6178
*/
6147
 
 
6148
 
} /* namespace drizzled */