~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/join.cc

  • Committer: Brian Aker
  • Date: 2010-05-18 15:49:50 UTC
  • Revision ID: brian@gaz-20100518154950-qhctxu6lvvnyxy9i
Simplify out Open_tables_state() backup/restore (no longer needed).

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 *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,
 
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 *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,
 
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,
121
121
                               List<Item> &fields,
122
122
                               List<Item> &all_fields,
123
123
                               COND **conds,
124
 
                               Order *order,
125
 
                               Order *group,
 
124
                               order_st *order,
 
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
 
static Table *get_sort_by_table(Order *a, Order *b,TableList *tables);
 
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);
131
 
static bool test_if_subpart(Order *a,Order *b);
 
131
static bool test_if_subpart(order_st *a,order_st *b);
132
132
static void restore_prev_nj_state(JoinTable *last);
133
133
static bool add_ref_to_table_cond(Session *session, JoinTable *join_tab);
134
134
static void free_blobs(Field **ptr); /* Rename this method...conflicts with another in global namespace... */
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,
152
152
                  uint32_t og_num,
153
 
                  Order *order_init,
154
 
                  Order *group_init,
 
153
                  order_st *order_init,
 
154
                  order_st *group_init,
155
155
                  Item *having_init,
156
156
                  Select_Lex *select_lex_arg,
157
157
                  Select_Lex_Unit *unit_arg)
184
184
      setup_tables_and_check_access(session, &select_lex->context, join_list,
185
185
                                    tables_list, &select_lex->leaf_tables,
186
186
                                    false))
187
 
  {
188
187
      return(-1);
189
 
  }
190
188
 
191
189
  TableList *table_ptr;
192
190
  for (table_ptr= select_lex->leaf_tables;
193
191
       table_ptr;
194
192
       table_ptr= table_ptr->next_leaf)
195
 
  {
196
193
    tables++;
197
 
  }
198
 
 
199
194
 
200
195
  if (setup_wild(session, fields_list, &all_fields, wild_num) ||
201
196
      select_lex->setup_ref_array(session, og_num) ||
291
286
 
292
287
  if (order)
293
288
  {
294
 
    Order *ord;
 
289
    order_st *ord;
295
290
    for (ord= order; ord; ord= ord->next)
296
291
    {
297
292
      Item *item= *ord->item;
336
331
  {
337
332
    /* Caclulate the number of groups */
338
333
    send_group_parts= 0;
339
 
    for (Order *group_tmp= group_list ; group_tmp ; group_tmp= group_tmp->next)
 
334
    for (order_st *group_tmp= group_list ; group_tmp ; group_tmp= group_tmp->next)
340
335
      send_group_parts++;
341
336
  }
342
337
 
343
338
  if (error)
344
 
    return(-1);
 
339
    goto err;
345
340
 
346
341
  /* 
347
342
   * The below will create the new table for
350
345
   * @see create_table_from_items() in drizzled/sql_insert.cc
351
346
   */
352
347
  if (result && result->prepare(fields_list, unit_arg))
353
 
    return(-1);
 
348
    goto err;
354
349
 
355
350
  /* Init join struct */
356
351
  count_field_types(select_lex, &tmp_table_param, all_fields, 0);
362
357
  if (sum_func_count && !group_list && (func_count || field_count))
363
358
  {
364
359
    my_message(ER_WRONG_SUM_SELECT,ER(ER_WRONG_SUM_SELECT),MYF(0));
365
 
    return(-1);
 
360
    goto err;
366
361
  }
367
362
#endif
368
363
  if (select_lex->olap == ROLLUP_TYPE && rollup_init())
369
 
    return(-1);
370
 
 
 
364
    goto err;
371
365
  if (alloc_func_list())
372
 
    return(-1);
373
 
 
374
 
  return 0; // All OK
 
366
    goto err;
 
367
 
 
368
  return(0); // All OK
 
369
 
 
370
err:
 
371
  return(-1);
375
372
}
376
373
 
377
374
/*
378
375
  Remove the predicates pushed down into the subquery
379
376
 
380
377
  SYNOPSIS
381
 
    Join::remove_subq_pushed_predicates()
 
378
    JOIN::remove_subq_pushed_predicates()
382
379
      where   IN  Must be NULL
383
380
              OUT The remaining WHERE condition, or NULL
384
381
 
403
400
    that is searched in a byte. But this requires homogenization of the return
404
401
    codes of all Field*::store() methods.
405
402
*/
406
 
void Join::remove_subq_pushed_predicates(Item **where)
 
403
void JOIN::remove_subq_pushed_predicates(Item **where)
407
404
{
408
405
  if (conds->type() == Item::FUNC_ITEM &&
409
406
      ((Item_func *)this->conds)->functype() == Item_func::EQ_FUNC &&
428
425
  @retval
429
426
    1   error
430
427
*/
431
 
int Join::optimize()
 
428
int JOIN::optimize()
432
429
{
433
430
  // to prevent double initialization on EXPLAIN
434
431
  if (optimized)
498
495
    {           /* Impossible cond */
499
496
      zero_result_cause=  having_value == Item::COND_FALSE ?
500
497
                           "Impossible HAVING" : "Impossible WHERE";
501
 
      tables = 0;
502
 
      goto setup_subq_exit;
 
498
      error= 0;
 
499
      return(0);
503
500
    }
504
501
  }
505
502
 
518
515
      if (res == HA_ERR_KEY_NOT_FOUND)
519
516
      {
520
517
        zero_result_cause= "No matching min/max row";
521
 
        tables = 0;
522
 
        goto setup_subq_exit;
 
518
        error=0;
 
519
        return(0);
523
520
      }
524
521
      if (res > 1)
525
522
      {
529
526
      if (res < 0)
530
527
      {
531
528
        zero_result_cause= "No matching min/max row";
532
 
        tables = 0;
533
 
        goto setup_subq_exit;
 
529
        error=0;
 
530
        return(0);
534
531
      }
535
532
      zero_result_cause= "Select tables optimized away";
536
533
      tables_list= 0;       // All tables resolved
537
 
      const_tables= tables;
538
534
      /*
539
535
        Extract all table-independent conditions and replace the WHERE
540
536
        clause with them. All other conditions were computed by optimizer::sum_query
550
546
        COND *table_independent_conds= make_cond_for_table(conds, PSEUDO_TABLE_BITS, 0, 0);
551
547
        conds= table_independent_conds;
552
548
      }
553
 
      goto setup_subq_exit;
554
549
    }
555
550
  }
556
551
  if (!tables_list)
583
578
       select_lex->master_unit() == &session->lex->unit)) // upper level SELECT
584
579
  {
585
580
    zero_result_cause= "no matching row in const table";
586
 
    goto setup_subq_exit;
 
581
    error= 0;
 
582
    return(0);
587
583
  }
588
584
  if (!(session->options & OPTION_BIG_SELECTS) &&
589
585
      best_read > (double) session->variables.max_join_size &&
594
590
    return 1;
595
591
  }
596
592
  if (const_tables && !(select_options & SELECT_NO_UNLOCK))
597
 
    session->unlockSomeTables(table, const_tables);
 
593
    mysql_unlock_some_tables(session, table, const_tables);
598
594
  if (!conds && outer_join)
599
595
  {
600
596
    /* Handle the case where we have an OUTER JOIN without a WHERE */
649
645
  {
650
646
    zero_result_cause=
651
647
      "Impossible WHERE noticed after reading const tables";
652
 
    goto setup_subq_exit;
 
648
    return(0);        // error == 0
653
649
  }
654
650
 
655
651
  error= -1;          /* if goto err */
656
652
 
657
653
  /* Optimize distinct away if possible */
658
654
  {
659
 
    Order *org_order= order;
 
655
    order_st *org_order= order;
660
656
    order= remove_constants(this, order,conds,1, &simple_order);
661
657
    if (session->is_error())
662
658
    {
790
786
  }
791
787
  simple_group= 0;
792
788
  {
793
 
    Order *old_group_list;
 
789
    order_st *old_group_list;
794
790
    group_list= remove_constants(this, (old_group_list= group_list), conds,
795
791
                                 rollup.state == ROLLUP::STATE_NONE,
796
792
                                 &simple_group);
868
864
        save_index_subquery_explain_info(join_tab, where);
869
865
        join_tab[0].type= AM_UNIQUE_SUBQUERY;
870
866
        error= 0;
871
 
        return(unit->item->change_engine(new subselect_uniquesubquery_engine(session, join_tab, unit->item, where)));
 
867
        return(unit->item->
 
868
                    change_engine(new
 
869
                                  subselect_uniquesubquery_engine(session,
 
870
                                                                  join_tab,
 
871
                                                                  unit->item,
 
872
                                                                  where)));
872
873
      }
873
874
      else if (join_tab[0].type == AM_REF &&
874
875
         join_tab[0].ref.items[0]->name == in_left_expr_name)
877
878
        save_index_subquery_explain_info(join_tab, where);
878
879
        join_tab[0].type= AM_INDEX_SUBQUERY;
879
880
        error= 0;
880
 
        return(unit->item->change_engine(new subselect_indexsubquery_engine(session, join_tab, unit->item, where, NULL, 0)));
 
881
        return(unit->item->
 
882
                    change_engine(new
 
883
                                  subselect_indexsubquery_engine(session,
 
884
                                                                 join_tab,
 
885
                                                                 unit->item,
 
886
                                                                 where,
 
887
                                                                 NULL,
 
888
                                                                 0)));
881
889
      }
882
890
    } 
883
891
    else if (join_tab[0].type == AM_REF_OR_NULL &&
888
896
      error= 0;
889
897
      conds= remove_additional_cond(conds);
890
898
      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)));
 
899
      return(unit->item->
 
900
      change_engine(new subselect_indexsubquery_engine(session,
 
901
                   join_tab,
 
902
                   unit->item,
 
903
                   conds,
 
904
                                                                   having,
 
905
                   1)));
892
906
    }
893
907
 
894
908
  }
