~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/join.cc

  • Committer: Lee Bieber
  • Date: 2010-01-30 23:42:02 UTC
  • mto: This revision was merged to the branch mainline in revision 1282.
  • Revision ID: lbieber@lee-biebers-macbook-pro.local-20100130234202-sxmqfteqwiq15ptg
add target to japanese tests

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