~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/opt_range.cc

  • Committer: Monty Taylor
  • Date: 2008-08-09 02:24:34 UTC
  • mto: (266.1.8 codestyle)
  • mto: This revision was merged to the branch mainline in revision 279.
  • Revision ID: monty@inaugust.com-20080809022434-97na8pnugghskxip
Removed mystringslt conv lib and replaced it with a noinst lib.

Show diffs side-by-side

added added

removed removed

Lines of Context:
117
117
*/
118
118
#define double2rows(x) ((ha_rows)(x))
119
119
 
120
 
static int sel_cmp(Field *f,unsigned char *a,unsigned char *b,uint8_t a_flag,uint8_t b_flag);
 
120
static int sel_cmp(Field *f,uchar *a,uchar *b,uint8_t a_flag,uint8_t b_flag);
121
121
 
122
 
static unsigned char is_null_string[2]= {1,0};
 
122
static uchar is_null_string[2]= {1,0};
123
123
 
124
124
class RANGE_OPT_PARAM;
125
125
/*
311
311
  ulong use_count;
312
312
 
313
313
  Field *field;
314
 
  unsigned char *min_value,*max_value;                  // Pointer to range
 
314
  uchar *min_value,*max_value;                  // Pointer to range
315
315
 
316
316
  /*
317
317
    eq_tree() requires that left == right == 0 if the type is MAYBE_KEY.
327
327
 
328
328
  SEL_ARG() {}
329
329
  SEL_ARG(SEL_ARG &);
330
 
  SEL_ARG(Field *,const unsigned char *, const unsigned char *);
331
 
  SEL_ARG(Field *field, uint8_t part, unsigned char *min_value, unsigned char *max_value,
 
330
  SEL_ARG(Field *,const uchar *, const uchar *);
 
331
  SEL_ARG(Field *field, uint8_t part, uchar *min_value, uchar *max_value,
332
332
          uint8_t min_flag, uint8_t max_flag, uint8_t maybe_flag);
333
333
  SEL_ARG(enum Type type_arg)
334
334
    :min_flag(0),elements(1),use_count(1),left(0),right(0),next_key_part(0),
364
364
  }
365
365
  SEL_ARG *clone_and(SEL_ARG* arg)
366
366
  {                                             // Get overlapping range
367
 
    unsigned char *new_min,*new_max;
 
367
    uchar *new_min,*new_max;
368
368
    uint8_t flag_min,flag_max;
369
369
    if (cmp_min_to_min(arg) >= 0)
370
370
    {
438
438
    min_flag=arg->max_flag & NEAR_MAX ? 0 : NEAR_MIN;
439
439
  }
440
440
  /* returns a number of keypart values (0 or 1) appended to the key buffer */
441
 
  int store_min(uint32_t length, unsigned char **min_key,uint32_t min_key_flag)
 
441
  int store_min(uint length, uchar **min_key,uint min_key_flag)