940
954
        Force using of tmp table if sorting by a SP or UDF function due to
941
955
        their expensive and probably non-deterministic nature.
942
956
      */
943
 
      for (Order *tmp_order= order; tmp_order ; tmp_order=tmp_order->next)
 
957
      for (order_st *tmp_order= order; tmp_order ; tmp_order=tmp_order->next)
944
958
      {
945
959
        Item *item= *tmp_order->item;
946
960
        if (item->is_expensive())
984
998
 
985
999
    tmp_table_param.hidden_field_count= (all_fields.elements -
986
1000
           fields_list.elements);
987
 
    Order *tmp_group= ((!simple_group &&
 
1001
    order_st *tmp_group= ((!simple_group && 
988
1002
                           ! (test_flags.test(TEST_NO_KEY_GROUP))) ? group_list :
989
 
                                                                     (Order*) 0);
 
1003
                                                                     (order_st*) 0);
990
1004
    /*
991
1005
      Pushing LIMIT to the temporary table creation is not applicable
992
1006
      when there is ORDER BY or GROUP BY or there is no GROUP BY, but
1089
1103
      If this join belongs to an uncacheable subquery save
1090
1104
      the original join
1091
1105
    */
1092
 
    if (select_lex->uncacheable.any() && 
1093
 
        ! is_top_level_join() &&
 
1106
    if (select_lex->uncacheable && !is_top_level_join() &&
1094
1107
        init_save_join_tab())
1095
 
    {
1096
 
      return -1;
1097
 
    }
 
1108
      return(-1);
1098
1109
  }
1099
1110
 
1100
1111
  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;
 
1112
  return(0);
1111
1113
}
1112
1114
 
1113
1115
/**
1114
1116
  Restore values in temporary join.
1115
1117
*/
1116
 
void Join::restore_tmp()
 
1118
void JOIN::restore_tmp()
1117
1119
{
1118
 
  memcpy(tmp_join, this, (size_t) sizeof(Join));
 
1120
  memcpy(tmp_join, this, (size_t) sizeof(JOIN));
1119
1121
}
1120
1122
 
1121
 
int Join::reinit()
 
1123
int JOIN::reinit()
1122
1124
{
1123
1125
  unit->offset_limit_cnt= (ha_rows)(select_lex->offset_limit ?
1124
1126
                                    select_lex->offset_limit->val_uint() :
1170
1172
   @retval 0      success.
1171
1173
   @retval 1      error occurred.
1172
1174
*/
1173
 
bool Join::init_save_join_tab()
 
1175
bool JOIN::init_save_join_tab()
1174
1176
{
1175
 
  if (!(tmp_join= (Join*)session->alloc(sizeof(Join))))
 
1177
  if (!(tmp_join= (JOIN*)session->alloc(sizeof(JOIN))))
1176
1178
    return 1;
1177
 
 
1178
1179
  error= 0;              // Ensure that tmp_join.error= 0
1179
1180
  restore_tmp();
1180
 
 
1181
1181
  return 0;
1182
1182
}
1183
1183
 
1184
 
bool Join::save_join_tab()
 
1184
bool JOIN::save_join_tab()
1185
1185
{
1186
 
  if (! join_tab_save && select_lex->master_unit()->uncacheable.any())
 
1186
  if (!join_tab_save && select_lex->master_unit()->uncacheable)
1187
1187
  {
1188
1188
    if (!(join_tab_save= (JoinTable*)session->memdup((unsigned char*) join_tab,
1189
1189
            sizeof(JoinTable) * tables)))
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;
1414
1414
                                                   - curr_join->tmp_fields_list1.elements;
1415
1415
 
1416
1416
      if (exec_tmp_table2)
1417
 
      {
1418
1417
        curr_tmp_table= exec_tmp_table2;
1419
 
      }
1420
1418
      else
1421
1419
      {
1422
1420
        /* group data to new table */
1424
1422
        /*
1425
1423
          If the access method is loose index scan then all MIN/MAX
1426
1424
          functions are precomputed, and should be treated as regular
1427
 
          functions. See extended comment in Join::exec.
 
1425
          functions. See extended comment in JOIN::exec.
1428
1426
        */
1429
1427
        if (curr_join->join_tab->is_using_loose_index_scan())
1430
1428
          curr_join->tmp_table_param.precomputed_group_by= true;
1433
1431
              exec_tmp_table2= create_tmp_table(session,
1434
1432
                                                &curr_join->tmp_table_param,
1435
1433
                                                *curr_all_fields,
1436
 
                                                (Order*) 0,
 
1434
                                                (order_st*) 0,
1437
1435
                                                curr_join->select_distinct &&
1438
1436
                                                !curr_join->group_list,
1439
1437
                                                1, curr_join->select_options,
1440
1438
                                                HA_POS_ERROR,
1441
1439
                                                (char *) "")))
1442
 
        {
1443
1440
          return;
1444
 
        }
1445
 
 
1446
1441
        curr_join->exec_tmp_table2= exec_tmp_table2;
1447
1442
      }
1448
1443
      if (curr_join->group_list)
1701
1696
  Clean up join.
1702
1697
 
1703
1698
  @return
1704
 
    Return error that hold Join.
 
1699
    Return error that hold JOIN.
1705
1700
*/
1706
 
int Join::destroy()
 
1701
int JOIN::destroy()
1707
1702
{
1708
1703
  select_lex->join= 0;
1709
1704
 
1722
1717
  cond_equal= 0;
1723
1718
 
1724
1719
  cleanup(1);
1725
 
  exec_tmp_table1= NULL;
1726
 
  exec_tmp_table2= NULL;
 
1720
  if (exec_tmp_table1)
 
1721
    exec_tmp_table1->free_tmp_table(session);
 
1722
  if (exec_tmp_table2)
 
1723
    exec_tmp_table2->free_tmp_table(session);
1727
1724
  delete select;
1728
1725
  delete_dynamic(&keyuse);
1729
 
 
1730
1726
  return(error);
1731
1727
}
1732
1728
 
1739
1735
  - try to initialize all data structures needed for the materialized execution
1740
1736
    of the IN predicate,
1741
1737
  - if this fails, then perform the IN=>EXISTS transformation which was
1742
 
    previously blocked during Join::prepare.
 
1738
    previously blocked during JOIN::prepare.
1743
1739
 
1744
1740
  This method is part of the "code generation" query processing phase.
1745
1741
 
1752
1748
  @retval false     success.
1753
1749
  @retval true      error occurred.
1754
1750
*/
1755
 
bool Join::setup_subquery_materialization()
 
1751
bool JOIN::setup_subquery_materialization()
1756
1752
{
1757
1753
  for (Select_Lex_Unit *un= select_lex->first_inner_unit(); un;
1758
1754
       un= un->next_unit())
1774
1770
}
1775
1771
 
1776
1772
/**
1777
 
  Partially cleanup Join after it has executed: close index or rnd read
 
1773
  Partially cleanup JOIN after it has executed: close index or rnd read
1778
1774
  (table cursors), free quick selects.
1779
1775
 
1780
 
    This function is called in the end of execution of a Join, before the used
 
1776
    This function is called in the end of execution of a JOIN, before the used
1781
1777
    tables are unlocked and closed.
1782
1778
 
1783
1779
    For a join that is resolved using a temporary table, the first sweep is
1791
1787
    is called after all rows are sent, but before EOF packet is sent.
1792
1788
 
1793
1789
    For a simple SELECT with no subqueries this function performs a full
1794
 
    cleanup of the Join and calls unlockReadTables to free used base
 
1790
    cleanup of the JOIN and calls mysql_unlock_read_tables to free used base
1795
1791
    tables.
1796
1792
 
1797
 
    If a Join is executed for a subquery or if it has a subquery, we can't
 
1793
    If a JOIN is executed for a subquery or if it has a subquery, we can't
1798
1794
    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
 
1795
    - If a JOIN is not the top level join, we must not unlock the tables
1800
1796
    because the outer select may not have been evaluated yet, and we
1801
1797
    can't unlock only selected tables of a query.
1802
 
    - Additionally, if this Join corresponds to a correlated subquery, we
 
1798
    - Additionally, if this JOIN corresponds to a correlated subquery, we
1803
1799
    should not free quick selects and join buffers because they will be
1804
1800
    needed for the next execution of the correlated subquery.
1805
 
    - However, if this is a Join for a [sub]select, which is not
 
1801
    - However, if this is a JOIN for a [sub]select, which is not
1806
1802
    a correlated subquery itself, but has subqueries, we can free it
1807
 
    fully and also free Joins of all its subqueries. The exception
 
1803
    fully and also free JOINs of all its subqueries. The exception
1808
1804
    is a subquery in SELECT list, e.g: @n
1809
1805
    SELECT a, (select cmax(b) from t1) group by c @n
1810
1806
    This subquery will not be evaluated at first sweep and its value will
1815
1811
  @todo
1816
1812
    Unlock tables even if the join isn't top level select in the tree
1817
1813
*/
1818
 
void Join::join_free()
 
1814
void JOIN::join_free()
1819
1815
{
1820
1816
  Select_Lex_Unit *tmp_unit;
1821
1817
  Select_Lex *sl;
1822
1818
  /*
1823
 
    Optimization: if not EXPLAIN and we are done with the Join,
 
1819
    Optimization: if not EXPLAIN and we are done with the JOIN,
1824
1820
    free all tables.
1825
1821
  */
1826
 
  bool full= (select_lex->uncacheable.none() && ! session->lex->describe);
 
1822
  bool full= (!select_lex->uncacheable && !session->lex->describe);
1827
1823
  bool can_unlock= full;
1828
1824
 
1829
1825
  cleanup(full);
1845
1841
        but all table cursors must be closed before the unlock.
1846
1842
      */
1847
1843
      sl->cleanup_all_joins(full_local);
1848
 
      /* Can't unlock if at least one Join is still needed */
 
1844
      /* Can't unlock if at least one JOIN is still needed */
1849
1845
      can_unlock= can_unlock && full_local;
1850
1846
    }
1851
1847
 
1863
1859
      TODO: unlock tables even if the join isn't top level select in the
1864
1860
      tree.
1865
1861
    */
1866
 
    session->unlockReadTables(lock);           // Don't free join->lock
 
1862
    mysql_unlock_read_tables(session, lock);           // Don't free join->lock
1867
1863
    lock= 0;
1868
1864
  }
1869
1865
 
1882
1878
    With subquery this function definitely will be called several times,
1883
1879
    but even for simple query it can be called several times.
1884
1880
*/
1885
 
void Join::cleanup(bool full)
 
1881
void JOIN::cleanup(bool full)
1886
1882
{
1887
1883
  if (table)
1888
1884
  {
1927
1923
    */
1928
1924
    tmp_table_param.copy_funcs.empty();
1929
1925
    /*
1930
 
      If we have tmp_join and 'this' Join is not tmp_join and
 
1926
      If we have tmp_join and 'this' JOIN is not tmp_join and
1931
1927
      tmp_table_param.copy_field's  of them are equal then we have to remove
1932
1928
      pointer to  tmp_table_param.copy_field from tmp_join, because it qill
1933
1929
      be removed in tmp_table_param.cleanup().
1946
1942
}
1947
1943
 
1948
1944
/*
1949
 
  used only in Join::clear
 
1945
  used only in JOIN::clear
1950
1946
*/
1951
 
static void clear_tables(Join *join)
 
1947
static void clear_tables(JOIN *join)
1952
1948
{
1953
1949
  /*
1954
1950
    must clear only the non-const tables, as const tables
1967
1963
  @retval
1968
1964
    1 Error
1969
1965
*/
1970
 
bool Join::alloc_func_list()
 
1966
bool JOIN::alloc_func_list()
1971
1967
{
1972
1968
  uint32_t func_count, group_parts;
1973
1969
 
1993
1989
    */
1994
1990
    if (order)
1995
1991
    {
1996
 
      Order *ord;
 
1992
      order_st *ord;
1997
1993
      for (ord= order; ord; ord= ord->next)
1998
1994
        group_parts++;
1999
1995
    }
2019
2015
  @retval
2020
2016
    1  error
2021
2017
*/
2022
 
bool Join::make_sum_func_list(List<Item> &field_list, 
 
2018
bool JOIN::make_sum_func_list(List<Item> &field_list, 
2023
2019
                              List<Item> &send_fields,
2024
2020
                              bool before_group_by, 
2025
2021
                              bool recompute)
2057
2053
}
2058
2054
 
2059
2055
/** Allocate memory needed for other rollup functions. */
2060
 
bool Join::rollup_init()
 
2056
bool JOIN::rollup_init()
2061
2057
{
2062
2058
  uint32_t i,j;
2063
2059
  Item **ref_array;
2103
2099
  Item *item;
2104
2100
  while ((item= it++))
2105
2101
  {
2106
 
    Order *group_tmp;
 
2102
    order_st *group_tmp;
2107
2103
    bool found_in_group= 0;
2108
2104
 
2109
2105
    for (group_tmp= group_list; group_tmp; group_tmp= group_tmp->next)
2132
2128
            return 1;
2133
2129
          new_item->fix_fields(session, (Item **) 0);
2134
2130
          session->change_item_tree(it.ref(), new_item);
2135
 
          for (Order *tmp= group_tmp; tmp; tmp= tmp->next)
 
2131
          for (order_st *tmp= group_tmp; tmp; tmp= tmp->next)
2136
2132
          {
2137
2133
            if (*tmp->item == item)
2138
2134
              session->change_item_tree(tmp->item, new_item);
2172
2168
  @retval
2173
2169
    1    on error
2174
2170
*/
2175
 
bool Join::rollup_make_fields(List<Item> &fields_arg, List<Item> &sel_fields, Item_sum ***func)
 
2171
bool JOIN::rollup_make_fields(List<Item> &fields_arg, List<Item> &sel_fields, Item_sum ***func)
2176
2172
{
2177
2173
  List_iterator_fast<Item> it(fields_arg);
2178
2174
  Item *first_field= sel_fields.head();
2207
2203
    Item *item;
2208
2204
    List_iterator<Item> new_it(rollup.fields[pos]);
2209
2205
    Item **ref_array_start= rollup.ref_pointer_arrays[pos];
2210
 
    Order *start_group;
 
2206
    order_st *start_group;
2211
2207
 
2212
2208
    /* Point to first hidden field */
2213
2209
    Item **ref_array= ref_array_start + fields_arg.elements-1;
2249
2245
      else
2250
2246
      {
2251
2247
        /* Check if this is something that is part of this group by */
2252
 
        Order *group_tmp;
 
2248
        order_st *group_tmp;
2253
2249
        for (group_tmp= start_group, i= pos ;
2254
2250
                  group_tmp ; group_tmp= group_tmp->next, i++)
2255
2251
        {
2302
2298
  @retval
2303
2299
    1   If send_data_failed()
2304
2300
*/
2305
 
int Join::rollup_send_data(uint32_t idx)
 
2301
int JOIN::rollup_send_data(uint32_t idx)
2306
2302
{
2307
2303
  uint32_t i;
2308
2304
  for (i= send_group_parts ; i-- > idx ; )
2342
2338
  @retval
2343
2339
    1   if write_data_failed()
2344
2340
*/
2345
 
int Join::rollup_write_data(uint32_t idx, Table *table_arg)
 
2341
int JOIN::rollup_write_data(uint32_t idx, Table *table_arg)
2346
2342
{
2347
2343
  uint32_t i;
2348
2344
  for (i= send_group_parts ; i-- > idx ; )
2361
2357
          item->save_in_result_field(1);
2362
2358
      }
2363
2359
      copy_sum_funcs(sum_funcs_end[i+1], sum_funcs_end[i]);
2364
 
      if ((write_error= table_arg->cursor->insertRecord(table_arg->getInsertRecord())))
 
2360
      if ((write_error= table_arg->cursor->insertRecord(table_arg->record[0])))
2365
2361
      {
2366
2362
        my_error(ER_USE_SQL_BIG_RESULT, MYF(0));
2367
2363
        return 1;
2377
2373
  clear results if there are not rows found for group
2378
2374
  (end_send_group/end_write_group)
2379
2375
*/
2380
 
void Join::clear()
 
2376
void JOIN::clear()
2381
2377
{
2382
2378
  clear_tables(this);
2383
2379
  copy_fields(&tmp_table_param);
2391
2387
}
2392
2388
 
2393
2389
/**
2394
 
  change select_result object of Join.
 
2390
  change select_result object of JOIN.
2395
2391
 
2396
2392
  @param res    new select_result object
2397
2393
 
2400
2396
  @retval
2401
2397
    true    error
2402
2398
*/
2403
 
bool Join::change_result(select_result *res)
 
2399
bool JOIN::change_result(select_result *res)
2404
2400
{
2405
2401
  result= res;
2406
2402
  if (result->prepare(fields_list, select_lex->master_unit()))
2414
2410
  Cache constant expressions in WHERE, HAVING, ON conditions.
2415
2411
*/
2416
2412
 
2417
 
void Join::cache_const_exprs()
 
2413
void JOIN::cache_const_exprs()
2418
2414
{
2419
2415
  bool cache_flag= false;
2420
2416
  bool *analyzer_arg= &cache_flag;
2455
2451
  applicable to the partial record on hand and in case of success
2456
2452
  submit this record to the next level of the nested loop.
2457
2453
*/
2458
 
enum_nested_loop_state evaluate_join_record(Join *join, JoinTable *join_tab, int error)
 
2454
enum_nested_loop_state evaluate_join_record(JOIN *join, JoinTable *join_tab, int error)
2459
2455
{
2460
2456
  bool not_used_in_distinct= join_tab->not_used_in_distinct;
2461
2457
  ha_rows found_records= join->found_records;
2465
2461
    return NESTED_LOOP_ERROR;
2466
2462
  if (error < 0)
2467
2463
    return NESTED_LOOP_NO_MORE_ROWS;
2468
 
  if (join->session->getKilled())                       // Aborted by user
 
2464
  if (join->session->killed)                    // Aborted by user
2469
2465
  {
2470
2466
    join->session->send_kill_message();
2471
2467
    return NESTED_LOOP_KILLED;
2579
2575
    level of the nested loop. This function is used in case we have
2580
2576
    an OUTER join and no matching record was found.
2581
2577
*/
2582
 
enum_nested_loop_state evaluate_null_complemented_join_record(Join *join, JoinTable *join_tab)
 
2578
enum_nested_loop_state evaluate_null_complemented_join_record(JOIN *join, JoinTable *join_tab)
2583
2579
{
2584
2580
  /*
2585
2581
    The table join_tab is the first inner table of a outer join operation
2635
2631
  return (*join_tab->next_select)(join, join_tab+1, 0);
2636
2632
}
2637
2633
 
2638
 
enum_nested_loop_state flush_cached_records(Join *join, JoinTable *join_tab, bool skip_last)
 
2634
enum_nested_loop_state flush_cached_records(JOIN *join, JoinTable *join_tab, bool skip_last)
2639
2635
{
2640
2636
  enum_nested_loop_state rc= NESTED_LOOP_OK;
2641
2637
  int error;
2643
2639
 
2644
2640
  join_tab->table->null_row= 0;
2645
2641
  if (!join_tab->cache.records)
2646
 
  {
2647
2642
    return NESTED_LOOP_OK;                      /* Nothing to do */
2648
 
  }
2649
 
 
2650
2643
  if (skip_last)
2651
 
  {
2652
 
    (void) join_tab->cache.store_record_in_cache(); // Must save this for later
2653
 
  }
2654
 
 
2655
 
 
 
2644
    (void) store_record_in_cache(&join_tab->cache); // Must save this for later
2656
2645
  if (join_tab->use_quick == 2)
2657
2646
  {
2658
2647
    if (join_tab->select->quick)
2664
2653
  /* read through all records */
2665
2654
  if ((error=join_init_read_record(join_tab)))
2666
2655
  {
2667
 
    join_tab->cache.reset_cache_write();
 
2656
    reset_cache_write(&join_tab->cache);
2668
2657
    return error < 0 ? NESTED_LOOP_NO_MORE_ROWS: NESTED_LOOP_ERROR;
2669
2658
  }
2670
2659
 
2677
2666
  info= &join_tab->read_record;
2678
2667
  do
2679
2668
  {
2680
 
    if (join->session->getKilled())
 
2669
    if (join->session->killed)
2681
2670
    {
2682
2671
      join->session->send_kill_message();
2683
2672
      return NESTED_LOOP_KILLED;
2687
2676
        (!join_tab->cache.select || !join_tab->cache.select->skip_record()))
2688
2677
    {
2689
2678
      uint32_t i;
2690
 
      join_tab->cache.reset_cache_read();
 
2679
      reset_cache_read(&join_tab->cache);
2691
2680
      for (i=(join_tab->cache.records- (skip_last ? 1 : 0)) ; i-- > 0 ;)
2692
2681
      {
2693
2682
              join_tab->readCachedRecord();
2698
2687
          rc= (join_tab->next_select)(join,join_tab+1,0);
2699
2688
          if (rc != NESTED_LOOP_OK && rc != NESTED_LOOP_NO_MORE_ROWS)
2700
2689
          {
2701
 
            join_tab->cache.reset_cache_write();
 
2690
            reset_cache_write(&join_tab->cache);
2702
2691
            return rc;
2703
2692
          }
2704
2693
 
2711
2700
 
2712
2701
  if (skip_last)
2713
2702
    join_tab->readCachedRecord();               // Restore current record
2714
 
  join_tab->cache.reset_cache_write();
 
2703
  reset_cache_write(&join_tab->cache);
2715
2704
  if (error > 0)                                // Fatal error
2716
2705
    return NESTED_LOOP_ERROR;
2717
2706
  for (JoinTable *tmp2=join->join_tab; tmp2 != join_tab ; tmp2++)
2743
2732
                               operation.
2744
2733
   All return values except NESTED_LOOP_OK abort the nested loop.
2745
2734
*****************************************************************************/
2746
 
enum_nested_loop_state end_send(Join *join, JoinTable *, bool end_of_records)
 
2735
enum_nested_loop_state end_send(JOIN *join, JoinTable *, bool end_of_records)
2747
2736
{
2748
2737
  if (! end_of_records)
2749
2738
  {
2805
2794
  return NESTED_LOOP_OK;
2806
2795
}
2807
2796
 
2808
 
enum_nested_loop_state end_write(Join *join, JoinTable *, bool end_of_records)
 
2797
enum_nested_loop_state end_write(JOIN *join, JoinTable *, bool end_of_records)
2809
2798
{
2810
2799
  Table *table= join->tmp_table;
2811
2800
 
2812
 
  if (join->session->getKilled())                       // Aborted by user
 
2801
  if (join->session->killed)                    // Aborted by user
2813
2802
  {
2814
2803
    join->session->send_kill_message();
2815
2804
    return NESTED_LOOP_KILLED;
2817
2806
  if (!end_of_records)
2818
2807
  {
2819
2808
    copy_fields(&join->tmp_table_param);
2820
 
    if (copy_funcs(join->tmp_table_param.items_to_copy, join->session))
2821
 
      return NESTED_LOOP_ERROR;
 
2809
    copy_funcs(join->tmp_table_param.items_to_copy);
2822
2810
    if (!join->having || join->having->val_int())
2823
2811
    {
2824
2812
      int error;
2825
2813
      join->found_records++;
2826
 
      if ((error=table->cursor->insertRecord(table->getInsertRecord())))
 
2814
      if ((error=table->cursor->insertRecord(table->record[0])))
2827
2815
      {
2828
2816
        if (!table->cursor->is_fatal_error(error, HA_CHECK_DUP))
2829
 
        {
2830
 
          return NESTED_LOOP_OK;
2831
 
        }
 
2817
          goto end;
2832
2818
 
2833
2819
        my_error(ER_USE_SQL_BIG_RESULT, MYF(0));
2834
2820
        return NESTED_LOOP_ERROR;        // Table is_full error
2843
2829
      }
2844
2830
    }
2845
2831
  }
2846
 
 
 
2832
end:
2847
2833
  return NESTED_LOOP_OK;
2848
2834
}
2849
2835
 
2850
2836
/** 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)
 
2837
enum_nested_loop_state end_update(JOIN *join, JoinTable *, bool end_of_records)
2852
2838
{
2853
2839
  Table *table= join->tmp_table;
2854
 
  Order *group;
 
2840
  order_st *group;
2855
2841
  int   error;
2856
2842
 
2857
2843
  if (end_of_records)
2858
2844
    return NESTED_LOOP_OK;
2859
 
  if (join->session->getKilled())                       // Aborted by user
 
2845
  if (join->session->killed)                    // Aborted by user
2860
2846
  {
2861
2847
    join->session->send_kill_message();
2862
2848
    return NESTED_LOOP_KILLED;
2873
2859
    if (item->maybe_null)
2874
2860
      group->buff[-1]= (char) group->field->is_null();
2875
2861
  }
2876
 
  if (!table->cursor->index_read_map(table->getUpdateRecord(),
 
2862
  if (!table->cursor->index_read_map(table->record[1],
2877
2863
                                   join->tmp_table_param.group_buff,
2878
2864
                                   HA_WHOLE_KEY,
2879
2865
                                   HA_READ_KEY_EXACT))
2880
2866
  {                                             /* Update old record */
2881
2867
    table->restoreRecord();
2882
2868
    update_tmptable_sum_func(join->sum_funcs,table);
2883
 
    if ((error= table->cursor->updateRecord(table->getUpdateRecord(),
2884
 
                                          table->getInsertRecord())))
 
2869
    if ((error= table->cursor->updateRecord(table->record[1],
 
2870
                                          table->record[0])))
2885
2871
    {
2886
2872
      table->print_error(error,MYF(0));
2887
2873
      return NESTED_LOOP_ERROR;
2900
2886
       group=group->next,key_part++)
2901
2887
  {
2902
2888
    if (key_part->null_bit)
2903
 
      memcpy(table->getInsertRecord()+key_part->offset, group->buff, 1);
 
2889
      memcpy(table->record[0]+key_part->offset, group->buff, 1);
2904
2890
  }
2905
2891
  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())))
 
2892
  copy_funcs(join->tmp_table_param.items_to_copy);
 
2893
  if ((error=table->cursor->insertRecord(table->record[0])))
2909
2894
  {
2910
2895
    my_error(ER_USE_SQL_BIG_RESULT, MYF(0));
2911
2896
    return NESTED_LOOP_ERROR;        // Table is_full error
2915
2900
}
2916
2901
 
2917
2902
/** 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)
 
2903
enum_nested_loop_state end_unique_update(JOIN *join, JoinTable *, bool end_of_records)
2919
2904
{
2920
2905
  Table *table= join->tmp_table;
2921
2906
  int   error;
2922
2907
 
2923
2908
  if (end_of_records)
2924
2909
    return NESTED_LOOP_OK;
2925
 
  if (join->session->getKilled())                       // Aborted by user
 
2910
  if (join->session->killed)                    // Aborted by user
2926
2911
  {
2927
2912
    join->session->send_kill_message();
2928
2913
    return NESTED_LOOP_KILLED;
2930
2915
 
2931
2916
  init_tmptable_sum_functions(join->sum_funcs);
2932
2917
  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;
 
2918
  copy_funcs(join->tmp_table_param.items_to_copy);
2935
2919
 
2936
 
  if (!(error= table->cursor->insertRecord(table->getInsertRecord())))
 
2920
  if (!(error= table->cursor->insertRecord(table->record[0])))
2937
2921
    join->send_records++;                       // New group
2938
2922
  else
2939
2923
  {
2942
2926
      table->print_error(error,MYF(0));
2943
2927
      return NESTED_LOOP_ERROR;
2944
2928
    }
2945
 
    if (table->cursor->rnd_pos(table->getUpdateRecord(),table->cursor->dup_ref))
 
2929
    if (table->cursor->rnd_pos(table->record[1],table->cursor->dup_ref))
2946
2930
    {
2947
2931
      table->print_error(error,MYF(0));
2948
2932
      return NESTED_LOOP_ERROR;
2949
2933
    }
2950
2934
    table->restoreRecord();
2951
2935
    update_tmptable_sum_func(join->sum_funcs,table);
2952
 
    if ((error= table->cursor->updateRecord(table->getUpdateRecord(),
2953
 
                                          table->getInsertRecord())))
 
2936
    if ((error= table->cursor->updateRecord(table->record[1],
 
2937
                                          table->record[0])))
2954
2938
    {
2955
2939
      table->print_error(error,MYF(0));
2956
2940
      return NESTED_LOOP_ERROR;
2971
2955
  @retval
2972
2956
    1   failed
2973
2957
*/
2974
 
static bool make_group_fields(Join *main_join, Join *curr_join)
 
2958
static bool make_group_fields(JOIN *main_join, JOIN *curr_join)
2975
2959
{
2976
2960
  if (main_join->group_fields_cache.elements)
2977
2961
  {
2990
2974
/**
2991
2975
  calc how big buffer we need for comparing group entries.
2992
2976
*/
2993
 
static void calc_group_buffer(Join *join, Order *group)
 
2977
static void calc_group_buffer(JOIN *join,order_st *group)
2994
2978
{
2995
2979
  uint32_t key_length=0, parts=0, null_parts=0;
2996
2980
 
3016
3000
      case REAL_RESULT:
3017
3001
        key_length+= sizeof(double);
3018
3002
        break;
3019
 
 
3020
3003
      case INT_RESULT:
3021
3004
        key_length+= sizeof(int64_t);
3022
3005
        break;
3023
 
 
3024
3006
      case DECIMAL_RESULT:
3025
3007
        key_length+= my_decimal_get_binary_size(group_item->max_length -
3026
3008
                                                (group_item->decimals ? 1 : 0),
3027
3009
                                                group_item->decimals);
3028
3010
        break;
3029
 
 
3030
3011
      case STRING_RESULT:
3031
 
        {
3032
 
          enum enum_field_types type= group_item->field_type();
 
3012
      {
 
3013
        enum enum_field_types type= group_item->field_type();
 
3014
        /*
 
3015
          As items represented as DATE/TIME fields in the group buffer
 
3016
          have STRING_RESULT result type, we increase the length
 
3017
          by 8 as maximum pack length of such fields.
 
3018
        */
 
3019
        if (type == DRIZZLE_TYPE_DATE ||
 
3020
            type == DRIZZLE_TYPE_DATETIME ||
 
3021
            type == DRIZZLE_TYPE_TIMESTAMP)
 
3022
        {
 
3023
          key_length+= 8;
 
3024
        }
 
3025
        else
 
3026
        {
3033
3027
          /*
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.
 
3028
            Group strings are taken as varstrings and require an length field.
 
3029
            A field is not yet created by create_tmp_field()
 
3030
            and the sizes should match up.
3037
3031
          */
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;
 
3032
          key_length+= group_item->max_length + HA_KEY_BLOB_LENGTH;
3054
3033
        }
3055
 
 
3056
 
      case ROW_RESULT:
 
3034
        break;
 
3035
      }
 
3036
      default:
3057
3037
        /* This case should never be choosen */
3058
3038
        assert(0);
3059
3039
        my_error(ER_OUT_OF_RESOURCES, MYF(ME_FATALERROR));
3060
3040
      }
3061
3041
    }
3062
 
 
3063
3042
    parts++;
3064
 
 
3065
3043
    if (group_item->maybe_null)
3066
3044
      null_parts++;
3067
3045
  }
3068
 
 
3069
3046
  join->tmp_table_param.group_length=key_length+null_parts;
3070
3047
  join->tmp_table_param.group_parts=parts;
3071
3048
  join->tmp_table_param.group_null_parts=null_parts;
3076
3053
 
3077
3054
  Groups are saved in reverse order for easyer check loop.
3078
3055
*/
3079
 
static bool alloc_group_fields(Join *join, Order *group)
 
3056
static bool alloc_group_fields(JOIN *join,order_st *group)
3080
3057
{
3081
3058
  if (group)
3082
3059
  {
3091
3068
  return false;
3092
3069
}
3093
3070
 
3094
 
static uint32_t cache_record_length(Join *join,uint32_t idx)
 
3071
static uint32_t cache_record_length(JOIN *join,uint32_t idx)
3095
3072
{
3096
3073
  uint32_t length=0;
3097
3074
  JoinTable **pos,**end;
3159
3136
  RETURN
3160
3137
    Expected number of row combinations
3161
3138
*/
3162
 
static double prev_record_reads(Join *join, uint32_t idx, table_map found_ref)
 
3139
static double prev_record_reads(JOIN *join, uint32_t idx, table_map found_ref)
3163
3140
{
3164
3141
  double found=1.0;
3165
3142
  optimizer::Position *pos_end= join->getSpecificPosInPartialPlan(-1);
3171
3148
    {
3172
3149
      found_ref|= pos->getRefDependMap();
3173
3150
      /*
3174
 
        For the case of "t1 LEFT Join t2 ON ..." where t2 is a const table
 
3151
        For the case of "t1 LEFT JOIN t2 ON ..." where t2 is a const table
3175
3152
        with no matching row we will get position[t2].records_read==0.
3176
3153
        Actually the size of output is one null-complemented row, therefore
3177
3154
        we will use value of 1 whenever we get records_read==0.
3196
3173
/**
3197
3174
  Set up join struct according to best position.
3198
3175
*/
3199
 
static bool get_best_combination(Join *join)
 
3176
static bool get_best_combination(JOIN *join)
3200
3177
{
3201
3178
  uint32_t i,tablenr;
3202
3179
  table_map used_tables;
3223
3200
    used_tables|= form->map;
3224
3201
    form->reginfo.join_tab=j;
3225
3202
    if (!*j->on_expr_ref)
3226
 
      form->reginfo.not_exists_optimize=0;  // Only with LEFT Join
 
3203
      form->reginfo.not_exists_optimize=0;  // Only with LEFT JOIN
3227
3204
    if (j->type == AM_CONST)
3228
3205
      continue;         // Handled in make_join_stat..
3229
3206
 
3249
3226
}
3250
3227
 
3251
3228
/** Save const tables first as used tables. */
3252
 
static void set_position(Join *join,
 
3229
static void set_position(JOIN *join,
3253
3230
                         uint32_t idx,
3254
3231
                         JoinTable *table,
3255
3232
                         optimizer::KeyUse *key)
3291
3268
  @retval
3292
3269
    true        Fatal error
3293
3270
*/
3294
 
static bool choose_plan(Join *join, table_map join_tables)
 
3271
static bool choose_plan(JOIN *join, table_map join_tables)
3295
3272
{
3296
3273
  uint32_t search_depth= join->session->variables.optimizer_search_depth;
3297
3274
  uint32_t prune_level=  join->session->variables.optimizer_prune_level;
3358
3335
  @return
3359
3336
    None
3360
3337
*/
3361
 
static void best_access_path(Join *join,
 
3338
static void best_access_path(JOIN *join,
3362
3339
                             JoinTable *s,
3363
3340
                             Session *session,
3364
3341
                             table_map remaining_tables,
3504
3481
                records=
3505
3482
                  ((double) s->records / (double) rec *
3506
3483
                   (1.0 +
3507
 
                    ((double) (table->getShare()->max_key_length-keyinfo->key_length) /
3508
 
                     (double) table->getShare()->max_key_length)));
 
3484
                    ((double) (table->s->max_key_length-keyinfo->key_length) /
 
3485
                     (double) table->s->max_key_length)));
3509
3486
                if (records < 2.0)
3510
3487
                  records=2.0;               /* Can't be as good as a unique */
3511
3488
              }
3888
3865
    Thus 'optimize_straight_join' can be used at any stage of the query
3889
3866
    optimization process to finalize a QEP as it is.
3890
3867
*/
3891
 
static void optimize_straight_join(Join *join, table_map join_tables)
 
3868
static void optimize_straight_join(JOIN *join, table_map join_tables)
3892
3869
{
3893
3870
  JoinTable *s;
3894
3871
  optimizer::Position partial_pos;
3998
3975
  @retval
3999
3976
    true        Fatal error
4000
3977
*/
4001
 
static bool greedy_search(Join      *join,
 
3978
static bool greedy_search(JOIN      *join,
4002
3979
              table_map remaining_tables,
4003
3980
              uint32_t      search_depth,
4004
3981
              uint32_t      prune_level)
4040
4017
    */
4041
4018
    join->setPosInPartialPlan(idx, best_pos);
4042
4019
 
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
4020
    /* find the position of 'best_table' in 'join->best_ref' */
4053
4021
    best_idx= idx;
4054
4022
    JoinTable *pos= join->best_ref[best_idx];
4186
4154
  @retval
4187
4155
    true        Fatal error
4188
4156
*/
4189
 
static bool best_extension_by_limited_search(Join *join,
 
4157
static bool best_extension_by_limited_search(JOIN *join,
4190
4158
                                             table_map remaining_tables,
4191
4159
                                             uint32_t idx,
4192
4160
                                             double record_count,
4195
4163
                                             uint32_t prune_level)
4196
4164
{
4197
4165
  Session *session= join->session;
4198
 
  if (session->getKilled())  // Abort
 
4166
  if (session->killed)  // Abort
4199
4167
    return(true);
4200
4168
 
4201
4169
  /*
4210
4178
  for (JoinTable **pos= join->best_ref + idx ; (s= *pos) ; pos++)
4211
4179
  {
4212
4180
    table_map real_table_bit= s->table->map;
 
4181
    if (idx)
 
4182
    {
 
4183
      partial_pos= join->getPosFromPartialPlan(idx - 1);
 
4184
    }
4213
4185
    if ((remaining_tables & real_table_bit) &&
4214
4186
        ! (remaining_tables & s->dependent) &&
4215
 
        (! idx || ! check_interleaving_with_nj(s)))
 
4187
        (! idx || ! check_interleaving_with_nj(partial_pos.getJoinTable(), s)))
4216
4188
    {
4217
4189
      double current_record_count, current_read_time;
4218
4190
 
4333
4305
    exhaustiveness) of the depth-first search algorithm used by
4334
4306
    'greedy_search'.
4335
4307
*/
4336
 
static uint32_t determine_search_depth(Join *join)
 
4308
static uint32_t determine_search_depth(JOIN *join)
4337
4309
{
4338
4310
  uint32_t table_count=  join->tables - join->const_tables;
4339
4311
  uint32_t search_depth;
4352
4324
  return search_depth;
4353
4325
}
4354
4326
 
4355
 
static bool make_simple_join(Join *join,Table *tmp_table)
 
4327
static bool make_simple_join(JOIN *join,Table *tmp_table)
4356
4328
{
4357
4329
  Table **tableptr;
4358
4330
  JoinTable *join_tab;
4359
4331
 
4360
4332
  /*
4361
4333
    Reuse Table * and JoinTable if already allocated by a previous call
4362
 
    to this function through Join::exec (may happen for sub-queries).
 
4334
    to this function through JOIN::exec (may happen for sub-queries).
4363
4335
  */
4364
4336
  if (!join->table_reexec)
4365
4337
  {
4409
4381
  join_tab->read_first_record= join_init_read_record;
4410
4382
  join_tab->join=join;
4411
4383
  join_tab->ref.key_parts= 0;
4412
 
  join_tab->read_record.init();
 
4384
  memset(&join_tab->read_record, 0, sizeof(join_tab->read_record));
4413
4385
  tmp_table->status=0;
4414
4386
  tmp_table->null_row=0;
4415
 
 
4416
 
  return false;
 
4387
  return(false);
4417
4388
}
4418
4389
 
4419
4390
/**
4457
4428
    This function can be called only after the execution plan
4458
4429
    has been chosen.
4459
4430
*/
4460
 
static void make_outerjoin_info(Join *join)
 
4431
static void make_outerjoin_info(JOIN *join)
4461
4432
{
4462
4433
  for (uint32_t i=join->const_tables ; i < join->tables ; i++)
4463
4434
  {
4464
4435
    JoinTable *tab=join->join_tab+i;
4465
4436
    Table *table=tab->table;
4466
4437
    TableList *tbl= table->pos_in_table_list;
4467
 
    TableList *embedding= tbl->getEmbedding();
 
4438
    TableList *embedding= tbl->embedding;
4468
4439
 
4469
4440
    if (tbl->outer_join)
4470
4441
    {
4477
4448
      tab->on_expr_ref= &tbl->on_expr;
4478
4449
      tab->cond_equal= tbl->cond_equal;
4479
4450
      if (embedding)
4480
 
        tab->first_upper= embedding->getNestedJoin()->first_nested;
 
4451
        tab->first_upper= embedding->nested_join->first_nested;
4481
4452
    }
4482
 
    for ( ; embedding ; embedding= embedding->getEmbedding())
 
4453
    for ( ; embedding ; embedding= embedding->embedding)
4483
4454
    {
4484
4455
      /* Ignore sj-nests: */
4485
4456
      if (!embedding->on_expr)
4486
4457
        continue;
4487
 
      nested_join_st *nested_join= embedding->getNestedJoin();
 
4458
      nested_join_st *nested_join= embedding->nested_join;
4488
4459
      if (!nested_join->counter_)
4489
4460
      {
4490
4461
        /*
4494
4465
        nested_join->first_nested= tab;
4495
4466
        tab->on_expr_ref= &embedding->on_expr;
4496
4467
        tab->cond_equal= tbl->cond_equal;
4497
 
        if (embedding->getEmbedding())
4498
 
          tab->first_upper= embedding->getEmbedding()->getNestedJoin()->first_nested;
 
4468
        if (embedding->embedding)
 
4469
          tab->first_upper= embedding->embedding->nested_join->first_nested;
4499
4470
      }
4500
4471
      if (!tab->first_inner)
4501
4472
        tab->first_inner= nested_join->first_nested;
4508
4479
  return;
4509
4480
}
4510
4481
 
4511
 
static bool make_join_select(Join *join,
 
4482
static bool make_join_select(JOIN *join,
4512
4483
                             optimizer::SqlSelect *select,
4513
4484
                             COND *cond)
4514
4485
{
4886
4857
    false - OK
4887
4858
    true  - Out of memory
4888
4859
*/
4889
 
static bool make_join_readinfo(Join *join)
 
4860
static bool make_join_readinfo(JOIN *join)
4890
4861
{
4891
4862
  bool sorted= true;
4892
4863
 
4934
4905
}
4935
4906
 
4936
4907
/** Update the dependency map for the tables. */
4937
 
static void update_depend_map(Join *join)
 
4908
static void update_depend_map(JOIN *join)
4938
4909
{
4939
4910
  JoinTable *join_tab=join->join_tab, *end=join_tab+join->tables;
4940
4911
 
4957
4928
}
4958
4929
 
4959
4930
/** Update the dependency map for the sort order. */
4960
 
static void update_depend_map(Join *join, Order *order)
 
4931
static void update_depend_map(JOIN *join, order_st *order)
4961
4932
{
4962
4933
  for (; order ; order=order->next)
4963
4934
  {
4995
4966
  @return
4996
4967
    Returns new sort order
4997
4968
*/
4998
 
static Order *remove_constants(Join *join,Order *first_order, COND *cond, bool change_list, bool *simple_order)
 
4969
static order_st *remove_constants(JOIN *join,order_st *first_order, COND *cond, bool change_list, bool *simple_order)
4999
4970
{
5000
4971
  if (join->tables == join->const_tables)
5001
4972
    return change_list ? 0 : first_order;               // No need to sort
5002
4973
 
5003
 
  Order *order,**prev_ptr;
 
4974
  order_st *order,**prev_ptr;
5004
4975
  table_map first_table= join->join_tab[join->const_tables].table->map;
5005
4976
  table_map not_const_tables= ~join->const_table_map;
5006
4977
  table_map ref;
5055
5026
  return(first_order);
5056
5027
}
5057
5028
 
5058
 
static int return_zero_rows(Join *join,
 
5029
static int return_zero_rows(JOIN *join,
5059
5030
                            select_result *result,
5060
5031
                            TableList *tables,
5061
5032
                                        List<Item> &fields,
5221
5192
    - The new condition, if success
5222
5193
    - 0, otherwise
5223
5194
*/
5224
 
static COND *simplify_joins(Join *join, List<TableList> *join_list, COND *conds, bool top)
 
5195
static COND *simplify_joins(JOIN *join, List<TableList> *join_list, COND *conds, bool top)
5225
5196
{
5226
5197
  TableList *table;
5227
5198
  nested_join_st *nested_join;
5237
5208
    table_map used_tables;
5238
5209
    table_map not_null_tables= (table_map) 0;
5239
5210
 
5240
 
    if ((nested_join= table->getNestedJoin()))
 
5211
    if ((nested_join= table->nested_join))
5241
5212
    {
5242
5213
      /*
5243
5214
         If the element of join_list is a nested join apply
5279
5250
        not_null_tables= conds->not_null_tables();
5280
5251
    }
5281
5252
 
5282
 
    if (table->getEmbedding())
 
5253
    if (table->embedding)
5283
5254
    {
5284
 
      table->getEmbedding()->getNestedJoin()->used_tables|= used_tables;
5285
 
      table->getEmbedding()->getNestedJoin()->not_null_tables|= not_null_tables;
 
5255
      table->embedding->nested_join->used_tables|= used_tables;
 
5256
      table->embedding->nested_join->not_null_tables|= not_null_tables;
5286
5257
    }
5287
5258
 
5288
5259
    if (!table->outer_join || (used_tables & not_null_tables))
5318
5289
    */
5319
5290
    if (table->on_expr)
5320
5291
    {
5321
 
      table->setDepTables(table->getDepTables() | table->on_expr->used_tables());
5322
 
      if (table->getEmbedding())
 
5292
      table->dep_tables|= table->on_expr->used_tables();
 
5293
      if (table->embedding)
5323
5294
      {
5324
 
        table->setDepTables(table->getDepTables() & ~table->getEmbedding()->getNestedJoin()->used_tables);
 
5295
        table->dep_tables&= ~table->embedding->nested_join->used_tables;
5325
5296
        /*
5326
5297
           Embedding table depends on tables used
5327
5298
           in embedded on expressions.
5328
5299
        */
5329
 
        table->getEmbedding()->setOnExprDepTables(table->getEmbedding()->getOnExprDepTables() & table->on_expr->used_tables());
 
5300
        table->embedding->on_expr_dep_tables|= table->on_expr->used_tables();
5330
5301
      }
5331
5302
      else
5332
 
        table->setDepTables(table->getDepTables() & ~table->table->map);
 
5303
        table->dep_tables&= ~table->table->map;
5333
5304
    }
5334
5305
 
5335
5306
    if (prev_table)
5336
5307
    {
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);
 
5308
      /* The order of tables is reverse: prev_table follows table */
 
5309
      if (prev_table->straight)
 
5310
        prev_table->dep_tables|= used_tables;
5342
5311
      if (prev_table->on_expr)
5343
5312
      {
5344
 
        prev_table->setDepTables(prev_table->getDepTables() | table->getOnExprDepTables());
5345
 
        table_map prev_used_tables= prev_table->getNestedJoin() ?
5346
 
                                    prev_table->getNestedJoin()->used_tables :
 
5313
        prev_table->dep_tables|= table->on_expr_dep_tables;
 
5314
        table_map prev_used_tables= prev_table->nested_join ?
 
5315
                                    prev_table->nested_join->used_tables :
5347
5316
                                    prev_table->table->map;
5348
5317
        /*
5349
5318
          If on expression contains only references to inner tables
5352
5321
          for them. Yet this is really a rare case.
5353
5322
              */
5354
5323
        if (!(prev_table->on_expr->used_tables() & ~prev_used_tables))
5355
 
          prev_table->setDepTables(prev_table->getDepTables() | used_tables);
 
5324
          prev_table->dep_tables|= used_tables;
5356
5325
      }
5357
5326
    }
5358
5327
    prev_table= table;
5365
5334
  li.rewind();
5366
5335
  while ((table= li++))
5367
5336
  {
5368
 
    nested_join= table->getNestedJoin();
 
5337
    nested_join= table->nested_join;
5369
5338
    if (nested_join && !table->on_expr)
5370
5339
    {
5371
5340
      TableList *tbl;
5372
5341
      List_iterator<TableList> it(nested_join->join_list);
5373
5342
      while ((tbl= it++))
5374
5343
      {
5375
 
        tbl->setEmbedding(table->getEmbedding());
5376
 
        tbl->setJoinList(table->getJoinList());
 
5344
        tbl->embedding= table->embedding;
 
5345
        tbl->join_list= table->join_list;
5377
5346
      }
5378
5347
      li.replace(nested_join->join_list);
5379
5348
    }
5381
5350
  return(conds);
5382
5351
}
5383
5352
 
5384
 
static int remove_duplicates(Join *join, Table *entry,List<Item> &fields, Item *having)
 
5353
static int remove_duplicates(JOIN *join, Table *entry,List<Item> &fields, Item *having)
5385
5354
{
5386
5355
  int error;
5387
5356
  uint32_t reclength,offset;
5405
5374
    join->unit->select_limit_cnt= 1;            // Only send first row
5406
5375
    return(0);
5407
5376
  }
5408
 
  Field **first_field=entry->getFields() + entry->getShare()->sizeFields() - field_count;
 
5377
  Field **first_field=entry->field+entry->s->fields - field_count;
5409
5378
  offset= (field_count ?
5410
 
           entry->getField(entry->getShare()->sizeFields() - field_count)->offset(entry->getInsertRecord()) : 0);
5411
 
  reclength= entry->getShare()->getRecordLength() - offset;
 
5379
           entry->field[entry->s->fields - field_count]->
 
5380
           offset(entry->record[0]) : 0);
 
5381
  reclength= entry->s->reclength-offset;
5412
5382
 
5413
5383
  entry->free_io_cache();                               // Safety
5414
5384
  entry->cursor->info(HA_STATUS_VARIABLE);
5415
 
  if (entry->getShare()->db_type() == heap_engine ||
5416
 
      (!entry->getShare()->blob_fields &&
 
5385
  if (entry->s->db_type() == heap_engine ||
 
5386
      (!entry->s->blob_fields &&
5417
5387
       ((ALIGN_SIZE(reclength) + HASH_OVERHEAD) * entry->cursor->stats.records <
5418
 
        session->variables.sortbuff_size)))
5419
 
  {
 
5388
        session->variables.sortbuff_size)))
5420
5389
    error= remove_dup_with_hash_index(join->session, entry,
5421
 
                                      field_count, first_field,
5422
 
                                      reclength, having);
5423
 
  }
 
5390
                                     field_count, first_field,
 
5391
                                     reclength, having);
5424
5392
  else
5425
 
  {
5426
 
    error= remove_dup_with_compare(join->session, entry, first_field, offset, having);
5427
 
  }
 
5393
    error= remove_dup_with_compare(join->session, entry, first_field, offset,
 
5394
                                  having);
5428
5395
 
5429
5396
  free_blobs(first_field);
5430
 
 
5431
5397
  return(error);
5432
5398
}
5433
5399
 
5441
5407
                               List<Item> &fields,
5442
5408
                               List<Item> &all_fields,
5443
5409
                               COND **conds,
5444
 
                               Order *order,
5445
 
                               Order *group,
 
5410
                               order_st *order,
 
5411
                               order_st *group,
5446
5412
                               bool *hidden_group_fields)
5447
5413
{
5448
5414
  int res;
5469
5435
  @retval
5470
5436
    1   Fatal error
5471
5437
*/
5472
 
static bool make_join_statistics(Join *join, TableList *tables, COND *conds, DYNAMIC_ARRAY *keyuse_array)
 
5438
static bool make_join_statistics(JOIN *join, TableList *tables, COND *conds, DYNAMIC_ARRAY *keyuse_array)
5473
5439
{
5474
5440
  int error;
5475
5441
  Table *table;
5512
5478
       tables;
5513
5479
       s++, tables= tables->next_leaf, i++)
5514
5480
  {
5515
 
    TableList *embedding= tables->getEmbedding();
 
5481
    TableList *embedding= tables->embedding;
5516
5482
    stat_vector[i]=s;
5517
5483
    s->keys.reset();
5518
5484
    s->const_keys.reset();
5520
5486
    s->needed_reg.reset();
5521
5487
    table_vector[i]=s->table=table=tables->table;
5522
5488
    table->pos_in_table_list= tables;
5523
 
    assert(table->cursor);
5524
5489
    error= table->cursor->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
5525
5490
    if (error)
5526
5491
    {
5531
5496
    table->reginfo.join_tab=s;
5532
5497
    table->reginfo.not_exists_optimize=0;
5533
5498
    memset(table->const_key_parts, 0,
5534
 
           sizeof(key_part_map)*table->getShare()->sizeKeys());
 
5499
           sizeof(key_part_map)*table->s->keys);
5535
5500
    all_table_map|= table->map;
5536
5501
    s->join=join;
5537
5502
    s->info=0;                                  // For describe
5538
5503
 
5539
 
    s->dependent= tables->getDepTables();
 
5504
    s->dependent= tables->dep_tables;
5540
5505
    s->key_dependent= 0;
5541
5506
    table->quick_condition_rows= table->cursor->stats.records;
5542
5507
 
5552
5517
      }
5553
5518
      outer_join|= table->map;
5554
5519
      s->embedding_map.reset();
5555
 
      for (;embedding; embedding= embedding->getEmbedding())
5556
 
        s->embedding_map|= embedding->getNestedJoin()->nj_map;
 
5520
      for (;embedding; embedding= embedding->embedding)
 
5521
        s->embedding_map|= embedding->nested_join->nj_map;
5557
5522
      continue;
5558
5523
    }
5559
 
    if (embedding && !(false && ! embedding->getEmbedding()))
 
5524
    if (embedding && !(false && ! embedding->embedding))
5560
5525
    {
5561
5526
      /* s belongs to a nested join, maybe to several embedded joins */
5562
5527
      s->embedding_map.reset();
5563
5528
      do
5564
5529
      {
5565
 
        nested_join_st *nested_join= embedding->getNestedJoin();
 
5530
        nested_join_st *nested_join= embedding->nested_join;
5566
5531
        s->embedding_map|= nested_join->nj_map;
5567
 
        s->dependent|= embedding->getDepTables();
5568
 
        embedding= embedding->getEmbedding();
 
5532
        s->dependent|= embedding->dep_tables;
 
5533
        embedding= embedding->embedding;
5569
5534
        outer_join|= nested_join->used_tables;
5570
5535
      }
5571
5536
      while (embedding);
5699
5664
          continue;
5700
5665
        if (table->cursor->stats.records <= 1L &&
5701
5666
            (table->cursor->getEngine()->check_flag(HTON_BIT_STATS_RECORDS_IS_EXACT)) &&
5702
 
                  !table->pos_in_table_list->getEmbedding())
 
5667
                  !table->pos_in_table_list->embedding)
5703
5668
        {                                       // system table
5704
5669
          int tmp= 0;
5705
5670
          s->type= AM_SYSTEM;
5744
5709
          } while (keyuse->getTable() == table && keyuse->getKey() == key);
5745
5710
 
5746
5711
          if (is_keymap_prefix(eq_part, table->key_info[key].key_parts) &&
5747
 
              ! table->pos_in_table_list->getEmbedding())
 
5712
              ! table->pos_in_table_list->embedding)
5748
5713
          {
5749
5714
            if ((table->key_info[key].flags & (HA_NOSAME)) == HA_NOSAME)
5750
5715
            {
5788
5753
    while (iter != sargables.end())
5789
5754
    {
5790
5755
      Field *field= (*iter).getField();
5791
 
      JoinTable *join_tab= field->getTable()->reginfo.join_tab;
 
5756
      JoinTable *join_tab= field->table->reginfo.join_tab;
5792
5757
      key_map possible_keys= field->key_start;
5793
 
      possible_keys&= field->getTable()->keys_in_use_for_query;
 
5758
      possible_keys&= field->table->keys_in_use_for_query;
5794
5759
      bool is_const= true;
5795
5760
      for (uint32_t j= 0; j < (*iter).getNumValues(); j++)
5796
5761
        is_const&= (*iter).isConstItem(j);
5831
5796
    add_group_and_distinct_keys(join, s);
5832
5797
 
5833
5798
    if (s->const_keys.any() &&
5834
 
        !s->table->pos_in_table_list->getEmbedding())
 
5799
        !s->table->pos_in_table_list->embedding)
5835
5800
    {
5836
5801
      ha_rows records;
5837
5802
      optimizer::SqlSelect *select= NULL;
5881
5846
  if (join->const_tables != join->tables)
5882
5847
  {
5883
5848
    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);
 
5849
    DRIZZLE_QUERY_OPT_CHOOSE_PLAN_START(join->session->query.c_str(), join->session->thread_id);
5887
5850
    bool res= choose_plan(join, all_table_map & ~join->const_table_map);
5888
5851
    DRIZZLE_QUERY_OPT_CHOOSE_PLAN_DONE(res ? 1 : 0);
5889
5852
    if (res)
5895
5858
    join->best_read= 1.0;
5896
5859
  }
5897
5860
  /* Generate an execution plan from the found optimal join order. */
5898
 
  return (join->session->getKilled() || get_best_combination(join));
 
5861
  return (join->session->killed || get_best_combination(join));
5899
5862
}
5900
5863
 
5901
5864
/**
5924
5887
  while ((table= li++))
5925
5888
  {
5926
5889
    nested_join_st *nested_join;
5927
 
    if ((nested_join= table->getNestedJoin()))
 
5890
    if ((nested_join= table->nested_join))
5928
5891
    {
5929
5892
      /*
5930
5893
        It is guaranteed by simplify_joins() function that a nested join
5955
5918
  Return table number if there is only one table in sort order
5956
5919
  and group and order is compatible, else return 0.
5957
5920
*/
5958
 
static Table *get_sort_by_table(Order *a, Order *b,TableList *tables)
 
5921
static Table *get_sort_by_table(order_st *a,order_st *b,TableList *tables)
5959
5922
{
5960
5923
  table_map map= (table_map) 0;
5961
5924
 
5995
5958
  while ((table= li++))
5996
5959
  {
5997
5960
    nested_join_st *nested_join;
5998
 
    if ((nested_join= table->getNestedJoin()))
 
5961
    if ((nested_join= table->nested_join))
5999
5962
    {
6000
5963
      nested_join->counter_= 0;
6001
5964
      reset_nj_counters(&nested_join->join_list);
6010
5973
  If first parts has different direction, change it to second part
6011
5974
  (group is sorted like order)
6012
5975
*/
6013
 
static bool test_if_subpart(Order *a, Order *b)
 
5976
static bool test_if_subpart(order_st *a,order_st *b)
6014
5977
{
6015
5978
  for (; a && b; a=a->next,b=b->next)
6016
5979
  {
6025
5988
/**
6026
5989
  Nested joins perspective: Remove the last table from the join order.
6027
5990
 
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
5991
    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 
 
5992
    joins counters and join->cur_embedding_map. It is ok to call this
 
5993
    function for the first table in join order (for which
6071
5994
    check_interleaving_with_nj has not been called)
6072
5995
 
6073
5996
  @param last  join table to remove, it is assumed to be the last in current
6074
5997
               partial join order.
6075
5998
*/
6076
 
 
6077
5999
static void restore_prev_nj_state(JoinTable *last)
6078
6000
{
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())
 
6001
  TableList *last_emb= last->table->pos_in_table_list->embedding;
 
6002
  JOIN *join= last->join;
 
6003
  while (last_emb)
6082
6004
  {
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)
6091
 
      break;
6092
 
    
6093
 
    join->cur_embedding_map|= nest->nj_map;
 
6005
    if (last_emb->on_expr)
 
6006
    {
 
6007
      if (!(--last_emb->nested_join->counter_))
 
6008
        join->cur_embedding_map&= ~last_emb->nested_join->nj_map;
 
6009
      else if (last_emb->nested_join->join_list.elements-1 ==
 
6010
               last_emb->nested_join->counter_)
 
6011
        join->cur_embedding_map|= last_emb->nested_join->nj_map;
 
6012
      else
 
6013
        break;
 
6014
    }
 
6015
    last_emb= last_emb->embedding;
6094
6016
  }
6095
6017
}
6096
6018
 
 
6019
 
6097
6020
/**
6098
6021
  Create a condition for a const reference and add this to the
6099
6022
  currenct select for the table.
6111
6034
 
6112
6035
  for (uint32_t i=0 ; i < join_tab->ref.key_parts ; i++)
6113
6036
  {
6114
 
    Field *field=table->getField(table->key_info[join_tab->ref.key].key_part[i].fieldnr - 1);
 
6037
    Field *field=table->field[table->key_info[join_tab->ref.key].key_part[i].
 
6038
                              fieldnr-1];
6115
6039
    Item *value=join_tab->ref.items[i];
6116
6040
    cond->add(new Item_func_equal(new Item_field(field), value));
6117
6041
  }