~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/join.cc

  • Committer: Brian Aker
  • Date: 2010-05-19 00:35:41 UTC
  • mto: This revision was merged to the branch mainline in revision 1542.
  • Revision ID: brian@gaz-20100519003541-7ecxcuwv9klvzi8l
JOIN -> Join rename

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
 * @{
70
70
extern std::bitset<12> test_flags;
71
71
 
72
72
/** 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_st *group);
75
 
static bool alloc_group_fields(JOIN *join,order_st *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,
 
73
static bool make_group_fields(Join *main_join, Join *curr_join);
 
74
static void calc_group_buffer(Join *join,order_st *group);
 
75
static bool alloc_group_fields(Join *join,order_st *group);
 
76
static uint32_t cache_record_length(Join *join, uint32_t index);
 
77
static double prev_record_reads(Join *join, uint32_t idx, table_map found_ref);
 
78
static bool get_best_combination(Join *join);
 
79
static void set_position(Join *join,
80
80
                         uint32_t index,
81
81
                         JoinTable *table,
82
82
                         optimizer::KeyUse *key);
83
 
static bool choose_plan(JOIN *join,table_map join_tables);
84
 
static void best_access_path(JOIN *join, JoinTable *s,
 
83
static bool choose_plan(Join *join,table_map join_tables);
 
84
static void best_access_path(Join *join, JoinTable *s,
85
85
                             Session *session,
86
86
                             table_map remaining_tables,
87
87
                             uint32_t idx,
88
88
                             double record_count,
89
89
                             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,
 
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,
93
93
                                             table_map remaining_tables,
94
94
                                             uint32_t idx,
95
95
                                             double record_count,
96
96
                                             double read_time,
97
97
                                             uint32_t depth,
98
98
                                             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_st *order);
106
 
static order_st *remove_constants(JOIN *join,order_st *first_order,COND *cond, bool change_list, bool *simple_order);
107
 
static int return_zero_rows(JOIN *join,
 
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_st *order);
 
106
static order_st *remove_constants(Join *join,order_st *first_order,COND *cond, bool change_list, bool *simple_order);
 
107
static int return_zero_rows(Join *join,
108
108
                            select_result *res,
109
109
                            TableList *tables,
110
110
                            List<Item> &fields,
112
112
                            uint64_t select_options,
113
113
                            const char *info,
114
114
                            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);
 
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);
117
117
static int setup_without_group(Session *session, 
118
118
                               Item **ref_pointer_array,
119
119
                               TableList *tables,
124
124
                               order_st *order,
125
125
                               order_st *group,
126
126
                               bool *hidden_group_fields);
127
 
static bool make_join_statistics(JOIN *join, TableList *leaves, COND *conds, DYNAMIC_ARRAY *keyuse);
 
127
static bool make_join_statistics(Join *join, TableList *leaves, COND *conds, DYNAMIC_ARRAY *keyuse);
128
128
static uint32_t build_bitmap_for_nested_joins(List<TableList> *join_list, uint32_t first_unused);
129
129
static Table *get_sort_by_table(order_st *a,order_st *b,TableList *tables);
130
130
static void reset_nj_counters(List<TableList> *join_list);
145
145
  @retval
146
146
    0   on success
147
147
*/
148
 
int JOIN::prepare(Item ***rref_pointer_array,
 
148
int Join::prepare(Item ***rref_pointer_array,
149
149
                  TableList *tables_init,
150
150
                  uint32_t wild_num,
151
151
                  COND *conds_init,
375
375
  Remove the predicates pushed down into the subquery
376
376
 
377
377
  SYNOPSIS
378
 
    JOIN::remove_subq_pushed_predicates()
 
378
    Join::remove_subq_pushed_predicates()
379
379
      where   IN  Must be NULL
380
380
              OUT The remaining WHERE condition, or NULL
381
381
 
400
400
    that is searched in a byte. But this requires homogenization of the return
401
401
    codes of all Field*::store() methods.
402
402
*/
403
 
void JOIN::remove_subq_pushed_predicates(Item **where)
 
403
void Join::remove_subq_pushed_predicates(Item **where)
404
404
{
405
405
  if (conds->type() == Item::FUNC_ITEM &&
406
406
      ((Item_func *)this->conds)->functype() == Item_func::EQ_FUNC &&
425
425
  @retval
426
426
    1   error
427
427
*/
428
 
int JOIN::optimize()
 
428
int Join::optimize()
429
429
{
430
430
  // to prevent double initialization on EXPLAIN
431
431
  if (optimized)
1115
1115
/**
1116
1116
  Restore values in temporary join.
1117
1117
*/
1118
 
void JOIN::restore_tmp()
 
1118
void Join::restore_tmp()
1119
1119
{
1120
 
  memcpy(tmp_join, this, (size_t) sizeof(JOIN));
 
1120
  memcpy(tmp_join, this, (size_t) sizeof(Join));
1121
1121
}
1122
1122
 
1123
 
int JOIN::reinit()
 
1123
int Join::reinit()
1124
1124
{
1125
1125
  unit->offset_limit_cnt= (ha_rows)(select_lex->offset_limit ?
1126
1126
                                    select_lex->offset_limit->val_uint() :
1172
1172
   @retval 0      success.
1173
1173
   @retval 1      error occurred.
1174
1174
*/
1175
 
bool JOIN::init_save_join_tab()
 
1175
bool Join::init_save_join_tab()
1176
1176
{
1177
 
  if (!(tmp_join= (JOIN*)session->alloc(sizeof(JOIN))))
 
1177
  if (!(tmp_join= (Join*)session->alloc(sizeof(Join))))
1178
1178
    return 1;
1179
1179
  error= 0;              // Ensure that tmp_join.error= 0
1180
1180
  restore_tmp();
1181
1181
  return 0;
1182
1182
}
1183
1183
 
1184
 
bool JOIN::save_join_tab()
 
1184
bool Join::save_join_tab()
1185
1185
{
1186
1186
  if (!join_tab_save && select_lex->master_unit()->uncacheable)
1187
1187
  {
1203
1203
  @todo
1204
1204
    When can we have here session->net.report_error not zero?
1205
1205
*/
1206
 
void JOIN::exec()
 
1206
void Join::exec()
1207
1207
{
1208
1208
  List<Item> *columns_list= &fields_list;
1209
1209
  int      tmp_error;
1304
1304
    return;
1305
1305
  }
1306
1306
 
1307
 
  JOIN *curr_join= this;
 
1307
  Join *curr_join= this;
1308
1308
  List<Item> *curr_all_fields= &all_fields;
1309
1309
  List<Item> *curr_fields_list= &fields_list;
1310
1310
  Table *curr_tmp_table= 0;
1424
1424
        /*
1425
1425
          If the access method is loose index scan then all MIN/MAX
1426
1426
          functions are precomputed, and should be treated as regular
1427
 
          functions. See extended comment in JOIN::exec.
 
1427
          functions. See extended comment in Join::exec.
1428
1428
        */
1429
1429
        if (curr_join->join_tab->is_using_loose_index_scan())
1430
1430
          curr_join->tmp_table_param.precomputed_group_by= true;
1701
1701
  Clean up join.
1702
1702
 
1703
1703
  @return
1704
 
    Return error that hold JOIN.
 
1704
    Return error that hold Join.
1705
1705
*/
1706
 
int JOIN::destroy()
 
1706
int Join::destroy()
1707
1707
{
1708
1708
  select_lex->join= 0;
1709
1709
 
1739
1739
  - try to initialize all data structures needed for the materialized execution
1740
1740
    of the IN predicate,
1741
1741
  - if this fails, then perform the IN=>EXISTS transformation which was
1742
 
    previously blocked during JOIN::prepare.
 
1742
    previously blocked during Join::prepare.
1743
1743
 
1744
1744
  This method is part of the "code generation" query processing phase.
1745
1745
 
1752
1752
  @retval false     success.
1753
1753
  @retval true      error occurred.
1754
1754
*/
1755
 
bool JOIN::setup_subquery_materialization()
 
1755
bool Join::setup_subquery_materialization()
1756
1756
{
1757
1757
  for (Select_Lex_Unit *un= select_lex->first_inner_unit(); un;
1758
1758
       un= un->next_unit())
1774
1774
}
1775
1775
 
1776
1776
/**
1777
 
  Partially cleanup JOIN after it has executed: close index or rnd read
 
1777
  Partially cleanup Join after it has executed: close index or rnd read
1778
1778
  (table cursors), free quick selects.
1779
1779
 
1780
 
    This function is called in the end of execution of a JOIN, before the used
 
1780
    This function is called in the end of execution of a Join, before the used
1781
1781
    tables are unlocked and closed.
1782
1782
 
1783
1783
    For a join that is resolved using a temporary table, the first sweep is
1791
1791
    is called after all rows are sent, but before EOF packet is sent.
1792
1792
 
1793
1793
    For a simple SELECT with no subqueries this function performs a full
1794
 
    cleanup of the JOIN and calls mysql_unlock_read_tables to free used base
 
1794
    cleanup of the Join and calls mysql_unlock_read_tables to free used base
1795
1795
    tables.
1796
1796
 
1797
 
    If a JOIN is executed for a subquery or if it has a subquery, we can't
 
1797
    If a Join is executed for a subquery or if it has a subquery, we can't
1798
1798
    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
 
1799
    - If a Join is not the top level join, we must not unlock the tables
1800
1800
    because the outer select may not have been evaluated yet, and we
1801
1801
    can't unlock only selected tables of a query.
1802
 
    - Additionally, if this JOIN corresponds to a correlated subquery, we
 
1802
    - Additionally, if this Join corresponds to a correlated subquery, we
1803
1803
    should not free quick selects and join buffers because they will be
1804
1804
    needed for the next execution of the correlated subquery.
1805
 
    - However, if this is a JOIN for a [sub]select, which is not
 
1805
    - However, if this is a Join for a [sub]select, which is not
1806
1806
    a correlated subquery itself, but has subqueries, we can free it
1807
 
    fully and also free JOINs of all its subqueries. The exception
 
1807
    fully and also free Joins of all its subqueries. The exception
1808
1808
    is a subquery in SELECT list, e.g: @n
1809
1809
    SELECT a, (select cmax(b) from t1) group by c @n
1810
1810
    This subquery will not be evaluated at first sweep and its value will
1815
1815
  @todo
1816
1816
    Unlock tables even if the join isn't top level select in the tree
1817
1817
*/
1818
 
void JOIN::join_free()
 
1818
void Join::join_free()
1819
1819
{
1820
1820
  Select_Lex_Unit *tmp_unit;
1821
1821
  Select_Lex *sl;
1822
1822
  /*
1823
 
    Optimization: if not EXPLAIN and we are done with the JOIN,
 
1823
    Optimization: if not EXPLAIN and we are done with the Join,
1824
1824
    free all tables.
1825
1825
  */
1826
1826
  bool full= (!select_lex->uncacheable && !session->lex->describe);
1845
1845
        but all table cursors must be closed before the unlock.
1846
1846
      */
1847
1847
      sl->cleanup_all_joins(full_local);
1848
 
      /* Can't unlock if at least one JOIN is still needed */
 
1848
      /* Can't unlock if at least one Join is still needed */
1849
1849
      can_unlock= can_unlock && full_local;
1850
1850
    }
1851
1851
 
1882
1882
    With subquery this function definitely will be called several times,
1883
1883
    but even for simple query it can be called several times.
1884
1884
*/
1885
 
void JOIN::cleanup(bool full)
 
1885
void Join::cleanup(bool full)
1886
1886
{
1887
1887
  if (table)
1888
1888
  {
1927
1927
    */
1928
1928
    tmp_table_param.copy_funcs.empty();
1929
1929
    /*
1930
 
      If we have tmp_join and 'this' JOIN is not tmp_join and
 
1930
      If we have tmp_join and 'this' Join is not tmp_join and
1931
1931
      tmp_table_param.copy_field's  of them are equal then we have to remove
1932
1932
      pointer to  tmp_table_param.copy_field from tmp_join, because it qill
1933
1933
      be removed in tmp_table_param.cleanup().
1946
1946
}
1947
1947
 
1948
1948
/*
1949
 
  used only in JOIN::clear
 
1949
  used only in Join::clear
1950
1950
*/
1951
 
static void clear_tables(JOIN *join)
 
1951
static void clear_tables(Join *join)
1952
1952
{
1953
1953
  /*
1954
1954
    must clear only the non-const tables, as const tables
1967
1967
  @retval
1968
1968
    1 Error
1969
1969
*/
1970
 
bool JOIN::alloc_func_list()
 
1970
bool Join::alloc_func_list()
1971
1971
{
1972
1972
  uint32_t func_count, group_parts;
1973
1973
 
2019
2019
  @retval
2020
2020
    1  error
2021
2021
*/
2022
 
bool JOIN::make_sum_func_list(List<Item> &field_list, 
 
2022
bool Join::make_sum_func_list(List<Item> &field_list, 
2023
2023
                              List<Item> &send_fields,
2024
2024
                              bool before_group_by, 
2025
2025
                              bool recompute)
2057
2057
}
2058
2058
 
2059
2059
/** Allocate memory needed for other rollup functions. */
2060
 
bool JOIN::rollup_init()
 
2060
bool Join::rollup_init()
2061
2061
{
2062
2062
  uint32_t i,j;
2063
2063
  Item **ref_array;
2172
2172
  @retval
2173
2173
    1    on error
2174
2174
*/
2175
 
bool JOIN::rollup_make_fields(List<Item> &fields_arg, List<Item> &sel_fields, Item_sum ***func)
 
2175
bool Join::rollup_make_fields(List<Item> &fields_arg, List<Item> &sel_fields, Item_sum ***func)
2176
2176
{
2177
2177
  List_iterator_fast<Item> it(fields_arg);
2178
2178
  Item *first_field= sel_fields.head();
2302
2302
  @retval
2303
2303
    1   If send_data_failed()
2304
2304
*/
2305
 
int JOIN::rollup_send_data(uint32_t idx)
 
2305
int Join::rollup_send_data(uint32_t idx)
2306
2306
{
2307
2307
  uint32_t i;
2308
2308
  for (i= send_group_parts ; i-- > idx ; )
2342
2342
  @retval
2343
2343
    1   if write_data_failed()
2344
2344
*/
2345
 
int JOIN::rollup_write_data(uint32_t idx, Table *table_arg)
 
2345
int Join::rollup_write_data(uint32_t idx, Table *table_arg)
2346
2346
{
2347
2347
  uint32_t i;
2348
2348
  for (i= send_group_parts ; i-- > idx ; )
2377
2377
  clear results if there are not rows found for group
2378
2378
  (end_send_group/end_write_group)
2379
2379
*/
2380
 
void JOIN::clear()
 
2380
void Join::clear()
2381
2381
{
2382
2382
  clear_tables(this);
2383
2383
  copy_fields(&tmp_table_param);
2391
2391
}
2392
2392
 
2393
2393
/**
2394
 
  change select_result object of JOIN.
 
2394
  change select_result object of Join.
2395
2395
 
2396
2396
  @param res    new select_result object
2397
2397
 
2400
2400
  @retval
2401
2401
    true    error
2402
2402
*/
2403
 
bool JOIN::change_result(select_result *res)
 
2403
bool Join::change_result(select_result *res)
2404
2404
{
2405
2405
  result= res;
2406
2406
  if (result->prepare(fields_list, select_lex->master_unit()))
2414
2414
  Cache constant expressions in WHERE, HAVING, ON conditions.
2415
2415
*/
2416
2416
 
2417
 
void JOIN::cache_const_exprs()
 
2417
void Join::cache_const_exprs()
2418
2418
{
2419
2419
  bool cache_flag= false;
2420
2420
  bool *analyzer_arg= &cache_flag;
2455
2455
  applicable to the partial record on hand and in case of success
2456
2456
  submit this record to the next level of the nested loop.
2457
2457
*/
2458
 
enum_nested_loop_state evaluate_join_record(JOIN *join, JoinTable *join_tab, int error)
 
2458
enum_nested_loop_state evaluate_join_record(Join *join, JoinTable *join_tab, int error)
2459
2459
{
2460
2460
  bool not_used_in_distinct= join_tab->not_used_in_distinct;
2461
2461
  ha_rows found_records= join->found_records;
2579
2579
    level of the nested loop. This function is used in case we have
2580
2580
    an OUTER join and no matching record was found.
2581
2581
*/
2582
 
enum_nested_loop_state evaluate_null_complemented_join_record(JOIN *join, JoinTable *join_tab)
 
2582
enum_nested_loop_state evaluate_null_complemented_join_record(Join *join, JoinTable *join_tab)
2583
2583
{
2584
2584
  /*
2585
2585
    The table join_tab is the first inner table of a outer join operation
2635
2635
  return (*join_tab->next_select)(join, join_tab+1, 0);
2636
2636
}
2637
2637
 
2638
 
enum_nested_loop_state flush_cached_records(JOIN *join, JoinTable *join_tab, bool skip_last)
 
2638
enum_nested_loop_state flush_cached_records(Join *join, JoinTable *join_tab, bool skip_last)
2639
2639
{
2640
2640
  enum_nested_loop_state rc= NESTED_LOOP_OK;
2641
2641
  int error;
2743
2743
                               operation.
2744
2744
   All return values except NESTED_LOOP_OK abort the nested loop.
2745
2745
*****************************************************************************/
2746
 
enum_nested_loop_state end_send(JOIN *join, JoinTable *, bool end_of_records)
 
2746
enum_nested_loop_state end_send(Join *join, JoinTable *, bool end_of_records)
2747
2747
{
2748
2748
  if (! end_of_records)
2749
2749
  {
2805
2805
  return NESTED_LOOP_OK;
2806
2806
}
2807
2807
 
2808
 
enum_nested_loop_state end_write(JOIN *join, JoinTable *, bool end_of_records)
 
2808
enum_nested_loop_state end_write(Join *join, JoinTable *, bool end_of_records)
2809
2809
{
2810
2810
  Table *table= join->tmp_table;
2811
2811
 
2845
2845
}
2846
2846
 
2847
2847
/** Group by searching after group record and updating it if possible. */
2848
 
enum_nested_loop_state end_update(JOIN *join, JoinTable *, bool end_of_records)
 
2848
enum_nested_loop_state end_update(Join *join, JoinTable *, bool end_of_records)
2849
2849
{
2850
2850
  Table *table= join->tmp_table;
2851
2851
  order_st *group;
2911
2911
}
2912
2912
 
2913
2913
/** Like end_update, but this is done with unique constraints instead of keys.  */
2914
 
enum_nested_loop_state end_unique_update(JOIN *join, JoinTable *, bool end_of_records)
 
2914
enum_nested_loop_state end_unique_update(Join *join, JoinTable *, bool end_of_records)
2915
2915
{
2916
2916
  Table *table= join->tmp_table;
2917
2917
  int   error;
2966
2966
  @retval
2967
2967
    1   failed
2968
2968
*/
2969
 
static bool make_group_fields(JOIN *main_join, JOIN *curr_join)
 
2969
static bool make_group_fields(Join *main_join, Join *curr_join)
2970
2970
{
2971
2971
  if (main_join->group_fields_cache.elements)
2972
2972
  {
2985
2985
/**
2986
2986
  calc how big buffer we need for comparing group entries.
2987
2987
*/
2988
 
static void calc_group_buffer(JOIN *join,order_st *group)
 
2988
static void calc_group_buffer(Join *join,order_st *group)
2989
2989
{
2990
2990
  uint32_t key_length=0, parts=0, null_parts=0;
2991
2991
 
3064
3064
 
3065
3065
  Groups are saved in reverse order for easyer check loop.
3066
3066
*/
3067
 
static bool alloc_group_fields(JOIN *join,order_st *group)
 
3067
static bool alloc_group_fields(Join *join,order_st *group)
3068
3068
{
3069
3069
  if (group)
3070
3070
  {
3079
3079
  return false;
3080
3080
}
3081
3081
 
3082
 
static uint32_t cache_record_length(JOIN *join,uint32_t idx)
 
3082
static uint32_t cache_record_length(Join *join,uint32_t idx)
3083
3083
{
3084
3084
  uint32_t length=0;
3085
3085
  JoinTable **pos,**end;
3147
3147
  RETURN
3148
3148
    Expected number of row combinations
3149
3149
*/
3150
 
static double prev_record_reads(JOIN *join, uint32_t idx, table_map found_ref)
 
3150
static double prev_record_reads(Join *join, uint32_t idx, table_map found_ref)
3151
3151
{
3152
3152
  double found=1.0;
3153
3153
  optimizer::Position *pos_end= join->getSpecificPosInPartialPlan(-1);
3159
3159
    {
3160
3160
      found_ref|= pos->getRefDependMap();
3161
3161
      /*
3162
 
        For the case of "t1 LEFT JOIN t2 ON ..." where t2 is a const table
 
3162
        For the case of "t1 LEFT Join t2 ON ..." where t2 is a const table
3163
3163
        with no matching row we will get position[t2].records_read==0.
3164
3164
        Actually the size of output is one null-complemented row, therefore
3165
3165
        we will use value of 1 whenever we get records_read==0.
3184
3184
/**
3185
3185
  Set up join struct according to best position.
3186
3186
*/
3187
 
static bool get_best_combination(JOIN *join)
 
3187
static bool get_best_combination(Join *join)
3188
3188
{
3189
3189
  uint32_t i,tablenr;
3190
3190
  table_map used_tables;
3211
3211
    used_tables|= form->map;
3212
3212
    form->reginfo.join_tab=j;
3213
3213
    if (!*j->on_expr_ref)
3214
 
      form->reginfo.not_exists_optimize=0;  // Only with LEFT JOIN
 
3214
      form->reginfo.not_exists_optimize=0;  // Only with LEFT Join
3215
3215
    if (j->type == AM_CONST)
3216
3216
      continue;         // Handled in make_join_stat..
3217
3217
 
3237
3237
}
3238
3238
 
3239
3239
/** Save const tables first as used tables. */
3240
 
static void set_position(JOIN *join,
 
3240
static void set_position(Join *join,
3241
3241
                         uint32_t idx,
3242
3242
                         JoinTable *table,
3243
3243
                         optimizer::KeyUse *key)
3279
3279
  @retval
3280
3280
    true        Fatal error
3281
3281
*/
3282
 
static bool choose_plan(JOIN *join, table_map join_tables)
 
3282
static bool choose_plan(Join *join, table_map join_tables)
3283
3283
{
3284
3284
  uint32_t search_depth= join->session->variables.optimizer_search_depth;
3285
3285
  uint32_t prune_level=  join->session->variables.optimizer_prune_level;
3346
3346
  @return
3347
3347
    None
3348
3348
*/
3349
 
static void best_access_path(JOIN *join,
 
3349
static void best_access_path(Join *join,
3350
3350
                             JoinTable *s,
3351
3351
                             Session *session,
3352
3352
                             table_map remaining_tables,
3876
3876
    Thus 'optimize_straight_join' can be used at any stage of the query
3877
3877
    optimization process to finalize a QEP as it is.
3878
3878
*/
3879
 
static void optimize_straight_join(JOIN *join, table_map join_tables)
 
3879
static void optimize_straight_join(Join *join, table_map join_tables)
3880
3880
{
3881
3881
  JoinTable *s;
3882
3882
  optimizer::Position partial_pos;
3986
3986
  @retval
3987
3987
    true        Fatal error
3988
3988
*/
3989
 
static bool greedy_search(JOIN      *join,
 
3989
static bool greedy_search(Join      *join,
3990
3990
              table_map remaining_tables,
3991
3991
              uint32_t      search_depth,
3992
3992
              uint32_t      prune_level)
4165
4165
  @retval
4166
4166
    true        Fatal error
4167
4167
*/
4168
 
static bool best_extension_by_limited_search(JOIN *join,
 
4168
static bool best_extension_by_limited_search(Join *join,
4169
4169
                                             table_map remaining_tables,
4170
4170
                                             uint32_t idx,
4171
4171
                                             double record_count,
4316
4316
    exhaustiveness) of the depth-first search algorithm used by
4317
4317
    'greedy_search'.
4318
4318
*/
4319
 
static uint32_t determine_search_depth(JOIN *join)
 
4319
static uint32_t determine_search_depth(Join *join)
4320
4320
{
4321
4321
  uint32_t table_count=  join->tables - join->const_tables;
4322
4322
  uint32_t search_depth;
4335
4335
  return search_depth;
4336
4336
}
4337
4337
 
4338
 
static bool make_simple_join(JOIN *join,Table *tmp_table)
 
4338
static bool make_simple_join(Join *join,Table *tmp_table)
4339
4339
{
4340
4340
  Table **tableptr;
4341
4341
  JoinTable *join_tab;
4342
4342
 
4343
4343
  /*
4344
4344
    Reuse Table * and JoinTable if already allocated by a previous call
4345
 
    to this function through JOIN::exec (may happen for sub-queries).
 
4345
    to this function through Join::exec (may happen for sub-queries).
4346
4346
  */
4347
4347
  if (!join->table_reexec)
4348
4348
  {
4439
4439
    This function can be called only after the execution plan
4440
4440
    has been chosen.
4441
4441
*/
4442
 
static void make_outerjoin_info(JOIN *join)
 
4442
static void make_outerjoin_info(Join *join)
4443
4443
{
4444
4444
  for (uint32_t i=join->const_tables ; i < join->tables ; i++)
4445
4445
  {
4490
4490
  return;
4491
4491
}
4492
4492
 
4493
 
static bool make_join_select(JOIN *join,
 
4493
static bool make_join_select(Join *join,
4494
4494
                             optimizer::SqlSelect *select,
4495
4495
                             COND *cond)
4496
4496
{
4868
4868
    false - OK
4869
4869
    true  - Out of memory
4870
4870
*/
4871
 
static bool make_join_readinfo(JOIN *join)
 
4871
static bool make_join_readinfo(Join *join)
4872
4872
{
4873
4873
  bool sorted= true;
4874
4874
 
4916
4916
}
4917
4917
 
4918
4918
/** Update the dependency map for the tables. */
4919
 
static void update_depend_map(JOIN *join)
 
4919
static void update_depend_map(Join *join)
4920
4920
{
4921
4921
  JoinTable *join_tab=join->join_tab, *end=join_tab+join->tables;
4922
4922
 
4939
4939
}
4940
4940
 
4941
4941
/** Update the dependency map for the sort order. */
4942
 
static void update_depend_map(JOIN *join, order_st *order)
 
4942
static void update_depend_map(Join *join, order_st *order)
4943
4943
{
4944
4944
  for (; order ; order=order->next)
4945
4945
  {
4977
4977
  @return
4978
4978
    Returns new sort order
4979
4979
*/
4980
 
static order_st *remove_constants(JOIN *join,order_st *first_order, COND *cond, bool change_list, bool *simple_order)
 
4980
static order_st *remove_constants(Join *join,order_st *first_order, COND *cond, bool change_list, bool *simple_order)
4981
4981
{
4982
4982
  if (join->tables == join->const_tables)
4983
4983
    return change_list ? 0 : first_order;               // No need to sort
5037
5037
  return(first_order);
5038
5038
}
5039
5039
 
5040
 
static int return_zero_rows(JOIN *join,
 
5040
static int return_zero_rows(Join *join,
5041
5041
                            select_result *result,
5042
5042
                            TableList *tables,
5043
5043
                                        List<Item> &fields,
5203
5203
    - The new condition, if success
5204
5204
    - 0, otherwise
5205
5205
*/
5206
 
static COND *simplify_joins(JOIN *join, List<TableList> *join_list, COND *conds, bool top)
 
5206
static COND *simplify_joins(Join *join, List<TableList> *join_list, COND *conds, bool top)
5207
5207
{
5208
5208
  TableList *table;
5209
5209
  nested_join_st *nested_join;
5361
5361
  return(conds);
5362
5362
}
5363
5363
 
5364
 
static int remove_duplicates(JOIN *join, Table *entry,List<Item> &fields, Item *having)
 
5364
static int remove_duplicates(Join *join, Table *entry,List<Item> &fields, Item *having)
5365
5365
{
5366
5366
  int error;
5367
5367
  uint32_t reclength,offset;
5446
5446
  @retval
5447
5447
    1   Fatal error
5448
5448
*/
5449
 
static bool make_join_statistics(JOIN *join, TableList *tables, COND *conds, DYNAMIC_ARRAY *keyuse_array)
 
5449
static bool make_join_statistics(Join *join, TableList *tables, COND *conds, DYNAMIC_ARRAY *keyuse_array)
5450
5450
{
5451
5451
  int error;
5452
5452
  Table *table;
6010
6010
static void restore_prev_nj_state(JoinTable *last)
6011
6011
{
6012
6012
  TableList *last_emb= last->table->pos_in_table_list->embedding;
6013
 
  JOIN *join= last->join;
 
6013
  Join *join= last->join;
6014
6014
  while (last_emb)
6015
6015
  {
6016
6016
    if (last_emb->on_expr)