~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_select.cc

  • Committer: Brian Aker
  • Date: 2009-07-11 05:59:19 UTC
  • mfrom: (1089.1.9 merge)
  • Revision ID: brian@gaz-20090711055919-m4px3crrdgta5lie
Collection of patches from new-cleanup (includes asserts for field in debug)

Show diffs side-by-side

added added

removed removed

Lines of Context:
24
24
*/
25
25
#include "drizzled/server_includes.h"
26
26
#include "drizzled/sql_select.h" /* include join.h */
27
 
#include "drizzled/sj_tmp_table.h"
 
27
#include "drizzled/semi_join_table.h"
28
28
#include "drizzled/table_map_iterator.h"
29
29
 
30
30
#include "drizzled/error.h"
61
61
                              "index_merge"
62
62
};
63
63
 
64
 
static int sort_keyuse(KEYUSE *a,KEYUSE *b);
 
64
static int sort_keyuse(KeyUse *a,KeyUse *b);
65
65
static COND *build_equal_items(Session *session, COND *cond,
66
66
                               COND_EQUAL *inherited,
67
67
                               List<TableList> *join_list,
68
68
                               COND_EQUAL **cond_equal_ref);
69
69
 
70
70
static Item* part_of_refkey(Table *form,Field *field);
71
 
static bool cmp_buffer_with_ref(JOIN_TAB *tab);
 
71
static bool cmp_buffer_with_ref(JoinTable *tab);
72
72
static void change_cond_ref_to_const(Session *session,
73
73
                                     vector<COND_CMP>& save_list,
74
74
                                     Item *and_father,
77
77
                                     Item *value);
78
78
static bool copy_blobs(Field **ptr);
79
79
 
80
 
int init_read_record_seq(JOIN_TAB *tab);
81
 
 
82
80
static bool eval_const_cond(COND *cond)
83
81
{
84
82
    return ((Item_func*) cond)->val_int() ? true : false;
281
279
      "Full scan on NULL key" (TAB_INFO_FULL_SCAN_ON_NULL)
282
280
    and set appropriate flags in join_tab->packed_info.
283
281
*/
284
 
void save_index_subquery_explain_info(JOIN_TAB *join_tab, Item* where)
 
282
void save_index_subquery_explain_info(JoinTable *join_tab, Item* where)
285
283
{
286
284
  join_tab->packed_info= TAB_INFO_HAVE_VALUE;
287
285
  if (join_tab->table->covering_keys.test(join_tab->ref.key))
775
773
}
776
774
 
777
775
/*
778
 
  Check if table's KEYUSE elements have an eq_ref(outer_tables) candidate
 
776
  Check if table's KeyUse elements have an eq_ref(outer_tables) candidate
779
777
 
780
778
  SYNOPSIS
781
779
    find_eq_ref_candidate()
784
782
                        count.
785
783
 
786
784
  DESCRIPTION
787
 
    Check if table's KEYUSE elements have an eq_ref(outer_tables) candidate
 
785
    Check if table's KeyUse elements have an eq_ref(outer_tables) candidate
788
786
 
789
787
  TODO
790
788
    Check again if it is feasible to factor common parts with constant table
796
794
*/
797
795
bool find_eq_ref_candidate(Table *table, table_map sj_inner_tables)
798
796
{
799
 
  KEYUSE *keyuse= table->reginfo.join_tab->keyuse;
 
797
  KeyUse *keyuse= table->reginfo.join_tab->keyuse;
800
798
  uint32_t key;
801
799
 
802
800
  if (keyuse)
840
838
}
841
839
 
842
840
/*****************************************************************************
843
 
  Create JOIN_TABS, make a guess about the table types,
 
841
  Create JoinTableS, make a guess about the table types,
844
842
  Approximate how many records will be used in each table
845
843
*****************************************************************************/
846
844
ha_rows get_quick_record_count(Session *session, SQL_SELECT *select, Table *table, const key_map *keys,ha_rows limit)
1060
1058
    }
1061
1059
    else
