~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/join.cc

  • Committer: Brian Aker
  • Date: 2010-02-03 21:54:38 UTC
  • mto: This revision was merged to the branch mainline in revision 1281.
  • Revision ID: brian@gaz-20100203215438-9ixkp214vio85mub
Fixing test cases/removed dead optimizer switches.

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
 * @{
51
51
#include "drizzled/optimizer/range.h"
52
52
#include "drizzled/optimizer/sum.h"
53
53
#include "drizzled/optimizer/explain_plan.h"
54
 
#include "drizzled/optimizer/access_method_factory.h"
55
 
#include "drizzled/optimizer/access_method.h"
56
54
#include "drizzled/records.h"
57
55
#include "drizzled/probes.h"
58
56
#include "drizzled/internal/my_bit.h"
62
60
#include <algorithm>
63
61
 
64
62
using namespace std;
65
 
 
66
 
namespace drizzled
67
 
{
68
 
 
69
 
extern plugin::StorageEngine *heap_engine;
 
63
using namespace drizzled;
 
64
 
 
65
extern drizzled::plugin::StorageEngine *heap_engine;
70
66
extern std::bitset<12> test_flags;
71
67
 
72
68
/** 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,
 
69
static bool make_group_fields(JOIN *main_join, JOIN *curr_join);
 
70
static void calc_group_buffer(JOIN *join,order_st *group);
 
71
static bool alloc_group_fields(JOIN *join,order_st *group);
 
72
static uint32_t cache_record_length(JOIN *join, uint32_t index);
 
73
static double prev_record_reads(JOIN *join, uint32_t idx, table_map found_ref);
 
74
static bool get_best_combination(JOIN *join);
 
75
static void set_position(JOIN *join,
80
76
                         uint32_t index,
81
77
                         JoinTable *table,
82
78
                         optimizer::KeyUse *key);
83
 
static bool choose_plan(Join *join,table_map join_tables);
84
 
static void best_access_path(Join *join, JoinTable *s,
 
79
static bool choose_plan(JOIN *join,table_map join_tables);
 
80
static void best_access_path(JOIN *join, JoinTable *s,
85
81
                             Session *session,
86
82
                             table_map remaining_tables,
87
83
                             uint32_t idx,
88
84
                             double record_count,
89
85
                             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,
 
86
static void optimize_straight_join(JOIN *join, table_map join_tables);
 
87
static bool greedy_search(JOIN *join, table_map remaining_tables, uint32_t depth, uint32_t prune_level);
 
88
static bool best_extension_by_limited_search(JOIN *join,
93
89
                                             table_map remaining_tables,
94
90
                                             uint32_t idx,
95
91
                                             double record_count,
96
92
                                             double read_time,
97
93
                                             uint32_t depth,
98
94
                                             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,
 
95
static uint32_t determine_search_depth(JOIN* join);
 
96
static bool make_simple_join(JOIN *join,Table *tmp_table);
 
97
static void make_outerjoin_info(JOIN *join);
 
98
static bool make_join_select(JOIN *join, optimizer::SqlSelect *select,COND *item);
 
99
static bool make_join_readinfo(JOIN *join, uint64_t options, uint32_t no_jbuf_after);
 
100
static void update_depend_map(JOIN *join);
 
101
static void update_depend_map(JOIN *join, order_st *order);
 
102
static order_st *remove_constants(JOIN *join,order_st *first_order,COND *cond, bool change_list, bool *simple_order);
 
103
static int return_zero_rows(JOIN *join,
108
104
                            select_result *res,
109
105
                            TableList *tables,
110
106
                            List<Item> &fields,
112
108
                            uint64_t select_options,
113
109
                            const char *info,
114
110
                            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);
 
111
static COND *simplify_joins(JOIN *join, List<TableList> *join_list, COND *conds, bool top);
 
112
static int remove_duplicates(JOIN *join,Table *entry,List<Item> &fields, Item *having);
117
113
static int setup_without_group(Session *session, 
118
114
                               Item **ref_pointer_array,
119
115
                               TableList *tables,
121
117
                               List<Item> &fields,
122
118
                               List<Item> &all_fields,
123
119
                               COND **conds,
124
 
                               Order *order,
125
 
                               Order *group,
 
120
                               order_st *order,
 
121
                               order_st *group,
126
122
                               bool *hidden_group_fields);
127
 
static bool make_join_statistics(Join *join, TableList *leaves, COND *conds, DYNAMIC_ARRAY *keyuse);
 
123
static bool make_join_statistics(JOIN *join, TableList *leaves, COND *conds, DYNAMIC_ARRAY *keyuse);
128
124
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);
 
125
static Table *get_sort_by_table(order_st *a,order_st *b,TableList *tables);
130
126
static void reset_nj_counters(List<TableList> *join_list);
131
 
static bool test_if_subpart(Order *a,Order *b);
 
127
static bool test_if_subpart(order_st *a,order_st *b);
132
128
static void restore_prev_nj_state(JoinTable *last);
 
129
static uint32_t make_join_orderinfo(JOIN *join);
133
130
static bool add_ref_to_table_cond(Session *session, JoinTable *join_tab);
134
131
static void free_blobs(Field **ptr); /* Rename this method...conflicts with another in global namespace... */
135
132
 
145
142
  @retval
146
143
    0   on success
147
144
*/
148
 
int Join::prepare(Item ***rref_pointer_array,
 
145
int JOIN::prepare(Item ***rref_pointer_array,
149
146
                  TableList *tables_init,
150
147
                  uint32_t wild_num,
151
148
                  COND *conds_init,
152
149
                  uint32_t og_num,
153
 
                  Order *order_init,
154
 
                  Order *group_init,
 
150
                  order_st *order_init,
 
151
                  order_st *group_init,
155
152
                  Item *having_init,
156
153
                  Select_Lex *select_lex_arg,
157
154
                  Select_Lex_Unit *unit_arg)
184
181
      setup_tables_and_check_access(session, &select_lex->context, join_list,
185
182
                                    tables_list, &select_lex->leaf_tables,
186
183
                                    false))
187
 
  {
188
184
      return(-1);
189
 
  }
190
185
 
191
186
  TableList *table_ptr;
192
187
  for (table_ptr= select_lex->leaf_tables;
193
188
       table_ptr;
194
189
       table_ptr= table_ptr->next_leaf)
195
 
  {
196
190
    tables++;
197
 
  }
198
 
 
199
191
 
200
192
  if (setup_wild(session, fields_list, &all_fields, wild_num) ||
201
193
      select_lex->setup_ref_array(session, og_num) ||
255
247
             (Subquery is non-correlated ||
256
248
              Subquery is correlated to any query outer to IN predicate ||
257
249
              (Subquery is correlated to the immediate outer query &&
258
 
               Subquery !contains {GROUP BY, ORDER BY [LIMIT],
 
250
               Subquery !contains {GROUP BY, order_st BY [LIMIT],
259
251
               aggregate functions) && subquery predicate is not under "NOT IN"))
260
252
          6. No execution method was already chosen (by a prepared statement).
261
253
 
291
283
 
292
284
  if (order)
293
285
  {
294
 
    Order *ord;
 
286
    order_st *ord;
295
287
    for (ord= order; ord; ord= ord->next)
296
288
    {
297
289
      Item *item= *ord->item;
336
328
  {
337
329
    /* Caclulate the number of groups */
338
330
    send_group_parts= 0;
339
 
    for (Order *group_tmp= group_list ; group_tmp ; group_tmp= group_tmp->next)
 
331
    for (order_st *group_tmp= group_list ; group_tmp ; group_tmp= group_tmp->next)
340
332
      send_group_parts++;
341
333
  }
342
334
 
343
335
  if (error)
344
 
    return(-1);
 
336
    goto err;
345
337
 
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
338
  if (result && result->prepare(fields_list, unit_arg))
353
 
    return(-1);
 
339
    goto err;
354
340
 
355
341
  /* Init join struct */
356
342
  count_field_types(select_lex, &tmp_table_param, all_fields, 0);
362
348
  if (sum_func_count && !group_list && (func_count || field_count))
363
349
  {
364
350
    my_message(ER_WRONG_SUM_SELECT,ER(ER_WRONG_SUM_SELECT),MYF(0));
365
 
    return(-1);
 
351
    goto err;
366
352
  }
367
353
#endif
368
354
  if (select_lex->olap == ROLLUP_TYPE && rollup_init())
369
 
    return(-1);
370
 
 
 
355
    goto err;
371
356
  if (alloc_func_list())
372
 
    return(-1);
373
 
 
374
 
  return 0; // All OK
 
357
    goto err;
 
358
 
 
359
  return(0); // All OK
 
360
 
 
361
err:
 
362
  return(-1);
375
363
}
376
364
 
377
365
/*
378
366
  Remove the predicates pushed down into the subquery
379
367
 
380
368
  SYNOPSIS
381
 
    Join::remove_subq_pushed_predicates()
 
369
    JOIN::remove_subq_pushed_predicates()
382
370
      where   IN  Must be NULL
383
371
              OUT The remaining WHERE condition, or NULL
384
372
 
403
391
    that is searched in a byte. But this requires homogenization of the return
404
392
    codes of all Field*::store() methods.
405
393
*/
406
 
void Join::remove_subq_pushed_predicates(Item **where)
 
394
void JOIN::remove_subq_pushed_predicates(Item **where)
407
395
{
408
396
  if (conds->type() == Item::FUNC_ITEM &&
409
397
      ((Item_func *)this->conds)->functype() == Item_func::EQ_FUNC &&
428
416
  @retval
429
417
    1   error
430
418
*/
431
 
int Join::optimize()
 
419
int JOIN::optimize()
432
420
{
433
421
  // to prevent double initialization on EXPLAIN
434
422
  if (optimized)
498
486
    {           /* Impossible cond */
499
487
      zero_result_cause=  having_value == Item::COND_FALSE ?
500
488
                           "Impossible HAVING" : "Impossible WHERE";
501
 
      tables = 0;
502
 
      goto setup_subq_exit;
 
489
      error= 0;
 
490
      return(0);
503
491
    }
504
492
  }
505
493
 
518
506
      if (res == HA_ERR_KEY_NOT_FOUND)
519
507
      {
520
508
        zero_result_cause= "No matching min/max row";
521
 
        tables = 0;
522
 
        goto setup_subq_exit;
 
509
        error=0;
 
510
        return(0);
523
511
      }
524
512
      if (res > 1)
525
513
      {
529
517
      if (res < 0)
530
518
      {
531
519
        zero_result_cause= "No matching min/max row";
532
 
        tables = 0;
533
 
        goto setup_subq_exit;
 
520
        error=0;
 
521
        return(0);
534
522
      }
535
523
      zero_result_cause= "Select tables optimized away";
536
524
      tables_list= 0;       // All tables resolved
537
 
      const_tables= tables;
538
525
      /*
539
526
        Extract all table-independent conditions and replace the WHERE
540
527
        clause with them. All other conditions were computed by optimizer::sum_query
550
537
        COND *table_independent_conds= make_cond_for_table(conds, PSEUDO_TABLE_BITS, 0, 0);
551
538
        conds= table_independent_conds;
552
539
      }
553
 
      goto setup_subq_exit;
554
540
    }
555
541
  }
556
542
  if (!tables_list)
583
569
       select_lex->master_unit() == &session->lex->unit)) // upper level SELECT
584
570
  {
585
571
    zero_result_cause= "no matching row in const table";
586
 
    goto setup_subq_exit;
 
572
    error= 0;
 
573
    return(0);
587
574
  }
588
575
  if (!(session->options & OPTION_BIG_SELECTS) &&
589
576
      best_read > (double) session->variables.max_join_size &&
594
581
    return 1;
595
582
  }
596
583
  if (const_tables && !(select_options & SELECT_NO_UNLOCK))
597
 
    session->unlockSomeTables(table, const_tables);
 
584
    mysql_unlock_some_tables(session, table, const_tables);
598
585
  if (!conds && outer_join)
599
586
  {
600
587
    /* Handle the case where we have an OUTER JOIN without a WHERE */
649
636
  {
650
637
    zero_result_cause=
651
638
      "Impossible WHERE noticed after reading const tables";
652
 
    goto setup_subq_exit;
 
639
    return(0);        // error == 0
653
640
  }
654
641
 
655
642
  error= -1;          /* if goto err */
656
643
 
657
644
  /* Optimize distinct away if possible */
658
645
  {
659
 
    Order *org_order= order;
 
646
    order_st *org_order= order;
660
647
    order= remove_constants(this, order,conds,1, &simple_order);
661
648
    if (session->is_error())
662
649
    {
665
652
    }
666
653
 
667
654
    /*
668
 
      If we are using ORDER BY NULL or ORDER BY const_expression,
 
655
      If we are using order_st BY NULL or order_st BY const_expression,
669
656
      return result in any order (even if we are using a GROUP BY)
670
657
    */
671
658
    if (!order && org_order)
696
683
        We have found that grouping can be removed since groups correspond to
697
684
        only one row anyway, but we still have to guarantee correct result
698
685
        order. The line below effectively rewrites the query from GROUP BY
699
 
        <fields> to ORDER BY <fields>. There are two exceptions:
 
686
        <fields> to order_st BY <fields>. There are two exceptions:
700
687
        - if skip_sort_order is set (see above), then we can simply skip
701
688
          GROUP BY;
702
 
        - we can only rewrite ORDER BY if the ORDER BY fields are 'compatible'
 
689
        - we can only rewrite order_st BY if the order_st BY fields are 'compatible'
703
690
          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
 
691
          We only check if the order_st BY is a prefix of GROUP BY. In this case
705
692
          test_if_subpart() copies the ASC/DESC attributes from the original
706
 
          ORDER BY fields.
 
693
          order_st BY fields.
707
694
          If GROUP BY is a prefix of order_st BY, then it is safe to leave
708
695
          'order' as is.
709
696
       */
742
729
      - We are scanning the whole table without LIMIT
743
730
        This can happen if:
744
731
        - We are using CALC_FOUND_ROWS
745
 
        - We are using an ORDER BY that can't be optimized away.
 
732
        - We are using an order_st BY that can't be optimized away.
746
733
 
747
734
      We don't want to use this optimization when we are using LIMIT
748
735
      because in this case we can just create a temporary table that
774
761
          {
775
762
            /*
776
763
              Force MySQL to read the table in sorted order to get result in
777
 
              ORDER BY order.
 
764
              order_st BY order.
778
765
            */
779
766
            tmp_table_param.quick_group=0;
780
767
          }
790
777
  }
791
778
  simple_group= 0;
792
779
  {
793
 
    Order *old_group_list;
 
780
    order_st *old_group_list;
794
781
    group_list= remove_constants(this, (old_group_list= group_list), conds,
795
782
                                 rollup.state == ROLLUP::STATE_NONE,
796
783
                                 &simple_group);
831
818
    This has to be done if all tables are not already read (const tables)
832
819
    and one of the following conditions holds:
833
820
    - 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
 
821
    - We are using an order_st BY or GROUP BY on fields not in the first table
 
822
    - We are using different order_st BY and GROUP BY orders
836
823
    - The user wants us to buffer the result.
837
824
  */
838
825
  need_tmp= (const_tables != tables &&
840
827
        (group_list && order) ||
841
828
        test(select_options & OPTION_BUFFER_RESULT)));
842
829
 
 
830
  uint32_t no_jbuf_after= make_join_orderinfo(this);
 
831
  uint64_t select_opts_for_readinfo=
 
832
    (select_options & (SELECT_DESCRIBE | SELECT_NO_JOIN_CACHE)) | (0);
 
833
 
843
834
  // No cache for MATCH == 'Don't use join buffering when we use MATCH'.
844
 
  if (make_join_readinfo(this))
 
835
  if (make_join_readinfo(this, select_opts_for_readinfo, no_jbuf_after))
845
836
    return 1;
846
837
 
847
838
  /* Create all structures needed for materialized subquery execution. */
868
859
        save_index_subquery_explain_info(join_tab, where);
869
860
        join_tab[0].type= AM_UNIQUE_SUBQUERY;
870
861
        error= 0;
871
 
        return(unit->item->change_engine(new subselect_uniquesubquery_engine(session, join_tab, unit->item, where)));
 
862
        return(unit->item->
 
863
                    change_engine(new
 
864
                                  subselect_uniquesubquery_engine(session,
 
865
                                                                  join_tab,
 
866
                                                                  unit->item,
 
867
                                                                  where)));
872
868
      }
873
869
      else if (join_tab[0].type == AM_REF &&
874
870
         join_tab[0].ref.items[0]->name == in_left_expr_name)
877
873
        save_index_subquery_explain_info(join_tab, where);
878
874
        join_tab[0].type= AM_INDEX_SUBQUERY;
879
875
        error= 0;
880
 
        return(unit->item->change_engine(new subselect_indexsubquery_engine(session, join_tab, unit->item, where, NULL, 0)));
 
876
        return(unit->item->
 
877
                    change_engine(new
 
878
                                  subselect_indexsubquery_engine(session,
 
879
                                                                 join_tab,
 
880
                                                                 unit->item,
 
881
                                                                 where,
 
882
                                                                 NULL,
 
883
                                                                 0)));
881
884
      }
882
885
    } 
883
886
    else if (join_tab[0].type == AM_REF_OR_NULL &&
888
891
      error= 0;
889
892
      conds= remove_additional_cond(conds);
890
893
      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)));
 
894
      return(unit->item->
 
895
      change_engine(new subselect_indexsubquery_engine(session,
 
896
                   join_tab,
 
897
                   unit->item,
 
898
                   conds,
 
899
                                                                   having,
 
900
                   1)));
892
901
    }
893
902
 
894
903
  }
940
949
        Force using of tmp table if sorting by a SP or UDF function due to
941
950
        their expensive and probably non-deterministic nature.
942
951
      */
943
 
      for (Order *tmp_order= order; tmp_order ; tmp_order=tmp_order->next)
 
952
      for (order_st *tmp_order= order; tmp_order ; tmp_order=tmp_order->next)
944
953
      {
945
954
        Item *item= *tmp_order->item;
946
955
        if (item->is_expensive())
984
993
 
985
994
    tmp_table_param.hidden_field_count= (all_fields.elements -
986
995
           fields_list.elements);
987
 
    Order *tmp_group= ((!simple_group &&
 
996
    order_st *tmp_group= ((!simple_group && 
988
997
                           ! (test_flags.test(TEST_NO_KEY_GROUP))) ? group_list :
989
 
                                                                     (Order*) 0);
 
998
                                                                     (order_st*) 0);
990
999
    /*
991
1000
      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
 
1001
      when there is order_st BY or GROUP BY or there is no GROUP BY, but
993
1002
      there are aggregate functions, because in all these cases we need
994
1003
      all result rows.
995
1004
    */
1089
1098
      If this join belongs to an uncacheable subquery save
1090
1099
      the original join
1091
1100
    */
1092
 
    if (select_lex->uncacheable.any() && 
1093
 
        ! is_top_level_join() &&
 
1101
    if (select_lex->uncacheable && !is_top_level_join() &&
1094
1102
        init_save_join_tab())
1095
 
    {
1096
 
      return -1;
1097
 
    }
 
1103
      return(-1);
1098
1104
  }
1099
1105
 
1100
1106
  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;
 
1107
  return(0);
1111
1108
}
1112
1109
 
1113
1110
/**
1114
1111
  Restore values in temporary join.
1115
1112
*/
1116
 
void Join::restore_tmp()
 
1113
void JOIN::restore_tmp()
1117
1114
{
1118
 
  memcpy(tmp_join, this, (size_t) sizeof(Join));
 
1115
  memcpy(tmp_join, this, (size_t) sizeof(JOIN));
1119
1116
}
1120
1117
 
1121
 
int Join::reinit()
 
1118
int JOIN::reinit()
1122
1119
{
1123
1120
  unit->offset_limit_cnt= (ha_rows)(select_lex->offset_limit ?
1124
1121
                                    select_lex->offset_limit->val_uint() :
1170
1167
   @retval 0      success.
1171
1168
   @retval 1      error occurred.
1172
1169
*/
1173
 
bool Join::init_save_join_tab()
 
1170
bool JOIN::init_save_join_tab()
1174
1171
{
1175
 
  if (!(tmp_join= (Join*)session->alloc(sizeof(Join))))
 
1172
  if (!(tmp_join= (JOIN*)session->alloc(sizeof(JOIN))))
1176
1173
    return 1;
1177
 
 
1178
1174
  error= 0;              // Ensure that tmp_join.error= 0
1179
1175
  restore_tmp();
1180
 
 
1181
1176
  return 0;
1182
1177
}
1183
1178
 
1184
 
bool Join::save_join_tab()
 
1179
bool JOIN::save_join_tab()
1185
1180
{
1186
 
  if (! join_tab_save && select_lex->master_unit()->uncacheable.any())
 
1181
  if (!join_tab_save && select_lex->master_unit()->uncacheable)
1187
1182
  {
1188
1183
    if (!(join_tab_save= (JoinTable*)session->memdup((unsigned char*) join_tab,
1189
1184
            sizeof(JoinTable) * tables)))
1203
1198
  @todo
1204
1199
    When can we have here session->net.report_error not zero?
1205
1200
*/
1206
 
void Join::exec()
 
1201
void JOIN::exec()
1207
1202
{
1208
1203
  List<Item> *columns_list= &fields_list;
1209
1204
  int      tmp_error;
1276
1271
  if (select_options & SELECT_DESCRIBE)
1277
1272
  {
1278
1273
    /*
1279
 
      Check if we managed to optimize ORDER BY away and don't use temporary
 
1274
      Check if we managed to optimize order_st BY away and don't use temporary
1280
1275
      table to resolve order_st BY: in that case, we only may need to do
1281
1276
      filesort for GROUP BY.
1282
1277
    */
1304
1299
    return;
1305
1300
  }
1306
1301
 
1307
 
  Join *curr_join= this;
 
1302
  JOIN *curr_join= this;
1308
1303
  List<Item> *curr_all_fields= &all_fields;
1309
1304
  List<Item> *curr_fields_list= &fields_list;
1310
1305
  Table *curr_tmp_table= 0;
1414
1409
                                                   - curr_join->tmp_fields_list1.elements;
1415
1410
 
1416
1411
      if (exec_tmp_table2)
1417
 
      {
1418
1412
        curr_tmp_table= exec_tmp_table2;
1419
 
      }
1420
1413
      else
1421
1414
      {
1422
1415
        /* group data to new table */
1424
1417
        /*
1425
1418
          If the access method is loose index scan then all MIN/MAX
1426
1419
          functions are precomputed, and should be treated as regular
1427
 
          functions. See extended comment in Join::exec.
 
1420
          functions. See extended comment in JOIN::exec.
1428
1421
        */
1429
1422
        if (curr_join->join_tab->is_using_loose_index_scan())
1430
1423
          curr_join->tmp_table_param.precomputed_group_by= true;
1433
1426
              exec_tmp_table2= create_tmp_table(session,
1434
1427
                                                &curr_join->tmp_table_param,
1435
1428
                                                *curr_all_fields,
1436
 
                                                (Order*) 0,
 
1429
                                                (order_st*) 0,
1437
1430
                                                curr_join->select_distinct &&
1438
1431
                                                !curr_join->group_list,
1439
1432
                                                1, curr_join->select_options,
1440
1433
                                                HA_POS_ERROR,
1441
1434
                                                (char *) "")))
1442
 
        {
1443
1435
          return;
1444
 
        }
1445
 
 
1446
1436
        curr_join->exec_tmp_table2= exec_tmp_table2;
1447
1437
      }
1448
1438
      if (curr_join->group_list)
1490
1480
        error= tmp_error;
1491
1481
        return;
1492
1482
      }
1493
 
      curr_join->join_tab->read_record.end_read_record();
 
1483
      end_read_record(&curr_join->join_tab->read_record);
1494
1484
      curr_join->const_tables= curr_join->tables; // Mark free for cleanup()
1495
1485
      curr_join->join_tab[0].table= 0;           // Table is freed
1496
1486
 
1701
1691
  Clean up join.
1702
1692
 
1703
1693
  @return
1704
 
    Return error that hold Join.
 
1694
    Return error that hold JOIN.
1705
1695
*/
1706
 
int Join::destroy()
 
1696
int JOIN::destroy()
1707
1697
{
1708
1698
  select_lex->join= 0;
1709
1699
 
1722
1712
  cond_equal= 0;
1723
1713
 
1724
1714
  cleanup(1);
1725
 
  exec_tmp_table1= NULL;
1726
 
  exec_tmp_table2= NULL;
 
1715
  if (exec_tmp_table1)
 
1716
    exec_tmp_table1->free_tmp_table(session);
 
1717
  if (exec_tmp_table2)
 
1718
    exec_tmp_table2->free_tmp_table(session);
1727
1719
  delete select;
1728
1720
  delete_dynamic(&keyuse);
1729
 
 
1730
1721
  return(error);
1731
1722
}
1732
1723
 
1739
1730
  - try to initialize all data structures needed for the materialized execution
1740
1731
    of the IN predicate,
1741
1732
  - if this fails, then perform the IN=>EXISTS transformation which was
1742
 
    previously blocked during Join::prepare.
 
1733
    previously blocked during JOIN::prepare.
1743
1734
 
1744
1735
  This method is part of the "code generation" query processing phase.
1745
1736
 
1752
1743
  @retval false     success.
1753
1744
  @retval true      error occurred.
1754
1745
*/
1755
 
bool Join::setup_subquery_materialization()
 
1746
bool JOIN::setup_subquery_materialization()
1756
1747
{
1757
1748
  for (Select_Lex_Unit *un= select_lex->first_inner_unit(); un;
1758
1749
       un= un->next_unit())
1774
1765
}
1775
1766
 
1776
1767
/**
1777
 
  Partially cleanup Join after it has executed: close index or rnd read
 
1768
  Partially cleanup JOIN after it has executed: close index or rnd read
1778
1769
  (table cursors), free quick selects.
1779
1770
 
1780
 
    This function is called in the end of execution of a Join, before the used
 
1771
    This function is called in the end of execution of a JOIN, before the used
1781
1772
    tables are unlocked and closed.
1782
1773
 
1783
1774
    For a join that is resolved using a temporary table, the first sweep is
1791
1782
    is called after all rows are sent, but before EOF packet is sent.
1792
1783
 
1793
1784
    For a simple SELECT with no subqueries this function performs a full
1794
 
    cleanup of the Join and calls unlockReadTables to free used base
 
1785
    cleanup of the JOIN and calls mysql_unlock_read_tables to free used base
1795
1786
    tables.
1796
1787
 
1797
 
    If a Join is executed for a subquery or if it has a subquery, we can't
 
1788
    If a JOIN is executed for a subquery or if it has a subquery, we can't
1798
1789
    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
 
1790
    - If a JOIN is not the top level join, we must not unlock the tables
1800
1791
    because the outer select may not have been evaluated yet, and we
1801
1792
    can't unlock only selected tables of a query.
1802
 
    - Additionally, if this Join corresponds to a correlated subquery, we
 
1793
    - Additionally, if this JOIN corresponds to a correlated subquery, we
1803
1794
    should not free quick selects and join buffers because they will be
1804
1795
    needed for the next execution of the correlated subquery.
1805
 
    - However, if this is a Join for a [sub]select, which is not
 
1796
    - However, if this is a JOIN for a [sub]select, which is not
1806
1797
    a correlated subquery itself, but has subqueries, we can free it
1807
 
    fully and also free Joins of all its subqueries. The exception
 
1798
    fully and also free JOINs of all its subqueries. The exception
1808
1799
    is a subquery in SELECT list, e.g: @n
1809
1800
    SELECT a, (select cmax(b) from t1) group by c @n
1810
1801
    This subquery will not be evaluated at first sweep and its value will
1815
1806
  @todo
1816
1807
    Unlock tables even if the join isn't top level select in the tree
1817
1808
*/
1818
 
void Join::join_free()
 
1809
void JOIN::join_free()
1819
1810
{
1820
1811
  Select_Lex_Unit *tmp_unit;
1821
1812
  Select_Lex *sl;
1822
1813
  /*
1823
 
    Optimization: if not EXPLAIN and we are done with the Join,
 
1814
    Optimization: if not EXPLAIN and we are done with the JOIN,
1824
1815
    free all tables.
1825
1816
  */
1826
 
  bool full= (select_lex->uncacheable.none() && ! session->lex->describe);
 
1817
  bool full= (!select_lex->uncacheable && !session->lex->describe);
1827
1818
  bool can_unlock= full;
1828
1819
 
1829
1820
  cleanup(full);
1845
1836
        but all table cursors must be closed before the unlock.
1846
1837
      */
1847
1838
      sl->cleanup_all_joins(full_local);
1848
 
      /* Can't unlock if at least one Join is still needed */
 
1839
      /* Can't unlock if at least one JOIN is still needed */
1849
1840
      can_unlock= can_unlock && full_local;
1850
1841
    }
1851
1842
 
1863
1854
      TODO: unlock tables even if the join isn't top level select in the
1864
1855
      tree.
1865
1856
    */
1866
 
    session->unlockReadTables(lock);           // Don't free join->lock
 
1857
    mysql_unlock_read_tables(session, lock);           // Don't free join->lock
1867
1858
    lock= 0;
1868
1859
  }
1869
1860
 
1882
1873
    With subquery this function definitely will be called several times,
1883
1874
    but even for simple query it can be called several times.
1884
1875
*/
1885
 
void Join::cleanup(bool full)
 
1876
void JOIN::cleanup(bool full)
1886
1877
{
1887
1878
  if (table)
1888
1879
  {
1927
1918
    */
1928
1919
    tmp_table_param.copy_funcs.empty();
1929
1920
    /*
1930
 
      If we have tmp_join and 'this' Join is not tmp_join and
 
1921
      If we have tmp_join and 'this' JOIN is not tmp_join and
1931
1922
      tmp_table_param.copy_field's  of them are equal then we have to remove
1932
1923
      pointer to  tmp_table_param.copy_field from tmp_join, because it qill
1933
1924
      be removed in tmp_table_param.cleanup().
1946
1937
}
1947
1938
 
1948
1939
/*
1949
 
  used only in Join::clear
 
1940
  used only in JOIN::clear
1950
1941
*/
1951
 
static void clear_tables(Join *join)
 
1942
static void clear_tables(JOIN *join)
1952
1943
{
1953
1944
  /*
1954
1945
    must clear only the non-const tables, as const tables
1967
1958
  @retval
1968
1959
    1 Error
1969
1960
*/
1970
 
bool Join::alloc_func_list()
 
1961
bool JOIN::alloc_func_list()
1971
1962
{
1972
1963
  uint32_t func_count, group_parts;
1973
1964
 
1993
1984
    */
1994
1985
    if (order)
1995
1986
    {
1996
 
      Order *ord;
 
1987
      order_st *ord;
1997
1988
      for (ord= order; ord; ord= ord->next)
1998
1989
        group_parts++;
1999
1990
    }
2019
2010
  @retval
2020
2011
    1  error
2021
2012
*/
2022
 
bool Join::make_sum_func_list(List<Item> &field_list, 
 
2013
bool JOIN::make_sum_func_list(List<Item> &field_list, 
2023
2014
                              List<Item> &send_fields,
2024
2015
                              bool before_group_by, 
2025
2016
                              bool recompute)
2057
2048
}
2058
2049
 
2059
2050
/** Allocate memory needed for other rollup functions. */
2060
 
bool Join::rollup_init()
 
2051
bool JOIN::rollup_init()
2061
2052
{
2062
2053
  uint32_t i,j;
2063
2054
  Item **ref_array;
2103
2094
  Item *item;
2104
2095
  while ((item= it++))
2105
2096
  {
2106
 
    Order *group_tmp;
 
2097
    order_st *group_tmp;
2107
2098
    bool found_in_group= 0;
2108
2099
 
2109
2100
    for (group_tmp= group_list; group_tmp; group_tmp= group_tmp->next)
2132
2123
            return 1;
2133
2124
          new_item->fix_fields(session, (Item **) 0);
2134
2125
          session->change_item_tree(it.ref(), new_item);
2135
 
          for (Order *tmp= group_tmp; tmp; tmp= tmp->next)
 
2126
          for (order_st *tmp= group_tmp; tmp; tmp= tmp->next)
2136
2127
          {
2137
2128
            if (*tmp->item == item)
2138
2129
              session->change_item_tree(tmp->item, new_item);
2172
2163
  @retval
2173
2164
    1    on error
2174
2165
*/
2175
 
bool Join::rollup_make_fields(List<Item> &fields_arg, List<Item> &sel_fields, Item_sum ***func)
 
2166
bool JOIN::rollup_make_fields(List<Item> &fields_arg, List<Item> &sel_fields, Item_sum ***func)
2176
2167
{
2177
2168
  List_iterator_fast<Item> it(fields_arg);
2178
2169
  Item *first_field= sel_fields.head();
2207
2198
    Item *item;
2208
2199
    List_iterator<Item> new_it(rollup.fields[pos]);
2209
2200
    Item **ref_array_start= rollup.ref_pointer_arrays[pos];
2210
 
    Order *start_group;
 
2201
    order_st *start_group;
2211
2202
 
2212
2203
    /* Point to first hidden field */
2213
2204
    Item **ref_array= ref_array_start + fields_arg.elements-1;
2249
2240
      else
2250
2241
      {
2251
2242
        /* Check if this is something that is part of this group by */
2252
 
        Order *group_tmp;
 
2243
        order_st *group_tmp;
2253
2244
        for (group_tmp= start_group, i= pos ;
2254
2245
                  group_tmp ; group_tmp= group_tmp->next, i++)
2255
2246
        {
2302
2293
  @retval
2303
2294
    1   If send_data_failed()
2304
2295
*/
2305
 
int Join::rollup_send_data(uint32_t idx)
 
2296
int JOIN::rollup_send_data(uint32_t idx)
2306
2297
{
2307
2298
  uint32_t i;
2308
2299
  for (i= send_group_parts ; i-- > idx ; )
2342
2333
  @retval
2343
2334
    1   if write_data_failed()
2344
2335
*/
2345
 
int Join::rollup_write_data(uint32_t idx, Table *table_arg)
 
2336
int JOIN::rollup_write_data(uint32_t idx, Table *table_arg)
2346
2337
{
2347
2338
  uint32_t i;
2348
2339
  for (i= send_group_parts ; i-- > idx ; )
2349
2340
  {
2350
2341
    /* Get reference pointers to sum functions in place */
2351
2342
    memcpy(ref_pointer_array, rollup.ref_pointer_arrays[i],
2352
 
           ref_pointer_array_size);
 
2343
     ref_pointer_array_size);
2353
2344
    if ((!having || having->val_int()))
2354
2345
    {
2355
2346
      int write_error;
2361
2352
          item->save_in_result_field(1);
2362
2353
      }
2363
2354
      copy_sum_funcs(sum_funcs_end[i+1], sum_funcs_end[i]);
2364
 
      if ((write_error= table_arg->cursor->insertRecord(table_arg->getInsertRecord())))
 
2355
      if ((write_error= table_arg->cursor->ha_write_row(table_arg->record[0])))
2365
2356
      {
2366
 
        my_error(ER_USE_SQL_BIG_RESULT, MYF(0));
2367
 
        return 1;
 
2357
  if (create_myisam_from_heap(session, table_arg,
 
2358
                                    tmp_table_param.start_recinfo,
 
2359
                                    &tmp_table_param.recinfo,
 
2360
                                    write_error, 0))
 
2361
    return 1;
2368
2362
      }
2369
2363
    }
2370
2364
  }
2377
2371
  clear results if there are not rows found for group
2378
2372
  (end_send_group/end_write_group)
2379
2373
*/
2380
 
void Join::clear()
 
2374
void JOIN::clear()
2381
2375
{
2382
2376
  clear_tables(this);
2383
2377
  copy_fields(&tmp_table_param);
2391
2385
}
2392
2386
 
2393
2387
/**
2394
 
  change select_result object of Join.
 
2388
  change select_result object of JOIN.
2395
2389
 
2396
2390
  @param res    new select_result object
2397
2391
 
2400
2394
  @retval
2401
2395
    true    error
2402
2396
*/
2403
 
bool Join::change_result(select_result *res)
 
2397
bool JOIN::change_result(select_result *res)
2404
2398
{
2405
2399
  result= res;
2406
2400
  if (result->prepare(fields_list, select_lex->master_unit()))
2414
2408
  Cache constant expressions in WHERE, HAVING, ON conditions.
2415
2409
*/
2416
2410
 
2417
 
void Join::cache_const_exprs()
 
2411
void JOIN::cache_const_exprs()
2418
2412
{
2419
2413
  bool cache_flag= false;
2420
2414
  bool *analyzer_arg= &cache_flag;
2455
2449
  applicable to the partial record on hand and in case of success
2456
2450
  submit this record to the next level of the nested loop.
2457
2451
*/
2458
 
enum_nested_loop_state evaluate_join_record(Join *join, JoinTable *join_tab, int error)
 
2452
enum_nested_loop_state evaluate_join_record(JOIN *join, JoinTable *join_tab, int error)
2459
2453
{
2460
2454
  bool not_used_in_distinct= join_tab->not_used_in_distinct;
2461
2455
  ha_rows found_records= join->found_records;
2465
2459
    return NESTED_LOOP_ERROR;
2466
2460
  if (error < 0)
2467
2461
    return NESTED_LOOP_NO_MORE_ROWS;
2468
 
  if (join->session->getKilled())                       // Aborted by user
 
2462
  if (join->session->killed)                    // Aborted by user
2469
2463
  {
2470
2464
    join->session->send_kill_message();
2471
2465
    return NESTED_LOOP_KILLED;
2579
2573
    level of the nested loop. This function is used in case we have
2580
2574
    an OUTER join and no matching record was found.
2581
2575
*/
2582
 
enum_nested_loop_state evaluate_null_complemented_join_record(Join *join, JoinTable *join_tab)
 
2576
enum_nested_loop_state evaluate_null_complemented_join_record(JOIN *join, JoinTable *join_tab)
2583
2577
{
2584
2578
  /*
2585
2579
    The table join_tab is the first inner table of a outer join operation
2635
2629
  return (*join_tab->next_select)(join, join_tab+1, 0);
2636
2630
}
2637
2631
 
2638
 
enum_nested_loop_state flush_cached_records(Join *join, JoinTable *join_tab, bool skip_last)
 
2632
enum_nested_loop_state flush_cached_records(JOIN *join, JoinTable *join_tab, bool skip_last)
2639
2633
{
2640
2634
  enum_nested_loop_state rc= NESTED_LOOP_OK;
2641
2635
  int error;
2642
 
  ReadRecord *info;
 
2636
  READ_RECORD *info;
2643
2637
 
2644
2638
  join_tab->table->null_row= 0;
2645
2639
  if (!join_tab->cache.records)
2646
 
  {
2647
2640
    return NESTED_LOOP_OK;                      /* Nothing to do */
2648
 
  }
2649
 
 
2650
2641
  if (skip_last)
2651
 
  {
2652
 
    (void) join_tab->cache.store_record_in_cache(); // Must save this for later
2653
 
  }
2654
 
 
2655
 
 
 
2642
    (void) store_record_in_cache(&join_tab->cache); // Must save this for later
2656
2643
  if (join_tab->use_quick == 2)
2657
2644
  {
2658
2645
    if (join_tab->select->quick)
2664
2651
  /* read through all records */
2665
2652
  if ((error=join_init_read_record(join_tab)))
2666
2653
  {
2667
 
    join_tab->cache.reset_cache_write();
 
2654
    reset_cache_write(&join_tab->cache);
2668
2655
    return error < 0 ? NESTED_LOOP_NO_MORE_ROWS: NESTED_LOOP_ERROR;
2669
2656
  }
2670
2657
 
2677
2664
  info= &join_tab->read_record;
2678
2665
  do
2679
2666
  {
2680
 
    if (join->session->getKilled())
 
2667
    if (join->session->killed)
2681
2668
    {
2682
2669
      join->session->send_kill_message();
2683
2670
      return NESTED_LOOP_KILLED;
2687
2674
        (!join_tab->cache.select || !join_tab->cache.select->skip_record()))
2688
2675
    {
2689
2676
      uint32_t i;
2690
 
      join_tab->cache.reset_cache_read();
 
2677
      reset_cache_read(&join_tab->cache);
2691
2678
      for (i=(join_tab->cache.records- (skip_last ? 1 : 0)) ; i-- > 0 ;)
2692
2679
      {
2693
2680
              join_tab->readCachedRecord();
2698
2685
          rc= (join_tab->next_select)(join,join_tab+1,0);
2699
2686
          if (rc != NESTED_LOOP_OK && rc != NESTED_LOOP_NO_MORE_ROWS)
2700
2687
          {
2701
 
            join_tab->cache.reset_cache_write();
 
2688
            reset_cache_write(&join_tab->cache);
2702
2689
            return rc;
2703
2690
          }
2704
2691
 
2711
2698
 
2712
2699
  if (skip_last)
2713
2700
    join_tab->readCachedRecord();               // Restore current record
2714
 
  join_tab->cache.reset_cache_write();
 
2701
  reset_cache_write(&join_tab->cache);
2715
2702
  if (error > 0)                                // Fatal error
2716
2703
    return NESTED_LOOP_ERROR;
2717
2704
  for (JoinTable *tmp2=join->join_tab; tmp2 != join_tab ; tmp2++)
2743
2730
                               operation.
2744
2731
   All return values except NESTED_LOOP_OK abort the nested loop.
2745
2732
*****************************************************************************/
2746
 
enum_nested_loop_state end_send(Join *join, JoinTable *, bool end_of_records)
 
2733
enum_nested_loop_state end_send(JOIN *join, JoinTable *, bool end_of_records)
2747
2734
{
2748
2735
  if (! end_of_records)
2749
2736
  {
2805
2792
  return NESTED_LOOP_OK;
2806
2793
}
2807
2794
 
2808
 
enum_nested_loop_state end_write(Join *join, JoinTable *, bool end_of_records)
 
2795
enum_nested_loop_state end_write(JOIN *join, JoinTable *, bool end_of_records)
2809
2796
{
2810
2797
  Table *table= join->tmp_table;
2811
2798
 
2812
 
  if (join->session->getKilled())                       // Aborted by user
 
2799
  if (join->session->killed)                    // Aborted by user
2813
2800
  {
2814
2801
    join->session->send_kill_message();
2815
2802
    return NESTED_LOOP_KILLED;
2817
2804
  if (!end_of_records)
2818
2805
  {
2819
2806
    copy_fields(&join->tmp_table_param);
2820
 
    if (copy_funcs(join->tmp_table_param.items_to_copy, join->session))
2821
 
      return NESTED_LOOP_ERROR;
 
2807
    copy_funcs(join->tmp_table_param.items_to_copy);
2822
2808
    if (!join->having || join->having->val_int())
2823
2809
    {
2824
2810
      int error;
2825
2811
      join->found_records++;
2826
 
      if ((error=table->cursor->insertRecord(table->getInsertRecord())))
 
2812
      if ((error=table->cursor->ha_write_row(table->record[0])))
2827
2813
      {
2828
2814
        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
 
2815
          goto end;
 
2816
        if (create_myisam_from_heap(join->session, table,
 
2817
                                          join->tmp_table_param.start_recinfo,
 
2818
                                          &join->tmp_table_param.recinfo,
 
2819
                  error, 1))
 
2820
          return NESTED_LOOP_ERROR;        // Not a table_is_full error
 
2821
        table->s->uniques= 0;                   // To ensure rows are the same
2835
2822
      }
2836
2823
      if (++join->send_records >= join->tmp_table_param.end_write_records && join->do_send_rows)
2837
2824
      {
2843
2830
      }
2844
2831
    }
2845
2832
  }
2846
 
 
 
2833
end:
2847
2834
  return NESTED_LOOP_OK;
2848
2835
}
2849
2836
 
2850
2837
/** 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)
 
2838
enum_nested_loop_state end_update(JOIN *join, JoinTable *, bool end_of_records)
2852
2839
{
2853
2840
  Table *table= join->tmp_table;
2854
 
  Order *group;
 
2841
  order_st *group;
2855
2842
  int   error;
2856
2843
 
2857
2844
  if (end_of_records)
2858
2845
    return NESTED_LOOP_OK;
2859
 
  if (join->session->getKilled())                       // Aborted by user
 
2846
  if (join->session->killed)                    // Aborted by user
2860
2847
  {
2861
2848
    join->session->send_kill_message();
2862
2849
    return NESTED_LOOP_KILLED;
2873
2860
    if (item->maybe_null)
2874
2861
      group->buff[-1]= (char) group->field->is_null();
2875
2862
  }
2876
 
  if (!table->cursor->index_read_map(table->getUpdateRecord(),
 
2863
  if (!table->cursor->index_read_map(table->record[1],
2877
2864
                                   join->tmp_table_param.group_buff,
2878
2865
                                   HA_WHOLE_KEY,
2879
2866
                                   HA_READ_KEY_EXACT))
2880
2867
  {                                             /* Update old record */
2881
2868
    table->restoreRecord();
2882
2869
    update_tmptable_sum_func(join->sum_funcs,table);
2883
 
    if ((error= table->cursor->updateRecord(table->getUpdateRecord(),
2884
 
                                          table->getInsertRecord())))
 
2870
    if ((error= table->cursor->ha_update_row(table->record[1],
 
2871
                                          table->record[0])))
2885
2872
    {
2886
2873
      table->print_error(error,MYF(0));
2887
2874
      return NESTED_LOOP_ERROR;
2894
2881
    We can't copy all data as the key may have different format
2895
2882
    as the row data (for example as with VARCHAR keys)
2896
2883
  */
2897
 
  KeyPartInfo *key_part;
 
2884
  KEY_PART_INFO *key_part;
2898
2885
  for (group=table->group,key_part=table->key_info[0].key_part;
2899
2886
       group ;
2900
2887
       group=group->next,key_part++)
2901
2888
  {
2902
2889
    if (key_part->null_bit)
2903
 
      memcpy(table->getInsertRecord()+key_part->offset, group->buff, 1);
 
2890
      memcpy(table->record[0]+key_part->offset, group->buff, 1);
2904
2891
  }
2905
2892
  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())))
 
2893
  copy_funcs(join->tmp_table_param.items_to_copy);
 
2894
  if ((error=table->cursor->ha_write_row(table->record[0])))
2909
2895
  {
2910
 
    my_error(ER_USE_SQL_BIG_RESULT, MYF(0));
2911
 
    return NESTED_LOOP_ERROR;        // Table is_full error
 
2896
    if (create_myisam_from_heap(join->session, table,
 
2897
                                join->tmp_table_param.start_recinfo,
 
2898
                                &join->tmp_table_param.recinfo,
 
2899
                                error, 0))
 
2900
      return NESTED_LOOP_ERROR;            // Not a table_is_full error
 
2901
    /* Change method to update rows */
 
2902
    table->cursor->ha_index_init(0, 0);
 
2903
    join->join_tab[join->tables-1].next_select= end_unique_update;
2912
2904
  }
2913
2905
  join->send_records++;
2914
2906
  return NESTED_LOOP_OK;
2915
2907
}
2916
2908
 
2917
2909
/** 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)
 
2910
enum_nested_loop_state end_unique_update(JOIN *join, JoinTable *, bool end_of_records)
2919
2911
{
2920
2912
  Table *table= join->tmp_table;
2921
2913
  int   error;
2922
2914
 
2923
2915
  if (end_of_records)
2924
2916
    return NESTED_LOOP_OK;
2925
 
  if (join->session->getKilled())                       // Aborted by user
 
2917
  if (join->session->killed)                    // Aborted by user
2926
2918
  {
2927
2919
    join->session->send_kill_message();
2928
2920
    return NESTED_LOOP_KILLED;
2930
2922
 
2931
2923
  init_tmptable_sum_functions(join->sum_funcs);
2932
2924
  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;
 
2925
  copy_funcs(join->tmp_table_param.items_to_copy);
2935
2926
 
2936
 
  if (!(error= table->cursor->insertRecord(table->getInsertRecord())))
 
2927
  if (!(error= table->cursor->ha_write_row(table->record[0])))
2937
2928
    join->send_records++;                       // New group
2938
2929
  else
2939
2930
  {
2942
2933
      table->print_error(error,MYF(0));
2943
2934
      return NESTED_LOOP_ERROR;
2944
2935
    }
2945
 
    if (table->cursor->rnd_pos(table->getUpdateRecord(),table->cursor->dup_ref))
 
2936
    if (table->cursor->rnd_pos(table->record[1],table->cursor->dup_ref))
2946
2937
    {
2947
2938
      table->print_error(error,MYF(0));
2948
2939
      return NESTED_LOOP_ERROR;
2949
2940
    }
2950
2941
    table->restoreRecord();
2951
2942
    update_tmptable_sum_func(join->sum_funcs,table);
2952
 
    if ((error= table->cursor->updateRecord(table->getUpdateRecord(),
2953
 
                                          table->getInsertRecord())))
 
2943
    if ((error= table->cursor->ha_update_row(table->record[1],
 
2944
                                          table->record[0])))
2954
2945
    {
2955
2946
      table->print_error(error,MYF(0));
2956
2947
      return NESTED_LOOP_ERROR;
2971
2962
  @retval
2972
2963
    1   failed
2973
2964
*/
2974
 
static bool make_group_fields(Join *main_join, Join *curr_join)
 
2965
static bool make_group_fields(JOIN *main_join, JOIN *curr_join)
2975
2966
{
2976
2967
  if (main_join->group_fields_cache.elements)
2977
2968
  {
2990
2981
/**
2991
2982
  calc how big buffer we need for comparing group entries.
2992
2983
*/
2993
 
static void calc_group_buffer(Join *join, Order *group)
 
2984
static void calc_group_buffer(JOIN *join,order_st *group)
2994
2985
{
2995
2986
  uint32_t key_length=0, parts=0, null_parts=0;
2996
2987
 
3016
3007
      case REAL_RESULT:
3017
3008
        key_length+= sizeof(double);
3018
3009
        break;
3019
 
 
3020
3010
      case INT_RESULT:
3021
3011
        key_length+= sizeof(int64_t);
3022
3012
        break;
3023
 
 
3024
3013
      case DECIMAL_RESULT:
3025
3014
        key_length+= my_decimal_get_binary_size(group_item->max_length -
3026
3015
                                                (group_item->decimals ? 1 : 0),
3027
3016
                                                group_item->decimals);
3028
3017
        break;
3029
 
 
3030
3018
      case STRING_RESULT:
3031
 
        {
3032
 
          enum enum_field_types type= group_item->field_type();
 
3019
      {
 
3020
        enum enum_field_types type= group_item->field_type();
 
3021
        /*
 
3022
          As items represented as DATE/TIME fields in the group buffer
 
3023
          have STRING_RESULT result type, we increase the length
 
3024
          by 8 as maximum pack length of such fields.
 
3025
        */
 
3026
        if (type == DRIZZLE_TYPE_DATE ||
 
3027
            type == DRIZZLE_TYPE_DATETIME ||
 
3028
            type == DRIZZLE_TYPE_TIMESTAMP)
 
3029
        {
 
3030
          key_length+= 8;
 
3031
        }
 
3032
        else
 
3033
        {
3033
3034
          /*
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.
 
3035
            Group strings are taken as varstrings and require an length field.
 
3036
            A field is not yet created by create_tmp_field()
 
3037
            and the sizes should match up.
3037
3038
          */
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;
 
3039
          key_length+= group_item->max_length + HA_KEY_BLOB_LENGTH;
3054
3040
        }
3055
 
 
3056
 
      case ROW_RESULT:
 
3041
        break;
 
3042
      }
 
3043
      default:
3057
3044
        /* This case should never be choosen */
3058
3045
        assert(0);
3059
3046
        my_error(ER_OUT_OF_RESOURCES, MYF(ME_FATALERROR));
3060
3047
      }
3061
3048
    }
3062
 
 
3063
3049
    parts++;
3064
 
 
3065
3050
    if (group_item->maybe_null)
3066
3051
      null_parts++;
3067
3052
  }
3068
 
 
3069
3053
  join->tmp_table_param.group_length=key_length+null_parts;
3070
3054
  join->tmp_table_param.group_parts=parts;
3071
3055
  join->tmp_table_param.group_null_parts=null_parts;
3076
3060
 
3077
3061
  Groups are saved in reverse order for easyer check loop.
3078
3062
*/
3079
 
static bool alloc_group_fields(Join *join, Order *group)
 
3063
static bool alloc_group_fields(JOIN *join,order_st *group)
3080
3064
{
3081
3065
  if (group)
3082
3066
  {
3091
3075
  return false;
3092
3076
}
3093
3077
 
3094
 
static uint32_t cache_record_length(Join *join,uint32_t idx)
 
3078
static uint32_t cache_record_length(JOIN *join,uint32_t idx)
3095
3079
{
3096
3080
  uint32_t length=0;
3097
3081
  JoinTable **pos,**end;
3159
3143
  RETURN
3160
3144
    Expected number of row combinations
3161
3145
*/
3162
 
static double prev_record_reads(Join *join, uint32_t idx, table_map found_ref)
 
3146
static double prev_record_reads(JOIN *join, uint32_t idx, table_map found_ref)
3163
3147
{
3164
3148
  double found=1.0;
3165
3149
  optimizer::Position *pos_end= join->getSpecificPosInPartialPlan(-1);
3171
3155
    {
3172
3156
      found_ref|= pos->getRefDependMap();
3173
3157
      /*
3174
 
        For the case of "t1 LEFT Join t2 ON ..." where t2 is a const table
 
3158
        For the case of "t1 LEFT JOIN t2 ON ..." where t2 is a const table
3175
3159
        with no matching row we will get position[t2].records_read==0.
3176
3160
        Actually the size of output is one null-complemented row, therefore
3177
3161
        we will use value of 1 whenever we get records_read==0.
3196
3180
/**
3197
3181
  Set up join struct according to best position.
3198
3182
*/
3199
 
static bool get_best_combination(Join *join)
 
3183
static bool get_best_combination(JOIN *join)
3200
3184
{
3201
3185
  uint32_t i,tablenr;
3202
3186
  table_map used_tables;
3223
3207
    used_tables|= form->map;
3224
3208
    form->reginfo.join_tab=j;
3225
3209
    if (!*j->on_expr_ref)
3226
 
      form->reginfo.not_exists_optimize=0;  // Only with LEFT Join
 
3210
      form->reginfo.not_exists_optimize=0;  // Only with LEFT JOIN
3227
3211
    if (j->type == AM_CONST)
3228
3212
      continue;         // Handled in make_join_stat..
3229
3213
 
3249
3233
}
3250
3234
 
3251
3235
/** Save const tables first as used tables. */
3252
 
static void set_position(Join *join,
 
3236
static void set_position(JOIN *join,
3253
3237
                         uint32_t idx,
3254
3238
                         JoinTable *table,
3255
3239
                         optimizer::KeyUse *key)
3291
3275
  @retval
3292
3276
    true        Fatal error
3293
3277
*/
3294
 
static bool choose_plan(Join *join, table_map join_tables)
 
3278
static bool choose_plan(JOIN *join, table_map join_tables)
3295
3279
{
3296
3280
  uint32_t search_depth= join->session->variables.optimizer_search_depth;
3297
3281
  uint32_t prune_level=  join->session->variables.optimizer_prune_level;
3307
3291
      Apply heuristic: pre-sort all access plans with respect to the number of
3308
3292
      records accessed.
3309
3293
  */
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);
 
3294
  my_qsort(join->best_ref + join->const_tables,
 
3295
           join->tables - join->const_tables, sizeof(JoinTable*),
 
3296
           straight_join ? join_tab_cmp_straight : join_tab_cmp);
3313
3297
  if (straight_join)
3314
3298
  {
3315
3299
    optimize_straight_join(join, join_tables);
3358
3342
  @return
3359
3343
    None
3360
3344
*/
3361
 
static void best_access_path(Join *join,
 
3345
static void best_access_path(JOIN *join,
3362
3346
                             JoinTable *s,
3363
3347
                             Session *session,
3364
3348
                             table_map remaining_tables,
3391
3375
      key_part_map found_part= 0;
3392
3376
      table_map found_ref= 0;
3393
3377
      uint32_t key= keyuse->getKey();
3394
 
      KeyInfo *keyinfo= table->key_info + key;
 
3378
      KEY *keyinfo= table->key_info + key;
3395
3379
      /* Bitmap of keyparts where the ref access is over 'keypart=const': */
3396
3380
      key_part_map const_part= 0;
3397
3381
      /* The or-null keypart in ref-or-null access: */
3504
3488
                records=
3505
3489
                  ((double) s->records / (double) rec *
3506
3490
                   (1.0 +
3507
 
                    ((double) (table->getShare()->max_key_length-keyinfo->key_length) /
3508
 
                     (double) table->getShare()->max_key_length)));
 
3491
                    ((double) (table->s->max_key_length-keyinfo->key_length) /
 
3492
                     (double) table->s->max_key_length)));
3509
3493
                if (records < 2.0)
3510
3494
                  records=2.0;               /* Can't be as good as a unique */
3511
3495
              }
3888
3872
    Thus 'optimize_straight_join' can be used at any stage of the query
3889
3873
    optimization process to finalize a QEP as it is.
3890
3874
*/
3891
 
static void optimize_straight_join(Join *join, table_map join_tables)
 
3875
static void optimize_straight_join(JOIN *join, table_map join_tables)
3892
3876
{
3893
3877
  JoinTable *s;
3894
3878
  optimizer::Position partial_pos;
3998
3982
  @retval
3999
3983
    true        Fatal error
4000
3984
*/
4001
 
static bool greedy_search(Join      *join,
 
3985
static bool greedy_search(JOIN      *join,
4002
3986
              table_map remaining_tables,
4003
3987
              uint32_t      search_depth,
4004
3988
              uint32_t      prune_level)
4012
3996
  JoinTable  *best_table; // the next plan node to be added to the curr QEP
4013
3997
 
4014
3998
  /* number of tables that remain to be optimized */
4015
 
  size_remain= internal::my_count_bits(remaining_tables);
 
3999
  size_remain= my_count_bits(remaining_tables);
4016
4000
 
4017
4001
  do {
4018
4002
    /* Find the extension of the current QEP with the lowest cost */
4040
4024
    */
4041
4025
    join->setPosInPartialPlan(idx, best_pos);
4042
4026
 
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
4027
    /* find the position of 'best_table' in 'join->best_ref' */
4053
4028
    best_idx= idx;
4054
4029
    JoinTable *pos= join->best_ref[best_idx];
4186
4161
  @retval
4187
4162
    true        Fatal error
4188
4163
*/
4189
 
static bool best_extension_by_limited_search(Join *join,
 
4164
static bool best_extension_by_limited_search(JOIN *join,
4190
4165
                                             table_map remaining_tables,
4191
4166
                                             uint32_t idx,
4192
4167
                                             double record_count,
4195
4170
                                             uint32_t prune_level)
4196
4171
{
4197
4172
  Session *session= join->session;
4198
 
  if (session->getKilled())  // Abort
 
4173
  if (session->killed)  // Abort
4199
4174
    return(true);
4200
4175
 
4201
4176
  /*
4210
4185
  for (JoinTable **pos= join->best_ref + idx ; (s= *pos) ; pos++)
4211
4186
  {
4212
4187
    table_map real_table_bit= s->table->map;
 
4188
    if (idx)
 
4189
    {
 
4190
      partial_pos= join->getPosFromPartialPlan(idx - 1);
 
4191
    }
4213
4192
    if ((remaining_tables & real_table_bit) &&
4214
4193
        ! (remaining_tables & s->dependent) &&
4215
 
        (! idx || ! check_interleaving_with_nj(s)))
 
4194
        (! idx || ! check_interleaving_with_nj(partial_pos.getJoinTable(), s)))
4216
4195
    {
4217
4196
      double current_record_count, current_read_time;
4218
4197
 
4333
4312
    exhaustiveness) of the depth-first search algorithm used by
4334
4313
    'greedy_search'.
4335
4314
*/
4336
 
static uint32_t determine_search_depth(Join *join)
 
4315
static uint32_t determine_search_depth(JOIN *join)
4337
4316
{
4338
4317
  uint32_t table_count=  join->tables - join->const_tables;
4339
4318
  uint32_t search_depth;
4352
4331
  return search_depth;
4353
4332
}
4354
4333
 
4355
 
static bool make_simple_join(Join *join,Table *tmp_table)
 
4334
static bool make_simple_join(JOIN *join,Table *tmp_table)
4356
4335
{
4357
4336
  Table **tableptr;
4358
4337
  JoinTable *join_tab;
4359
4338
 
4360
4339
  /*
4361
4340
    Reuse Table * and JoinTable if already allocated by a previous call
4362
 
    to this function through Join::exec (may happen for sub-queries).
 
4341
    to this function through JOIN::exec (may happen for sub-queries).
4363
4342
  */
4364
4343
  if (!join->table_reexec)
4365
4344
  {
4409
4388
  join_tab->read_first_record= join_init_read_record;
4410
4389
  join_tab->join=join;
4411
4390
  join_tab->ref.key_parts= 0;
4412
 
  join_tab->read_record.init();
 
4391
  memset(&join_tab->read_record, 0, sizeof(join_tab->read_record));
4413
4392
  tmp_table->status=0;
4414
4393
  tmp_table->null_row=0;
4415
 
 
4416
 
  return false;
 
4394
  return(false);
4417
4395
}
4418
4396
 
4419
4397
/**
4457
4435
    This function can be called only after the execution plan
4458
4436
    has been chosen.
4459
4437
*/
4460
 
static void make_outerjoin_info(Join *join)
 
4438
static void make_outerjoin_info(JOIN *join)
4461
4439
{
4462
4440
  for (uint32_t i=join->const_tables ; i < join->tables ; i++)
4463
4441
  {
4464
4442
    JoinTable *tab=join->join_tab+i;
4465
4443
    Table *table=tab->table;
4466
4444
    TableList *tbl= table->pos_in_table_list;
4467
 
    TableList *embedding= tbl->getEmbedding();
 
4445
    TableList *embedding= tbl->embedding;
4468
4446
 
4469
4447
    if (tbl->outer_join)
4470
4448
    {
4477
4455
      tab->on_expr_ref= &tbl->on_expr;
4478
4456
      tab->cond_equal= tbl->cond_equal;
4479
4457
      if (embedding)
4480
 
        tab->first_upper= embedding->getNestedJoin()->first_nested;
 
4458
        tab->first_upper= embedding->nested_join->first_nested;
4481
4459
    }
4482
 
    for ( ; embedding ; embedding= embedding->getEmbedding())
 
4460
    for ( ; embedding ; embedding= embedding->embedding)
4483
4461
    {
4484
4462
      /* Ignore sj-nests: */
4485
4463
      if (!embedding->on_expr)
4486
4464
        continue;
4487
 
      nested_join_st *nested_join= embedding->getNestedJoin();
 
4465
      nested_join_st *nested_join= embedding->nested_join;
4488
4466
      if (!nested_join->counter_)
4489
4467
      {
4490
4468
        /*
4494
4472
        nested_join->first_nested= tab;
4495
4473
        tab->on_expr_ref= &embedding->on_expr;
4496
4474
        tab->cond_equal= tbl->cond_equal;
4497
 
        if (embedding->getEmbedding())
4498
 
          tab->first_upper= embedding->getEmbedding()->getNestedJoin()->first_nested;
 
4475
        if (embedding->embedding)
 
4476
          tab->first_upper= embedding->embedding->nested_join->first_nested;
4499
4477
      }
4500
4478
      if (!tab->first_inner)
4501
4479
        tab->first_inner= nested_join->first_nested;
4508
4486
  return;
4509
4487
}
4510
4488
 
4511
 
static bool make_join_select(Join *join,
 
4489
static bool make_join_select(JOIN *join,
4512
4490
                             optimizer::SqlSelect *select,
4513
4491
                             COND *cond)
4514
4492
{
4886
4864
    false - OK
4887
4865
    true  - Out of memory
4888
4866
*/
4889
 
static bool make_join_readinfo(Join *join)
 
4867
static bool make_join_readinfo(JOIN *join, uint64_t options, uint32_t no_jbuf_after)
4890
4868
{
4891
 
  bool sorted= true;
 
4869
  uint32_t i;
 
4870
  bool statistics= test(!(join->select_options & SELECT_DESCRIBE));
 
4871
  bool sorted= 1;
4892
4872
 
4893
 
  for (uint32_t i= join->const_tables ; i < join->tables ; i++)
 
4873
  for (i=join->const_tables ; i < join->tables ; i++)
4894
4874
  {
4895
4875
    JoinTable *tab=join->join_tab+i;
4896
4876
    Table *table=tab->table;
 
4877
    bool using_join_cache;
4897
4878
    tab->read_record.table= table;
4898
4879
    tab->read_record.cursor= table->cursor;
4899
4880
    tab->next_select=sub_select;                /* normal select */
4902
4883
      produce sorted output.
4903
4884
    */
4904
4885
    tab->sorted= sorted;
4905
 
    sorted= false; // only first must be sorted
4906
 
 
 
4886
    sorted= 0;                                  // only first must be sorted
4907
4887
    if (tab->insideout_match_tab)
4908
4888
    {
4909
 
      if (! (tab->insideout_buf= (unsigned char*) join->session->alloc(tab->table->key_info
4910
 
                                                                       [tab->index].
4911
 
                                                                       key_length)))
 
4889
      if (!(tab->insideout_buf= (unsigned char*)join->session->alloc(tab->table->key_info
 
4890
                                                         [tab->index].
 
4891
                                                         key_length)))
4912
4892
        return true;
4913
4893
    }
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
 
       */
 
4894
    switch (tab->type) {
 
4895
    case AM_SYSTEM:                             // Only happens with left join
 
4896
      table->status=STATUS_NO_RECORD;
 
4897
      tab->read_first_record= join_read_system;
 
4898
      tab->read_record.read_record= join_no_more_records;
 
4899
      break;
 
4900
    case AM_CONST:                              // Only happens with left join
 
4901
      table->status=STATUS_NO_RECORD;
 
4902
      tab->read_first_record= join_read_const;
 
4903
      tab->read_record.read_record= join_no_more_records;
 
4904
      if (table->covering_keys.test(tab->ref.key) &&
 
4905
          !table->no_keyread)
 
4906
      {
 
4907
        table->key_read=1;
 
4908
        table->cursor->extra(HA_EXTRA_KEYREAD);
 
4909
      }
 
4910
      break;
 
4911
    case AM_EQ_REF:
 
4912
      table->status=STATUS_NO_RECORD;
 
4913
      if (tab->select)
 
4914
      {
 
4915
        delete tab->select->quick;
 
4916
        tab->select->quick=0;
 
4917
      }
 
4918
      delete tab->quick;
 
4919
      tab->quick=0;
 
4920
      tab->read_first_record= join_read_key;
 
4921
      tab->read_record.read_record= join_no_more_records;
 
4922
      if (table->covering_keys.test(tab->ref.key) && !table->no_keyread)
 
4923
      {
 
4924
        table->key_read=1;
 
4925
        table->cursor->extra(HA_EXTRA_KEYREAD);
 
4926
      }
 
4927
      break;
 
4928
    case AM_REF_OR_NULL:
 
4929
    case AM_REF:
 
4930
      table->status=STATUS_NO_RECORD;
 
4931
      if (tab->select)
 
4932
      {
 
4933
        delete tab->select->quick;
 
4934
        tab->select->quick=0;
 
4935
      }
 
4936
      delete tab->quick;
 
4937
      tab->quick=0;
 
4938
      if (table->covering_keys.test(tab->ref.key) && !table->no_keyread)
 
4939
      {
 
4940
        table->key_read=1;
 
4941
        table->cursor->extra(HA_EXTRA_KEYREAD);
 
4942
      }
 
4943
      if (tab->type == AM_REF)
 
4944
      {
 
4945
        tab->read_first_record= join_read_always_key;
 
4946
        tab->read_record.read_record= tab->insideout_match_tab?
 
4947
           join_read_next_same_diff : join_read_next_same;
 
4948
      }
 
4949
      else
 
4950
      {
 
4951
        tab->read_first_record= join_read_always_key_or_null;
 
4952
        tab->read_record.read_record= join_read_next_same_or_null;
 
4953
      }
 
4954
      break;
 
4955
    case AM_ALL:
 
4956
      /*
 
4957
        If previous table use cache
 
4958
        If the incoming data set is already sorted don't use cache.
 
4959
      */
 
4960
      table->status=STATUS_NO_RECORD;
 
4961
      using_join_cache= false;
 
4962
      if (i != join->const_tables && !(options & SELECT_NO_JOIN_CACHE) &&
 
4963
          tab->use_quick != 2 && !tab->first_inner && i <= no_jbuf_after &&
 
4964
          !tab->insideout_match_tab)
 
4965
      {
 
4966
        if ((options & SELECT_DESCRIBE) ||
 
4967
            !join_init_cache(join->session,join->join_tab+join->const_tables,
 
4968
                i-join->const_tables))
 
4969
        {
 
4970
                using_join_cache= true;
 
4971
          tab[-1].next_select=sub_select_cache; /* Patch previous */
 
4972
        }
 
4973
      }
 
4974
      /* These init changes read_record */
 
4975
      if (tab->use_quick == 2)
 
4976
      {
 
4977
        join->session->server_status|=SERVER_QUERY_NO_GOOD_INDEX_USED;
 
4978
        tab->read_first_record= join_init_quick_read_record;
 
4979
        if (statistics)
 
4980
          status_var_increment(join->session->status_var.select_range_check_count);
 
4981
      }
 
4982
      else
 
4983
      {
 
4984
        tab->read_first_record= join_init_read_record;
 
4985
        if (i == join->const_tables)
 
4986
        {
 
4987
          if (tab->select && tab->select->quick)
 
4988
          {
 
4989
            if (statistics)
 
4990
              status_var_increment(join->session->status_var.select_range_count);
 
4991
          }
 
4992
          else
 
4993
          {
 
4994
            join->session->server_status|=SERVER_QUERY_NO_INDEX_USED;
 
4995
            if (statistics)
 
4996
              status_var_increment(join->session->status_var.select_scan_count);
 
4997
          }
 
4998
        }
 
4999
        else
 
5000
        {
 
5001
          if (tab->select && tab->select->quick)
 
5002
          {
 
5003
            if (statistics)
 
5004
              status_var_increment(join->session->status_var.select_full_range_join_count);
 
5005
          }
 
5006
          else
 
5007
          {
 
5008
            join->session->server_status|=SERVER_QUERY_NO_INDEX_USED;
 
5009
            if (statistics)
 
5010
              status_var_increment(join->session->status_var.select_full_join_count);
 
5011
          }
 
5012
        }
 
5013
        if (!table->no_keyread)
 
5014
        {
 
5015
          if (tab->select && tab->select->quick &&
 
5016
                    tab->select->quick->index != MAX_KEY && //not index_merge
 
5017
              table->covering_keys.test(tab->select->quick->index))
 
5018
          {
 
5019
            table->key_read=1;
 
5020
            table->cursor->extra(HA_EXTRA_KEYREAD);
 
5021
          }
 
5022
          else if (!table->covering_keys.none() &&
 
5023
            !(tab->select && tab->select->quick))
 
5024
          {                                     // Only read index tree
 
5025
                  if (!tab->insideout_match_tab)
 
5026
                  {
 
5027
                    /*
 
5028
                      See bug #26447: "Using the clustered index for a table scan
 
5029
                      is always faster than using a secondary index".
 
5030
                    */
 
5031
                    if (table->s->primary_key != MAX_KEY &&
 
5032
                        table->cursor->primary_key_is_clustered())
 
5033
                      tab->index= table->s->primary_key;
 
5034
                    else
 
5035
                      tab->index= table->find_shortest_key(&table->covering_keys);
 
5036
                  }
 
5037
            tab->read_first_record= join_read_first;
 
5038
            tab->type= AM_NEXT;         // Read with index_first / index_next
 
5039
          }
 
5040
        }
 
5041
      }
 
5042
      break;
 
5043
    default:
 
5044
      break;
 
5045
    case AM_UNKNOWN:
 
5046
    case AM_MAYBE_REF:
4925
5047
      abort();
4926
5048
    }
4927
 
 
4928
 
    access_method->getStats(table, tab);
4929
5049
  }
4930
 
 
4931
 
  join->join_tab[join->tables-1].next_select= NULL; /* Set by do_select */
4932
 
 
4933
 
  return false;
 
5050
  join->join_tab[join->tables-1].next_select=0; /* Set by do_select */
 
5051
  return(false);
4934
5052
}
4935
5053
 
4936
5054
/** Update the dependency map for the tables. */
4937
 
static void update_depend_map(Join *join)
 
5055
static void update_depend_map(JOIN *join)
4938
5056
{
4939
5057
  JoinTable *join_tab=join->join_tab, *end=join_tab+join->tables;
4940
5058
 
4957
5075
}
4958
5076
 
4959
5077
/** Update the dependency map for the sort order. */
4960
 
static void update_depend_map(Join *join, Order *order)
 
5078
static void update_depend_map(JOIN *join, order_st *order)
4961
5079
{
4962
5080
  for (; order ; order=order->next)
4963
5081
  {
4995
5113
  @return
4996
5114
    Returns new sort order
4997
5115
*/
4998
 
static Order *remove_constants(Join *join,Order *first_order, COND *cond, bool change_list, bool *simple_order)
 
5116
static order_st *remove_constants(JOIN *join,order_st *first_order, COND *cond, bool change_list, bool *simple_order)
4999
5117
{
5000
5118
  if (join->tables == join->const_tables)
5001
5119
    return change_list ? 0 : first_order;               // No need to sort
5002
5120
 
5003
 
  Order *order,**prev_ptr;
 
5121
  order_st *order,**prev_ptr;
5004
5122
  table_map first_table= join->join_tab[join->const_tables].table->map;
5005
5123
  table_map not_const_tables= ~join->const_table_map;
5006
5124
  table_map ref;
5055
5173
  return(first_order);
5056
5174
}
5057
5175
 
5058
 
static int return_zero_rows(Join *join,
 
5176
static int return_zero_rows(JOIN *join,
5059
5177
                            select_result *result,
5060
5178
                            TableList *tables,
5061
5179
                                        List<Item> &fields,
5221
5339
    - The new condition, if success
5222
5340
    - 0, otherwise
5223
5341
*/
5224
 
static COND *simplify_joins(Join *join, List<TableList> *join_list, COND *conds, bool top)
 
5342
static COND *simplify_joins(JOIN *join, List<TableList> *join_list, COND *conds, bool top)
5225
5343
{
5226
5344
  TableList *table;
5227
5345
  nested_join_st *nested_join;
5237
5355
    table_map used_tables;
5238
5356
    table_map not_null_tables= (table_map) 0;
5239
5357
 
5240
 
    if ((nested_join= table->getNestedJoin()))
 
5358
    if ((nested_join= table->nested_join))
5241
5359
    {
5242
5360
      /*
5243
5361
         If the element of join_list is a nested join apply
5279
5397
        not_null_tables= conds->not_null_tables();
5280
5398
    }
5281
5399
 
5282
 
    if (table->getEmbedding())
 
5400
    if (table->embedding)
5283
5401
    {
5284
 
      table->getEmbedding()->getNestedJoin()->used_tables|= used_tables;
5285
 
      table->getEmbedding()->getNestedJoin()->not_null_tables|= not_null_tables;
 
5402
      table->embedding->nested_join->used_tables|= used_tables;
 
5403
      table->embedding->nested_join->not_null_tables|= not_null_tables;
5286
5404
    }
5287
5405
 
5288
5406
    if (!table->outer_join || (used_tables & not_null_tables))
5318
5436
    */
5319
5437
    if (table->on_expr)
5320
5438
    {
5321
 
      table->setDepTables(table->getDepTables() | table->on_expr->used_tables());
5322
 
      if (table->getEmbedding())
 
5439
      table->dep_tables|= table->on_expr->used_tables();
 
5440
      if (table->embedding)
5323
5441
      {
5324
 
        table->setDepTables(table->getDepTables() & ~table->getEmbedding()->getNestedJoin()->used_tables);
 
5442
        table->dep_tables&= ~table->embedding->nested_join->used_tables;
5325
5443
        /*
5326
5444
           Embedding table depends on tables used
5327
5445
           in embedded on expressions.
5328
5446
        */
5329
 
        table->getEmbedding()->setOnExprDepTables(table->getEmbedding()->getOnExprDepTables() & table->on_expr->used_tables());
 
5447
        table->embedding->on_expr_dep_tables|= table->on_expr->used_tables();
5330
5448
      }
5331
5449
      else
5332
 
        table->setDepTables(table->getDepTables() & ~table->table->map);
 
5450
        table->dep_tables&= ~table->table->map;
5333
5451
    }
5334
5452
 
5335
5453
    if (prev_table)
5336
5454
    {
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);
 
5455
      /* The order of tables is reverse: prev_table follows table */
 
5456
      if (prev_table->straight)
 
5457
        prev_table->dep_tables|= used_tables;
5342
5458
      if (prev_table->on_expr)
5343
5459
      {
5344
 
        prev_table->setDepTables(prev_table->getDepTables() | table->getOnExprDepTables());
5345
 
        table_map prev_used_tables= prev_table->getNestedJoin() ?
5346
 
                                    prev_table->getNestedJoin()->used_tables :
 
5460
        prev_table->dep_tables|= table->on_expr_dep_tables;
 
5461
        table_map prev_used_tables= prev_table->nested_join ?
 
5462
                                    prev_table->nested_join->used_tables :
5347
5463
                                    prev_table->table->map;
5348
5464
        /*
5349
5465
          If on expression contains only references to inner tables
5352
5468
          for them. Yet this is really a rare case.
5353
5469
              */
5354
5470
        if (!(prev_table->on_expr->used_tables() & ~prev_used_tables))
5355
 
          prev_table->setDepTables(prev_table->getDepTables() | used_tables);
 
5471
          prev_table->dep_tables|= used_tables;
5356
5472
      }
5357
5473
    }
5358
5474
    prev_table= table;
5365
5481
  li.rewind();
5366
5482
  while ((table= li++))
5367
5483
  {
5368
 
    nested_join= table->getNestedJoin();
 
5484
    nested_join= table->nested_join;
5369
5485
    if (nested_join && !table->on_expr)
5370
5486
    {
5371
5487
      TableList *tbl;
5372
5488
      List_iterator<TableList> it(nested_join->join_list);
5373
5489
      while ((tbl= it++))
5374
5490
      {
5375
 
        tbl->setEmbedding(table->getEmbedding());
5376
 
        tbl->setJoinList(table->getJoinList());
 
5491
        tbl->embedding= table->embedding;
 
5492
        tbl->join_list= table->join_list;
5377
5493
      }
5378
5494
      li.replace(nested_join->join_list);
5379
5495
    }
5381
5497
  return(conds);
5382
5498
}
5383
5499
 
5384
 
static int remove_duplicates(Join *join, Table *entry,List<Item> &fields, Item *having)
 
5500
static int remove_duplicates(JOIN *join, Table *entry,List<Item> &fields, Item *having)
5385
5501
{
5386
5502
  int error;
5387
5503
  uint32_t reclength,offset;
5405
5521
    join->unit->select_limit_cnt= 1;            // Only send first row
5406
5522
    return(0);
5407
5523
  }
5408
 
  Field **first_field=entry->getFields() + entry->getShare()->sizeFields() - field_count;
 
5524
  Field **first_field=entry->field+entry->s->fields - field_count;
5409
5525
  offset= (field_count ?
5410
 
           entry->getField(entry->getShare()->sizeFields() - field_count)->offset(entry->getInsertRecord()) : 0);
5411
 
  reclength= entry->getShare()->getRecordLength() - offset;
 
5526
           entry->field[entry->s->fields - field_count]->
 
5527
           offset(entry->record[0]) : 0);
 
5528
  reclength= entry->s->reclength-offset;
5412
5529
 
5413
5530
  entry->free_io_cache();                               // Safety
5414
5531
  entry->cursor->info(HA_STATUS_VARIABLE);
5415
 
  if (entry->getShare()->db_type() == heap_engine ||
5416
 
      (!entry->getShare()->blob_fields &&
 
5532
  if (entry->s->db_type() == heap_engine ||
 
5533
      (!entry->s->blob_fields &&
5417
5534
       ((ALIGN_SIZE(reclength) + HASH_OVERHEAD) * entry->cursor->stats.records <
5418
 
        session->variables.sortbuff_size)))
5419
 
  {
 
5535
        session->variables.sortbuff_size)))
5420
5536
    error= remove_dup_with_hash_index(join->session, entry,
5421
 
                                      field_count, first_field,
5422
 
                                      reclength, having);
5423
 
  }
 
5537
                                     field_count, first_field,
 
5538
                                     reclength, having);
5424
5539
  else
5425
 
  {
5426
 
    error= remove_dup_with_compare(join->session, entry, first_field, offset, having);
5427
 
  }
 
5540
    error= remove_dup_with_compare(join->session, entry, first_field, offset,
 
5541
                                  having);
5428
5542
 
5429
5543
  free_blobs(first_field);
5430
 
 
5431
5544
  return(error);
5432
5545
}
5433
5546
 
5441
5554
                               List<Item> &fields,
5442
5555
                               List<Item> &all_fields,
5443
5556
                               COND **conds,
5444
 
                               Order *order,
5445
 
                               Order *group,
 
5557
                               order_st *order,
 
5558
                               order_st *group,
5446
5559
                               bool *hidden_group_fields)
5447
5560
{
5448
5561
  int res;
5469
5582
  @retval
5470
5583
    1   Fatal error
5471
5584
*/
5472
 
static bool make_join_statistics(Join *join, TableList *tables, COND *conds, DYNAMIC_ARRAY *keyuse_array)
 
5585
static bool make_join_statistics(JOIN *join, TableList *tables, COND *conds, DYNAMIC_ARRAY *keyuse_array)
5473
5586
{
5474
5587
  int error;
5475
5588
  Table *table;
5512
5625
       tables;
5513
5626
       s++, tables= tables->next_leaf, i++)
5514
5627
  {
5515
 
    TableList *embedding= tables->getEmbedding();
 
5628
    TableList *embedding= tables->embedding;
5516
5629
    stat_vector[i]=s;
5517
5630
    s->keys.reset();
5518
5631
    s->const_keys.reset();
5520
5633
    s->needed_reg.reset();
5521
5634
    table_vector[i]=s->table=table=tables->table;
5522
5635
    table->pos_in_table_list= tables;
5523
 
    assert(table->cursor);
5524
5636
    error= table->cursor->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
5525
5637
    if (error)
5526
5638
    {
5531
5643
    table->reginfo.join_tab=s;
5532
5644
    table->reginfo.not_exists_optimize=0;
5533
5645
    memset(table->const_key_parts, 0,
5534
 
           sizeof(key_part_map)*table->getShare()->sizeKeys());
 
5646
           sizeof(key_part_map)*table->s->keys);
5535
5647
    all_table_map|= table->map;
5536
5648
    s->join=join;
5537
5649
    s->info=0;                                  // For describe
5538
5650
 
5539
 
    s->dependent= tables->getDepTables();
 
5651
    s->dependent= tables->dep_tables;
5540
5652
    s->key_dependent= 0;
5541
5653
    table->quick_condition_rows= table->cursor->stats.records;
5542
5654
 
5552
5664
      }
5553
5665
      outer_join|= table->map;
5554
5666
      s->embedding_map.reset();
5555
 
      for (;embedding; embedding= embedding->getEmbedding())
5556
 
        s->embedding_map|= embedding->getNestedJoin()->nj_map;
 
5667
      for (;embedding; embedding= embedding->embedding)
 
5668
        s->embedding_map|= embedding->nested_join->nj_map;
5557
5669
      continue;
5558
5670
    }
5559
 
    if (embedding && !(false && ! embedding->getEmbedding()))
 
5671
    if (embedding && !(false && ! embedding->embedding))
5560
5672
    {
5561
5673
      /* s belongs to a nested join, maybe to several embedded joins */
5562
5674
      s->embedding_map.reset();
5563
5675
      do
5564
5676
      {
5565
 
        nested_join_st *nested_join= embedding->getNestedJoin();
 
5677
        nested_join_st *nested_join= embedding->nested_join;
5566
5678
        s->embedding_map|= nested_join->nj_map;
5567
 
        s->dependent|= embedding->getDepTables();
5568
 
        embedding= embedding->getEmbedding();
 
5679
        s->dependent|= embedding->dep_tables;
 
5680
        embedding= embedding->embedding;
5569
5681
        outer_join|= nested_join->used_tables;
5570
5682
      }
5571
5683
      while (embedding);
5699
5811
          continue;
5700
5812
        if (table->cursor->stats.records <= 1L &&
5701
5813
            (table->cursor->getEngine()->check_flag(HTON_BIT_STATS_RECORDS_IS_EXACT)) &&
5702
 
                  !table->pos_in_table_list->getEmbedding())
 
5814
                  !table->pos_in_table_list->embedding)
5703
5815
        {                                       // system table
5704
5816
          int tmp= 0;
5705
5817
          s->type= AM_SYSTEM;
5744
5856
          } while (keyuse->getTable() == table && keyuse->getKey() == key);
5745
5857
 
5746
5858
          if (is_keymap_prefix(eq_part, table->key_info[key].key_parts) &&
5747
 
              ! table->pos_in_table_list->getEmbedding())
 
5859
              ! table->pos_in_table_list->embedding)
5748
5860
          {
5749
5861
            if ((table->key_info[key].flags & (HA_NOSAME)) == HA_NOSAME)
5750
5862
            {
5788
5900
    while (iter != sargables.end())
5789
5901
    {
5790
5902
      Field *field= (*iter).getField();
5791
 
      JoinTable *join_tab= field->getTable()->reginfo.join_tab;
 
5903
      JoinTable *join_tab= field->table->reginfo.join_tab;
5792
5904
      key_map possible_keys= field->key_start;
5793
 
      possible_keys&= field->getTable()->keys_in_use_for_query;
 
5905
      possible_keys&= field->table->keys_in_use_for_query;
5794
5906
      bool is_const= true;
5795
5907
      for (uint32_t j= 0; j < (*iter).getNumValues(); j++)
5796
5908
        is_const&= (*iter).isConstItem(j);
5831
5943
    add_group_and_distinct_keys(join, s);
5832
5944
 
5833
5945
    if (s->const_keys.any() &&
5834
 
        !s->table->pos_in_table_list->getEmbedding())
 
5946
        !s->table->pos_in_table_list->embedding)
5835
5947
    {
5836
5948
      ha_rows records;
5837
5949
      optimizer::SqlSelect *select= NULL;
5881
5993
  if (join->const_tables != join->tables)
5882
5994
  {
5883
5995
    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);
 
5996
    DRIZZLE_QUERY_OPT_CHOOSE_PLAN_START(join->session->query, join->session->thread_id);
5887
5997
    bool res= choose_plan(join, all_table_map & ~join->const_table_map);
5888
5998
    DRIZZLE_QUERY_OPT_CHOOSE_PLAN_DONE(res ? 1 : 0);
5889
5999
    if (res)
5895
6005
    join->best_read= 1.0;
5896
6006
  }
5897
6007
  /* Generate an execution plan from the found optimal join order. */
5898
 
  return (join->session->getKilled() || get_best_combination(join));
 
6008
  return (join->session->killed || get_best_combination(join));
5899
6009
}
5900
6010
 
5901
6011
/**
5924
6034
  while ((table= li++))
5925
6035
  {
5926
6036
    nested_join_st *nested_join;
5927
 
    if ((nested_join= table->getNestedJoin()))
 
6037
    if ((nested_join= table->nested_join))
5928
6038
    {
5929
6039
      /*
5930
6040
        It is guaranteed by simplify_joins() function that a nested join
5955
6065
  Return table number if there is only one table in sort order
5956
6066
  and group and order is compatible, else return 0.
5957
6067
*/
5958
 
static Table *get_sort_by_table(Order *a, Order *b,TableList *tables)
 
6068
static Table *get_sort_by_table(order_st *a,order_st *b,TableList *tables)
5959
6069
{
5960
6070
  table_map map= (table_map) 0;
5961
6071
 
5995
6105
  while ((table= li++))
5996
6106
  {
5997
6107
    nested_join_st *nested_join;
5998
 
    if ((nested_join= table->getNestedJoin()))
 
6108
    if ((nested_join= table->nested_join))
5999
6109
    {
6000
6110
      nested_join->counter_= 0;
6001
6111
      reset_nj_counters(&nested_join->join_list);
6010
6120
  If first parts has different direction, change it to second part
6011
6121
  (group is sorted like order)
6012
6122
*/
6013
 
static bool test_if_subpart(Order *a, Order *b)
 
6123
static bool test_if_subpart(order_st *a,order_st *b)
6014
6124
{
6015
6125
  for (; a && b; a=a->next,b=b->next)
6016
6126
  {
6025
6135
/**
6026
6136
  Nested joins perspective: Remove the last table from the join order.
6027
6137
 
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
6138
    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 
 
6139
    joins counters and join->cur_embedding_map. It is ok to call this
 
6140
    function for the first table in join order (for which
6071
6141
    check_interleaving_with_nj has not been called)
6072
6142
 
6073
6143
  @param last  join table to remove, it is assumed to be the last in current
6074
6144
               partial join order.
6075
6145
*/
6076
 
 
6077
6146
static void restore_prev_nj_state(JoinTable *last)
6078
6147
{
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)
 
6148
  TableList *last_emb= last->table->pos_in_table_list->embedding;
 
6149
  JOIN *join= last->join;
 
6150
  while (last_emb)
 
6151
  {
 
6152
    if (last_emb->on_expr)
 
6153
    {
 
6154
      if (!(--last_emb->nested_join->counter_))
 
6155
        join->cur_embedding_map&= ~last_emb->nested_join->nj_map;
 
6156
      else if (last_emb->nested_join->join_list.elements-1 ==
 
6157
               last_emb->nested_join->counter_)
 
6158
        join->cur_embedding_map|= last_emb->nested_join->nj_map;
 
6159
      else
 
6160
        break;
 
6161
    }
 
6162
    last_emb= last_emb->embedding;
 
6163
  }
 
6164
}
 
6165
 
 
6166
/**
 
6167
  Determine if the set is already ordered for order_st BY, so it can
 
6168
  disable join cache because it will change the ordering of the results.
 
6169
  Code handles sort table that is at any location (not only first after
 
6170
  the const tables) despite the fact that it's currently prohibited.
 
6171
  We must disable join cache if the first non-const table alone is
 
6172
  ordered. If there is a temp table the ordering is done as a last
 
6173
  operation and doesn't prevent join cache usage.
 
6174
*/
 
6175
static uint32_t make_join_orderinfo(JOIN *join)
 
6176
{
 
6177
  uint32_t i;
 
6178
  if (join->need_tmp)
 
6179
    return join->tables;
 
6180
 
 
6181
  for (i=join->const_tables ; i < join->tables ; i++)
 
6182
  {
 
6183
    JoinTable *tab= join->join_tab+i;
 
6184
    Table *table= tab->table;
 
6185
    if ((table == join->sort_by_table &&
 
6186
        (!join->order || join->skip_sort_order)) ||
 
6187
        (join->sort_by_table == (Table *) 1 &&  i != join->const_tables))
 
6188
    {
6091
6189
      break;
6092
 
    
6093
 
    join->cur_embedding_map|= nest->nj_map;
 
6190
    }
6094
6191
  }
 
6192
  return i;
6095
6193
}
6096
6194
 
6097
6195
/**
6111
6209
 
6112
6210
  for (uint32_t i=0 ; i < join_tab->ref.key_parts ; i++)
6113
6211
  {
6114
 
    Field *field=table->getField(table->key_info[join_tab->ref.key].key_part[i].fieldnr - 1);
 
6212
    Field *field=table->field[table->key_info[join_tab->ref.key].key_part[i].
 
6213
                              fieldnr-1];
6115
6214
    Item *value=join_tab->ref.items[i];
6116
6215
    cond->add(new Item_func_equal(new Item_field(field), value));
6117
6216
  }
6144
6243
/**
6145
6244
  @} (end of group Query_Optimizer)
6146
6245
*/
6147
 
 
6148
 
} /* namespace drizzled */