442
442
  {
443
443
    /* "(kp1 > c1) AND (kp2 OP c2) AND ..." -> (kp1 > c1) */
444
444
    if ((!(min_flag & NO_MIN_RANGE) &&
457
457
    return 0;
458
458
  }
459
459
  /* returns a number of keypart values (0 or 1) appended to the key buffer */
460
 
  int store_max(uint32_t length, unsigned char **max_key, uint32_t max_key_flag)
 
460
  int store_max(uint length, uchar **max_key, uint max_key_flag)
461
461
  {
462
462
    if (!(max_flag & NO_MAX_RANGE) &&
463
463
        !(max_key_flag & (NO_MAX_RANGE | NEAR_MAX)))
476
476
  }
477
477
 
478
478
  /* returns a number of keypart values appended to the key buffer */
479
 
  int store_min_key(KEY_PART *key, unsigned char **range_key, uint32_t *range_key_flag)
 
479
  int store_min_key(KEY_PART *key, uchar **range_key, uint *range_key_flag)
480
480
  {
481
481
    SEL_ARG *key_tree= first();
482
 
    uint32_t res= key_tree->store_min(key[key_tree->part].store_length,
 
482
    uint res= key_tree->store_min(key[key_tree->part].store_length,
483
483
                                  range_key, *range_key_flag);
484
484
    *range_key_flag|= key_tree->min_flag;
485
485
    
493
493
  }
494
494
 
495
495
  /* returns a number of keypart values appended to the key buffer */
496
 
  int store_max_key(KEY_PART *key, unsigned char **range_key, uint32_t *range_key_flag)
 
496
  int store_max_key(KEY_PART *key, uchar **range_key, uint *range_key_flag)
497
497
  {
498
498
    SEL_ARG *key_tree= last();
499
 
    uint32_t res=key_tree->store_max(key[key_tree->part].store_length,
 
499
    uint res=key_tree->store_max(key[key_tree->part].store_length,
500
500
                                 range_key, *range_key_flag);
501
501
    (*range_key_flag)|= key_tree->max_flag;
502
502
    if (key_tree->next_key_part &&
575
575
    */
576
576
    if (min_flag || max_flag)
577
577
      return false;
578
 
    unsigned char *min_val= min_value;
579
 
    unsigned char *max_val= max_value;
 
578
    uchar *min_val= min_value;
 
579
    uchar *max_val= max_value;
580
580
 
581
581
    if (maybe_null)
582
582
    {
629
629
 
630
630
  /* The members below are filled/used only after get_mm_tree is done */
631
631
  key_map ror_scans_map;   /* bitmask of ROR scan-able elements in keys */
632
 
  uint32_t    n_ror_scans;     /* number of set bits in ror_scans_map */
 
632
  uint    n_ror_scans;     /* number of set bits in ror_scans_map */
633
633
 
634
634
  struct st_ror_scan_info **ror_scans;     /* list of ROR key scans */
635
635
  struct st_ror_scan_info **ror_scans_end; /* last ROR scan */
640
640
{
641
641
public:
642
642
  THD   *thd;   /* Current thread handle */
643
 
  Table *table; /* Table being analyzed */
 
643
  TABLE *table; /* Table being analyzed */
644
644
  COND *cond;   /* Used inside get_mm_tree(). */
645
645
  table_map prev_tables;
646
646
  table_map read_tables;
655
655
    Number of indexes used in range analysis (In SEL_TREE::keys only first
656
656
    #keys elements are not empty)
657
657
  */
658
 
  uint32_t keys;
 
658
  uint keys;
659
659
  
660
660
  /* 
661
661
    If true, the index descriptions describe real indexes (and it is ok to
670
670
    used_key_no -> table_key_no translation table. Only makes sense if
671
671
    using_real_indexes==true
672
672
  */
673
 
  uint32_t real_keynr[MAX_KEY];
 
673
  uint real_keynr[MAX_KEY];
674
674
  /* Number of SEL_ARG objects allocated by SEL_ARG::clone_tree operations */
675
 
  uint32_t alloced_sel_args; 
 
675
  uint alloced_sel_args; 
676
676
  bool force_default_mrr;
677
677
};
678
678
 
681
681
public:
682
682
  KEY_PART *key[MAX_KEY]; /* First key parts of keys used in the query */
683
683
  int64_t baseflag;
684
 
  uint32_t max_key_part;
 
684
  uint max_key_part;
685
685
  /* Number of ranges in the last checked tree->key */
686
 
  uint32_t range_count;
687
 
  unsigned char min_key[MAX_KEY_LENGTH+MAX_FIELD_WIDTH],
 
686
  uint range_count;
 
687
  uchar min_key[MAX_KEY_LENGTH+MAX_FIELD_WIDTH],
688
688
    max_key[MAX_KEY_LENGTH+MAX_FIELD_WIDTH];
689
689
  bool quick;                           // Don't calulate possible keys
690
690
 
691
 
  uint32_t fields_bitmap_size;
 
691
  uint fields_bitmap_size;
692
692
  MY_BITMAP needed_fields;    /* bitmask of fields needed by the query */
693
693
  MY_BITMAP tmp_covered_fields;
694
694
 
695
695
  key_map *needed_reg;        /* ptr to SQL_SELECT::needed_reg */
696
696
 
697
 
  uint32_t *imerge_cost_buff;     /* buffer for index_merge cost estimates */
698
 
  uint32_t imerge_cost_buff_size; /* size of the buffer */
 
697
  uint *imerge_cost_buff;     /* buffer for index_merge cost estimates */
 
698
  uint imerge_cost_buff_size; /* size of the buffer */
699
699
 
700
700
  /* true if last checked tree->key can be used for ROR-scan */
701
701
  bool is_ror_scan;
702
702
  /* Number of ranges in the last checked tree->key */
703
 
  uint32_t n_ranges;
 
703
  uint n_ranges;
704
704
};
705
705
 
706
706
class TABLE_READ_PLAN;
720
720
                            Item_func::Functype type,Item *value);
721
721
static SEL_TREE *get_mm_tree(RANGE_OPT_PARAM *param,COND *cond);
722
722
 
723
 
static bool is_key_scan_ror(PARAM *param, uint32_t keynr, uint8_t nparts);
724
 
static ha_rows check_quick_select(PARAM *param, uint32_t idx, bool index_only,
 
723
static bool is_key_scan_ror(PARAM *param, uint keynr, uint8_t nparts);
 
724
static ha_rows check_quick_select(PARAM *param, uint idx, bool index_only,
725
725
                                  SEL_ARG *tree, bool update_tbl_stats, 
726
 
                                  uint32_t *mrr_flags, uint32_t *bufsize,
 
726
                                  uint *mrr_flags, uint *bufsize,
727
727
                                  COST_VECT *cost);
728
728
                                  //bool update_tbl_stats);
729
 
/*static ha_rows check_quick_keys(PARAM *param,uint32_t index,SEL_ARG *key_tree,
730
 
                                unsigned char *min_key, uint32_t min_key_flag, int,
731
 
                                unsigned char *max_key, uint32_t max_key_flag, int);
 
729
/*static ha_rows check_quick_keys(PARAM *param,uint index,SEL_ARG *key_tree,
 
730
                                uchar *min_key, uint min_key_flag, int,
 
731
                                uchar *max_key, uint max_key_flag, int);
732
732
*/
733
733
 
734
 
QUICK_RANGE_SELECT *get_quick_select(PARAM *param,uint32_t index,
735
 
                                     SEL_ARG *key_tree, uint32_t mrr_flags, 
736
 
                                     uint32_t mrr_buf_size, MEM_ROOT *alloc);
 
734
QUICK_RANGE_SELECT *get_quick_select(PARAM *param,uint index,
 
735
                                     SEL_ARG *key_tree, uint mrr_flags, 
 
736
                                     uint mrr_buf_size, MEM_ROOT *alloc);
737
737
static TRP_RANGE *get_key_scans_params(PARAM *param, SEL_TREE *tree,
738
738
                                       bool index_read_must_be_used,
739
739
                                       bool update_tbl_stats,
754
754
 
755
755
static void print_sel_tree(PARAM *param, SEL_TREE *tree, key_map *tree_map,
756
756
                           const char *msg);
757
 
static void print_ror_scans_arr(Table *table, const char *msg,
 
757
static void print_ror_scans_arr(TABLE *table, const char *msg,
758
758
                                struct st_ror_scan_info **start,
759
759
                                struct st_ror_scan_info **end);
760
760
 
763
763
static SEL_ARG *sel_add(SEL_ARG *key1,SEL_ARG *key2);
764
764
static SEL_ARG *key_or(RANGE_OPT_PARAM *param, SEL_ARG *key1, SEL_ARG *key2);
765
765
static SEL_ARG *key_and(RANGE_OPT_PARAM *param, SEL_ARG *key1, SEL_ARG *key2,
766
 
                        uint32_t clone_flag);
 
766
                        uint clone_flag);
767
767
static bool get_range(SEL_ARG **e1,SEL_ARG **e2,SEL_ARG *root1);
768
768
bool get_quick_keys(PARAM *param,QUICK_RANGE_SELECT *quick,KEY_PART *key,
769
 
                    SEL_ARG *key_tree, unsigned char *min_key,uint32_t min_key_flag,
770
 
                    unsigned char *max_key,uint32_t max_key_flag);
 
769
                    SEL_ARG *key_tree, uchar *min_key,uint min_key_flag,
 
770
                    uchar *max_key,uint max_key_flag);
771
771
static bool eq_tree(SEL_ARG* a,SEL_ARG *b);
772
772
 
773
773
static SEL_ARG null_element(SEL_ARG::IMPOSSIBLE);
774
 
static bool null_part_in_key(KEY_PART *key_part, const unsigned char *key,
775
 
                             uint32_t length);
 
774
static bool null_part_in_key(KEY_PART *key_part, const uchar *key,
 
775
                             uint length);
776
776
bool sel_trees_can_be_ored(SEL_TREE *tree1, SEL_TREE *tree2, RANGE_OPT_PARAM* param);
777
777
 
778
778
 
828
828
  if (trees_next == trees_end)
829
829
  {
830
830
    const int realloc_ratio= 2;         /* Double size for next round */
831
 
    uint32_t old_elements= (trees_end - trees);
832
 
    uint32_t old_size= sizeof(SEL_TREE**) * old_elements;
833
 
    uint32_t new_size= old_size * realloc_ratio;
 
831
    uint old_elements= (trees_end - trees);
 
832
    uint old_size= sizeof(SEL_TREE**) * old_elements;
 
833
    uint new_size= old_size * realloc_ratio;
834
834
    SEL_TREE **new_trees;
835
835
    if (!(new_trees= (SEL_TREE**)alloc_root(param->mem_root, new_size)))
836
836
      return -1;
999
999
           1 = Got some error (out of memory?)
1000
1000
           */
1001
1001
 
1002
 
SQL_SELECT *make_select(Table *head, table_map const_tables,
 
1002
SQL_SELECT *make_select(TABLE *head, table_map const_tables,
1003
1003
                        table_map read_tables, COND *conds,
1004
1004
                        bool allow_null_cond,
1005
1005
                        int *error)
1025
1025
    select->file= *head->sort.io_cache;
1026
1026
    select->records=(ha_rows) (select->file.end_of_file/
1027
1027
                               head->file->ref_length);
1028
 
    free(head->sort.io_cache);
 
1028
    my_free(head->sort.io_cache, MYF(0));
1029
1029
    head->sort.io_cache=0;
1030
1030
  }
1031
1031
  return(select);
1063
1063
   used_key_parts(0)
1064
1064
{}
1065
1065
 
1066
 
QUICK_RANGE_SELECT::QUICK_RANGE_SELECT(THD *thd, Table *table, uint32_t key_nr,
 
1066
QUICK_RANGE_SELECT::QUICK_RANGE_SELECT(THD *thd, TABLE *table, uint key_nr,
1067
1067
                                       bool no_alloc, MEM_ROOT *parent_alloc,
1068
1068
                                       bool *create_error)
1069
1069
  :free_file(0),cur_range(NULL),last_range(0),dont_free(0)
1144
1144
    }
1145
1145
    delete_dynamic(&ranges); /* ranges are allocated in alloc */
1146
1146
    free_root(&alloc,MYF(0));
1147
 
    free((char*) column_bitmap.bitmap);
 
1147
    my_free((char*) column_bitmap.bitmap, MYF(MY_ALLOW_ZERO_PTR));
1148
1148
  }
1149
1149
  head->column_bitmaps_set(save_read_set, save_write_set);
1150
 
  if (mrr_buf_desc)
1151
 
    free(mrr_buf_desc);
 
1150
  x_free(mrr_buf_desc);
1152
1151
  return;
1153
1152
}
1154
1153
 
1155
1154
 
1156
1155
QUICK_INDEX_MERGE_SELECT::QUICK_INDEX_MERGE_SELECT(THD *thd_param,
1157
 
                                                   Table *table)
 
1156
                                                   TABLE *table)
1158
1157
  :pk_quick_select(NULL), thd(thd_param)
1159
1158
{
1160
1159
  index= MAX_KEY;
1204
1203
 
1205
1204
 
1206
1205
QUICK_ROR_INTERSECT_SELECT::QUICK_ROR_INTERSECT_SELECT(THD *thd_param,
1207
 
                                                       Table *table,
 
1206
                                                       TABLE *table,
1208
1207
                                                       bool retrieve_full_rows,
1209
1208
                                                       MEM_ROOT *parent_alloc)
1210
1209
  : cpk_quick(NULL), thd(thd_param), need_to_fetch_row(retrieve_full_rows),
1217
1216
    init_sql_alloc(&alloc, thd->variables.range_alloc_block_size, 0);
1218
1217
  else
1219
1218
    memset(&alloc, 0, sizeof(MEM_ROOT));
1220
 
  last_rowid= (unsigned char*) alloc_root(parent_alloc? parent_alloc : &alloc,
 
1219
  last_rowid= (uchar*) alloc_root(parent_alloc? parent_alloc : &alloc,
1221
1220
                                  head->file->ref_length);
1222
1221
}
1223
1222
 
1443
1442
 
1444
1443
 
1445
1444
QUICK_ROR_UNION_SELECT::QUICK_ROR_UNION_SELECT(THD *thd_param,
1446
 
                                               Table *table)
 
1445
                                               TABLE *table)
1447
1446
  : thd(thd_param), scans_inited(false)
1448
1447
{
1449
1448
  index= MAX_KEY;
1475
1474
    return(1);
1476
1475
  }
1477
1476
 
1478
 
  if (!(cur_rowid= (unsigned char*) alloc_root(&alloc, 2*head->file->ref_length)))
 
1477
  if (!(cur_rowid= (uchar*) alloc_root(&alloc, 2*head->file->ref_length)))
1479
1478
    return(1);
1480
1479
  prev_rowid= cur_rowid + head->file->ref_length;
1481
1480
  return(0);
1493
1492
      val2  Second merged select
1494
1493
*/
1495
1494
 
1496
 
int QUICK_ROR_UNION_SELECT::queue_cmp(void *arg, unsigned char *val1, unsigned char *val2)
 
1495
int QUICK_ROR_UNION_SELECT::queue_cmp(void *arg, uchar *val1, uchar *val2)
1497
1496
{
1498
1497
  QUICK_ROR_UNION_SELECT *self= (QUICK_ROR_UNION_SELECT*)arg;
1499
1498
  return self->head->file->cmp_ref(((QUICK_SELECT_I*)val1)->last_rowid,
1543
1542
      return(error);
1544
1543
    }
1545
1544
    quick->save_last_pos();
1546
 
    queue_insert(&queue, (unsigned char*)quick);
 
1545
    queue_insert(&queue, (uchar*)quick);
1547
1546
  }
1548
1547
 
1549
1548
  if (head->file->ha_rnd_init(1))
1602
1601
  use_count=0; elements=1;
1603
1602
}
1604
1603
 
1605
 
SEL_ARG::SEL_ARG(Field *f,const unsigned char *min_value_arg,
1606
 
                 const unsigned char *max_value_arg)
 
1604
SEL_ARG::SEL_ARG(Field *f,const uchar *min_value_arg,
 
1605
                 const uchar *max_value_arg)
1607
1606
  :min_flag(0), max_flag(0), maybe_flag(0), maybe_null(f->real_maybe_null()),
1608
 
   elements(1), use_count(1), field(f), min_value((unsigned char*) min_value_arg),
1609
 
   max_value((unsigned char*) max_value_arg), next(0),prev(0),
 
1607
   elements(1), use_count(1), field(f), min_value((uchar*) min_value_arg),
 
1608
   max_value((uchar*) max_value_arg), next(0),prev(0),
1610
1609
   next_key_part(0),color(BLACK),type(KEY_RANGE)
1611
1610
{
1612
1611
  left=right= &null_element;
1613
1612
}
1614
1613
 
1615
1614
SEL_ARG::SEL_ARG(Field *field_,uint8_t part_,
1616
 
                 unsigned char *min_value_, unsigned char *max_value_,
 
1615
                 uchar *min_value_, uchar *max_value_,
1617
1616
                 uint8_t min_flag_,uint8_t max_flag_,uint8_t maybe_flag_)
1618
1617
  :min_flag(min_flag_),max_flag(max_flag_),maybe_flag(maybe_flag_),
1619
1618
   part(part_),maybe_null(field_->real_maybe_null()), elements(1),use_count(1),
1691
1690
  Returns -2 or 2 if the ranges where 'joined' like  < 2 and >= 2
1692
1691
*/
1693
1692
 
1694
 
static int sel_cmp(Field *field, unsigned char *a, unsigned char *b, uint8_t a_flag,
 
1693
static int sel_cmp(Field *field, uchar *a, uchar *b, uint8_t a_flag,
1695
1694
                   uint8_t b_flag)
1696
1695
{
1697
1696
  int cmp;
1778
1777
    MAX_KEY if no such index was found.
1779
1778
*/
1780
1779
 
1781
 
uint32_t get_index_for_order(Table *table, order_st *order, ha_rows limit)
 
1780
uint get_index_for_order(TABLE *table, ORDER *order, ha_rows limit)
1782
1781
{
1783
 
  uint32_t idx;
1784
 
  uint32_t match_key= MAX_KEY, match_key_len= MAX_KEY_LENGTH + 1;
1785
 
  order_st *ord;
 
1782
  uint idx;
 
1783
  uint match_key= MAX_KEY, match_key_len= MAX_KEY_LENGTH + 1;
 
1784
  ORDER *ord;
1786
1785
  
1787
1786
  for (ord= order; ord; ord= ord->next)
1788
1787
    if (!ord->asc)
1793
1792
    if (!(table->keys_in_use_for_query.is_set(idx)))
1794
1793
      continue;
1795
1794
    KEY_PART_INFO *keyinfo= table->key_info[idx].key_part;
1796
 
    uint32_t n_parts=  table->key_info[idx].key_parts;
1797
 
    uint32_t partno= 0;
 
1795
    uint n_parts=  table->key_info[idx].key_parts;
 
1796
    uint partno= 0;
1798
1797
    
1799
1798
    /* 
1800
1799
      The below check is sufficient considering we now have either BTREE 
1908
1907
{
1909
1908
public:
1910
1909
  SEL_ARG *key; /* set of intervals to be used in "range" method retrieval */
1911
 
  uint32_t     key_idx; /* key number in PARAM::key */
1912
 
  uint32_t     mrr_flags; 
1913
 
  uint32_t     mrr_buf_size;
 
1910
  uint     key_idx; /* key number in PARAM::key */
 
1911
  uint     mrr_flags; 
 
1912
  uint     mrr_buf_size;
1914
1913
 
1915
 
  TRP_RANGE(SEL_ARG *key_arg, uint32_t idx_arg, uint32_t mrr_flags_arg)
 
1914
  TRP_RANGE(SEL_ARG *key_arg, uint idx_arg, uint mrr_flags_arg)
1916
1915
   : key(key_arg), key_idx(idx_arg), mrr_flags(mrr_flags_arg)
1917
1916
  {}
1918
1917
  virtual ~TRP_RANGE() {}                     /* Remove gcc warning */
1997
1996
private:
1998
1997
  bool have_min, have_max;
1999
1998
  KEY_PART_INFO *min_max_arg_part;
2000
 
  uint32_t group_prefix_len;
2001
 
  uint32_t used_key_parts;
2002
 
  uint32_t group_key_parts;
 
1999
  uint group_prefix_len;
 
2000
  uint used_key_parts;
 
2001
  uint group_key_parts;
2003
2002
  KEY *index_info;
2004
 
  uint32_t index;
2005
 
  uint32_t key_infix_len;
2006
 
  unsigned char key_infix[MAX_KEY_LENGTH];
 
2003
  uint index;
 
2004
  uint key_infix_len;
 
2005
  uchar key_infix[MAX_KEY_LENGTH];
2007
2006
  SEL_TREE *range_tree; /* Represents all range predicates in the query. */
2008
2007
  SEL_ARG  *index_tree; /* The SEL_ARG sub-tree corresponding to index_info. */
2009
 
  uint32_t param_idx; /* Index of used key in param->key. */
 
2008
  uint param_idx; /* Index of used key in param->key. */
2010
2009
  /* Number of records selected by the ranges in index_tree. */
2011
2010
public:
2012
2011
  ha_rows quick_prefix_records;
2013
2012
public:
2014
2013
  TRP_GROUP_MIN_MAX(bool have_min_arg, bool have_max_arg,
2015
2014
                    KEY_PART_INFO *min_max_arg_part_arg,
2016
 
                    uint32_t group_prefix_len_arg, uint32_t used_key_parts_arg,
2017
 
                    uint32_t group_key_parts_arg, KEY *index_info_arg,
2018
 
                    uint32_t index_arg, uint32_t key_infix_len_arg,
2019
 
                    unsigned char *key_infix_arg,
 
2015
                    uint group_prefix_len_arg, uint used_key_parts_arg,
 
2016
                    uint group_key_parts_arg, KEY *index_info_arg,
 
2017
                    uint index_arg, uint key_infix_len_arg,
 
2018
                    uchar *key_infix_arg,
2020
2019
                    SEL_TREE *tree_arg, SEL_ARG *index_tree_arg,
2021
 
                    uint32_t param_idx_arg, ha_rows quick_prefix_records_arg)
 
2020
                    uint param_idx_arg, ha_rows quick_prefix_records_arg)
2022
2021
  : have_min(have_min_arg), have_max(have_max_arg),
2023
2022
    min_max_arg_part(min_max_arg_part_arg),
2024
2023
    group_prefix_len(group_prefix_len_arg), used_key_parts(used_key_parts_arg),
2053
2052
 
2054
2053
static int fill_used_fields_bitmap(PARAM *param)
2055
2054
{
2056
 
  Table *table= param->table;
 
2055
  TABLE *table= param->table;
2057
2056
  my_bitmap_map *tmp;
2058
 
  uint32_t pk;
 
2057
  uint pk;
2059
2058
  param->tmp_covered_fields.bitmap= 0;
2060
2059
  param->fields_bitmap_size= table->s->column_bitmap_size;
2061
2060
  if (!(tmp= (my_bitmap_map*) alloc_root(param->mem_root,
2151
2150
                                  ha_rows limit, bool force_quick_range, 
2152
2151
                                  bool ordered_output)
2153
2152
{
2154
 
  uint32_t idx;
 
2153
  uint idx;
2155
2154
  double scan_time;
2156
2155
  delete quick;
2157
2156
  quick=0;
2226
2225
 
2227
2226
      param.key[param.keys]=key_parts;
2228
2227
      key_part_info= key_info->key_part;
2229
 
      for (uint32_t part=0 ; part < key_info->key_parts ;
 
2228
      for (uint part=0 ; part < key_info->key_parts ;
2230
2229
           part++, key_parts++, key_part_info++)
2231
2230
      {
2232
2231
        key_parts->key=          param.keys;
2247
2246
    /* Calculate cost of full index read for the shortest covering index */
2248
2247
    if (!head->covering_keys.is_clear_all())
2249
2248
    {
2250
 
      int key_for_use= head->find_shortest_key(&head->covering_keys);
 
2249
      int key_for_use= find_shortest_key(head, &head->covering_keys);
2251
2250
      double key_read_time= 
2252
2251
        param.table->file->index_only_read_time(key_for_use, 
2253
2252
                                                rows2double(records)) +
2286
2285
    group_trp= get_best_group_min_max(&param, tree);
2287
2286
    if (group_trp)
2288
2287
    {
2289
 
      param.table->quick_condition_rows= cmin(group_trp->records,
 
2288
      param.table->quick_condition_rows= min(group_trp->records,
2290
2289
                                             head->file->stats.records);
2291
2290
      if (group_trp->read_cost < best_read_time)
2292
2291
      {
2460
2459
{
2461
2460
  SEL_TREE **ptree;
2462
2461
  TRP_INDEX_MERGE *imerge_trp= NULL;
2463
 
  uint32_t n_child_scans= imerge->trees_next - imerge->trees;
 
2462
  uint n_child_scans= imerge->trees_next - imerge->trees;
2464
2463
  TRP_RANGE **range_scans;
2465
2464
  TRP_RANGE **cur_child;
2466
2465
  TRP_RANGE **cpk_scan= NULL;
2471
2470
  bool pk_is_clustered= param->table->file->primary_key_is_clustered();
2472
2471
  bool all_scans_ror_able= true;
2473
2472
  bool all_scans_rors= true;
2474
 
  uint32_t unique_calc_buff_size;
 
2473
  uint unique_calc_buff_size;
2475
2474
  TABLE_READ_PLAN **roru_read_plans;
2476
2475
  TABLE_READ_PLAN **cur_roru_plan;
2477
2476
  double roru_index_costs;
2577
2576
    {
2578
2577
      imerge_trp->read_cost= imerge_cost;
2579
2578
      imerge_trp->records= non_cpk_scan_records + cpk_scan_records;
2580
 
      imerge_trp->records= cmin(imerge_trp->records,
 
2579
      imerge_trp->records= min(imerge_trp->records,
2581
2580
                               param->table->file->stats.records);
2582
2581
      imerge_trp->range_scans= range_scans;
2583
2582
      imerge_trp->range_scans_end= range_scans + n_child_scans;
2689
2688
 
2690
2689
typedef struct st_ror_scan_info
2691
2690
{
2692
 
  uint32_t      idx;      /* # of used key in param->keys */
2693
 
  uint32_t      keynr;    /* # of used key in table */
 
2691
  uint      idx;      /* # of used key in param->keys */
 
2692
  uint      keynr;    /* # of used key in table */
2694
2693
  ha_rows   records;  /* estimate of # records this scan will return */
2695
2694
 
2696
2695
  /* Set of intervals over key fields that will be used for row retrieval. */
2698
2697
 
2699
2698
  /* Fields used in the query and covered by this ROR scan. */
2700
2699
  MY_BITMAP covered_fields;
2701
 
  uint32_t      used_fields_covered; /* # of set bits in covered_fields */
 
2700
  uint      used_fields_covered; /* # of set bits in covered_fields */
2702
2701
  int       key_rec_length; /* length of key record (including rowid) */
2703
2702
 
2704
2703
  /*
2706
2705
    (assuming there is no need to access full table records)
2707
2706
  */
2708
2707
  double    index_read_cost;
2709
 
  uint32_t      first_uncovered_field; /* first unused bit in covered_fields */
2710
 
  uint32_t      key_components; /* # of parts in the key */
 
2708
  uint      first_uncovered_field; /* first unused bit in covered_fields */
 
2709
  uint      key_components; /* # of parts in the key */
2711
2710
} ROR_SCAN_INFO;
2712
2711
 
2713
2712
 
2731
2730
{
2732
2731
  ROR_SCAN_INFO *ror_scan;
2733
2732
  my_bitmap_map *bitmap_buf;
2734
 
  uint32_t keynr;
 
2733
  uint keynr;
2735
2734
 
2736
2735
  if (!(ror_scan= (ROR_SCAN_INFO*)alloc_root(param->mem_root,
2737
2736
                                             sizeof(ROR_SCAN_INFO))))
2986
2985
{
2987
2986
  double selectivity_mult= 1.0;
2988
2987
  KEY_PART_INFO *key_part= info->param->table->key_info[scan->keynr].key_part;
2989
 
  unsigned char key_val[MAX_KEY_LENGTH+MAX_FIELD_WIDTH]; /* key values tuple */
2990
 
  unsigned char *key_ptr= key_val;
 
2988
  uchar key_val[MAX_KEY_LENGTH+MAX_FIELD_WIDTH]; /* key values tuple */
 
2989
  uchar *key_ptr= key_val;
2991
2990
  SEL_ARG *sel_arg, *tuple_arg= NULL;
2992
2991
  key_part_map keypart_map= 0;
2993
2992
  bool cur_covered;
3208
3207
                                          double read_time,
3209
3208
                                          bool *are_all_covering)
3210
3209
{
3211
 
  uint32_t idx;
 
3210
  uint idx;
3212
3211
  double min_cost= DBL_MAX;
3213
3212
 
3214
3213
  if ((tree->n_ror_scans < 2) || !param->table->file->stats.records)
3220
3219
  */
3221
3220
  ROR_SCAN_INFO **cur_ror_scan;
3222
3221
  ROR_SCAN_INFO *cpk_scan= NULL;
3223
 
  uint32_t cpk_no;
 
3222
  uint cpk_no;
3224
3223
  bool cpk_scan_used= false;
3225
3224
 
3226
3225
  if (!(tree->ror_scans= (ROR_SCAN_INFO**)alloc_root(param->mem_root,
3310
3309
                                          intersect_scans_best);
3311
3310
 
3312
3311
  *are_all_covering= intersect->is_covering;
3313
 
  uint32_t best_num= intersect_scans_best - intersect_scans;
 
3312
  uint best_num= intersect_scans_best - intersect_scans;
3314
3313
  ror_intersect_cpy(intersect, intersect_best);
3315
3314
 
3316
3315
  /*
3481
3480
  TRP_ROR_INTERSECT *trp;
3482
3481
  if (!(trp= new (param->mem_root) TRP_ROR_INTERSECT))
3483
3482
    return(trp);
3484
 
  uint32_t best_num= (ror_scan_mark - tree->ror_scans);
 
3483
  uint best_num= (ror_scan_mark - tree->ror_scans);
3485
3484
  if (!(trp->first_scan= (ROR_SCAN_INFO**)alloc_root(param->mem_root,
3486
3485
                                                     sizeof(ROR_SCAN_INFO*)*
3487
3486
                                                     best_num)))
3529
3528
                                       bool update_tbl_stats,
3530
3529
                                       double read_time)
3531
3530
{
3532
 
  uint32_t idx;
 
3531
  uint idx;
3533
3532
  SEL_ARG **key,**end, **key_to_read= NULL;
3534
3533
  ha_rows best_records= 0;
3535
 
  uint32_t    best_mrr_flags= 0, best_buf_size= 0;
 
3534
  uint    best_mrr_flags= 0, best_buf_size= 0;
3536
3535
  TRP_RANGE* read_plan= NULL;
3537
3536
  /*
3538
3537
    Note that there may be trees that have type SEL_TREE::KEY but contain no
3549
3548
      ha_rows found_records;
3550
3549
      COST_VECT cost;
3551
3550
      double found_read_time;
3552
 
      uint32_t mrr_flags, buf_size;
3553
 
      uint32_t keynr= param->real_keynr[idx];
 
3551
      uint mrr_flags, buf_size;
 
3552
      uint keynr= param->real_keynr[idx];
3554
3553
      if ((*key)->type == SEL_ARG::MAYBE_KEY ||
3555
3554
          (*key)->maybe_flag)
3556
3555
        param->needed_reg->set_bit(keynr);
3856
3855
          break;
3857
3856
 
3858
3857
        /* Get a SEL_TREE for "(-inf|NULL) < X < c_0" interval.  */
3859
 
        uint32_t i=0;
 
3858
        uint i=0;
3860
3859
        do 
3861
3860
        {
3862
3861
          func->array->value_to_item(i, value_item);
3889
3888
            }
3890
3889
 
3891
3890
            /* Change all intervals to be "c_{i-1} < X < c_i" */
3892
 
            for (uint32_t idx= 0; idx < param->keys; idx++)
 
3891
            for (uint idx= 0; idx < param->keys; idx++)
3893
3892
            {
3894
3893
              SEL_ARG *new_interval, *last_val;
3895
3894
              if (((new_interval= tree2->keys[idx])) &&
4055
4054
  table_map param_comp= ~(param->prev_tables | param->read_tables |
4056
4055
                          param->current_table);
4057
4056
 
4058
 
  for (uint32_t i= 0; i < cond_func->arg_count; i++)
 
4057
  for (uint i= 0; i < cond_func->arg_count; i++)
4059
4058
  {
4060
4059
    Item *arg= cond_func->arguments()[i]->real_item();
4061
4060
    if (arg != field_item)
4183
4182
      Concerning the code below see the NOTES section in
4184
4183
      the comments for the function get_full_func_mm_tree()
4185
4184
    */
4186
 
    for (uint32_t i= 1 ; i < cond_func->arg_count ; i++)
 
4185
    for (uint i= 1 ; i < cond_func->arg_count ; i++)
4187
4186
    {
4188
4187
      if (cond_func->arguments()[i]->real_item()->type() == Item::FIELD_ITEM)
4189
4188
      {
4296
4295
        if (!(sel_arg= new SEL_ARG(SEL_ARG::MAYBE_KEY)))
4297
4296
          return(0);                    // OOM
4298
4297
      }
4299
 
      sel_arg->part=(unsigned char) key_part->part;
 
4298
      sel_arg->part=(uchar) key_part->part;
4300
4299
      tree->keys[key_part->key]=sel_add(tree->keys[key_part->key],sel_arg);
4301
4300
      tree->keys_map.set_bit(key_part->key);
4302
4301
    }
4310
4309
get_mm_leaf(RANGE_OPT_PARAM *param, COND *conf_func, Field *field,
4311
4310
            KEY_PART *key_part, Item_func::Functype type,Item *value)
4312
4311
{
4313
 
  uint32_t maybe_null=(uint) field->real_maybe_null();
 
4312
  uint maybe_null=(uint) field->real_maybe_null();
4314
4313
  bool optimize_range;
4315
4314
  SEL_ARG *tree= 0;
4316
4315
  MEM_ROOT *alloc= param->mem_root;
4317
 
  unsigned char *str;
 
4316
  uchar *str;
4318
4317
  ulong orig_sql_mode;
4319
4318
  int err;
4320
4319
 
4376
4375
  {
4377
4376
    bool like_error;
4378
4377
    char buff1[MAX_FIELD_WIDTH];
4379
 
    unsigned char *min_str,*max_str;
 
4378
    uchar *min_str,*max_str;
4380
4379
    String tmp(buff1,sizeof(buff1),value->collation.collation),*res;
4381
4380
    size_t length, offset, min_length, max_length;
4382
 
    uint32_t field_length= field->pack_length()+maybe_null;
 
4381
    uint field_length= field->pack_length()+maybe_null;
4383
4382
 
4384
4383
    if (!optimize_range)
4385
4384
      goto end;
4425
4424
        field_length= length;
4426
4425
    }
4427
4426
    length+=offset;
4428
 
    if (!(min_str= (unsigned char*) alloc_root(alloc, length*2)))
 
4427
    if (!(min_str= (uchar*) alloc_root(alloc, length*2)))
4429
4428
      goto end;
4430
4429
 
4431
4430
    max_str=min_str+length;
4543
4542
    goto end;
4544
4543
  }
4545
4544
  field->table->in_use->variables.sql_mode= orig_sql_mode;
4546
 
  str= (unsigned char*) alloc_root(alloc, key_part->store_length+1);
 
4545
  str= (uchar*) alloc_root(alloc, key_part->store_length+1);
4547
4546
  if (!str)
4548
4547
    goto end;
4549
4548
  if (maybe_null)
4550
 
    *str= (unsigned char) field->is_real_null();        // Set to 1 if null
 
4549
    *str= (uchar) field->is_real_null();        // Set to 1 if null
4551
4550
  field->get_key_image(str+maybe_null, key_part->length,
4552
4551
                       key_part->image_type);
4553
4552
  if (!(tree= new (alloc) SEL_ARG(field, str, str)))
4699
4698
  for (key1= tree1->keys,key2= tree2->keys,end=key1+param->keys ;
4700
4699
       key1 != end ; key1++,key2++)
4701
4700
  {
4702
 
    uint32_t flag=0;
 
4701
    uint flag=0;
4703
4702
    if (*key1 || *key2)
4704
4703
    {
4705
4704
      if (*key1 && !(*key1)->simple_key())
4750
4749
 
4751
4750
  /* trees have a common key, check if they refer to same key part */
4752
4751
  SEL_ARG **key1,**key2;
4753
 
  for (uint32_t key_no=0; key_no < param->keys; key_no++)
 
4752
  for (uint key_no=0; key_no < param->keys; key_no++)
4754
4753
  {
4755
4754
    if (common_keys.is_set(key_no))
4756
4755
    {
4824
4823
static bool remove_nonrange_trees(RANGE_OPT_PARAM *param, SEL_TREE *tree)
4825
4824
{
4826
4825
  bool res= false;
4827
 
  for (uint32_t i=0; i < param->keys; i++)
 
4826
  for (uint i=0; i < param->keys; i++)
4828
4827
  {
4829
4828
    if (tree->keys[i])
4830
4829
    {
4912
4911
    {
4913
4912
      /* one tree is index merge tree and another is range tree */
4914
4913
      if (tree1->merges.is_empty())
4915
 
        std::swap(tree1, tree2);
 
4914
        swap_variables(SEL_TREE*, tree1, tree2);
4916
4915
      
4917
4916
      if (param->remove_jump_scans && remove_nonrange_trees(param, tree2))
4918
4917
         return(new SEL_TREE(SEL_TREE::ALWAYS));
4931
4930
 
4932
4931
static SEL_ARG *
4933
4932
and_all_keys(RANGE_OPT_PARAM *param, SEL_ARG *key1, SEL_ARG *key2, 
4934
 
             uint32_t clone_flag)
 
4933
             uint clone_flag)
4935
4934
{
4936
4935
  SEL_ARG *next;
4937
4936
  ulong use_count=key1->use_count;
4988
4987
*/
4989
4988
 
4990
4989
static SEL_ARG *
4991
 
key_and(RANGE_OPT_PARAM *param, SEL_ARG *key1, SEL_ARG *key2, uint32_t clone_flag)
 
4990
key_and(RANGE_OPT_PARAM *param, SEL_ARG *key1, SEL_ARG *key2, uint clone_flag)
4992
4991
{
4993
4992
  if (!key1)
4994
4993
    return key2;
4998
4997
  {
4999
4998
    if (key1->part > key2->part)
5000
4999
    {
5001
 
      std::swap(key1, key2);
 
5000
      swap_variables(SEL_ARG *, key1, key2);
5002
5001
      clone_flag=swap_clone_flag(clone_flag);
5003
5002
    }
5004
5003
    // key1->part < key2->part
5014
5013
       key2->type != SEL_ARG::MAYBE_KEY) ||
5015
5014
      key1->type == SEL_ARG::MAYBE_KEY)
5016
5015
  {                                             // Put simple key in key2
5017
 
    std::swap(key1, key2);
 
5016
    swap_variables(SEL_ARG *, key1, key2);
5018
5017
    clone_flag=swap_clone_flag(clone_flag);
5019
5018
  }
5020
5019
 
5157
5156
  {
5158
5157
    if (key2->use_count == 0 || key1->elements > key2->elements)
5159
5158
    {
5160
 
      std::swap(key1,key2);
 
5159
      swap_variables(SEL_ARG *,key1,key2);
5161
5160
    }
5162
5161
    if (key1->use_count > 0 || !(key1=key1->clone_tree(param)))
5163
5162
      return 0;                                 // OOM
5242
5241
      }
5243
5242
    }
5244
5243
 
5245
 
    // tmp.max >= key2.min && tmp.min <= key.cmax(overlapping ranges)
 
5244
    // tmp.max >= key2.min && tmp.min <= key.max  (overlapping ranges)
5246
5245
    if (eq_tree(tmp->next_key_part,key2->next_key_part))
5247
5246
    {
5248
5247
      if (tmp->is_same(key2))
5834
5833
 
5835
5834
void SEL_ARG::test_use_count(SEL_ARG *root)
5836
5835
{
5837
 
  uint32_t e_count=0;
 
5836
  uint e_count=0;
5838
5837
  if (this == root && use_count != 1)
5839
5838
  {
5840
5839
    sql_print_information("Use_count: Wrong count %lu for root",use_count);
5876
5875
    Pointers in min and max keys. They point to right-after-end of key
5877
5876
    images. The 0-th entry has these pointing to key tuple start.
5878
5877
  */
5879
 
  unsigned char *min_key, *max_key;
 
5878
  uchar *min_key, *max_key;
5880
5879
  
5881
5880
  /* 
5882
5881
    Flags, for {keypart0, keypart1, ... this_keypart} subtuple.
5883
5882
    min_key_flag may have NULL_RANGE set.
5884
5883
  */
5885
 
  uint32_t min_key_flag, max_key_flag;
 
5884
  uint min_key_flag, max_key_flag;
5886
5885
  
5887
5886
  /* Number of key parts */
5888
 
  uint32_t min_key_parts, max_key_parts;
 
5887
  uint min_key_parts, max_key_parts;
5889
5888
  SEL_ARG *key_tree;
5890
5889
} RANGE_SEQ_ENTRY;
5891
5890
 
5895
5894
*/
5896
5895
typedef struct st_sel_arg_range_seq
5897
5896
{
5898
 
  uint32_t keyno;      /* index of used tree in SEL_TREE structure */
5899
 
  uint32_t real_keyno; /* Number of the index in tables */
 
5897
  uint keyno;      /* index of used tree in SEL_TREE structure */
 
5898
  uint real_keyno; /* Number of the index in tables */
5900
5899
  PARAM *param;
5901
5900
  SEL_ARG *start; /* Root node of the traversed SEL_ARG* graph */
5902
5901
  
5921
5920
*/
5922
5921
 
5923
5922
range_seq_t sel_arg_range_seq_init(void *init_param,
5924
 
                                   uint32_t n_ranges __attribute__((unused)),
5925
 
                                   uint32_t flags __attribute__((unused)))
 
5923
                                   uint n_ranges __attribute__((unused)),
 
5924
                                   uint flags __attribute__((unused)))
5926
5925
{
5927
5926
  SEL_ARG_RANGE_SEQ *seq= (SEL_ARG_RANGE_SEQ*)init_param;
5928
5927
  seq->at_start= true;
5989
5988
*/
5990
5989
 
5991
5990
//psergey-merge-todo: support check_quick_keys:max_keypart
5992
 
uint32_t sel_arg_range_seq_next(range_seq_t rseq, KEY_MULTI_RANGE *range)
 
5991
uint sel_arg_range_seq_next(range_seq_t rseq, KEY_MULTI_RANGE *range)
5993
5992
{
5994
5993
  SEL_ARG *key_tree;
5995
5994
  SEL_ARG_RANGE_SEQ *seq= (SEL_ARG_RANGE_SEQ*)rseq;
6045
6044
  {
6046
6045
    {
6047
6046
      RANGE_SEQ_ENTRY *cur= &seq->stack[seq->i];
6048
 
      uint32_t min_key_length= cur->min_key - seq->param->min_key;
6049
 
      uint32_t max_key_length= cur->max_key - seq->param->max_key;
6050
 
      uint32_t len= cur->min_key - cur[-1].min_key;
 
6047
      uint min_key_length= cur->min_key - seq->param->min_key;
 
6048
      uint max_key_length= cur->max_key - seq->param->max_key;
 
6049
      uint len= cur->min_key - cur[-1].min_key;
6051
6050
      if (!(min_key_length == max_key_length &&
6052
6051
            !memcmp(cur[-1].min_key, cur[-1].max_key, len) &&
6053
6052
            !key_tree->min_flag && !key_tree->max_flag))
6128
6127
    }
6129
6128
  }
6130
6129
  seq->param->range_count++;
6131
 
  seq->param->max_key_part=cmax(seq->param->max_key_part,(uint)key_tree->part);
 
6130
  seq->param->max_key_part=max(seq->param->max_key_part,key_tree->part);
6132
6131
  return 0;
6133
6132
}
6134
6133
 
6161
6160
*/
6162
6161
 
6163
6162
static
6164
 
ha_rows check_quick_select(PARAM *param, uint32_t idx, bool index_only,
 
6163
ha_rows check_quick_select(PARAM *param, uint idx, bool index_only,
6165
6164
                           SEL_ARG *tree, bool update_tbl_stats, 
6166
 
                           uint32_t *mrr_flags, uint32_t *bufsize, COST_VECT *cost)
 
6165
                           uint *mrr_flags, uint *bufsize, COST_VECT *cost)
6167
6166
{
6168
6167
  SEL_ARG_RANGE_SEQ seq;
6169
6168
  RANGE_SEQ_IF seq_if = {sel_arg_range_seq_init, sel_arg_range_seq_next};
6170
6169
  handler *file= param->table->file;
6171
6170
  ha_rows rows;
6172
 
  uint32_t keynr= param->real_keynr[idx];
 
6171
  uint keynr= param->real_keynr[idx];
6173
6172
  
6174
6173
  /* Handle cases when we don't have a valid non-empty list of range */
6175
6174
  if (!tree)
6215
6214
      param->table->quick_key_parts[keynr]=param->max_key_part+1;
6216
6215
      param->table->quick_n_ranges[keynr]= param->range_count;
6217
6216
      param->table->quick_condition_rows=
6218
 
        cmin(param->table->quick_condition_rows, rows);
 
6217
        min(param->table->quick_condition_rows, rows);
6219
6218
    }
6220
6219
  }
6221
6220
  /* Figure out if the key scan is ROR (returns rows in ROWID order) or not */
6277
6276
    false  Otherwise
6278
6277
*/
6279
6278
 
6280
 
static bool is_key_scan_ror(PARAM *param, uint32_t keynr, uint8_t nparts)
 
6279
static bool is_key_scan_ror(PARAM *param, uint keynr, uint8_t nparts)
6281
6280
{
6282
6281
  KEY *table_key= param->table->key_info + keynr;
6283
6282
  KEY_PART_INFO *key_part= table_key->key_part + nparts;
6284
6283
  KEY_PART_INFO *key_part_end= (table_key->key_part +
6285
6284
                                table_key->key_parts);
6286
 
  uint32_t pk_number;
 
6285
  uint pk_number;
6287
6286
  
6288
6287
  for (KEY_PART_INFO *kp= table_key->key_part; kp < key_part; kp++)
6289
6288
  {
6339
6338
*/
6340
6339
 
6341
6340
QUICK_RANGE_SELECT *
6342
 
get_quick_select(PARAM *param,uint32_t idx,SEL_ARG *key_tree, uint32_t mrr_flags,
6343
 
                 uint32_t mrr_buf_size, MEM_ROOT *parent_alloc)
 
6341
get_quick_select(PARAM *param,uint idx,SEL_ARG *key_tree, uint mrr_flags,
 
6342
                 uint mrr_buf_size, MEM_ROOT *parent_alloc)
6344
6343
{
6345
6344
  QUICK_RANGE_SELECT *quick;
6346
6345
  bool create_err= false;
6378
6377
*/
6379
6378
bool
6380
6379
get_quick_keys(PARAM *param,QUICK_RANGE_SELECT *quick,KEY_PART *key,
6381
 
               SEL_ARG *key_tree, unsigned char *min_key,uint32_t min_key_flag,
6382
 
               unsigned char *max_key, uint32_t max_key_flag)
 
6380
               SEL_ARG *key_tree, uchar *min_key,uint min_key_flag,
 
6381
               uchar *max_key, uint max_key_flag)
6383
6382
{
6384
6383
  QUICK_RANGE *range;
6385
 
  uint32_t flag;
 
6384
  uint flag;
6386
6385
  int min_part= key_tree->part-1, // # of keypart values in min_key buffer
6387
6386
      max_part= key_tree->part-1; // # of keypart values in max_key buffer
6388
6387
 
6392
6391
                       min_key,min_key_flag, max_key, max_key_flag))
6393
6392
      return 1;
6394
6393
  }
6395
 
  unsigned char *tmp_min_key=min_key,*tmp_max_key=max_key;
 
6394
  uchar *tmp_min_key=min_key,*tmp_max_key=max_key;
6396
6395
  min_part+= key_tree->store_min(key[key_tree->part].store_length,
6397
6396
                                 &tmp_min_key,min_key_flag);
6398
6397
  max_part+= key_tree->store_max(key[key_tree->part].store_length,
6413
6412
      goto end;                                 // Ugly, but efficient
6414
6413
    }
6415
6414
    {
6416
 
      uint32_t tmp_min_flag=key_tree->min_flag,tmp_max_flag=key_tree->max_flag;
 
6415
      uint tmp_min_flag=key_tree->min_flag,tmp_max_flag=key_tree->max_flag;
6417
6416
      if (!tmp_min_flag)
6418
6417
        min_part+= key_tree->next_key_part->store_min_key(key, &tmp_min_key,
6419
6418
                                                          &tmp_min_flag);
6444
6443
  }
6445
6444
  if (flag == 0)
6446
6445
  {
6447
 
    uint32_t length= (uint) (tmp_min_key - param->min_key);
 
6446
    uint length= (uint) (tmp_min_key - param->min_key);
6448
6447
    if (length == (uint) (tmp_max_key - param->max_key) &&
6449
6448
        !memcmp(param->min_key,param->max_key,length))
6450
6449
    {
6477
6476
  set_if_bigger(quick->max_used_key_length, range->min_length);
6478
6477
  set_if_bigger(quick->max_used_key_length, range->max_length);
6479
6478
  set_if_bigger(quick->used_key_parts, (uint) key_tree->part+1);
6480
 
  if (insert_dynamic(&quick->ranges, (unsigned char*) &range))
 
6479
  if (insert_dynamic(&quick->ranges, (uchar*) &range))
6481
6480
    return 1;
6482
6481
 
6483
6482
 end:
6523
6522
    false  Otherwise
6524
6523
*/
6525
6524
 
6526
 
static bool null_part_in_key(KEY_PART *key_part, const unsigned char *key, uint32_t length)
 
6525
static bool null_part_in_key(KEY_PART *key_part, const uchar *key, uint length)
6527
6526
{
6528
 
  for (const unsigned char *end=key+length ;
 
6527
  for (const uchar *end=key+length ;
6529
6528
       key < end;
6530
6529
       key+= key_part++->store_length)
6531
6530
  {
6597
6596
    NULL on error.
6598
6597
*/
6599
6598
 
6600
 
QUICK_RANGE_SELECT *get_quick_select_for_ref(THD *thd, Table *table,
 
6599
QUICK_RANGE_SELECT *get_quick_select_for_ref(THD *thd, TABLE *table,
6601
6600
                                             TABLE_REF *ref, ha_rows records)
6602
6601
{
6603
6602
  MEM_ROOT *old_root, *alloc;
6605
6604
  KEY *key_info = &table->key_info[ref->key];
6606
6605
  KEY_PART *key_part;
6607
6606
  QUICK_RANGE *range;
6608
 
  uint32_t part;
 
6607
  uint part;
6609
6608
  bool create_err= false;
6610
6609
  COST_VECT cost;
6611
6610
 
6626
6625
    goto err;
6627
6626
  quick->records= records;
6628
6627
 
6629
 
  if ((cp_buffer_from_ref(thd, ref) && thd->is_fatal_error) ||
 
6628
  if ((cp_buffer_from_ref(thd, table, ref) && thd->is_fatal_error) ||
6630
6629
      !(range= new(alloc) QUICK_RANGE()))
6631
6630
    goto err;                                   // out of memory
6632
6631
 
6650
6649
    key_part->null_bit=     key_info->key_part[part].null_bit;
6651
6650
    key_part->flag=         (uint8_t) key_info->key_part[part].key_part_flag;
6652
6651
  }
6653
 
  if (insert_dynamic(&quick->ranges,(unsigned char*)&range))
 
6652
  if (insert_dynamic(&quick->ranges,(uchar*)&range))
6654
6653
    goto err;
6655
6654
 
6656
6655
  /*
6671
6670
                      make_prev_keypart_map(ref->key_parts), EQ_RANGE)))
6672
6671
      goto err;
6673
6672
    *ref->null_ref_key= 0;              // Clear null byte
6674
 
    if (insert_dynamic(&quick->ranges,(unsigned char*)&null_range))
 
6673
    if (insert_dynamic(&quick->ranges,(uchar*)&null_range))
6675
6674
      goto err;
6676
6675
  }
6677
6676
 
6849
6848
  List_iterator_fast<QUICK_RANGE_SELECT> quick_it(quick_selects);
6850
6849
  QUICK_RANGE_SELECT* quick;
6851
6850
  int error, cmp;
6852
 
  uint32_t last_rowid_count=0;
 
6851
  uint last_rowid_count=0;
6853
6852
 
6854
6853
  do
6855
6854
  {
6933
6932
{
6934
6933
  int error, dup_row;
6935
6934
  QUICK_SELECT_I *quick;
6936
 
  unsigned char *tmp;
 
6935
  uchar *tmp;
6937
6936
 
6938
6937
  do
6939
6938
  {
6981
6980
 
6982
6981
int QUICK_RANGE_SELECT::reset()
6983
6982
{
6984
 
  uint32_t  buf_size;
6985
 
  unsigned char *mrange_buff;
 
6983
  uint  buf_size;
 
6984
  uchar *mrange_buff;
6986
6985
  int   error;
6987
6986
  HANDLER_BUFFER empty_buf;
6988
6987
  last_range= NULL;
6998
6997
    while (buf_size && !my_multi_malloc(MYF(MY_WME),
6999
6998
                                        &mrr_buf_desc, sizeof(*mrr_buf_desc),
7000
6999
                                        &mrange_buff, buf_size,
7001
 
                                        NULL))
 
7000
                                        NullS))
7002
7001
    {
7003
7002
      /* Try to shrink the buffers until both are 0. */
7004
7003
      buf_size/= 2;
7039
7038
*/
7040
7039
 
7041
7040
range_seq_t quick_range_seq_init(void *init_param,
7042
 
                                 uint32_t n_ranges __attribute__((unused)),
7043
 
                                 uint32_t flags __attribute__((unused)))
 
7041
                                 uint n_ranges __attribute__((unused)),
 
7042
                                 uint flags __attribute__((unused)))
7044
7043
{
7045
7044
  QUICK_RANGE_SELECT *quick= (QUICK_RANGE_SELECT*)init_param;
7046
7045
  quick->qr_traversal_ctx.first=  (QUICK_RANGE**)quick->ranges.buffer;
7064
7063
    1  No more ranges in the sequence
7065
7064
*/
7066
7065
 
7067
 
uint32_t quick_range_seq_next(range_seq_t rseq, KEY_MULTI_RANGE *range)
 
7066
uint quick_range_seq_next(range_seq_t rseq, KEY_MULTI_RANGE *range)
7068
7067
{
7069
7068
  QUICK_RANGE_SEQ_CTX *ctx= (QUICK_RANGE_SEQ_CTX*)rseq;
7070
7069
 
7116
7115
    Reference to range_flag associated with range number #idx
7117
7116
*/
7118
7117
 
7119
 
uint16_t &mrr_persistent_flag_storage(range_seq_t seq, uint32_t idx)
 
7118
uint16_t &mrr_persistent_flag_storage(range_seq_t seq, uint idx)
7120
7119
{
7121
7120
  QUICK_RANGE_SEQ_CTX *ctx= (QUICK_RANGE_SEQ_CTX*)seq;
7122
7121
  return ctx->first[idx]->flag;
7149
7148
*/
7150
7149
 
7151
7150
char* &mrr_get_ptr_by_idx(range_seq_t seq __attribute__((unused)),
7152
 
                          uint32_t idx __attribute__((unused)))
 
7151
                          uint idx __attribute__((unused)))
7153
7152
{
7154
7153
  static char *dummy;
7155
7154
  return dummy;
7222
7221
    other              if some error occurred
7223
7222
*/
7224
7223
 
7225
 
int QUICK_RANGE_SELECT::get_next_prefix(uint32_t prefix_length,
 
7224
int QUICK_RANGE_SELECT::get_next_prefix(uint prefix_length,
7226
7225
                                        key_part_map keypart_map,
7227
 
                                        unsigned char *cur_prefix)
 
7226
                                        uchar *cur_prefix)
7228
7227
{
7229
7228
  for (;;)
7230
7229
  {
7240
7239
        return(result);
7241
7240
    }
7242
7241
 
7243
 
    uint32_t count= ranges.elements - (cur_range - (QUICK_RANGE**) ranges.buffer);
 
7242
    uint count= ranges.elements - (cur_range - (QUICK_RANGE**) ranges.buffer);
7244
7243
    if (count == 0)
7245
7244
    {
7246
7245
      /* Ranges have already been used up before. None is left for read. */
7249
7248
    }
7250
7249
    last_range= *(cur_range++);
7251
7250
 
7252
 
    start_key.key=    (const unsigned char*) last_range->min_key;
7253
 
    start_key.length= cmin(last_range->min_length, (uint16_t)prefix_length);
 
7251
    start_key.key=    (const uchar*) last_range->min_key;
 
7252
    start_key.length= min(last_range->min_length, prefix_length);
7254
7253
    start_key.keypart_map= last_range->min_keypart_map & keypart_map;
7255
7254
    start_key.flag=   ((last_range->flag & NEAR_MIN) ? HA_READ_AFTER_KEY :
7256
7255
                       (last_range->flag & EQ_RANGE) ?
7257
7256
                       HA_READ_KEY_EXACT : HA_READ_KEY_OR_NEXT);
7258
 
    end_key.key=      (const unsigned char*) last_range->max_key;
7259
 
    end_key.length=   cmin(last_range->max_length, (uint16_t)prefix_length);
 
7257
    end_key.key=      (const uchar*) last_range->max_key;
 
7258
    end_key.length=   min(last_range->max_length, prefix_length);
7260
7259
    end_key.keypart_map= last_range->max_keypart_map & keypart_map;
7261
7260
    /*
7262
7261
      We use READ_AFTER_KEY here because if we are reading on a key
7300
7299
bool QUICK_RANGE_SELECT::row_in_ranges()
7301
7300
{
7302
7301
  QUICK_RANGE *res;
7303
 
  uint32_t min= 0;
7304
 
  uint32_t max= ranges.elements - 1;
7305
 
  uint32_t mid= (max + min)/2;
 
7302
  uint min= 0;
 
7303
  uint max= ranges.elements - 1;
 
7304
  uint mid= (max + min)/2;
7306
7305
 
7307
7306
  while (min != max)
7308
7307
  {
7330
7329
 */
7331
7330
 
7332
7331
QUICK_SELECT_DESC::QUICK_SELECT_DESC(QUICK_RANGE_SELECT *q,
7333
 
                                     uint32_t used_key_parts_arg __attribute__((unused)),
 
7332
                                     uint used_key_parts_arg __attribute__((unused)),
7334
7333
                                     bool *create_err __attribute__((unused)))
7335
7334
 :QUICK_RANGE_SELECT(*q), rev_it(rev_ranges)
7336
7335
{
7445
7444
    return 0;                                   /* key can't be to large */
7446
7445
 
7447
7446
  KEY_PART *key_part=key_parts;
7448
 
  uint32_t store_length;
 
7447
  uint store_length;
7449
7448
 
7450
 
  for (unsigned char *key=range_arg->max_key, *end=key+range_arg->max_length;
 
7449
  for (uchar *key=range_arg->max_key, *end=key+range_arg->max_length;
7451
7450
       key < end;
7452
7451
       key+= store_length, key_part++)
7453
7452
  {
7580
7579
                                              String *used_lengths)
7581
7580
{
7582
7581
  char buf[64];
7583
 
  uint32_t length;
 
7582
  uint length;
7584
7583
  KEY *key_info= head->key_info + index;
7585
7584
  key_names->append(key_info->name);
7586
7585
  length= int64_t2str(max_used_key_length, buf, 10) - buf;
7591
7590
                                                    String *used_lengths)
7592
7591
{
7593
7592
  char buf[64];
7594
 
  uint32_t length;
 
7593
  uint length;
7595
7594
  bool first= true;
7596
7595
  QUICK_RANGE_SELECT *quick;
7597
7596
 
7626
7625
                                                      String *used_lengths)
7627
7626
{
7628
7627
  char buf[64];
7629
 
  uint32_t length;
 
7628
  uint length;
7630
7629
  bool first= true;
7631
7630
  QUICK_RANGE_SELECT *quick;
7632
7631
  List_iterator_fast<QUICK_RANGE_SELECT> it(quick_selects);
7680
7679
* Implementation of QUICK_GROUP_MIN_MAX_SELECT
7681
7680
*******************************************************************************/
7682
7681
 
7683
 
static inline uint32_t get_field_keypart(KEY *index, Field *field);
7684
 
static inline SEL_ARG * get_index_range_tree(uint32_t index, SEL_TREE* range_tree,
7685
 
                                             PARAM *param, uint32_t *param_idx);
 
7682
static inline uint get_field_keypart(KEY *index, Field *field);
 
7683
static inline SEL_ARG * get_index_range_tree(uint index, SEL_TREE* range_tree,
 
7684
                                             PARAM *param, uint *param_idx);
7686
7685
static bool get_constant_key_infix(KEY *index_info, SEL_ARG *index_range_tree,
7687
7686
                       KEY_PART_INFO *first_non_group_part,
7688
7687
                       KEY_PART_INFO *min_max_arg_part,
7689
7688
                       KEY_PART_INFO *last_part, THD *thd,
7690
 
                       unsigned char *key_infix, uint32_t *key_infix_len,
 
7689
                       uchar *key_infix, uint *key_infix_len,
7691
7690
                       KEY_PART_INFO **first_non_infix_part);
7692
7691
static bool
7693
7692
check_group_min_max_predicates(COND *cond, Item_field *min_max_arg_item,
7694
7693
                               Field::imagetype image_type);
7695
7694
 
7696
7695
static void
7697
 
cost_group_min_max(Table* table, KEY *index_info, uint32_t used_key_parts,
7698
 
                   uint32_t group_key_parts, SEL_TREE *range_tree,
 
7696
cost_group_min_max(TABLE* table, KEY *index_info, uint used_key_parts,
 
7697
                   uint group_key_parts, SEL_TREE *range_tree,
7699
7698
                   SEL_ARG *index_tree, ha_rows quick_prefix_records,
7700
7699
                   bool have_min, bool have_max,
7701
7700
                   double *read_cost, ha_rows *records);
7834
7833
{
7835
7834
  THD *thd= param->thd;
7836
7835
  JOIN *join= thd->lex->current_select->join;
7837
 
  Table *table= param->table;
 
7836
  TABLE *table= param->table;
7838
7837
  bool have_min= false;              /* true if there is a MIN function. */
7839
7838
  bool have_max= false;              /* true if there is a MAX function. */
7840
7839
  Item_field *min_max_arg_item= NULL; // The argument of all MIN/MAX functions
7841
7840
  KEY_PART_INFO *min_max_arg_part= NULL; /* The corresponding keypart. */
7842
 
  uint32_t group_prefix_len= 0; /* Length (in bytes) of the key prefix. */
 
7841
  uint group_prefix_len= 0; /* Length (in bytes) of the key prefix. */
7843
7842
  KEY *index_info= NULL;    /* The index chosen for data access. */
7844
 
  uint32_t index= 0;            /* The id of the chosen index. */
7845
 
  uint32_t group_key_parts= 0;  // Number of index key parts in the group prefix.
7846
 
  uint32_t used_key_parts= 0;   /* Number of index key parts used for access. */
7847
 
  unsigned char key_infix[MAX_KEY_LENGTH]; /* Constants from equality predicates.*/
7848
 
  uint32_t key_infix_len= 0;          /* Length of key_infix. */
 
7843
  uint index= 0;            /* The id of the chosen index. */
 
7844
  uint group_key_parts= 0;  // Number of index key parts in the group prefix.
 
7845
  uint used_key_parts= 0;   /* Number of index key parts used for access. */
 
7846
  uchar key_infix[MAX_KEY_LENGTH]; /* Constants from equality predicates.*/
 
7847
  uint key_infix_len= 0;          /* Length of key_infix. */
7849
7848
  TRP_GROUP_MIN_MAX *read_plan= NULL; /* The eventually constructed TRP. */
7850
 
  uint32_t key_part_nr;
7851
 
  order_st *tmp_group;
 
7849
  uint key_part_nr;
 
7850
  ORDER *tmp_group;
7852
7851
  Item *item;
7853
7852
  Item_field *item_field;
7854
7853
 
7926
7925
  KEY_PART_INFO *last_part= NULL;
7927
7926
  KEY_PART_INFO *first_non_group_part= NULL;
7928
7927
  KEY_PART_INFO *first_non_infix_part= NULL;
7929
 
  uint32_t key_infix_parts= 0;
7930
 
  uint32_t cur_group_key_parts= 0;
7931
 
  uint32_t cur_group_prefix_len= 0;
 
7928
  uint key_infix_parts= 0;
 
7929
  uint cur_group_key_parts= 0;
 
7930
  uint cur_group_prefix_len= 0;
7932
7931
  /* Cost-related variables for the best index so far. */
7933
7932
  double best_read_cost= DBL_MAX;
7934
7933
  ha_rows best_records= 0;
7935
7934
  SEL_ARG *best_index_tree= NULL;
7936
7935
  ha_rows best_quick_prefix_records= 0;
7937
 
  uint32_t best_param_idx= 0;
 
7936
  uint best_param_idx= 0;
7938
7937
  double cur_read_cost= DBL_MAX;
7939
7938
  ha_rows cur_records;
7940
7939
  SEL_ARG *cur_index_tree= NULL;
7941
7940
  ha_rows cur_quick_prefix_records= 0;
7942
 
  uint32_t cur_param_idx=MAX_KEY;
 
7941
  uint cur_param_idx=MAX_KEY;
7943
7942
  key_map cur_used_key_parts;
7944
 
  uint32_t pk= param->table->s->primary_key;
 
7943
  uint pk= param->table->s->primary_key;
7945
7944
 
7946
 
  for (uint32_t cur_index= 0 ; cur_index_info != cur_index_info_end ;
 
7945
  for (uint cur_index= 0 ; cur_index_info != cur_index_info_end ;
7947
7946
       cur_index_info++, cur_index++)
7948
7947
  {
7949
7948
    /* Check (B1) - if current index is covering. */
7963
7962
        (table->file->ha_table_flags() & HA_PRIMARY_KEY_IN_READ_INDEX))
7964
7963
    {
7965
7964
      /* For each table field */
7966
 
      for (uint32_t i= 0; i < table->s->fields; i++)
 
7965
      for (uint i= 0; i < table->s->fields; i++)
7967
7966
      {
7968
7967
        Field *cur_field= table->field[i];
7969
7968
        /*
8006
8005
    }
8007
8006
    /*
8008
8007
      Check (GA2) if this is a DISTINCT query.
8009
 
      If GA2, then Store a new order_st object in group_fields_array at the
8010
 
      position of the key part of item_field->field. Thus we get the order_st
 
8008
      If GA2, then Store a new ORDER object in group_fields_array at the
 
8009
      position of the key part of item_field->field. Thus we get the ORDER
8011
8010
      objects for each field ordered as the corresponding key parts.
8012
 
      Later group_fields_array of order_st objects is used to convert the query
 
8011
      Later group_fields_array of ORDER objects is used to convert the query
8013
8012
      to a GROUP query.
8014
8013
    */
8015
8014
    else if (join->select_distinct)
8016
8015
    {
8017
8016
      select_items_it.rewind();
8018
8017
      cur_used_key_parts.clear_all();
8019
 
      uint32_t max_key_part= 0;
 
8018
      uint max_key_part= 0;
8020
8019
      while ((item= select_items_it++))
8021
8020
      {
8022
8021
        item_field= (Item_field*) item; /* (SA5) already checked above. */
8034
8033
        cur_group_prefix_len+= cur_part->store_length;
8035
8034
        cur_used_key_parts.set_bit(key_part_nr);
8036
8035
        ++cur_group_key_parts;
8037
 
        max_key_part= cmax(max_key_part,key_part_nr);
 
8036
        max_key_part= max(max_key_part,key_part_nr);
8038
8037
      }
8039
8038
      /*
8040
8039
        Check that used key parts forms a prefix of the index.
8089
8088
    {
8090
8089
      if (tree)
8091
8090
      {
8092
 
        uint32_t dummy;
 
8091
        uint dummy;
8093
8092
        SEL_ARG *index_range_tree= get_index_range_tree(cur_index, tree, param,
8094
8093
                                                        &dummy);
8095
8094
        if (!get_constant_key_infix(cur_index_info, index_range_tree,
8127
8126
 
8128
8127
        /* Check if cur_part is referenced in the WHERE clause. */
8129
8128
        if (join->conds->walk(&Item::find_item_in_field_list_processor, 0,
8130
 
                              (unsigned char*) key_part_range))
 
8129
                              (uchar*) key_part_range))
8131
8130
          goto next_index;
8132
8131
      }
8133
8132
    }
8160
8159
                                           &cur_param_idx);
8161
8160
      /* Check if this range tree can be used for prefix retrieval. */
8162
8161
      COST_VECT dummy_cost;
8163
 
      uint32_t mrr_flags= HA_MRR_USE_DEFAULT_IMPL;
8164
 
      uint32_t mrr_bufsize=0;
 
8162
      uint mrr_flags= HA_MRR_USE_DEFAULT_IMPL;
 
8163
      uint mrr_bufsize=0;
8165
8164
      cur_quick_prefix_records= check_quick_select(param, cur_param_idx, 
8166
8165
                                                   false /*don't care*/, 
8167
8166
                                                   cur_index_tree, true,
8287
8286
  Item_func *pred= (Item_func*) cond;
8288
8287
  Item **arguments= pred->arguments();
8289
8288
  Item *cur_arg;
8290
 
  for (uint32_t arg_idx= 0; arg_idx < pred->argument_count (); arg_idx++)
 
8289
  for (uint arg_idx= 0; arg_idx < pred->argument_count (); arg_idx++)
8291
8290
  {
8292
8291
    cur_arg= arguments[arg_idx]->real_item();
8293
8292
    if (cur_arg->type() == Item::FIELD_ITEM)
8395
8394
                       KEY_PART_INFO *min_max_arg_part,
8396
8395
                       KEY_PART_INFO *last_part,
8397
8396
                       THD *thd __attribute__((unused)),
8398
 
                       unsigned char *key_infix, uint32_t *key_infix_len,
 
8397
                       uchar *key_infix, uint *key_infix_len,
8399
8398
                       KEY_PART_INFO **first_non_infix_part)
8400
8399
{
8401
8400
  SEL_ARG       *cur_range;
8404
8403
  KEY_PART_INFO *end_part= min_max_arg_part ? min_max_arg_part : last_part;
8405
8404
 
8406
8405
  *key_infix_len= 0;
8407
 
  unsigned char *key_ptr= key_infix;
 
8406
  uchar *key_ptr= key_infix;
8408
8407
  for (cur_part= first_non_group_part; cur_part != end_part; cur_part++)
8409
8408
  {
8410
8409
    /*
8436
8435
        (cur_range->min_flag & NEAR_MIN) || (cur_range->max_flag & NEAR_MAX))
8437
8436
      return false;
8438
8437
 
8439
 
    uint32_t field_length= cur_part->store_length;
 
8438
    uint field_length= cur_part->store_length;
8440
8439
    if ((cur_range->maybe_null &&
8441
8440
         cur_range->min_value[0] && cur_range->max_value[0]) ||
8442
8441
        !memcmp(cur_range->min_value, cur_range->max_value, field_length))
8511
8510
    Pointer to the SEL_ARG subtree that corresponds to index.
8512
8511
*/
8513
8512
 
8514
 
SEL_ARG * get_index_range_tree(uint32_t index, SEL_TREE* range_tree, PARAM *param,
8515
 
                               uint32_t *param_idx)
 
8513
SEL_ARG * get_index_range_tree(uint index, SEL_TREE* range_tree, PARAM *param,
 
8514
                               uint *param_idx)
8516
8515
{
8517
 
  uint32_t idx= 0; /* Index nr in param->key_parts */
 
8516
  uint idx= 0; /* Index nr in param->key_parts */
8518
8517
  while (idx < param->keys)
8519
8518
  {
8520
8519
    if (index == param->real_keynr[idx])
8586
8585
    None
8587
8586
*/
8588
8587
 
8589
 
void cost_group_min_max(Table* table, KEY *index_info, uint32_t used_key_parts,
8590
 
                        uint32_t group_key_parts, SEL_TREE *range_tree,
 
8588
void cost_group_min_max(TABLE* table, KEY *index_info, uint used_key_parts,
 
8589
                        uint group_key_parts, SEL_TREE *range_tree,
8591
8590
                        SEL_ARG *index_tree __attribute__((unused)),
8592
8591
                        ha_rows quick_prefix_records,
8593
8592
                        bool have_min, bool have_max,
8594
8593
                        double *read_cost, ha_rows *records)
8595
8594
{
8596
8595
  ha_rows table_records;
8597
 
  uint32_t num_groups;
8598
 
  uint32_t num_blocks;
8599
 
  uint32_t keys_per_block;
8600
 
  uint32_t keys_per_group;
8601
 
  uint32_t keys_per_subgroup; /* Average number of keys in sub-groups */
 
8596
  uint num_groups;
 
8597
  uint num_blocks;
 
8598
  uint keys_per_block;
 
8599
  uint keys_per_group;
 
8600
  uint keys_per_subgroup; /* Average number of keys in sub-groups */
8602
8601
                          /* formed by a key infix. */
8603
8602
  double p_overlap; /* Probability that a sub-group overlaps two blocks. */
8604
8603
  double quick_prefix_selectivity;
8639
8638
    {
8640
8639
      double blocks_per_group= (double) num_blocks / (double) num_groups;
8641
8640
      p_overlap= (blocks_per_group * (keys_per_subgroup - 1)) / keys_per_group;
8642
 
      p_overlap= cmin(p_overlap, 1.0);
 
8641
      p_overlap= min(p_overlap, 1.0);
8643
8642
    }
8644
 
    io_cost= (double) cmin(num_groups * (1 + p_overlap), (double)num_blocks);
 
8643
    io_cost= (double) min(num_groups * (1 + p_overlap), num_blocks);
8645
8644
  }
8646
8645
  else
8647
8646
    io_cost= (keys_per_group > keys_per_block) ?
8783
8782
*/
8784
8783
 
8785
8784
QUICK_GROUP_MIN_MAX_SELECT::
8786
 
QUICK_GROUP_MIN_MAX_SELECT(Table *table, JOIN *join_arg, bool have_min_arg,
 
8785
QUICK_GROUP_MIN_MAX_SELECT(TABLE *table, JOIN *join_arg, bool have_min_arg,
8787
8786
                           bool have_max_arg,
8788
8787
                           KEY_PART_INFO *min_max_arg_part_arg,
8789
 
                           uint32_t group_prefix_len_arg, uint32_t group_key_parts_arg,
8790
 
                           uint32_t used_key_parts_arg, KEY *index_info_arg,
8791
 
                           uint32_t use_index, double read_cost_arg,
8792
 
                           ha_rows records_arg, uint32_t key_infix_len_arg,
8793
 
                           unsigned char *key_infix_arg, MEM_ROOT *parent_alloc)
 
8788
                           uint group_prefix_len_arg, uint group_key_parts_arg,
 
8789
                           uint used_key_parts_arg, KEY *index_info_arg,
 
8790
                           uint use_index, double read_cost_arg,
 
8791
                           ha_rows records_arg, uint key_infix_len_arg,
 
8792
                           uchar *key_infix_arg, MEM_ROOT *parent_alloc)
8794
8793
  :join(join_arg), index_info(index_info_arg),
8795
8794
   group_prefix_len(group_prefix_len_arg),
8796
8795
   group_key_parts(group_key_parts_arg), have_min(have_min_arg),
8849
8848
  if (group_prefix) /* Already initialized. */
8850
8849
    return 0;
8851
8850
 
8852
 
  if (!(last_prefix= (unsigned char*) alloc_root(&alloc, group_prefix_len)))
 
8851
  if (!(last_prefix= (uchar*) alloc_root(&alloc, group_prefix_len)))
8853
8852
      return 1;
8854
8853
  /*
8855
8854
    We may use group_prefix to store keys with all select fields, so allocate
8856
8855
    enough space for it.
8857
8856
  */
8858
 
  if (!(group_prefix= (unsigned char*) alloc_root(&alloc,
 
8857
  if (!(group_prefix= (uchar*) alloc_root(&alloc,
8859
8858
                                         real_prefix_len + min_max_arg_len)))
8860
8859
    return 1;
8861
8860
 
8865
8864
      The memory location pointed to by key_infix will be deleted soon, so
8866
8865
      allocate a new buffer and copy the key_infix into it.
8867
8866
    */
8868
 
    unsigned char *tmp_key_infix= (unsigned char*) alloc_root(&alloc, key_infix_len);
 
8867
    uchar *tmp_key_infix= (uchar*) alloc_root(&alloc, key_infix_len);
8869
8868
    if (!tmp_key_infix)
8870
8869
      return 1;
8871
8870
    memcpy(tmp_key_infix, this->key_infix, key_infix_len);
8956
8955
bool QUICK_GROUP_MIN_MAX_SELECT::add_range(SEL_ARG *sel_range)
8957
8956
{
8958
8957
  QUICK_RANGE *range;
8959
 
  uint32_t range_flag= sel_range->min_flag | sel_range->max_flag;
 
8958
  uint range_flag= sel_range->min_flag | sel_range->max_flag;
8960
8959
 
8961
8960
  /* Skip (-inf,+inf) ranges, e.g. (x < 5 or x > 4). */
8962
8961
  if ((range_flag & NO_MIN_RANGE) && (range_flag & NO_MAX_RANGE))
8979
8978
                         range_flag);
8980
8979
  if (!range)
8981
8980
    return true;
8982
 
  if (insert_dynamic(&min_max_ranges, (unsigned char*)&range))
 
8981
  if (insert_dynamic(&min_max_ranges, (uchar*)&range))
8983
8982
    return true;
8984
8983
  return false;
8985
8984
}
9008
9007
      group_prefix_len < quick_prefix_select->max_used_key_length)
9009
9008
  {
9010
9009
    DYNAMIC_ARRAY *arr;
9011
 
    uint32_t inx;
 
9010
    uint inx;
9012
9011
 
9013
9012
    for (inx= 0, arr= &quick_prefix_select->ranges; inx < arr->elements; inx++)
9014
9013
    {
9015
9014
      QUICK_RANGE *range;
9016
9015
 
9017
 
      get_dynamic(arr, (unsigned char*)&range, inx);
 
9016
      get_dynamic(arr, (uchar*)&range, inx);
9018
9017
      range->flag &= ~(NEAR_MIN | NEAR_MAX);
9019
9018
    }
9020
9019
  }
9050
9049
    QUICK_RANGE *cur_range;
9051
9050
    if (have_min)
9052
9051
    { /* Check if the right-most range has a lower boundary. */
9053
 
      get_dynamic(&min_max_ranges, (unsigned char*)&cur_range,
 
9052
      get_dynamic(&min_max_ranges, (uchar*)&cur_range,
9054
9053
                  min_max_ranges.elements - 1);
9055
9054
      if (!(cur_range->flag & NO_MIN_RANGE))
9056
9055
      {
9061
9060
    }
9062
9061
    if (have_max)
9063
9062
    { /* Check if the left-most range has an upper boundary. */
9064
 
      get_dynamic(&min_max_ranges, (unsigned char*)&cur_range, 0);
 
9063
      get_dynamic(&min_max_ranges, (uchar*)&cur_range, 0);
9065
9064
      if (!(cur_range->flag & NO_MAX_RANGE))
9066
9065
      {
9067
9066
        max_used_key_length+= min_max_arg_len;
9372
9371
 
9373
9372
  if (quick_prefix_select)
9374
9373
  {
9375
 
    unsigned char *cur_prefix= seen_first_key ? group_prefix : NULL;
 
9374
    uchar *cur_prefix= seen_first_key ? group_prefix : NULL;
9376
9375
    if ((result= quick_prefix_select->get_next_prefix(group_prefix_len,
9377
9376
                         make_prev_keypart_map(group_key_parts), cur_prefix)))
9378
9377
      return(result);
9440
9439
 
9441
9440
  assert(min_max_ranges.elements > 0);
9442
9441
 
9443
 
  for (uint32_t range_idx= 0; range_idx < min_max_ranges.elements; range_idx++)
 
9442
  for (uint range_idx= 0; range_idx < min_max_ranges.elements; range_idx++)
9444
9443
  { /* Search from the left-most range to the right. */
9445
 
    get_dynamic(&min_max_ranges, (unsigned char*)&cur_range, range_idx);
 
9444
    get_dynamic(&min_max_ranges, (uchar*)&cur_range, range_idx);
9446
9445
 
9447
9446
    /*
9448
9447
      If the current value for the min/max argument is bigger than the right
9449
9448
      boundary of cur_range, there is no need to check this range.
9450
9449
    */
9451
9450
    if (range_idx != 0 && !(cur_range->flag & NO_MAX_RANGE) &&
9452
 
        (key_cmp(min_max_arg_part, (const unsigned char*) cur_range->max_key,
 
9451
        (key_cmp(min_max_arg_part, (const uchar*) cur_range->max_key,
9453
9452
                 min_max_arg_len) == 1))
9454
9453
      continue;
9455
9454
 
9510
9509
    if ( !(cur_range->flag & NO_MAX_RANGE) )
9511
9510
    {
9512
9511
      /* Compose the MAX key for the range. */
9513
 
      unsigned char *max_key= (unsigned char*) my_alloca(real_prefix_len + min_max_arg_len);
 
9512
      uchar *max_key= (uchar*) my_alloca(real_prefix_len + min_max_arg_len);
9514
9513
      memcpy(max_key, group_prefix, real_prefix_len);
9515
9514
      memcpy(max_key + real_prefix_len, cur_range->max_key,
9516
9515
             cur_range->max_length);
9571
9570
 
9572
9571
  assert(min_max_ranges.elements > 0);
9573
9572
 
9574
 
  for (uint32_t range_idx= min_max_ranges.elements; range_idx > 0; range_idx--)
 
9573
  for (uint range_idx= min_max_ranges.elements; range_idx > 0; range_idx--)
9575
9574
  { /* Search from the right-most range to the left. */
9576
 
    get_dynamic(&min_max_ranges, (unsigned char*)&cur_range, range_idx - 1);
 
9575
    get_dynamic(&min_max_ranges, (uchar*)&cur_range, range_idx - 1);
9577
9576
 
9578
9577
    /*
9579
9578
      If the current value for the min/max argument is smaller than the left
9581
9580
    */
9582
9581
    if (range_idx != min_max_ranges.elements &&
9583
9582
        !(cur_range->flag & NO_MIN_RANGE) &&
9584
 
        (key_cmp(min_max_arg_part, (const unsigned char*) cur_range->min_key,
 
9583
        (key_cmp(min_max_arg_part, (const uchar*) cur_range->min_key,
9585
9584
                 min_max_arg_len) == -1))
9586
9585
      continue;
9587
9586
 
9627
9626
    if ( !(cur_range->flag & NO_MIN_RANGE) )
9628
9627
    {
9629
9628
      /* Compose the MIN key for the range. */
9630
 
      unsigned char *min_key= (unsigned char*) my_alloca(real_prefix_len + min_max_arg_len);
 
9629
      uchar *min_key= (uchar*) my_alloca(real_prefix_len + min_max_arg_len);
9631
9630
      memcpy(min_key, group_prefix, real_prefix_len);
9632
9631
      memcpy(min_key + real_prefix_len, cur_range->min_key,
9633
9632
             cur_range->min_length);
9729
9728
                                                      String *used_lengths)
9730
9729
{
9731
9730
  char buf[64];
9732
 
  uint32_t length;
 
9731
  uint length;
9733
9732
  key_names->append(index_info->name);
9734
9733
  length= int64_t2str(max_used_key_length, buf, 10) - buf;
9735
9734
  used_lengths->append(buf, length);
9750
9749
  {
9751
9750
    if (tree_map->is_set(idx))
9752
9751
    {
9753
 
      uint32_t keynr= param->real_keynr[idx];
 
9752
      uint keynr= param->real_keynr[idx];
9754
9753
      if (tmp.length())
9755
9754
        tmp.append(',');
9756
9755
      tmp.append(param->table->key_info[keynr].name);
9763
9762
}
9764
9763
 
9765
9764
 
9766
 
static void print_ror_scans_arr(Table *table,
 
9765
static void print_ror_scans_arr(TABLE *table,
9767
9766
                                const char *msg __attribute__((unused)),
9768
9767
                                struct st_ror_scan_info **start,
9769
9768
                                struct st_ror_scan_info **end)