1062
1060
    {
1063
 
      JOIN_TAB *stat=field->table->reginfo.join_tab;
 
1061
      JoinTable *stat=field->table->reginfo.join_tab;
1064
1062
      key_map possible_keys= field->key_start;
1065
1063
      possible_keys&= field->table->keys_in_use_for_query;
1066
1064
      stat[0].keys|= possible_keys;             // Add possible keys
1272
1270
  /*
1273
1271
    Subquery optimization: Conditions that are pushed down into subqueries
1274
1272
    are wrapped into Item_func_trig_cond. We process the wrapped condition
1275
 
    but need to set cond_guard for KEYUSE elements generated from it.
 
1273
    but need to set cond_guard for KeyUse elements generated from it.
1276
1274
  */
1277
1275
  {
1278
1276
    if (cond->type() == Item::FUNC_ITEM &&
1442
1440
{
1443
1441
  Field *field=key_field->field;
1444
1442
  Table *form= field->table;
1445
 
  KEYUSE keyuse;
 
1443
  KeyUse keyuse;
1446
1444
 
1447
1445
  if (key_field->eq_func && !(key_field->optimize & KEY_OPTIMIZE_EXISTS))
1448
1446
  {
1473
1471
  }
1474
1472
}
1475
1473
 
1476
 
static int sort_keyuse(KEYUSE *a,KEYUSE *b)
 
1474
static int sort_keyuse(KeyUse *a,KeyUse *b)
1477
1475
{
1478
1476
  int res;
1479
1477
  if (a->table->tablenr != b->table->tablenr)
1566
1564
  Update keyuse array with all possible keys we can use to fetch rows.
1567
1565
 
1568
1566
  @param       session
1569
 
  @param[out]  keyuse         Put here ordered array of KEYUSE structures
 
1567
  @param[out]  keyuse         Put here ordered array of KeyUse structures
1570
1568
  @param       join_tab       Array in tablenr_order
1571
1569
  @param       tables         Number of tables in join
1572
1570
  @param       cond           WHERE condition (note that the function analyzes
1584
1582
*/
1585
1583
bool update_ref_and_keys(Session *session,
1586
1584
                         DYNAMIC_ARRAY *keyuse,
1587
 
                         JOIN_TAB *join_tab,
 
1585
                         JoinTable *join_tab,
1588
1586
                         uint32_t tables,
1589
1587
                         COND *cond, 
1590
1588
                         COND_EQUAL *,
1630
1628
  /* set a barrier for the array of SARGABLE_PARAM */
1631
1629
  (*sargables)[0].field= 0;
1632
1630
 
1633
 
  if (my_init_dynamic_array(keyuse,sizeof(KEYUSE),20,64))
 
1631
  if (my_init_dynamic_array(keyuse,sizeof(KeyUse),20,64))
1634
1632
    return true;
1635
1633
  if (cond)
1636
1634
  {
1689
1687
  */
1690
1688
  if (keyuse->elements)
1691
1689
  {
1692
 
    KEYUSE key_end,*prev,*save_pos,*use;
 
1690
    KeyUse key_end,*prev,*save_pos,*use;
1693
1691
 
1694
 
    my_qsort(keyuse->buffer,keyuse->elements,sizeof(KEYUSE),
 
1692
    my_qsort(keyuse->buffer,keyuse->elements,sizeof(KeyUse),
1695
1693
          (qsort_cmp) sort_keyuse);
1696
1694
 
1697
1695
    memset(&key_end, 0, sizeof(key_end)); /* Add for easy testing */
1698
1696
    insert_dynamic(keyuse,(unsigned char*) &key_end);
1699
1697
 
1700
 
    use=save_pos=dynamic_element(keyuse,0,KEYUSE*);
 
1698
    use=save_pos=dynamic_element(keyuse,0,KeyUse*);
1701
1699
    prev= &key_end;
1702
1700
    found_eq_constant=0;
1703
1701
    for (i=0 ; i < keyuse->elements-1 ; i++,use++)
1725
1723
      use->table->reginfo.join_tab->checked_keys.set(use->key);
1726
1724
      save_pos++;
1727
1725
    }
1728
 
    i=(uint32_t) (save_pos-(KEYUSE*) keyuse->buffer);
 
1726
    i=(uint32_t) (save_pos-(KeyUse*) keyuse->buffer);
1729
1727
    set_dynamic(keyuse,(unsigned char*) &key_end,i);
1730
1728
    keyuse->elements=i;
1731
1729
  }
1737
1735
*/
1738
1736
void optimize_keyuse(JOIN *join, DYNAMIC_ARRAY *keyuse_array)
1739
1737
{
1740
 
  KEYUSE *end,*keyuse= dynamic_element(keyuse_array, 0, KEYUSE*);
 
1738
  KeyUse *end,*keyuse= dynamic_element(keyuse_array, 0, KeyUse*);
1741
1739
 
1742
1740
  for (end= keyuse+ keyuse_array->elements ; keyuse < end ; keyuse++)
1743
1741
  {
1788
1786
  @return
1789
1787
    None
1790
1788
*/
1791
 
void add_group_and_distinct_keys(JOIN *join, JOIN_TAB *join_tab)
 
1789
void add_group_and_distinct_keys(JOIN *join, JoinTable *join_tab)
1792
1790
{
1793
1791
  List<Item_field> indexed_fields;
1794
1792
  List_iterator<Item_field> indexed_fields_it(indexed_fields);
1873
1871
}
1874
1872
 
1875
1873
/**
1876
 
  Compare two JOIN_TAB objects based on the number of accessed records.
 
1874
  Compare two JoinTable objects based on the number of accessed records.
1877
1875
 
1878
 
  @param ptr1 pointer to first JOIN_TAB object
1879
 
  @param ptr2 pointer to second JOIN_TAB object
 
1876
  @param ptr1 pointer to first JoinTable object
 
1877
  @param ptr2 pointer to second JoinTable object
1880
1878
 
1881
1879
  NOTES
1882
1880
    The order relation implemented by join_tab_cmp() is not transitive,
1898
1896
*/
1899
1897
int join_tab_cmp(const void* ptr1, const void* ptr2)
1900
1898
{
1901
 
  JOIN_TAB *jt1= *(JOIN_TAB**) ptr1;
1902
 
  JOIN_TAB *jt2= *(JOIN_TAB**) ptr2;
 
1899
  JoinTable *jt1= *(JoinTable**) ptr1;
 
1900
  JoinTable *jt2= *(JoinTable**) ptr2;
1903
1901
 
1904
1902
  if (jt1->dependent & jt2->table->map)
1905
1903
    return 1;
1917
1915
*/
1918
1916
int join_tab_cmp_straight(const void* ptr1, const void* ptr2)
1919
1917
{
1920
 
  JOIN_TAB *jt1= *(JOIN_TAB**) ptr1;
1921
 
  JOIN_TAB *jt2= *(JOIN_TAB**) ptr2;
 
1918
  JoinTable *jt1= *(JoinTable**) ptr1;
 
1919
  JoinTable *jt2= *(JoinTable**) ptr2;
1922
1920
 
1923
1921
  if (jt1->dependent & jt2->table->map)
1924
1922
    return 1;
1930
1928
/**
1931
1929
  Find how much space the prevous read not const tables takes in cache.
1932
1930
*/
1933
 
void calc_used_field_length(Session *, JOIN_TAB *join_tab)
 
1931
void calc_used_field_length(Session *, JoinTable *join_tab)
1934
1932
{
1935
1933
  uint32_t null_fields,blobs,fields,rec_length;
1936
1934
  Field **f_ptr,*field;
1965
1963
}
1966
1964
 
1967
1965
StoredKey *get_store_key(Session *session,
1968
 
                         KEYUSE *keyuse,
 
1966
                         KeyUse *keyuse,
1969
1967
                         table_map used_tables,
1970
1968
                               KEY_PART_INFO *key_part,
1971
1969
                         unsigned char *key_buff,
2041
2039
    *e1= e2;
2042
2040
}
2043
2041
 
2044
 
bool create_ref_for_key(JOIN *join, JOIN_TAB *j, KEYUSE *org_keyuse,
 
2042
bool create_ref_for_key(JOIN *join, JoinTable *j, KeyUse *org_keyuse,
2045
2043
             table_map used_tables)
2046
2044
{
2047
 
  KEYUSE *keyuse=org_keyuse;
 
2045
  KeyUse *keyuse=org_keyuse;
2048
2046
  Session  *session= join->session;
2049
2047
  uint32_t keyparts,length,key;
2050
2048
  Table *table;
2211
2209
    Implementation overview
2212
2210
      1. update_ref_and_keys() accumulates info about null-rejecting
2213
2211
         predicates in in KEY_FIELD::null_rejecting
2214
 
      1.1 add_key_part saves these to KEYUSE.
 
2212
      1.1 add_key_part saves these to KeyUse.
2215
2213
      2. create_ref_for_key copies them to TABLE_REF.
2216
2214
      3. add_not_null_conds adds "x IS NOT NULL" to join_tab->select_cond of
2217
 
         appropiate JOIN_TAB members.
 
2215
         appropiate JoinTable members.
2218
2216
*/
2219
2217
void add_not_null_conds(JOIN *join)
2220
2218
{
2221
2219
  for (uint32_t i=join->const_tables ; i < join->tables ; i++)
2222
2220
  {
2223
 
    JOIN_TAB *tab=join->join_tab+i;
 
2221
    JoinTable *tab=join->join_tab+i;
2224
2222
    if ((tab->type == JT_REF || tab->type == JT_EQ_REF ||
2225
2223
         tab->type == JT_REF_OR_NULL) &&
2226
2224
        !tab->table->maybe_null)
2233
2231
          Item *notnull;
2234
2232
          assert(item->type() == Item::FIELD_ITEM);
2235
2233
          Item_field *not_null_item= (Item_field*)item;
2236
 
          JOIN_TAB *referred_tab= not_null_item->field->table->reginfo.join_tab;
 
2234
          JoinTable *referred_tab= not_null_item->field->table->reginfo.join_tab;
2237
2235
          /*
2238
2236
            For UPDATE queries such as:
2239
2237
            UPDATE t1 SET t1.f2=(SELECT MAX(t2.f4) FROM t2 WHERE t2.f3=t1.f1);
2274
2272
    -  pointer to the guarded predicate, if success
2275
2273
    -  0, otherwise
2276
2274
*/
2277
 
COND *add_found_match_trig_cond(JOIN_TAB *tab, COND *cond, JOIN_TAB *root_tab)
 
2275
COND *add_found_match_trig_cond(JoinTable *tab, COND *cond, JoinTable *root_tab)
2278
2276
{
2279
2277
  COND *tmp;
2280
2278
  assert(cond != 0);
2539
2537
  DESCRIPTION
2540
2538
    Try to extract and push the index condition down to table handler
2541
2539
*/
2542
 
void push_index_cond(JOIN_TAB *tab, uint32_t keyno, bool other_tbls_ok)
 
2540
void push_index_cond(JoinTable *tab, uint32_t keyno, bool other_tbls_ok)
2543
2541
{
2544
2542
  Item *idx_cond;
2545
2543
  if (tab->table->file->index_flags(keyno, 0, 1) & HA_DO_INDEX_COND_PUSHDOWN &&
2590
2588
}
2591
2589
 
2592
2590
/**
2593
 
  cleanup JOIN_TAB.
 
2591
  cleanup JoinTable.
2594
2592
*/
2595
 
void JOIN_TAB::cleanup()
 
2593
void JoinTable::cleanup()
2596
2594
{
2597
2595
  delete select;
2598
2596
  select= 0;
2621
2619
 
2622
2620
bool only_eq_ref_tables(JOIN *join,order_st *order,table_map tables)
2623
2621
{
2624
 
  for (JOIN_TAB **tab=join->map2table ; tables ; tab++, tables>>=1)
 
2622
  for (JoinTable **tab=join->map2table ; tables ; tab++, tables>>=1)
2625
2623
  {
2626
2624
    if (tables & 1 && !eq_ref_table(join, order, *tab))
2627
2625
      return 0;
2648
2646
  SELECT * FROM t1,t2 WHERE t1.a=t2.a order_st BY t2.b,t1.a
2649
2647
  @endcode
2650
2648
*/
2651
 
bool eq_ref_table(JOIN *join, order_st *start_order, JOIN_TAB *tab)
 
2649
bool eq_ref_table(JOIN *join, order_st *start_order, JoinTable *tab)
2652
2650
{
2653
2651
  if (tab->cached_eq_ref_table)                 // If cached
2654
2652
    return tab->eq_ref_table;
3460
3458
  }
3461
3459
  if (outer_ref)
3462
3460
    return cmp;
3463
 
  JOIN_TAB **idx= (JOIN_TAB **) table_join_idx;
 
3461
  JoinTable **idx= (JoinTable **) table_join_idx;
3464
3462
  cmp= idx[field2->field->table->tablenr]-idx[field1->field->table->tablenr];
3465
3463
  return cmp < 0 ? -1 : (cmp ? 1 : 0);
3466
3464
}
3681
3679
  @param cond       condition whose multiple equalities are to be checked
3682
3680
  @param table      constant table that has been read
3683
3681
*/
3684
 
static void update_const_equal_items(COND *cond, JOIN_TAB *tab)
 
3682
static void update_const_equal_items(COND *cond, JoinTable *tab)
3685
3683
{
3686
3684
  if (!(cond->used_tables() & tab->table->map))
3687
3685
    return;
3708
3706
      while ((item_field= it++))
3709
3707
      {
3710
3708
        Field *field= item_field->field;
3711
 
        JOIN_TAB *stat= field->table->reginfo.join_tab;
 
3709
        JoinTable *stat= field->table->reginfo.join_tab;
3712
3710
        key_map possible_keys= field->key_start;
3713
3711
        possible_keys&= field->table->keys_in_use_for_query;
3714
3712
        stat[0].const_keys|= possible_keys;
3721
3719
        if (possible_keys.any())
3722
3720
        {
3723
3721
          Table *field_tab= field->table;
3724
 
          KEYUSE *use;
 
3722
          KeyUse *use;
3725
3723
          for (use= stat->keyuse; use && use->table == field_tab; use++)
3726
3724
            if (possible_keys.test(use->key) &&
3727
3725
                field_tab->key_info[use->key].key_part[use->keypart].field ==
3997
3995
  @retval
3998
3996
    true   Requested join order extension not allowed.
3999
3997
*/
4000
 
bool check_interleaving_with_nj(JOIN_TAB *last_tab, JOIN_TAB *next_tab)
 
3998
bool check_interleaving_with_nj(JoinTable *last_tab, JoinTable *next_tab)
4001
3999
{
4002
4000
  TableList *next_emb= next_tab->table->pos_in_table_list->embedding;
4003
4001
  JOIN *join= last_tab->join;
4041
4039
  return false;
4042
4040
}
4043
4041
 
4044
 
void advance_sj_state(const table_map remaining_tables, const JOIN_TAB *tab)
 
4042
void advance_sj_state(const table_map remaining_tables, const JoinTable *tab)
4045
4043
{
4046
4044
  TableList *emb_sj_nest;
4047
4045
  if ((emb_sj_nest= tab->emb_sj_nest))
4056
4054
/*
4057
4055
  we assume remaining_tables doesnt contain @tab.
4058
4056
*/
4059
 
void restore_prev_sj_state(const table_map remaining_tables, const JOIN_TAB *tab)
 
4057
void restore_prev_sj_state(const table_map remaining_tables, const JoinTable *tab)
4060
4058
{
4061
4059
  TableList *emb_sj_nest;
4062
4060
  if ((emb_sj_nest= tab->emb_sj_nest))
4448
4446
{
4449
4447
  int rc= 0;
4450
4448
  enum_nested_loop_state error= NESTED_LOOP_OK;
4451
 
  JOIN_TAB *join_tab= NULL;
 
4449
  JoinTable *join_tab= NULL;
4452
4450
 
4453
4451
  join->tmp_table= table;                       /* Save for easy recursion */
4454
4452
  join->fields= fields;
4545
4543
  return(join->session->is_error() ? -1 : rc);
4546
4544
}
4547
4545
 
4548
 
enum_nested_loop_state sub_select_cache(JOIN *join, JOIN_TAB *join_tab, bool end_of_records)
 
4546
enum_nested_loop_state sub_select_cache(JOIN *join, JoinTable *join_tab, bool end_of_records)
4549
4547
{
4550
4548
  enum_nested_loop_state rc;
4551
4549
 
4692
4690
  @return
4693
4691
    return one of enum_nested_loop_state, except NESTED_LOOP_NO_MORE_ROWS.
4694
4692
*/
4695
 
enum_nested_loop_state sub_select(JOIN *join,JOIN_TAB *join_tab,bool end_of_records)
 
4693
enum_nested_loop_state sub_select(JOIN *join,JoinTable *join_tab,bool end_of_records)
4696
4694
{
4697
4695
  join_tab->table->null_row=0;
4698
4696
  if (end_of_records)
4761
4759
/*
4762
4760
  SemiJoinDuplicateElimination: Reset the temporary table
4763
4761
*/
4764
 
int do_sj_reset(SJ_TMP_TABLE *sj_tbl)
 
4762
int do_sj_reset(SemiJoinTable *sj_tbl)
4765
4763
{
4766
4764
  if (sj_tbl->tmp_table)
4767
4765
    return sj_tbl->tmp_table->file->ha_delete_all_rows();
4768
4766
  return 0;
4769
4767
}
4770
4768
 
4771
 
int safe_index_read(JOIN_TAB *tab)
 
4769
int safe_index_read(JoinTable *tab)
4772
4770
{
4773
4771
  int error;
4774
4772
  Table *table= tab->table;
4780
4778
  return 0;
4781
4779
}
4782
4780
 
4783
 
int join_read_const_table(JOIN_TAB *tab, POSITION *pos)
 
4781
int join_read_const_table(JoinTable *tab, POSITION *pos)
4784
4782
{
4785
4783
  int error;
4786
4784
  Table *table=tab->table;
4858
4856
  return(0);
4859
4857
}
4860
4858
 
4861
 
int join_read_system(JOIN_TAB *tab)
 
4859
int join_read_system(JoinTable *tab)
4862
4860
{
4863
4861
  Table *table= tab->table;
4864
4862
  int error;
4893
4891
  @retval
4894
4892
    1   Got an error (other than row not found) during read
4895
4893
*/
4896
 
int join_read_const(JOIN_TAB *tab)
 
4894
int join_read_const(JoinTable *tab)
4897
4895
{
4898
4896
  int error;
4899
4897
  Table *table= tab->table;
4934
4932
 
4935
4933
  SYNOPSIS
4936
4934
    join_read_key()
4937
 
      tab  JOIN_TAB of the accessed table
 
4935
      tab  JoinTable of the accessed table
4938
4936
 
4939
4937
  DESCRIPTION
4940
4938
    This is "read_fist" function for the "ref" access method. The difference
4945
4943
   -1  - Row not found
4946
4944
    1  - Error
4947
4945
*/
4948
 
int join_read_key(JOIN_TAB *tab)
 
4946
int join_read_key(JoinTable *tab)
4949
4947
{
4950
4948
  int error;
4951
4949
  Table *table= tab->table;
4980
4978
 
4981
4979
  SYNOPSIS
4982
4980
    join_read_always_key()
4983
 
      tab  JOIN_TAB of the accessed table
 
4981
      tab  JoinTable of the accessed table
4984
4982
 
4985
4983
  DESCRIPTION
4986
4984
    This is "read_first" function for the "ref" access method.
4993
4991
   -1  - Row not found
4994
4992
    1  - Error
4995
4993
*/
4996
 
int join_read_always_key(JOIN_TAB *tab)
 
4994
int join_read_always_key(JoinTable *tab)
4997
4995
{
4998
4996
  int error;
4999
4997
  Table *table= tab->table;
5028
5026
  This function is used when optimizing away order_st BY in
5029
5027
  SELECT * FROM t1 WHERE a=1 order_st BY a DESC,b DESC.
5030
5028
*/
5031
 
int join_read_last_key(JOIN_TAB *tab)
 
5029
int join_read_last_key(JoinTable *tab)
5032
5030
{
5033
5031
  int error;
5034
5032
  Table *table= tab->table;
5056
5054
int join_read_next_same_diff(READ_RECORD *info)
5057
5055
{
5058
5056
  Table *table= info->table;
5059
 
  JOIN_TAB *tab=table->reginfo.join_tab;
 
5057
  JoinTable *tab=table->reginfo.join_tab;
5060
5058
  if (tab->insideout_match_tab->found_match)
5061
5059
  {
5062
5060
    KEY *key= tab->table->key_info + tab->index;
5088
5086
{
5089
5087
  int error;
5090
5088
  Table *table= info->table;
5091
 
  JOIN_TAB *tab=table->reginfo.join_tab;
 
5089
  JoinTable *tab=table->reginfo.join_tab;
5092
5090
 
5093
5091
  if ((error=table->file->index_next_same(table->record[0],
5094
5092
                                          tab->ref.key_buff,
5107
5105
{
5108
5106
  int error;
5109
5107
  Table *table= info->table;
5110
 
  JOIN_TAB *tab=table->reginfo.join_tab;
 
5108
  JoinTable *tab=table->reginfo.join_tab;
5111
5109
 
5112
5110
  if ((error=table->file->index_prev(table->record[0])))
5113
5111
    return table->report_error(error);
5120
5118
  return error;
5121
5119
}
5122
5120
 
5123
 
int join_init_quick_read_record(JOIN_TAB *tab)
 
5121
int join_init_quick_read_record(JoinTable *tab)
5124
5122
{
5125
5123
  if (test_if_quick_select(tab) == -1)
5126
5124
    return -1;                                  /* No possible records */
5128
5126
}
5129
5127
 
5130
5128
int rr_sequential(READ_RECORD *info);
5131
 
int init_read_record_seq(JOIN_TAB *tab)
 
5129
int init_read_record_seq(JoinTable *tab)
5132
5130
{
5133
5131
  tab->read_record.read_record= rr_sequential;
5134
5132
  if (tab->read_record.file->ha_rnd_init(1))
5136
5134
  return (*tab->read_record.read_record)(&tab->read_record);
5137
5135
}
5138
5136
 
5139
 
int test_if_quick_select(JOIN_TAB *tab)
 
5137
int test_if_quick_select(JoinTable *tab)
5140
5138
{
5141
5139
  delete tab->select->quick;
5142
5140
  tab->select->quick= 0;
5144
5142
                                        (table_map) 0, HA_POS_ERROR, 0, false);
5145
5143
}
5146
5144
 
5147
 
int join_init_read_record(JOIN_TAB *tab)
 
5145
int join_init_read_record(JoinTable *tab)
5148
5146
{
5149
5147
  if (tab->select && tab->select->quick && tab->select->quick->reset())
5150
5148
    return 1;
5153
5151
  return (*tab->read_record.read_record)(&tab->read_record);
5154
5152
}
5155
5153
 
5156
 
int join_read_first(JOIN_TAB *tab)
 
5154
int join_read_first(JoinTable *tab)
5157
5155
{
5158
5156
  int error;
5159
5157
  Table *table=tab->table;
5194
5192
 
5195
5193
int join_read_next_different(READ_RECORD *info)
5196
5194
{
5197
 
  JOIN_TAB *tab= info->do_insideout_scan;
 
5195
  JoinTable *tab= info->do_insideout_scan;
5198
5196
  if (tab->insideout_match_tab->found_match)
5199
5197
  {
5200
5198
    KEY *key= tab->table->key_info + tab->index;
5223
5221
  return 0;
5224
5222
}
5225
5223
 
5226
 
int join_read_last(JOIN_TAB *tab)
 
5224
int join_read_last(JoinTable *tab)
5227
5225
{
5228
5226
  Table *table=tab->table;
5229
5227
  int error;
5259
5257
/**
5260
5258
  Reading of key with key reference and one part that may be NULL.
5261
5259
*/
5262
 
int join_read_always_key_or_null(JOIN_TAB *tab)
 
5260
int join_read_always_key_or_null(JoinTable *tab)
5263
5261
{
5264
5262
  int res;
5265
5263
 
5278
5276
  int error;
5279
5277
  if ((error= join_read_next_same(info)) >= 0)
5280
5278
    return error;
5281
 
  JOIN_TAB *tab= info->table->reginfo.join_tab;
 
5279
  JoinTable *tab= info->table->reginfo.join_tab;
5282
5280
 
5283
5281
  /* Test if we have already done a read after null key */
5284
5282
  if (*tab->ref.null_ref_key)
5287
5285
  return safe_index_read(tab);                  // then read null keys
5288
5286
}
5289
5287
 
5290
 
enum_nested_loop_state end_send_group(JOIN *join, JOIN_TAB *, bool end_of_records)
 
5288
enum_nested_loop_state end_send_group(JOIN *join, JoinTable *, bool end_of_records)
5291
5289
{
5292
5290
  int idx= -1;
5293
5291
  enum_nested_loop_state ok_code= NESTED_LOOP_OK;
5376
5374
  return(NESTED_LOOP_OK);
5377
5375
}
5378
5376
 
5379
 
enum_nested_loop_state end_write_group(JOIN *join, JOIN_TAB *, bool end_of_records)
 
5377
enum_nested_loop_state end_write_group(JOIN *join, JoinTable *, bool end_of_records)
5380
5378
{
5381
5379
  Table *table=join->tmp_table;
5382
5380
  int     idx= -1;
5942
5940
      no_changes
5943
5941
      map
5944
5942
 
5945
 
  If we can use an index, the JOIN_TAB / tab->select struct
 
5943
  If we can use an index, the JoinTable / tab->select struct
5946
5944
  is changed to use the index.
5947
5945
 
5948
5946
  The index must cover all fields in <order>, or it will not be considered.
5956
5954
  @retval
5957
5955
    1    We can use an index.
5958
5956
*/
5959
 
bool test_if_skip_sort_order(JOIN_TAB *tab, order_st *order, ha_rows select_limit, bool no_changes, const key_map *map)
 
5957
bool test_if_skip_sort_order(JoinTable *tab, order_st *order, ha_rows select_limit, bool no_changes, const key_map *map)
5960
5958
{
5961
5959
  int32_t ref_key;
5962
5960
  uint32_t ref_key_parts;
6046
6044
            "part1 = const1 AND part2=const2".
6047
6045
            So we build tab->ref from scratch here.
6048
6046
          */
6049
 
          KEYUSE *keyuse= tab->keyuse;
 
6047
          KeyUse *keyuse= tab->keyuse;
6050
6048
          while (keyuse->key != new_ref_key && keyuse->table == tab->table)
6051
6049
            keyuse++;
6052
6050
 
6402
6400
  ha_rows examined_rows;
6403
6401
  Table *table;
6404
6402
  SQL_SELECT *select;
6405
 
  JOIN_TAB *tab;
 
6403
  JoinTable *tab;
6406
6404
 
6407
6405
  if (join->tables == join->const_tables)
6408
6406
    return(0);                          // One row, no need to sort
6725
6723
  return(sort);
6726
6724
}
6727
6725
 
6728
 
void read_cached_record(JOIN_TAB *tab)
 
6726
void read_cached_record(JoinTable *tab)
6729
6727
{
6730
6728
  unsigned char *pos;
6731
6729
  uint32_t length;
6790
6788
    false  The created key is the same as the previous one (and the record
6791
6789
           is already in table->record)
6792
6790
*/
6793
 
static bool cmp_buffer_with_ref(JOIN_TAB *tab)
 
6791
static bool cmp_buffer_with_ref(JoinTable *tab)
6794
6792
{
6795
6793
  bool no_prev_key;
6796
6794
  if (!tab->ref.disable_cache)
7877
7875
    table_map used_tables=0;
7878
7876
    for (uint32_t i=0 ; i < join->tables ; i++)
7879
7877
    {
7880
 
      JOIN_TAB *tab=join->join_tab+i;
 
7878
      JoinTable *tab=join->join_tab+i;
7881
7879
      Table *table=tab->table;
7882
7880
      TableList *table_list= tab->table->pos_in_table_list;
7883
7881
      char buff[512];