~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to sql/opt_range.cc

Removed DBUG symbols and fixed TRUE/FALSE

Show diffs side-by-side

added added

removed removed

Lines of Context:
103
103
           subject and may omit some details.
104
104
*/
105
105
 
106
 
#include <drizzled/server_includes.h>
107
 
#include <drizzled/sql_select.h>
 
106
#ifdef USE_PRAGMA_IMPLEMENTATION
 
107
#pragma implementation                          // gcc: Class implementation
 
108
#endif
 
109
 
 
110
#include "mysql_priv.h"
 
111
#include <m_ctype.h>
 
112
#include "sql_select.h"
108
113
 
109
114
#ifndef EXTRA_DEBUG
110
115
#define test_rb_tree(A,B) {}
117
122
*/
118
123
#define double2rows(x) ((ha_rows)(x))
119
124
 
120
 
static int sel_cmp(Field *f,unsigned char *a,unsigned char *b,uint8_t a_flag,uint8_t b_flag);
 
125
static int sel_cmp(Field *f,uchar *a,uchar *b,uint8 a_flag,uint8 b_flag);
121
126
 
122
 
static unsigned char is_null_string[2]= {1,0};
 
127
static uchar is_null_string[2]= {1,0};
123
128
 
124
129
class RANGE_OPT_PARAM;
125
130
/*
295
300
class SEL_ARG :public Sql_alloc
296
301
{
297
302
public:
298
 
  uint8_t min_flag,max_flag,maybe_flag;
299
 
  uint8_t part;                                 // Which key part
300
 
  uint8_t maybe_null;
 
303
  uint8 min_flag,max_flag,maybe_flag;
 
304
  uint8 part;                                   // Which key part
 
305
  uint8 maybe_null;
301
306
  /* 
302
307
    Number of children of this element in the RB-tree, plus 1 for this
303
308
    element itself.
304
309
  */
305
 
  uint16_t elements;
 
310
  uint16 elements;
306
311
  /*
307
312
    Valid only for elements which are RB-tree roots: Number of times this
308
313
    RB-tree is referred to (it is referred by SEL_ARG::next_key_part or by
311
316
  ulong use_count;
312
317
 
313
318
  Field *field;
314
 
  unsigned char *min_value,*max_value;                  // Pointer to range
 
319
  uchar *min_value,*max_value;                  // Pointer to range
315
320
 
316
321
  /*
317
322
    eq_tree() requires that left == right == 0 if the type is MAYBE_KEY.
327
332
 
328
333
  SEL_ARG() {}
329
334
  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,
332
 
          uint8_t min_flag, uint8_t max_flag, uint8_t maybe_flag);
 
335
  SEL_ARG(Field *,const uchar *, const uchar *);
 
336
  SEL_ARG(Field *field, uint8 part, uchar *min_value, uchar *max_value,
 
337
          uint8 min_flag, uint8 max_flag, uint8 maybe_flag);
333
338
  SEL_ARG(enum Type type_arg)
334
339
    :min_flag(0),elements(1),use_count(1),left(0),right(0),next_key_part(0),
335
340
    color(BLACK), type(type_arg)
364
369
  }
365
370
  SEL_ARG *clone_and(SEL_ARG* arg)
366
371
  {                                             // Get overlapping range
367
 
    unsigned char *new_min,*new_max;
368
 
    uint8_t flag_min,flag_max;
 
372
    uchar *new_min,*new_max;
 
373
    uint8 flag_min,flag_max;
369
374
    if (cmp_min_to_min(arg) >= 0)
370
375
    {
371
376
      new_min=min_value; flag_min=min_flag;
438
443
    min_flag=arg->max_flag & NEAR_MAX ? 0 : NEAR_MIN;
439
444
  }
440
445
  /* 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)
 
446
  int store_min(uint length, uchar **min_key,uint min_key_flag)
442
447
  {
443
448
    /* "(kp1 > c1) AND (kp2 OP c2) AND ..." -> (kp1 > c1) */
444
449
    if ((!(min_flag & NO_MIN_RANGE) &&
447
452
      if (maybe_null && *min_value)
448
453
      {
449
454
        **min_key=1;
450
 
        memset(*min_key+1, 0, length-1);
 
455
        bzero(*min_key+1,length-1);
451
456
      }
452
457
      else
453
458
        memcpy(*min_key,min_value,length);
457
462
    return 0;
458
463
  }
459
464
  /* 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)
 
465
  int store_max(uint length, uchar **max_key, uint max_key_flag)
461
466
  {
462
467
    if (!(max_flag & NO_MAX_RANGE) &&
463
468
        !(max_key_flag & (NO_MAX_RANGE | NEAR_MAX)))
465
470
      if (maybe_null && *max_value)
466
471
      {
467
472
        **max_key=1;
468
 
        memset(*max_key+1, 0, length-1);
 
473
        bzero(*max_key+1,length-1);
469
474
      }
470
475
      else
471
476
        memcpy(*max_key,max_value,length);
476
481
  }
477
482
 
478
483
  /* 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)
 
484
  int store_min_key(KEY_PART *key, uchar **range_key, uint *range_key_flag)
480
485
  {
481
486
    SEL_ARG *key_tree= first();
482
 
    uint32_t res= key_tree->store_min(key[key_tree->part].store_length,
 
487
    uint res= key_tree->store_min(key[key_tree->part].store_length,
483
488
                                  range_key, *range_key_flag);
484
489
    *range_key_flag|= key_tree->min_flag;
485
490
    
493
498
  }
494
499
 
495
500
  /* 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)
 
501
  int store_max_key(KEY_PART *key, uchar **range_key, uint *range_key_flag)
497
502
  {
498
503
    SEL_ARG *key_tree= last();
499
 
    uint32_t res=key_tree->store_max(key[key_tree->part].store_length,
 
504
    uint res=key_tree->store_max(key[key_tree->part].store_length,
500
505
                                 range_key, *range_key_flag);
501
506
    (*range_key_flag)|= key_tree->max_flag;
502
507
    if (key_tree->next_key_part &&
575
580
    */
576
581
    if (min_flag || max_flag)
577
582
      return false;
578
 
    unsigned char *min_val= min_value;
579
 
    unsigned char *max_val= max_value;
 
583
    uchar *min_val= min_value;
 
584
    uchar *max_val= max_value;
580
585
 
581
586
    if (maybe_null)
582
587
    {
610
615
  SEL_TREE() :type(KEY)
611
616
  {
612
617
    keys_map.clear_all();
613
 
    memset(keys, 0, sizeof(keys));
 
618
    bzero((char*) keys,sizeof(keys));
614
619
  }
615
620
  /*
616
621
    Note: there may exist SEL_TREE objects with sel_tree->type=KEY and
629
634
 
630
635
  /* The members below are filled/used only after get_mm_tree is done */
631
636
  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 */
 
637
  uint    n_ror_scans;     /* number of set bits in ror_scans_map */
633
638
 
634
639
  struct st_ror_scan_info **ror_scans;     /* list of ROR key scans */
635
640
  struct st_ror_scan_info **ror_scans_end; /* last ROR scan */
640
645
{
641
646
public:
642
647
  THD   *thd;   /* Current thread handle */
643
 
  Table *table; /* Table being analyzed */
 
648
  TABLE *table; /* Table being analyzed */
644
649
  COND *cond;   /* Used inside get_mm_tree(). */
645
650
  table_map prev_tables;
646
651
  table_map read_tables;
655
660
    Number of indexes used in range analysis (In SEL_TREE::keys only first
656
661
    #keys elements are not empty)
657
662
  */
658
 
  uint32_t keys;
 
663
  uint keys;
659
664
  
660
665
  /* 
661
666
    If true, the index descriptions describe real indexes (and it is ok to
670
675
    used_key_no -> table_key_no translation table. Only makes sense if
671
676
    using_real_indexes==true
672
677
  */
673
 
  uint32_t real_keynr[MAX_KEY];
 
678
  uint real_keynr[MAX_KEY];
674
679
  /* Number of SEL_ARG objects allocated by SEL_ARG::clone_tree operations */
675
 
  uint32_t alloced_sel_args; 
 
680
  uint alloced_sel_args; 
676
681
  bool force_default_mrr;
677
682
};
678
683
 
680
685
{
681
686
public:
682
687
  KEY_PART *key[MAX_KEY]; /* First key parts of keys used in the query */
683
 
  int64_t baseflag;
684
 
  uint32_t max_key_part;
 
688
  longlong baseflag;
 
689
  uint max_key_part;
685
690
  /* 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],
 
691
  uint range_count;
 
692
  uchar min_key[MAX_KEY_LENGTH+MAX_FIELD_WIDTH],
688
693
    max_key[MAX_KEY_LENGTH+MAX_FIELD_WIDTH];
689
694
  bool quick;                           // Don't calulate possible keys
690
695
 
691
 
  uint32_t fields_bitmap_size;
 
696
  uint fields_bitmap_size;
692
697
  MY_BITMAP needed_fields;    /* bitmask of fields needed by the query */
693
698
  MY_BITMAP tmp_covered_fields;
694
699
 
695
700
  key_map *needed_reg;        /* ptr to SQL_SELECT::needed_reg */
696
701
 
697
 
  uint32_t *imerge_cost_buff;     /* buffer for index_merge cost estimates */
698
 
  uint32_t imerge_cost_buff_size; /* size of the buffer */
 
702
  uint *imerge_cost_buff;     /* buffer for index_merge cost estimates */
 
703
  uint imerge_cost_buff_size; /* size of the buffer */
699
704
 
700
705
  /* true if last checked tree->key can be used for ROR-scan */
701
706
  bool is_ror_scan;
702
707
  /* Number of ranges in the last checked tree->key */
703
 
  uint32_t n_ranges;
 
708
  uint n_ranges;
704
709
};
705
710
 
706
711
class TABLE_READ_PLAN;
720
725
                            Item_func::Functype type,Item *value);
721
726
static SEL_TREE *get_mm_tree(RANGE_OPT_PARAM *param,COND *cond);
722
727
 
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,
 
728
static bool is_key_scan_ror(PARAM *param, uint keynr, uint8 nparts);
 
729
static ha_rows check_quick_select(PARAM *param, uint idx, bool index_only,
725
730
                                  SEL_ARG *tree, bool update_tbl_stats, 
726
 
                                  uint32_t *mrr_flags, uint32_t *bufsize,
 
731
                                  uint *mrr_flags, uint *bufsize,
727
732
                                  COST_VECT *cost);
728
733
                                  //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);
 
734
/*static ha_rows check_quick_keys(PARAM *param,uint index,SEL_ARG *key_tree,
 
735
                                uchar *min_key, uint min_key_flag, int,
 
736
                                uchar *max_key, uint max_key_flag, int);
732
737
*/
733
738
 
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);
 
739
QUICK_RANGE_SELECT *get_quick_select(PARAM *param,uint index,
 
740
                                     SEL_ARG *key_tree, uint mrr_flags, 
 
741
                                     uint mrr_buf_size, MEM_ROOT *alloc);
737
742
static TRP_RANGE *get_key_scans_params(PARAM *param, SEL_TREE *tree,
738
743
                                       bool index_read_must_be_used,
739
744
                                       bool update_tbl_stats,
754
759
 
755
760
static void print_sel_tree(PARAM *param, SEL_TREE *tree, key_map *tree_map,
756
761
                           const char *msg);
757
 
static void print_ror_scans_arr(Table *table, const char *msg,
 
762
static void print_ror_scans_arr(TABLE *table, const char *msg,
758
763
                                struct st_ror_scan_info **start,
759
764
                                struct st_ror_scan_info **end);
 
765
static void print_quick(QUICK_SELECT_I *quick, const key_map *needed_reg);
760
766
 
761
767
static SEL_TREE *tree_and(RANGE_OPT_PARAM *param,SEL_TREE *tree1,SEL_TREE *tree2);
762
768
static SEL_TREE *tree_or(RANGE_OPT_PARAM *param,SEL_TREE *tree1,SEL_TREE *tree2);
763
769
static SEL_ARG *sel_add(SEL_ARG *key1,SEL_ARG *key2);
764
770
static SEL_ARG *key_or(RANGE_OPT_PARAM *param, SEL_ARG *key1, SEL_ARG *key2);
765
771
static SEL_ARG *key_and(RANGE_OPT_PARAM *param, SEL_ARG *key1, SEL_ARG *key2,
766
 
                        uint32_t clone_flag);
 
772
                        uint clone_flag);
767
773
static bool get_range(SEL_ARG **e1,SEL_ARG **e2,SEL_ARG *root1);
768
774
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);
 
775
                    SEL_ARG *key_tree, uchar *min_key,uint min_key_flag,
 
776
                    uchar *max_key,uint max_key_flag);
771
777
static bool eq_tree(SEL_ARG* a,SEL_ARG *b);
772
778
 
773
779
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);
 
780
static bool null_part_in_key(KEY_PART *key_part, const uchar *key,
 
781
                             uint length);
776
782
bool sel_trees_can_be_ored(SEL_TREE *tree1, SEL_TREE *tree2, RANGE_OPT_PARAM* param);
777
783
 
778
784
 
828
834
  if (trees_next == trees_end)
829
835
  {
830
836
    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;
 
837
    uint old_elements= (trees_end - trees);
 
838
    uint old_size= sizeof(SEL_TREE**) * old_elements;
 
839
    uint new_size= old_size * realloc_ratio;
834
840
    SEL_TREE **new_trees;
835
841
    if (!(new_trees= (SEL_TREE**)alloc_root(param->mem_root, new_size)))
836
842
      return -1;
999
1005
           1 = Got some error (out of memory?)
1000
1006
           */
1001
1007
 
1002
 
SQL_SELECT *make_select(Table *head, table_map const_tables,
 
1008
SQL_SELECT *make_select(TABLE *head, table_map const_tables,
1003
1009
                        table_map read_tables, COND *conds,
1004
1010
                        bool allow_null_cond,
1005
1011
                        int *error)
1025
1031
    select->file= *head->sort.io_cache;
1026
1032
    select->records=(ha_rows) (select->file.end_of_file/
1027
1033
                               head->file->ref_length);
1028
 
    free(head->sort.io_cache);
 
1034
    my_free(head->sort.io_cache, MYF(0));
1029
1035
    head->sort.io_cache=0;
1030
1036
  }
1031
1037
  return(select);
1063
1069
   used_key_parts(0)
1064
1070
{}
1065
1071
 
1066
 
QUICK_RANGE_SELECT::QUICK_RANGE_SELECT(THD *thd, Table *table, uint32_t key_nr,
 
1072
QUICK_RANGE_SELECT::QUICK_RANGE_SELECT(THD *thd, TABLE *table, uint key_nr,
1067
1073
                                       bool no_alloc, MEM_ROOT *parent_alloc,
1068
1074
                                       bool *create_error)
1069
1075
  :free_file(0),cur_range(NULL),last_range(0),dont_free(0)
1088
1094
    thd->mem_root= &alloc;
1089
1095
  }
1090
1096
  else
1091
 
    memset(&alloc, 0, sizeof(alloc));
 
1097
    bzero((char*) &alloc,sizeof(alloc));
1092
1098
  file= head->file;
1093
1099
  record= head->record[0];
1094
1100
  save_read_set= head->read_set;
1144
1150
    }
1145
1151
    delete_dynamic(&ranges); /* ranges are allocated in alloc */
1146
1152
    free_root(&alloc,MYF(0));
1147
 
    free((char*) column_bitmap.bitmap);
 
1153
    my_free((char*) column_bitmap.bitmap, MYF(MY_ALLOW_ZERO_PTR));
1148
1154
  }
1149
1155
  head->column_bitmaps_set(save_read_set, save_write_set);
1150
 
  if (mrr_buf_desc)
1151
 
    free(mrr_buf_desc);
 
1156
  x_free(mrr_buf_desc);
1152
1157
  return;
1153
1158
}
1154
1159
 
1155
1160
 
1156
1161
QUICK_INDEX_MERGE_SELECT::QUICK_INDEX_MERGE_SELECT(THD *thd_param,
1157
 
                                                   Table *table)
 
1162
                                                   TABLE *table)
1158
1163
  :pk_quick_select(NULL), thd(thd_param)
1159
1164
{
1160
1165
  index= MAX_KEY;
1161
1166
  head= table;
1162
 
  memset(&read_record, 0, sizeof(read_record));
 
1167
  bzero(&read_record, sizeof(read_record));
1163
1168
  init_sql_alloc(&alloc, thd->variables.range_alloc_block_size, 0);
1164
1169
  return;
1165
1170
}
1204
1209
 
1205
1210
 
1206
1211
QUICK_ROR_INTERSECT_SELECT::QUICK_ROR_INTERSECT_SELECT(THD *thd_param,
1207
 
                                                       Table *table,
 
1212
                                                       TABLE *table,
1208
1213
                                                       bool retrieve_full_rows,
1209
1214
                                                       MEM_ROOT *parent_alloc)
1210
1215
  : cpk_quick(NULL), thd(thd_param), need_to_fetch_row(retrieve_full_rows),
1216
1221
  if (!parent_alloc)
1217
1222
    init_sql_alloc(&alloc, thd->variables.range_alloc_block_size, 0);
1218
1223
  else
1219
 
    memset(&alloc, 0, sizeof(MEM_ROOT));
1220
 
  last_rowid= (unsigned char*) alloc_root(parent_alloc? parent_alloc : &alloc,
 
1224
    bzero(&alloc, sizeof(MEM_ROOT));
 
1225
  last_rowid= (uchar*) alloc_root(parent_alloc? parent_alloc : &alloc,
1221
1226
                                  head->file->ref_length);
1222
1227
}
1223
1228
 
1443
1448
 
1444
1449
 
1445
1450
QUICK_ROR_UNION_SELECT::QUICK_ROR_UNION_SELECT(THD *thd_param,
1446
 
                                               Table *table)
 
1451
                                               TABLE *table)
1447
1452
  : thd(thd_param), scans_inited(false)
1448
1453
{
1449
1454
  index= MAX_KEY;
1471
1476
                 false , QUICK_ROR_UNION_SELECT::queue_cmp,
1472
1477
                 (void*) this))
1473
1478
  {
1474
 
    memset(&queue, 0, sizeof(QUEUE));
 
1479
    bzero(&queue, sizeof(QUEUE));
1475
1480
    return(1);
1476
1481
  }
1477
1482
 
1478
 
  if (!(cur_rowid= (unsigned char*) alloc_root(&alloc, 2*head->file->ref_length)))
 
1483
  if (!(cur_rowid= (uchar*) alloc_root(&alloc, 2*head->file->ref_length)))
1479
1484
    return(1);
1480
1485
  prev_rowid= cur_rowid + head->file->ref_length;
1481
1486
  return(0);
1493
1498
      val2  Second merged select
1494
1499
*/
1495
1500
 
1496
 
int QUICK_ROR_UNION_SELECT::queue_cmp(void *arg, unsigned char *val1, unsigned char *val2)
 
1501
int QUICK_ROR_UNION_SELECT::queue_cmp(void *arg, uchar *val1, uchar *val2)
1497
1502
{
1498
1503
  QUICK_ROR_UNION_SELECT *self= (QUICK_ROR_UNION_SELECT*)arg;
1499
1504
  return self->head->file->cmp_ref(((QUICK_SELECT_I*)val1)->last_rowid,
1543
1548
      return(error);
1544
1549
    }
1545
1550
    quick->save_last_pos();
1546
 
    queue_insert(&queue, (unsigned char*)quick);
 
1551
    queue_insert(&queue, (uchar*)quick);
1547
1552
  }
1548
1553
 
1549
1554
  if (head->file->ha_rnd_init(1))
1602
1607
  use_count=0; elements=1;
1603
1608
}
1604
1609
 
1605
 
SEL_ARG::SEL_ARG(Field *f,const unsigned char *min_value_arg,
1606
 
                 const unsigned char *max_value_arg)
 
1610
SEL_ARG::SEL_ARG(Field *f,const uchar *min_value_arg,
 
1611
                 const uchar *max_value_arg)
1607
1612
  :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),
 
1613
   elements(1), use_count(1), field(f), min_value((uchar*) min_value_arg),
 
1614
   max_value((uchar*) max_value_arg), next(0),prev(0),
1610
1615
   next_key_part(0),color(BLACK),type(KEY_RANGE)
1611
1616
{
1612
1617
  left=right= &null_element;
1613
1618
}
1614
1619
 
1615
 
SEL_ARG::SEL_ARG(Field *field_,uint8_t part_,
1616
 
                 unsigned char *min_value_, unsigned char *max_value_,
1617
 
                 uint8_t min_flag_,uint8_t max_flag_,uint8_t maybe_flag_)
 
1620
SEL_ARG::SEL_ARG(Field *field_,uint8 part_,
 
1621
                 uchar *min_value_, uchar *max_value_,
 
1622
                 uint8 min_flag_,uint8 max_flag_,uint8 maybe_flag_)
1618
1623
  :min_flag(min_flag_),max_flag(max_flag_),maybe_flag(maybe_flag_),
1619
1624
   part(part_),maybe_null(field_->real_maybe_null()), elements(1),use_count(1),
1620
1625
   field(field_), min_value(min_value_), max_value(max_value_),
1691
1696
  Returns -2 or 2 if the ranges where 'joined' like  < 2 and >= 2
1692
1697
*/
1693
1698
 
1694
 
static int sel_cmp(Field *field, unsigned char *a, unsigned char *b, uint8_t a_flag,
1695
 
                   uint8_t b_flag)
 
1699
static int sel_cmp(Field *field, uchar *a, uchar *b, uint8 a_flag,
 
1700
                   uint8 b_flag)
1696
1701
{
1697
1702
  int cmp;
1698
1703
  /* First check if there was a compare to a min or max element */
1778
1783
    MAX_KEY if no such index was found.
1779
1784
*/
1780
1785
 
1781
 
uint32_t get_index_for_order(Table *table, order_st *order, ha_rows limit)
 
1786
uint get_index_for_order(TABLE *table, ORDER *order, ha_rows limit)
1782
1787
{
1783
 
  uint32_t idx;
1784
 
  uint32_t match_key= MAX_KEY, match_key_len= MAX_KEY_LENGTH + 1;
1785
 
  order_st *ord;
 
1788
  uint idx;
 
1789
  uint match_key= MAX_KEY, match_key_len= MAX_KEY_LENGTH + 1;
 
1790
  ORDER *ord;
1786
1791
  
1787
1792
  for (ord= order; ord; ord= ord->next)
1788
1793
    if (!ord->asc)
1793
1798
    if (!(table->keys_in_use_for_query.is_set(idx)))
1794
1799
      continue;
1795
1800
    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;
 
1801
    uint n_parts=  table->key_info[idx].key_parts;
 
1802
    uint partno= 0;
1798
1803
    
1799
1804
    /* 
1800
1805
      The below check is sufficient considering we now have either BTREE 
1882
1887
  /* Table read plans are allocated on MEM_ROOT and are never deleted */
1883
1888
  static void *operator new(size_t size, MEM_ROOT *mem_root)
1884
1889
  { return (void*) alloc_root(mem_root, (uint) size); }
1885
 
  static void operator delete(void *ptr __attribute__((unused)),
1886
 
                              size_t size __attribute__((unused)))
1887
 
    { TRASH(ptr, size); }
1888
 
  static void operator delete(void *ptr __attribute__((unused)),
1889
 
                              MEM_ROOT *mem_root __attribute__((unused)))
1890
 
    { /* Never called */ }
 
1890
  static void operator delete(void *ptr,size_t size) { TRASH(ptr, size); }
 
1891
  static void operator delete(void *ptr, MEM_ROOT *mem_root) { /* Never called */ }
1891
1892
  virtual ~TABLE_READ_PLAN() {}               /* Remove gcc warning */
1892
1893
 
1893
1894
};
1908
1909
{
1909
1910
public:
1910
1911
  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;
 
1912
  uint     key_idx; /* key number in PARAM::key */
 
1913
  uint     mrr_flags; 
 
1914
  uint     mrr_buf_size;
1914
1915
 
1915
 
  TRP_RANGE(SEL_ARG *key_arg, uint32_t idx_arg, uint32_t mrr_flags_arg)
 
1916
  TRP_RANGE(SEL_ARG *key_arg, uint idx_arg, uint mrr_flags_arg)
1916
1917
   : key(key_arg), key_idx(idx_arg), mrr_flags(mrr_flags_arg)
1917
1918
  {}
1918
1919
  virtual ~TRP_RANGE() {}                     /* Remove gcc warning */
1919
1920
 
1920
 
  QUICK_SELECT_I *make_quick(PARAM *param,
1921
 
                             bool retrieve_full_rows __attribute__((unused)),
 
1921
  QUICK_SELECT_I *make_quick(PARAM *param, bool retrieve_full_rows,
1922
1922
                             MEM_ROOT *parent_alloc)
1923
1923
  {
1924
1924
    QUICK_RANGE_SELECT *quick;
1997
1997
private:
1998
1998
  bool have_min, have_max;
1999
1999
  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;
 
2000
  uint group_prefix_len;
 
2001
  uint used_key_parts;
 
2002
  uint group_key_parts;
2003
2003
  KEY *index_info;
2004
 
  uint32_t index;
2005
 
  uint32_t key_infix_len;
2006
 
  unsigned char key_infix[MAX_KEY_LENGTH];
 
2004
  uint index;
 
2005
  uint key_infix_len;
 
2006
  uchar key_infix[MAX_KEY_LENGTH];
2007
2007
  SEL_TREE *range_tree; /* Represents all range predicates in the query. */
2008
2008
  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. */
 
2009
  uint param_idx; /* Index of used key in param->key. */
2010
2010
  /* Number of records selected by the ranges in index_tree. */
2011
2011
public:
2012
2012
  ha_rows quick_prefix_records;
2013
2013
public:
2014
2014
  TRP_GROUP_MIN_MAX(bool have_min_arg, bool have_max_arg,
2015
2015
                    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,
 
2016
                    uint group_prefix_len_arg, uint used_key_parts_arg,
 
2017
                    uint group_key_parts_arg, KEY *index_info_arg,
 
2018
                    uint index_arg, uint key_infix_len_arg,
 
2019
                    uchar *key_infix_arg,
2020
2020
                    SEL_TREE *tree_arg, SEL_ARG *index_tree_arg,
2021
 
                    uint32_t param_idx_arg, ha_rows quick_prefix_records_arg)
 
2021
                    uint param_idx_arg, ha_rows quick_prefix_records_arg)
2022
2022
  : have_min(have_min_arg), have_max(have_max_arg),
2023
2023
    min_max_arg_part(min_max_arg_part_arg),
2024
2024
    group_prefix_len(group_prefix_len_arg), used_key_parts(used_key_parts_arg),
2053
2053
 
2054
2054
static int fill_used_fields_bitmap(PARAM *param)
2055
2055
{
2056
 
  Table *table= param->table;
 
2056
  TABLE *table= param->table;
2057
2057
  my_bitmap_map *tmp;
2058
 
  uint32_t pk;
 
2058
  uint pk;
2059
2059
  param->tmp_covered_fields.bitmap= 0;
2060
2060
  param->fields_bitmap_size= table->s->column_bitmap_size;
2061
2061
  if (!(tmp= (my_bitmap_map*) alloc_root(param->mem_root,
2151
2151
                                  ha_rows limit, bool force_quick_range, 
2152
2152
                                  bool ordered_output)
2153
2153
{
2154
 
  uint32_t idx;
 
2154
  uint idx;
2155
2155
  double scan_time;
2156
2156
  delete quick;
2157
2157
  quick=0;
2226
2226
 
2227
2227
      param.key[param.keys]=key_parts;
2228
2228
      key_part_info= key_info->key_part;
2229
 
      for (uint32_t part=0 ; part < key_info->key_parts ;
 
2229
      for (uint part=0 ; part < key_info->key_parts ;
2230
2230
           part++, key_parts++, key_part_info++)
2231
2231
      {
2232
2232
        key_parts->key=          param.keys;
2237
2237
        key_parts->null_bit=     key_part_info->null_bit;
2238
2238
        key_parts->image_type =  Field::itRAW;
2239
2239
        /* Only HA_PART_KEY_SEG is used */
2240
 
        key_parts->flag=         (uint8_t) key_part_info->key_part_flag;
 
2240
        key_parts->flag=         (uint8) key_part_info->key_part_flag;
2241
2241
      }
2242
2242
      param.real_keynr[param.keys++]=idx;
2243
2243
    }
2247
2247
    /* Calculate cost of full index read for the shortest covering index */
2248
2248
    if (!head->covering_keys.is_clear_all())
2249
2249
    {
2250
 
      int key_for_use= head->find_shortest_key(&head->covering_keys);
 
2250
      int key_for_use= find_shortest_key(head, &head->covering_keys);
2251
2251
      double key_read_time= 
2252
2252
        param.table->file->index_only_read_time(key_for_use, 
2253
2253
                                                rows2double(records)) +
2286
2286
    group_trp= get_best_group_min_max(&param, tree);
2287
2287
    if (group_trp)
2288
2288
    {
2289
 
      param.table->quick_condition_rows= cmin(group_trp->records,
 
2289
      param.table->quick_condition_rows= min(group_trp->records,
2290
2290
                                             head->file->stats.records);
2291
2291
      if (group_trp->read_cost < best_read_time)
2292
2292
      {
2382
2382
    thd->no_errors=0;
2383
2383
  }
2384
2384
 
 
2385
  print_quick(quick, &needed_reg);
 
2386
 
2385
2387
  /*
2386
2388
    Assume that if the user is using 'limit' we will only need to scan
2387
2389
    limit rows if we are using a key
2460
2462
{
2461
2463
  SEL_TREE **ptree;
2462
2464
  TRP_INDEX_MERGE *imerge_trp= NULL;
2463
 
  uint32_t n_child_scans= imerge->trees_next - imerge->trees;
 
2465
  uint n_child_scans= imerge->trees_next - imerge->trees;
2464
2466
  TRP_RANGE **range_scans;
2465
2467
  TRP_RANGE **cur_child;
2466
2468
  TRP_RANGE **cpk_scan= NULL;
2471
2473
  bool pk_is_clustered= param->table->file->primary_key_is_clustered();
2472
2474
  bool all_scans_ror_able= true;
2473
2475
  bool all_scans_rors= true;
2474
 
  uint32_t unique_calc_buff_size;
 
2476
  uint unique_calc_buff_size;
2475
2477
  TABLE_READ_PLAN **roru_read_plans;
2476
2478
  TABLE_READ_PLAN **cur_roru_plan;
2477
2479
  double roru_index_costs;
2577
2579
    {
2578
2580
      imerge_trp->read_cost= imerge_cost;
2579
2581
      imerge_trp->records= non_cpk_scan_records + cpk_scan_records;
2580
 
      imerge_trp->records= cmin(imerge_trp->records,
 
2582
      imerge_trp->records= min(imerge_trp->records,
2581
2583
                               param->table->file->stats.records);
2582
2584
      imerge_trp->range_scans= range_scans;
2583
2585
      imerge_trp->range_scans_end= range_scans + n_child_scans;
2689
2691
 
2690
2692
typedef struct st_ror_scan_info
2691
2693
{
2692
 
  uint32_t      idx;      /* # of used key in param->keys */
2693
 
  uint32_t      keynr;    /* # of used key in table */
 
2694
  uint      idx;      /* # of used key in param->keys */
 
2695
  uint      keynr;    /* # of used key in table */
2694
2696
  ha_rows   records;  /* estimate of # records this scan will return */
2695
2697
 
2696
2698
  /* Set of intervals over key fields that will be used for row retrieval. */
2698
2700
 
2699
2701
  /* Fields used in the query and covered by this ROR scan. */
2700
2702
  MY_BITMAP covered_fields;
2701
 
  uint32_t      used_fields_covered; /* # of set bits in covered_fields */
 
2703
  uint      used_fields_covered; /* # of set bits in covered_fields */
2702
2704
  int       key_rec_length; /* length of key record (including rowid) */
2703
2705
 
2704
2706
  /*
2706
2708
    (assuming there is no need to access full table records)
2707
2709
  */
2708
2710
  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 */
 
2711
  uint      first_uncovered_field; /* first unused bit in covered_fields */
 
2712
  uint      key_components; /* # of parts in the key */
2711
2713
} ROR_SCAN_INFO;
2712
2714
 
2713
2715
 
2731
2733
{
2732
2734
  ROR_SCAN_INFO *ror_scan;
2733
2735
  my_bitmap_map *bitmap_buf;
2734
 
  uint32_t keynr;
 
2736
  uint keynr;
2735
2737
 
2736
2738
  if (!(ror_scan= (ROR_SCAN_INFO*)alloc_root(param->mem_root,
2737
2739
                                             sizeof(ROR_SCAN_INFO))))
2986
2988
{
2987
2989
  double selectivity_mult= 1.0;
2988
2990
  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;
 
2991
  uchar key_val[MAX_KEY_LENGTH+MAX_FIELD_WIDTH]; /* key values tuple */
 
2992
  uchar *key_ptr= key_val;
2991
2993
  SEL_ARG *sel_arg, *tuple_arg= NULL;
2992
2994
  key_part_map keypart_map= 0;
2993
2995
  bool cur_covered;
3208
3210
                                          double read_time,
3209
3211
                                          bool *are_all_covering)
3210
3212
{
3211
 
  uint32_t idx;
 
3213
  uint idx;
3212
3214
  double min_cost= DBL_MAX;
3213
3215
 
3214
3216
  if ((tree->n_ror_scans < 2) || !param->table->file->stats.records)
3220
3222
  */
3221
3223
  ROR_SCAN_INFO **cur_ror_scan;
3222
3224
  ROR_SCAN_INFO *cpk_scan= NULL;
3223
 
  uint32_t cpk_no;
 
3225
  uint cpk_no;
3224
3226
  bool cpk_scan_used= false;
3225
3227
 
3226
3228
  if (!(tree->ror_scans= (ROR_SCAN_INFO**)alloc_root(param->mem_root,
3310
3312
                                          intersect_scans_best);
3311
3313
 
3312
3314
  *are_all_covering= intersect->is_covering;
3313
 
  uint32_t best_num= intersect_scans_best - intersect_scans;
 
3315
  uint best_num= intersect_scans_best - intersect_scans;
3314
3316
  ror_intersect_cpy(intersect, intersect_best);
3315
3317
 
3316
3318
  /*
3481
3483
  TRP_ROR_INTERSECT *trp;
3482
3484
  if (!(trp= new (param->mem_root) TRP_ROR_INTERSECT))
3483
3485
    return(trp);
3484
 
  uint32_t best_num= (ror_scan_mark - tree->ror_scans);
 
3486
  uint best_num= (ror_scan_mark - tree->ror_scans);
3485
3487
  if (!(trp->first_scan= (ROR_SCAN_INFO**)alloc_root(param->mem_root,
3486
3488
                                                     sizeof(ROR_SCAN_INFO*)*
3487
3489
                                                     best_num)))
3529
3531
                                       bool update_tbl_stats,
3530
3532
                                       double read_time)
3531
3533
{
3532
 
  uint32_t idx;
 
3534
  uint idx;
3533
3535
  SEL_ARG **key,**end, **key_to_read= NULL;
3534
3536
  ha_rows best_records= 0;
3535
 
  uint32_t    best_mrr_flags= 0, best_buf_size= 0;
 
3537
  uint    best_mrr_flags= 0, best_buf_size= 0;
3536
3538
  TRP_RANGE* read_plan= NULL;
3537
3539
  /*
3538
3540
    Note that there may be trees that have type SEL_TREE::KEY but contain no
3549
3551
      ha_rows found_records;
3550
3552
      COST_VECT cost;
3551
3553
      double found_read_time;
3552
 
      uint32_t mrr_flags, buf_size;
3553
 
      uint32_t keynr= param->real_keynr[idx];
 
3554
      uint mrr_flags, buf_size;
 
3555
      uint keynr= param->real_keynr[idx];
3554
3556
      if ((*key)->type == SEL_ARG::MAYBE_KEY ||
3555
3557
          (*key)->maybe_flag)
3556
3558
        param->needed_reg->set_bit(keynr);
3597
3599
 
3598
3600
 
3599
3601
QUICK_SELECT_I *TRP_INDEX_MERGE::make_quick(PARAM *param,
3600
 
                                            bool retrieve_full_rows __attribute__((unused)),
3601
 
                                            MEM_ROOT *parent_alloc __attribute__((unused)))
 
3602
                                            bool retrieve_full_rows,
 
3603
                                            MEM_ROOT *parent_alloc)
3602
3604
{
3603
3605
  QUICK_INDEX_MERGE_SELECT *quick_imerge;
3604
3606
  QUICK_RANGE_SELECT *quick;
3674
3676
 
3675
3677
 
3676
3678
QUICK_SELECT_I *TRP_ROR_UNION::make_quick(PARAM *param,
3677
 
                                          bool retrieve_full_rows __attribute__((unused)),
3678
 
                                          MEM_ROOT *parent_alloc __attribute__((unused)))
 
3679
                                          bool retrieve_full_rows,
 
3680
                                          MEM_ROOT *parent_alloc)
3679
3681
{
3680
3682
  QUICK_ROR_UNION_SELECT *quick_roru;
3681
3683
  TABLE_READ_PLAN **scan;
3856
3858
          break;
3857
3859
 
3858
3860
        /* Get a SEL_TREE for "(-inf|NULL) < X < c_0" interval.  */
3859
 
        uint32_t i=0;
 
3861
        uint i=0;
3860
3862
        do 
3861
3863
        {
3862
3864
          func->array->value_to_item(i, value_item);
3889
3891
            }
3890
3892
 
3891
3893
            /* Change all intervals to be "c_{i-1} < X < c_i" */
3892
 
            for (uint32_t idx= 0; idx < param->keys; idx++)
 
3894
            for (uint idx= 0; idx < param->keys; idx++)
3893
3895
            {
3894
3896
              SEL_ARG *new_interval, *last_val;
3895
3897
              if (((new_interval= tree2->keys[idx])) &&
4055
4057
  table_map param_comp= ~(param->prev_tables | param->read_tables |
4056
4058
                          param->current_table);
4057
4059
 
4058
 
  for (uint32_t i= 0; i < cond_func->arg_count; i++)
 
4060
  for (uint i= 0; i < cond_func->arg_count; i++)
4059
4061
  {
4060
4062
    Item *arg= cond_func->arguments()[i]->real_item();
4061
4063
    if (arg != field_item)
4183
4185
      Concerning the code below see the NOTES section in
4184
4186
      the comments for the function get_full_func_mm_tree()
4185
4187
    */
4186
 
    for (uint32_t i= 1 ; i < cond_func->arg_count ; i++)
 
4188
    for (uint i= 1 ; i < cond_func->arg_count ; i++)
4187
4189
    {
4188
4190
      if (cond_func->arguments()[i]->real_item()->type() == Item::FIELD_ITEM)
4189
4191
      {
4190
4192
        field_item= (Item_field*) (cond_func->arguments()[i]->real_item());
4191
4193
        SEL_TREE *tmp= get_full_func_mm_tree(param, cond_func, 
4192
 
                                    field_item, (Item*)(intptr_t)i, inv);
 
4194
                                    field_item, (Item*)(intptr)i, inv);
4193
4195
        if (inv)
4194
4196
          tree= !tree ? tmp : tree_or(param, tree, tmp);
4195
4197
        else 
4259
4261
static SEL_TREE *
4260
4262
get_mm_parts(RANGE_OPT_PARAM *param, COND *cond_func, Field *field,
4261
4263
             Item_func::Functype type,
4262
 
             Item *value,
4263
 
             Item_result cmp_type __attribute__((unused)))
 
4264
             Item *value, Item_result cmp_type)
4264
4265
{
4265
4266
  if (field->table != param->table)
4266
4267
    return(0);
4296
4297
        if (!(sel_arg= new SEL_ARG(SEL_ARG::MAYBE_KEY)))
4297
4298
          return(0);                    // OOM
4298
4299
      }
4299
 
      sel_arg->part=(unsigned char) key_part->part;
 
4300
      sel_arg->part=(uchar) key_part->part;
4300
4301
      tree->keys[key_part->key]=sel_add(tree->keys[key_part->key],sel_arg);
4301
4302
      tree->keys_map.set_bit(key_part->key);
4302
4303
    }
4310
4311
get_mm_leaf(RANGE_OPT_PARAM *param, COND *conf_func, Field *field,
4311
4312
            KEY_PART *key_part, Item_func::Functype type,Item *value)
4312
4313
{
4313
 
  uint32_t maybe_null=(uint) field->real_maybe_null();
 
4314
  uint maybe_null=(uint) field->real_maybe_null();
4314
4315
  bool optimize_range;
4315
4316
  SEL_ARG *tree= 0;
4316
4317
  MEM_ROOT *alloc= param->mem_root;
4317
 
  unsigned char *str;
 
4318
  uchar *str;
4318
4319
  ulong orig_sql_mode;
4319
4320
  int err;
4320
4321
 
4376
4377
  {
4377
4378
    bool like_error;
4378
4379
    char buff1[MAX_FIELD_WIDTH];
4379
 
    unsigned char *min_str,*max_str;
 
4380
    uchar *min_str,*max_str;
4380
4381
    String tmp(buff1,sizeof(buff1),value->collation.collation),*res;
4381
4382
    size_t length, offset, min_length, max_length;
4382
 
    uint32_t field_length= field->pack_length()+maybe_null;
 
4383
    uint field_length= field->pack_length()+maybe_null;
4383
4384
 
4384
4385
    if (!optimize_range)
4385
4386
      goto end;
4425
4426
        field_length= length;
4426
4427
    }
4427
4428
    length+=offset;
4428
 
    if (!(min_str= (unsigned char*) alloc_root(alloc, length*2)))
 
4429
    if (!(min_str= (uchar*) alloc_root(alloc, length*2)))
4429
4430
      goto end;
4430
4431
 
4431
4432
    max_str=min_str+length;
4468
4469
  /* For comparison purposes allow invalid dates like 2000-01-32 */
4469
4470
  orig_sql_mode= field->table->in_use->variables.sql_mode;
4470
4471
  if (value->real_item()->type() == Item::STRING_ITEM &&
4471
 
      (field->type() == DRIZZLE_TYPE_NEWDATE ||
4472
 
       field->type() == DRIZZLE_TYPE_DATETIME))
 
4472
      (field->type() == MYSQL_TYPE_NEWDATE ||
 
4473
       field->type() == MYSQL_TYPE_DATETIME))
4473
4474
    field->table->in_use->variables.sql_mode|= MODE_INVALID_DATES;
4474
4475
  err= value->save_in_field_no_warnings(field, 1);
4475
4476
  if (err > 0)
4491
4492
          for the cases like int_field > 999999999999999999999999 as well.
4492
4493
        */
4493
4494
        tree= 0;
4494
 
        if (err == 3 && field->type() == DRIZZLE_TYPE_NEWDATE &&
 
4495
        if (err == 3 && field->type() == FIELD_TYPE_NEWDATE &&
4495
4496
            (type == Item_func::GT_FUNC || type == Item_func::GE_FUNC ||
4496
4497
             type == Item_func::LT_FUNC || type == Item_func::LE_FUNC) )
4497
4498
        {
4543
4544
    goto end;
4544
4545
  }
4545
4546
  field->table->in_use->variables.sql_mode= orig_sql_mode;
4546
 
  str= (unsigned char*) alloc_root(alloc, key_part->store_length+1);
 
4547
  str= (uchar*) alloc_root(alloc, key_part->store_length+1);
4547
4548
  if (!str)
4548
4549
    goto end;
4549
4550
  if (maybe_null)
4550
 
    *str= (unsigned char) field->is_real_null();        // Set to 1 if null
 
4551
    *str= (uchar) field->is_real_null();        // Set to 1 if null
4551
4552
  field->get_key_image(str+maybe_null, key_part->length,
4552
4553
                       key_part->image_type);
4553
4554
  if (!(tree= new (alloc) SEL_ARG(field, str, str)))
4568
4569
      value->result_type() == INT_RESULT &&
4569
4570
      ((Field_num*)field)->unsigned_flag && !((Item_int*)value)->unsigned_flag)
4570
4571
  {
4571
 
    int64_t item_val= value->val_int();
 
4572
    longlong item_val= value->val_int();
4572
4573
    if (item_val < 0)
4573
4574
    {
4574
4575
      if (type == Item_func::LT_FUNC || type == Item_func::LE_FUNC)
4699
4700
  for (key1= tree1->keys,key2= tree2->keys,end=key1+param->keys ;
4700
4701
       key1 != end ; key1++,key2++)
4701
4702
  {
4702
 
    uint32_t flag=0;
 
4703
    uint flag=0;
4703
4704
    if (*key1 || *key2)
4704
4705
    {
4705
4706
      if (*key1 && !(*key1)->simple_key())
4750
4751
 
4751
4752
  /* trees have a common key, check if they refer to same key part */
4752
4753
  SEL_ARG **key1,**key2;
4753
 
  for (uint32_t key_no=0; key_no < param->keys; key_no++)
 
4754
  for (uint key_no=0; key_no < param->keys; key_no++)
4754
4755
  {
4755
4756
    if (common_keys.is_set(key_no))
4756
4757
    {
4824
4825
static bool remove_nonrange_trees(RANGE_OPT_PARAM *param, SEL_TREE *tree)
4825
4826
{
4826
4827
  bool res= false;
4827
 
  for (uint32_t i=0; i < param->keys; i++)
 
4828
  for (uint i=0; i < param->keys; i++)
4828
4829
  {
4829
4830
    if (tree->keys[i])
4830
4831
    {
4912
4913
    {
4913
4914
      /* one tree is index merge tree and another is range tree */
4914
4915
      if (tree1->merges.is_empty())
4915
 
        std::swap(tree1, tree2);
 
4916
        swap_variables(SEL_TREE*, tree1, tree2);
4916
4917
      
4917
4918
      if (param->remove_jump_scans && remove_nonrange_trees(param, tree2))
4918
4919
         return(new SEL_TREE(SEL_TREE::ALWAYS));
4931
4932
 
4932
4933
static SEL_ARG *
4933
4934
and_all_keys(RANGE_OPT_PARAM *param, SEL_ARG *key1, SEL_ARG *key2, 
4934
 
             uint32_t clone_flag)
 
4935
             uint clone_flag)
4935
4936
{
4936
4937
  SEL_ARG *next;
4937
4938
  ulong use_count=key1->use_count;
4988
4989
*/
4989
4990
 
4990
4991
static SEL_ARG *
4991
 
key_and(RANGE_OPT_PARAM *param, SEL_ARG *key1, SEL_ARG *key2, uint32_t clone_flag)
 
4992
key_and(RANGE_OPT_PARAM *param, SEL_ARG *key1, SEL_ARG *key2, uint clone_flag)
4992
4993
{
4993
4994
  if (!key1)
4994
4995
    return key2;
4998
4999
  {
4999
5000
    if (key1->part > key2->part)
5000
5001
    {
5001
 
      std::swap(key1, key2);
 
5002
      swap_variables(SEL_ARG *, key1, key2);
5002
5003
      clone_flag=swap_clone_flag(clone_flag);
5003
5004
    }
5004
5005
    // key1->part < key2->part
5014
5015
       key2->type != SEL_ARG::MAYBE_KEY) ||
5015
5016
      key1->type == SEL_ARG::MAYBE_KEY)
5016
5017
  {                                             // Put simple key in key2
5017
 
    std::swap(key1, key2);
 
5018
    swap_variables(SEL_ARG *, key1, key2);
5018
5019
    clone_flag=swap_clone_flag(clone_flag);
5019
5020
  }
5020
5021
 
5157
5158
  {
5158
5159
    if (key2->use_count == 0 || key1->elements > key2->elements)
5159
5160
    {
5160
 
      std::swap(key1,key2);
 
5161
      swap_variables(SEL_ARG *,key1,key2);
5161
5162
    }
5162
5163
    if (key1->use_count > 0 || !(key1=key1->clone_tree(param)))
5163
5164
      return 0;                                 // OOM
5242
5243
      }
5243
5244
    }
5244
5245
 
5245
 
    // tmp.max >= key2.min && tmp.min <= key.cmax(overlapping ranges)
 
5246
    // tmp.max >= key2.min && tmp.min <= key.max  (overlapping ranges)
5246
5247
    if (eq_tree(tmp->next_key_part,key2->next_key_part))
5247
5248
    {
5248
5249
      if (tmp->is_same(key2))
5834
5835
 
5835
5836
void SEL_ARG::test_use_count(SEL_ARG *root)
5836
5837
{
5837
 
  uint32_t e_count=0;
 
5838
  uint e_count=0;
5838
5839
  if (this == root && use_count != 1)
5839
5840
  {
5840
5841
    sql_print_information("Use_count: Wrong count %lu for root",use_count);
5876
5877
    Pointers in min and max keys. They point to right-after-end of key
5877
5878
    images. The 0-th entry has these pointing to key tuple start.
5878
5879
  */
5879
 
  unsigned char *min_key, *max_key;
 
5880
  uchar *min_key, *max_key;
5880
5881
  
5881
5882
  /* 
5882
5883
    Flags, for {keypart0, keypart1, ... this_keypart} subtuple.
5883
5884
    min_key_flag may have NULL_RANGE set.
5884
5885
  */
5885
 
  uint32_t min_key_flag, max_key_flag;
 
5886
  uint min_key_flag, max_key_flag;
5886
5887
  
5887
5888
  /* Number of key parts */
5888
 
  uint32_t min_key_parts, max_key_parts;
 
5889
  uint min_key_parts, max_key_parts;
5889
5890
  SEL_ARG *key_tree;
5890
5891
} RANGE_SEQ_ENTRY;
5891
5892
 
5895
5896
*/
5896
5897
typedef struct st_sel_arg_range_seq
5897
5898
{
5898
 
  uint32_t keyno;      /* index of used tree in SEL_TREE structure */
5899
 
  uint32_t real_keyno; /* Number of the index in tables */
 
5899
  uint keyno;      /* index of used tree in SEL_TREE structure */
 
5900
  uint real_keyno; /* Number of the index in tables */
5900
5901
  PARAM *param;
5901
5902
  SEL_ARG *start; /* Root node of the traversed SEL_ARG* graph */
5902
5903
  
5920
5921
    Value of init_param
5921
5922
*/
5922
5923
 
5923
 
range_seq_t sel_arg_range_seq_init(void *init_param,
5924
 
                                   uint32_t n_ranges __attribute__((unused)),
5925
 
                                   uint32_t flags __attribute__((unused)))
 
5924
range_seq_t sel_arg_range_seq_init(void *init_param, uint n_ranges, uint flags)
5926
5925
{
5927
5926
  SEL_ARG_RANGE_SEQ *seq= (SEL_ARG_RANGE_SEQ*)init_param;
5928
5927
  seq->at_start= true;
5950
5949
  cur->min_key_parts= prev->min_key_parts;
5951
5950
  cur->max_key_parts= prev->max_key_parts;
5952
5951
 
5953
 
  uint16_t stor_length= arg->param->key[arg->keyno][key_tree->part].store_length;
 
5952
  uint16 stor_length= arg->param->key[arg->keyno][key_tree->part].store_length;
5954
5953
  cur->min_key_parts += key_tree->store_min(stor_length, &cur->min_key,
5955
5954
                                            prev->min_key_flag);
5956
5955
  cur->max_key_parts += key_tree->store_max(stor_length, &cur->max_key,
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 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
  {
6290
 
    uint16_t fieldnr= param->table->key_info[keynr].
 
6289
    uint16 fieldnr= param->table->key_info[keynr].
6291
6290
                    key_part[kp - table_key->key_part].fieldnr - 1;
6292
6291
    if (param->table->field[fieldnr]->key_length() != kp->length)
6293
6292
      return false;
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
 
6648
6647
    key_part->length=       key_info->key_part[part].length;
6649
6648
    key_part->store_length= key_info->key_part[part].store_length;
6650
6649
    key_part->null_bit=     key_info->key_part[part].null_bit;
6651
 
    key_part->flag=         (uint8_t) key_info->key_part[part].key_part_flag;
 
6650
    key_part->flag=         (uint8) 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;
7038
7037
    Opaque value to be passed to quick_range_seq_next
7039
7038
*/
7040
7039
 
7041
 
range_seq_t quick_range_seq_init(void *init_param,
7042
 
                                 uint32_t n_ranges __attribute__((unused)),
7043
 
                                 uint32_t flags __attribute__((unused)))
 
7040
range_seq_t quick_range_seq_init(void *init_param, uint n_ranges, uint flags)
7044
7041
{
7045
7042
  QUICK_RANGE_SELECT *quick= (QUICK_RANGE_SELECT*)init_param;
7046
7043
  quick->qr_traversal_ctx.first=  (QUICK_RANGE**)quick->ranges.buffer;
7047
7044
  quick->qr_traversal_ctx.cur=    (QUICK_RANGE**)quick->ranges.buffer;
7048
 
  quick->qr_traversal_ctx.last=   quick->qr_traversal_ctx.cur +
 
7045
  quick->qr_traversal_ctx.last=   quick->qr_traversal_ctx.cur + 
7049
7046
                                  quick->ranges.elements;
7050
7047
  return &quick->qr_traversal_ctx;
7051
7048
}
7064
7061
    1  No more ranges in the sequence
7065
7062
*/
7066
7063
 
7067
 
uint32_t quick_range_seq_next(range_seq_t rseq, KEY_MULTI_RANGE *range)
 
7064
uint quick_range_seq_next(range_seq_t rseq, KEY_MULTI_RANGE *range)
7068
7065
{
7069
7066
  QUICK_RANGE_SEQ_CTX *ctx= (QUICK_RANGE_SEQ_CTX*)rseq;
7070
7067
 
7116
7113
    Reference to range_flag associated with range number #idx
7117
7114
*/
7118
7115
 
7119
 
uint16_t &mrr_persistent_flag_storage(range_seq_t seq, uint32_t idx)
 
7116
uint16 &mrr_persistent_flag_storage(range_seq_t seq, uint idx)
7120
7117
{
7121
7118
  QUICK_RANGE_SEQ_CTX *ctx= (QUICK_RANGE_SEQ_CTX*)seq;
7122
7119
  return ctx->first[idx]->flag;
7148
7145
    Reference to range-associated data
7149
7146
*/
7150
7147
 
7151
 
char* &mrr_get_ptr_by_idx(range_seq_t seq __attribute__((unused)),
7152
 
                          uint32_t idx __attribute__((unused)))
 
7148
char* &mrr_get_ptr_by_idx(range_seq_t seq, uint idx)
7153
7149
{
7154
7150
  static char *dummy;
7155
7151
  return dummy;
7222
7218
    other              if some error occurred
7223
7219
*/
7224
7220
 
7225
 
int QUICK_RANGE_SELECT::get_next_prefix(uint32_t prefix_length,
 
7221
int QUICK_RANGE_SELECT::get_next_prefix(uint prefix_length,
7226
7222
                                        key_part_map keypart_map,
7227
 
                                        unsigned char *cur_prefix)
 
7223
                                        uchar *cur_prefix)
7228
7224
{
7229
7225
  for (;;)
7230
7226
  {
7240
7236
        return(result);
7241
7237
    }
7242
7238
 
7243
 
    uint32_t count= ranges.elements - (cur_range - (QUICK_RANGE**) ranges.buffer);
 
7239
    uint count= ranges.elements - (cur_range - (QUICK_RANGE**) ranges.buffer);
7244
7240
    if (count == 0)
7245
7241
    {
7246
7242
      /* Ranges have already been used up before. None is left for read. */
7249
7245
    }
7250
7246
    last_range= *(cur_range++);
7251
7247
 
7252
 
    start_key.key=    (const unsigned char*) last_range->min_key;
7253
 
    start_key.length= cmin(last_range->min_length, (uint16_t)prefix_length);
 
7248
    start_key.key=    (const uchar*) last_range->min_key;
 
7249
    start_key.length= min(last_range->min_length, prefix_length);
7254
7250
    start_key.keypart_map= last_range->min_keypart_map & keypart_map;
7255
7251
    start_key.flag=   ((last_range->flag & NEAR_MIN) ? HA_READ_AFTER_KEY :
7256
7252
                       (last_range->flag & EQ_RANGE) ?
7257
7253
                       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);
 
7254
    end_key.key=      (const uchar*) last_range->max_key;
 
7255
    end_key.length=   min(last_range->max_length, prefix_length);
7260
7256
    end_key.keypart_map= last_range->max_keypart_map & keypart_map;
7261
7257
    /*
7262
7258
      We use READ_AFTER_KEY here because if we are reading on a key
7300
7296
bool QUICK_RANGE_SELECT::row_in_ranges()
7301
7297
{
7302
7298
  QUICK_RANGE *res;
7303
 
  uint32_t min= 0;
7304
 
  uint32_t max= ranges.elements - 1;
7305
 
  uint32_t mid= (max + min)/2;
 
7299
  uint min= 0;
 
7300
  uint max= ranges.elements - 1;
 
7301
  uint mid= (max + min)/2;
7306
7302
 
7307
7303
  while (min != max)
7308
7304
  {
7330
7326
 */
7331
7327
 
7332
7328
QUICK_SELECT_DESC::QUICK_SELECT_DESC(QUICK_RANGE_SELECT *q,
7333
 
                                     uint32_t used_key_parts_arg __attribute__((unused)),
7334
 
                                     bool *create_err __attribute__((unused)))
 
7329
                                     uint used_key_parts_arg,
 
7330
                                     bool *create_err)
7335
7331
 :QUICK_RANGE_SELECT(*q), rev_it(rev_ranges)
7336
7332
{
7337
7333
  QUICK_RANGE *r;
7445
7441
    return 0;                                   /* key can't be to large */
7446
7442
 
7447
7443
  KEY_PART *key_part=key_parts;
7448
 
  uint32_t store_length;
 
7444
  uint store_length;
7449
7445
 
7450
 
  for (unsigned char *key=range_arg->max_key, *end=key+range_arg->max_length;
 
7446
  for (uchar *key=range_arg->max_key, *end=key+range_arg->max_length;
7451
7447
       key < end;
7452
7448
       key+= store_length, key_part++)
7453
7449
  {
7580
7576
                                              String *used_lengths)
7581
7577
{
7582
7578
  char buf[64];
7583
 
  uint32_t length;
 
7579
  uint length;
7584
7580
  KEY *key_info= head->key_info + index;
7585
7581
  key_names->append(key_info->name);
7586
 
  length= int64_t2str(max_used_key_length, buf, 10) - buf;
 
7582
  length= longlong2str(max_used_key_length, buf, 10) - buf;
7587
7583
  used_lengths->append(buf, length);
7588
7584
}
7589
7585
 
7591
7587
                                                    String *used_lengths)
7592
7588
{
7593
7589
  char buf[64];
7594
 
  uint32_t length;
 
7590
  uint length;
7595
7591
  bool first= true;
7596
7592
  QUICK_RANGE_SELECT *quick;
7597
7593
 
7608
7604
 
7609
7605
    KEY *key_info= head->key_info + quick->index;
7610
7606
    key_names->append(key_info->name);
7611
 
    length= int64_t2str(quick->max_used_key_length, buf, 10) - buf;
 
7607
    length= longlong2str(quick->max_used_key_length, buf, 10) - buf;
7612
7608
    used_lengths->append(buf, length);
7613
7609
  }
7614
7610
  if (pk_quick_select)
7616
7612
    KEY *key_info= head->key_info + pk_quick_select->index;
7617
7613
    key_names->append(',');
7618
7614
    key_names->append(key_info->name);
7619
 
    length= int64_t2str(pk_quick_select->max_used_key_length, buf, 10) - buf;
 
7615
    length= longlong2str(pk_quick_select->max_used_key_length, buf, 10) - buf;
7620
7616
    used_lengths->append(',');
7621
7617
    used_lengths->append(buf, length);
7622
7618
  }
7626
7622
                                                      String *used_lengths)
7627
7623
{
7628
7624
  char buf[64];
7629
 
  uint32_t length;
 
7625
  uint length;
7630
7626
  bool first= true;
7631
7627
  QUICK_RANGE_SELECT *quick;
7632
7628
  List_iterator_fast<QUICK_RANGE_SELECT> it(quick_selects);
7641
7637
      used_lengths->append(',');
7642
7638
    }
7643
7639
    key_names->append(key_info->name);
7644
 
    length= int64_t2str(quick->max_used_key_length, buf, 10) - buf;
 
7640
    length= longlong2str(quick->max_used_key_length, buf, 10) - buf;
7645
7641
    used_lengths->append(buf, length);
7646
7642
  }
7647
7643
 
7650
7646
    KEY *key_info= head->key_info + cpk_quick->index;
7651
7647
    key_names->append(',');
7652
7648
    key_names->append(key_info->name);
7653
 
    length= int64_t2str(cpk_quick->max_used_key_length, buf, 10) - buf;
 
7649
    length= longlong2str(cpk_quick->max_used_key_length, buf, 10) - buf;
7654
7650
    used_lengths->append(',');
7655
7651
    used_lengths->append(buf, length);
7656
7652
  }
7680
7676
* Implementation of QUICK_GROUP_MIN_MAX_SELECT
7681
7677
*******************************************************************************/
7682
7678
 
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);
 
7679
static inline uint get_field_keypart(KEY *index, Field *field);
 
7680
static inline SEL_ARG * get_index_range_tree(uint index, SEL_TREE* range_tree,
 
7681
                                             PARAM *param, uint *param_idx);
7686
7682
static bool get_constant_key_infix(KEY *index_info, SEL_ARG *index_range_tree,
7687
7683
                       KEY_PART_INFO *first_non_group_part,
7688
7684
                       KEY_PART_INFO *min_max_arg_part,
7689
7685
                       KEY_PART_INFO *last_part, THD *thd,
7690
 
                       unsigned char *key_infix, uint32_t *key_infix_len,
 
7686
                       uchar *key_infix, uint *key_infix_len,
7691
7687
                       KEY_PART_INFO **first_non_infix_part);
7692
7688
static bool
7693
7689
check_group_min_max_predicates(COND *cond, Item_field *min_max_arg_item,
7694
7690
                               Field::imagetype image_type);
7695
7691
 
7696
7692
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,
 
7693
cost_group_min_max(TABLE* table, KEY *index_info, uint used_key_parts,
 
7694
                   uint group_key_parts, SEL_TREE *range_tree,
7699
7695
                   SEL_ARG *index_tree, ha_rows quick_prefix_records,
7700
7696
                   bool have_min, bool have_max,
7701
7697
                   double *read_cost, ha_rows *records);
7834
7830
{
7835
7831
  THD *thd= param->thd;
7836
7832
  JOIN *join= thd->lex->current_select->join;
7837
 
  Table *table= param->table;
 
7833
  TABLE *table= param->table;
7838
7834
  bool have_min= false;              /* true if there is a MIN function. */
7839
7835
  bool have_max= false;              /* true if there is a MAX function. */
7840
7836
  Item_field *min_max_arg_item= NULL; // The argument of all MIN/MAX functions
7841
7837
  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. */
 
7838
  uint group_prefix_len= 0; /* Length (in bytes) of the key prefix. */
7843
7839
  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. */
 
7840
  uint index= 0;            /* The id of the chosen index. */
 
7841
  uint group_key_parts= 0;  // Number of index key parts in the group prefix.
 
7842
  uint used_key_parts= 0;   /* Number of index key parts used for access. */
 
7843
  uchar key_infix[MAX_KEY_LENGTH]; /* Constants from equality predicates.*/
 
7844
  uint key_infix_len= 0;          /* Length of key_infix. */
7849
7845
  TRP_GROUP_MIN_MAX *read_plan= NULL; /* The eventually constructed TRP. */
7850
 
  uint32_t key_part_nr;
7851
 
  order_st *tmp_group;
 
7846
  uint key_part_nr;
 
7847
  ORDER *tmp_group;
7852
7848
  Item *item;
7853
7849
  Item_field *item_field;
7854
7850
 
7926
7922
  KEY_PART_INFO *last_part= NULL;
7927
7923
  KEY_PART_INFO *first_non_group_part= NULL;
7928
7924
  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;
 
7925
  uint key_infix_parts= 0;
 
7926
  uint cur_group_key_parts= 0;
 
7927
  uint cur_group_prefix_len= 0;
7932
7928
  /* Cost-related variables for the best index so far. */
7933
7929
  double best_read_cost= DBL_MAX;
7934
7930
  ha_rows best_records= 0;
7935
7931
  SEL_ARG *best_index_tree= NULL;
7936
7932
  ha_rows best_quick_prefix_records= 0;
7937
 
  uint32_t best_param_idx= 0;
 
7933
  uint best_param_idx= 0;
7938
7934
  double cur_read_cost= DBL_MAX;
7939
7935
  ha_rows cur_records;
7940
7936
  SEL_ARG *cur_index_tree= NULL;
7941
7937
  ha_rows cur_quick_prefix_records= 0;
7942
 
  uint32_t cur_param_idx=MAX_KEY;
 
7938
  uint cur_param_idx=MAX_KEY;
7943
7939
  key_map cur_used_key_parts;
7944
 
  uint32_t pk= param->table->s->primary_key;
 
7940
  uint pk= param->table->s->primary_key;
7945
7941
 
7946
 
  for (uint32_t cur_index= 0 ; cur_index_info != cur_index_info_end ;
 
7942
  for (uint cur_index= 0 ; cur_index_info != cur_index_info_end ;
7947
7943
       cur_index_info++, cur_index++)
7948
7944
  {
7949
7945
    /* Check (B1) - if current index is covering. */
7963
7959
        (table->file->ha_table_flags() & HA_PRIMARY_KEY_IN_READ_INDEX))
7964
7960
    {
7965
7961
      /* For each table field */
7966
 
      for (uint32_t i= 0; i < table->s->fields; i++)
 
7962
      for (uint i= 0; i < table->s->fields; i++)
7967
7963
      {
7968
7964
        Field *cur_field= table->field[i];
7969
7965
        /*
8006
8002
    }
8007
8003
    /*
8008
8004
      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
 
8005
      If GA2, then Store a new ORDER object in group_fields_array at the
 
8006
      position of the key part of item_field->field. Thus we get the ORDER
8011
8007
      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
 
8008
      Later group_fields_array of ORDER objects is used to convert the query
8013
8009
      to a GROUP query.
8014
8010
    */
8015
8011
    else if (join->select_distinct)
8016
8012
    {
8017
8013
      select_items_it.rewind();
8018
8014
      cur_used_key_parts.clear_all();
8019
 
      uint32_t max_key_part= 0;
 
8015
      uint max_key_part= 0;
8020
8016
      while ((item= select_items_it++))
8021
8017
      {
8022
8018
        item_field= (Item_field*) item; /* (SA5) already checked above. */
8034
8030
        cur_group_prefix_len+= cur_part->store_length;
8035
8031
        cur_used_key_parts.set_bit(key_part_nr);
8036
8032
        ++cur_group_key_parts;
8037
 
        max_key_part= cmax(max_key_part,key_part_nr);
 
8033
        max_key_part= max(max_key_part,key_part_nr);
8038
8034
      }
8039
8035
      /*
8040
8036
        Check that used key parts forms a prefix of the index.
8042
8038
        all_parts have all bits set from 0 to (max_key_part-1).
8043
8039
        cur_parts have bits set for only used keyparts.
8044
8040
      */
8045
 
      uint64_t all_parts, cur_parts;
 
8041
      ulonglong all_parts, cur_parts;
8046
8042
      all_parts= (1<<max_key_part) - 1;
8047
 
      cur_parts= cur_used_key_parts.to_uint64_t() >> 1;
 
8043
      cur_parts= cur_used_key_parts.to_ulonglong() >> 1;
8048
8044
      if (all_parts != cur_parts)
8049
8045
        goto next_index;
8050
8046
    }
8089
8085
    {
8090
8086
      if (tree)
8091
8087
      {
8092
 
        uint32_t dummy;
 
8088
        uint dummy;
8093
8089
        SEL_ARG *index_range_tree= get_index_range_tree(cur_index, tree, param,
8094
8090
                                                        &dummy);
8095
8091
        if (!get_constant_key_infix(cur_index_info, index_range_tree,
8127
8123
 
8128
8124
        /* Check if cur_part is referenced in the WHERE clause. */
8129
8125
        if (join->conds->walk(&Item::find_item_in_field_list_processor, 0,
8130
 
                              (unsigned char*) key_part_range))
 
8126
                              (uchar*) key_part_range))
8131
8127
          goto next_index;
8132
8128
      }
8133
8129
    }
8160
8156
                                           &cur_param_idx);
8161
8157
      /* Check if this range tree can be used for prefix retrieval. */
8162
8158
      COST_VECT dummy_cost;
8163
 
      uint32_t mrr_flags= HA_MRR_USE_DEFAULT_IMPL;
8164
 
      uint32_t mrr_bufsize=0;
 
8159
      uint mrr_flags= HA_MRR_USE_DEFAULT_IMPL;
 
8160
      uint mrr_bufsize=0;
8165
8161
      cur_quick_prefix_records= check_quick_select(param, cur_param_idx, 
8166
8162
                                                   false /*don't care*/, 
8167
8163
                                                   cur_index_tree, true,
8200
8196
 
8201
8197
  /* Check (SA3) for the where clause. */
8202
8198
  if (join->conds && min_max_arg_item &&
8203
 
      !check_group_min_max_predicates(join->conds, min_max_arg_item, Field::itRAW))
 
8199
      !check_group_min_max_predicates(join->conds, min_max_arg_item,
 
8200
                                      (index_info->flags & HA_SPATIAL) ?
 
8201
                                      Field::itMBR : Field::itRAW))
8204
8202
    return(NULL);
8205
8203
 
8206
8204
  /* The query passes all tests, so construct a new TRP object. */
8287
8285
  Item_func *pred= (Item_func*) cond;
8288
8286
  Item **arguments= pred->arguments();
8289
8287
  Item *cur_arg;
8290
 
  for (uint32_t arg_idx= 0; arg_idx < pred->argument_count (); arg_idx++)
 
8288
  for (uint arg_idx= 0; arg_idx < pred->argument_count (); arg_idx++)
8291
8289
  {
8292
8290
    cur_arg= arguments[arg_idx]->real_item();
8293
8291
    if (cur_arg->type() == Item::FIELD_ITEM)
8313
8311
 
8314
8312
        /* Check that pred compares min_max_arg_item with a constant. */
8315
8313
        Item *args[3];
8316
 
        memset(args, 0, 3 * sizeof(Item*));
 
8314
        bzero(args, 3 * sizeof(Item*));
8317
8315
        bool inv;
8318
8316
        /* Test if this is a comparison of a field and a constant. */
8319
8317
        if (!simple_pred(pred, args, &inv))
8389
8387
*/
8390
8388
 
8391
8389
static bool
8392
 
get_constant_key_infix(KEY *index_info __attribute__((unused)),
8393
 
                       SEL_ARG *index_range_tree,
 
8390
get_constant_key_infix(KEY *index_info, SEL_ARG *index_range_tree,
8394
8391
                       KEY_PART_INFO *first_non_group_part,
8395
8392
                       KEY_PART_INFO *min_max_arg_part,
8396
 
                       KEY_PART_INFO *last_part,
8397
 
                       THD *thd __attribute__((unused)),
8398
 
                       unsigned char *key_infix, uint32_t *key_infix_len,
 
8393
                       KEY_PART_INFO *last_part, THD *thd,
 
8394
                       uchar *key_infix, uint *key_infix_len,
8399
8395
                       KEY_PART_INFO **first_non_infix_part)
8400
8396
{
8401
8397
  SEL_ARG       *cur_range;
8404
8400
  KEY_PART_INFO *end_part= min_max_arg_part ? min_max_arg_part : last_part;
8405
8401
 
8406
8402
  *key_infix_len= 0;
8407
 
  unsigned char *key_ptr= key_infix;
 
8403
  uchar *key_ptr= key_infix;
8408
8404
  for (cur_part= first_non_group_part; cur_part != end_part; cur_part++)
8409
8405
  {
8410
8406
    /*
8436
8432
        (cur_range->min_flag & NEAR_MIN) || (cur_range->max_flag & NEAR_MAX))
8437
8433
      return false;
8438
8434
 
8439
 
    uint32_t field_length= cur_part->store_length;
 
8435
    uint field_length= cur_part->store_length;
8440
8436
    if ((cur_range->maybe_null &&
8441
8437
         cur_range->min_value[0] && cur_range->max_value[0]) ||
8442
8438
        !memcmp(cur_range->min_value, cur_range->max_value, field_length))
8511
8507
    Pointer to the SEL_ARG subtree that corresponds to index.
8512
8508
*/
8513
8509
 
8514
 
SEL_ARG * get_index_range_tree(uint32_t index, SEL_TREE* range_tree, PARAM *param,
8515
 
                               uint32_t *param_idx)
 
8510
SEL_ARG * get_index_range_tree(uint index, SEL_TREE* range_tree, PARAM *param,
 
8511
                               uint *param_idx)
8516
8512
{
8517
 
  uint32_t idx= 0; /* Index nr in param->key_parts */
 
8513
  uint idx= 0; /* Index nr in param->key_parts */
8518
8514
  while (idx < param->keys)
8519
8515
  {
8520
8516
    if (index == param->real_keynr[idx])
8586
8582
    None
8587
8583
*/
8588
8584
 
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,
8591
 
                        SEL_ARG *index_tree __attribute__((unused)),
8592
 
                        ha_rows quick_prefix_records,
 
8585
void cost_group_min_max(TABLE* table, KEY *index_info, uint used_key_parts,
 
8586
                        uint group_key_parts, SEL_TREE *range_tree,
 
8587
                        SEL_ARG *index_tree, ha_rows quick_prefix_records,
8593
8588
                        bool have_min, bool have_max,
8594
8589
                        double *read_cost, ha_rows *records)
8595
8590
{
8596
8591
  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 */
 
8592
  uint num_groups;
 
8593
  uint num_blocks;
 
8594
  uint keys_per_block;
 
8595
  uint keys_per_group;
 
8596
  uint keys_per_subgroup; /* Average number of keys in sub-groups */
8602
8597
                          /* formed by a key infix. */
8603
8598
  double p_overlap; /* Probability that a sub-group overlaps two blocks. */
8604
8599
  double quick_prefix_selectivity;
8639
8634
    {
8640
8635
      double blocks_per_group= (double) num_blocks / (double) num_groups;
8641
8636
      p_overlap= (blocks_per_group * (keys_per_subgroup - 1)) / keys_per_group;
8642
 
      p_overlap= cmin(p_overlap, 1.0);
 
8637
      p_overlap= min(p_overlap, 1.0);
8643
8638
    }
8644
 
    io_cost= (double) cmin(num_groups * (1 + p_overlap), (double)num_blocks);
 
8639
    io_cost= (double) min(num_groups * (1 + p_overlap), num_blocks);
8645
8640
  }
8646
8641
  else
8647
8642
    io_cost= (keys_per_group > keys_per_block) ?
8684
8679
*/
8685
8680
 
8686
8681
QUICK_SELECT_I *
8687
 
TRP_GROUP_MIN_MAX::make_quick(PARAM *param,
8688
 
                              bool retrieve_full_rows __attribute__((unused)),
 
8682
TRP_GROUP_MIN_MAX::make_quick(PARAM *param, bool retrieve_full_rows,
8689
8683
                              MEM_ROOT *parent_alloc)
8690
8684
{
8691
8685
  QUICK_GROUP_MIN_MAX_SELECT *quick;
8783
8777
*/
8784
8778
 
8785
8779
QUICK_GROUP_MIN_MAX_SELECT::
8786
 
QUICK_GROUP_MIN_MAX_SELECT(Table *table, JOIN *join_arg, bool have_min_arg,
 
8780
QUICK_GROUP_MIN_MAX_SELECT(TABLE *table, JOIN *join_arg, bool have_min_arg,
8787
8781
                           bool have_max_arg,
8788
8782
                           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)
 
8783
                           uint group_prefix_len_arg, uint group_key_parts_arg,
 
8784
                           uint used_key_parts_arg, KEY *index_info_arg,
 
8785
                           uint use_index, double read_cost_arg,
 
8786
                           ha_rows records_arg, uint key_infix_len_arg,
 
8787
                           uchar *key_infix_arg, MEM_ROOT *parent_alloc)
8794
8788
  :join(join_arg), index_info(index_info_arg),
8795
8789
   group_prefix_len(group_prefix_len_arg),
8796
8790
   group_key_parts(group_key_parts_arg), have_min(have_min_arg),
8823
8817
    join->thd->mem_root= &alloc;
8824
8818
  }
8825
8819
  else
8826
 
    memset(&alloc, 0, sizeof(MEM_ROOT));  // ensure that it's not used
 
8820
    bzero(&alloc, sizeof(MEM_ROOT));            // ensure that it's not used
8827
8821
}
8828
8822
 
8829
8823
 
8849
8843
  if (group_prefix) /* Already initialized. */
8850
8844
    return 0;
8851
8845
 
8852
 
  if (!(last_prefix= (unsigned char*) alloc_root(&alloc, group_prefix_len)))
 
8846
  if (!(last_prefix= (uchar*) alloc_root(&alloc, group_prefix_len)))
8853
8847
      return 1;
8854
8848
  /*
8855
8849
    We may use group_prefix to store keys with all select fields, so allocate
8856
8850
    enough space for it.
8857
8851
  */
8858
 
  if (!(group_prefix= (unsigned char*) alloc_root(&alloc,
 
8852
  if (!(group_prefix= (uchar*) alloc_root(&alloc,
8859
8853
                                         real_prefix_len + min_max_arg_len)))
8860
8854
    return 1;
8861
8855
 
8865
8859
      The memory location pointed to by key_infix will be deleted soon, so
8866
8860
      allocate a new buffer and copy the key_infix into it.
8867
8861
    */
8868
 
    unsigned char *tmp_key_infix= (unsigned char*) alloc_root(&alloc, key_infix_len);
 
8862
    uchar *tmp_key_infix= (uchar*) alloc_root(&alloc, key_infix_len);
8869
8863
    if (!tmp_key_infix)
8870
8864
      return 1;
8871
8865
    memcpy(tmp_key_infix, this->key_infix, key_infix_len);
8956
8950
bool QUICK_GROUP_MIN_MAX_SELECT::add_range(SEL_ARG *sel_range)
8957
8951
{
8958
8952
  QUICK_RANGE *range;
8959
 
  uint32_t range_flag= sel_range->min_flag | sel_range->max_flag;
 
8953
  uint range_flag= sel_range->min_flag | sel_range->max_flag;
8960
8954
 
8961
8955
  /* Skip (-inf,+inf) ranges, e.g. (x < 5 or x > 4). */
8962
8956
  if ((range_flag & NO_MIN_RANGE) && (range_flag & NO_MAX_RANGE))
8979
8973
                         range_flag);
8980
8974
  if (!range)
8981
8975
    return true;
8982
 
  if (insert_dynamic(&min_max_ranges, (unsigned char*)&range))
 
8976
  if (insert_dynamic(&min_max_ranges, (uchar*)&range))
8983
8977
    return true;
8984
8978
  return false;
8985
8979
}
9008
9002
      group_prefix_len < quick_prefix_select->max_used_key_length)
9009
9003
  {
9010
9004
    DYNAMIC_ARRAY *arr;
9011
 
    uint32_t inx;
 
9005
    uint inx;
9012
9006
 
9013
9007
    for (inx= 0, arr= &quick_prefix_select->ranges; inx < arr->elements; inx++)
9014
9008
    {
9015
9009
      QUICK_RANGE *range;
9016
9010
 
9017
 
      get_dynamic(arr, (unsigned char*)&range, inx);
 
9011
      get_dynamic(arr, (uchar*)&range, inx);
9018
9012
      range->flag &= ~(NEAR_MIN | NEAR_MAX);
9019
9013
    }
9020
9014
  }
9050
9044
    QUICK_RANGE *cur_range;
9051
9045
    if (have_min)
9052
9046
    { /* Check if the right-most range has a lower boundary. */
9053
 
      get_dynamic(&min_max_ranges, (unsigned char*)&cur_range,
 
9047
      get_dynamic(&min_max_ranges, (uchar*)&cur_range,
9054
9048
                  min_max_ranges.elements - 1);
9055
9049
      if (!(cur_range->flag & NO_MIN_RANGE))
9056
9050
      {
9061
9055
    }
9062
9056
    if (have_max)
9063
9057
    { /* Check if the left-most range has an upper boundary. */
9064
 
      get_dynamic(&min_max_ranges, (unsigned char*)&cur_range, 0);
 
9058
      get_dynamic(&min_max_ranges, (uchar*)&cur_range, 0);
9065
9059
      if (!(cur_range->flag & NO_MAX_RANGE))
9066
9060
      {
9067
9061
        max_used_key_length+= min_max_arg_len;
9372
9366
 
9373
9367
  if (quick_prefix_select)
9374
9368
  {
9375
 
    unsigned char *cur_prefix= seen_first_key ? group_prefix : NULL;
 
9369
    uchar *cur_prefix= seen_first_key ? group_prefix : NULL;
9376
9370
    if ((result= quick_prefix_select->get_next_prefix(group_prefix_len,
9377
9371
                         make_prev_keypart_map(group_key_parts), cur_prefix)))
9378
9372
      return(result);
9440
9434
 
9441
9435
  assert(min_max_ranges.elements > 0);
9442
9436
 
9443
 
  for (uint32_t range_idx= 0; range_idx < min_max_ranges.elements; range_idx++)
 
9437
  for (uint range_idx= 0; range_idx < min_max_ranges.elements; range_idx++)
9444
9438
  { /* Search from the left-most range to the right. */
9445
 
    get_dynamic(&min_max_ranges, (unsigned char*)&cur_range, range_idx);
 
9439
    get_dynamic(&min_max_ranges, (uchar*)&cur_range, range_idx);
9446
9440
 
9447
9441
    /*
9448
9442
      If the current value for the min/max argument is bigger than the right
9449
9443
      boundary of cur_range, there is no need to check this range.
9450
9444
    */
9451
9445
    if (range_idx != 0 && !(cur_range->flag & NO_MAX_RANGE) &&
9452
 
        (key_cmp(min_max_arg_part, (const unsigned char*) cur_range->max_key,
 
9446
        (key_cmp(min_max_arg_part, (const uchar*) cur_range->max_key,
9453
9447
                 min_max_arg_len) == 1))
9454
9448
      continue;
9455
9449
 
9510
9504
    if ( !(cur_range->flag & NO_MAX_RANGE) )
9511
9505
    {
9512
9506
      /* Compose the MAX key for the range. */
9513
 
      unsigned char *max_key= (unsigned char*) my_alloca(real_prefix_len + min_max_arg_len);
 
9507
      uchar *max_key= (uchar*) my_alloca(real_prefix_len + min_max_arg_len);
9514
9508
      memcpy(max_key, group_prefix, real_prefix_len);
9515
9509
      memcpy(max_key + real_prefix_len, cur_range->max_key,
9516
9510
             cur_range->max_length);
9571
9565
 
9572
9566
  assert(min_max_ranges.elements > 0);
9573
9567
 
9574
 
  for (uint32_t range_idx= min_max_ranges.elements; range_idx > 0; range_idx--)
 
9568
  for (uint range_idx= min_max_ranges.elements; range_idx > 0; range_idx--)
9575
9569
  { /* Search from the right-most range to the left. */
9576
 
    get_dynamic(&min_max_ranges, (unsigned char*)&cur_range, range_idx - 1);
 
9570
    get_dynamic(&min_max_ranges, (uchar*)&cur_range, range_idx - 1);
9577
9571
 
9578
9572
    /*
9579
9573
      If the current value for the min/max argument is smaller than the left
9581
9575
    */
9582
9576
    if (range_idx != min_max_ranges.elements &&
9583
9577
        !(cur_range->flag & NO_MIN_RANGE) &&
9584
 
        (key_cmp(min_max_arg_part, (const unsigned char*) cur_range->min_key,
 
9578
        (key_cmp(min_max_arg_part, (const uchar*) cur_range->min_key,
9585
9579
                 min_max_arg_len) == -1))
9586
9580
      continue;
9587
9581
 
9627
9621
    if ( !(cur_range->flag & NO_MIN_RANGE) )
9628
9622
    {
9629
9623
      /* Compose the MIN key for the range. */
9630
 
      unsigned char *min_key= (unsigned char*) my_alloca(real_prefix_len + min_max_arg_len);
 
9624
      uchar *min_key= (uchar*) my_alloca(real_prefix_len + min_max_arg_len);
9631
9625
      memcpy(min_key, group_prefix, real_prefix_len);
9632
9626
      memcpy(min_key + real_prefix_len, cur_range->min_key,
9633
9627
             cur_range->min_length);
9729
9723
                                                      String *used_lengths)
9730
9724
{
9731
9725
  char buf[64];
9732
 
  uint32_t length;
 
9726
  uint length;
9733
9727
  key_names->append(index_info->name);
9734
 
  length= int64_t2str(max_used_key_length, buf, 10) - buf;
 
9728
  length= longlong2str(max_used_key_length, buf, 10) - buf;
9735
9729
  used_lengths->append(buf, length);
9736
9730
}
9737
9731
 
9738
9732
static void print_sel_tree(PARAM *param, SEL_TREE *tree, key_map *tree_map,
9739
 
                           const char *msg __attribute__((unused)))
 
9733
                           const char *msg)
9740
9734
{
9741
9735
  SEL_ARG **key,**end;
9742
9736
  int idx;
9750
9744
  {
9751
9745
    if (tree_map->is_set(idx))
9752
9746
    {
9753
 
      uint32_t keynr= param->real_keynr[idx];
 
9747
      uint keynr= param->real_keynr[idx];
9754
9748
      if (tmp.length())
9755
9749
        tmp.append(',');
9756
9750
      tmp.append(param->table->key_info[keynr].name);
9763
9757
}
9764
9758
 
9765
9759
 
9766
 
static void print_ror_scans_arr(Table *table,
9767
 
                                const char *msg __attribute__((unused)),
 
9760
static void print_ror_scans_arr(TABLE *table, const char *msg,
9768
9761
                                struct st_ror_scan_info **start,
9769
9762
                                struct st_ror_scan_info **end)
9770
9763
{
9782
9775
  return;
9783
9776
}
9784
9777
 
 
9778
 
 
9779
/*****************************************************************************
 
9780
** Print a quick range for debugging
 
9781
** TODO:
 
9782
** This should be changed to use a String to store each row instead
 
9783
** of locking the DEBUG stream !
 
9784
*****************************************************************************/
 
9785
 
 
9786
static void
 
9787
print_key(KEY_PART *key_part, const uchar *key, uint used_length)
 
9788
{
 
9789
  char buff[1024];
 
9790
  const uchar *key_end= key+used_length;
 
9791
  String tmp(buff,sizeof(buff),&my_charset_bin);
 
9792
  uint store_length;
 
9793
  TABLE *table= key_part->field->table;
 
9794
  my_bitmap_map *old_write_set, *old_read_set;
 
9795
  old_write_set= dbug_tmp_use_all_columns(table, table->write_set);
 
9796
  old_read_set=  dbug_tmp_use_all_columns(table, table->read_set);
 
9797
 
 
9798
  for (; key < key_end; key+=store_length, key_part++)
 
9799
  {
 
9800
    Field *field=      key_part->field;
 
9801
    store_length= key_part->store_length;
 
9802
 
 
9803
    if (field->real_maybe_null())
 
9804
    {
 
9805
      if (*key)
 
9806
      {
 
9807
        fwrite("NULL",sizeof(char),4,DBUG_FILE);
 
9808
        continue;
 
9809
      }
 
9810
      key++;                                    // Skip null byte
 
9811
      store_length--;
 
9812
    }
 
9813
    field->set_key_image(key, key_part->length);
 
9814
    field->val_str(&tmp);
 
9815
    fwrite(tmp.ptr(),sizeof(char),tmp.length(),DBUG_FILE);
 
9816
    if (key+store_length < key_end)
 
9817
      fputc('/',DBUG_FILE);
 
9818
  }
 
9819
  dbug_tmp_restore_column_map(table->write_set, old_write_set);
 
9820
  dbug_tmp_restore_column_map(table->read_set, old_read_set);
 
9821
}
 
9822
 
 
9823
 
 
9824
static void print_quick(QUICK_SELECT_I *quick, const key_map *needed_reg)
 
9825
{
 
9826
  char buf[MAX_KEY/8+1];
 
9827
  TABLE *table;
 
9828
  my_bitmap_map *old_read_map, *old_write_map;
 
9829
  if (!quick)
 
9830
    return;
 
9831
  DBUG_LOCK_FILE;
 
9832
 
 
9833
  table= quick->head;
 
9834
  old_read_map=  dbug_tmp_use_all_columns(table, table->read_set);
 
9835
  old_write_map= dbug_tmp_use_all_columns(table, table->write_set);
 
9836
  quick->dbug_dump(0, true);
 
9837
  dbug_tmp_restore_column_map(table->read_set, old_read_map);
 
9838
  dbug_tmp_restore_column_map(table->write_set, old_write_map);
 
9839
 
 
9840
  fprintf(DBUG_FILE,"other_keys: 0x%s:\n", needed_reg->print(buf));
 
9841
 
 
9842
  DBUG_UNLOCK_FILE;
 
9843
  return;
 
9844
}
 
9845
 
 
9846
 
 
9847
void QUICK_RANGE_SELECT::dbug_dump(int indent, bool verbose)
 
9848
{
 
9849
  /* purecov: begin inspected */
 
9850
  fprintf(DBUG_FILE, "%*squick range select, key %s, length: %d\n",
 
9851
          indent, "", head->key_info[index].name, max_used_key_length);
 
9852
 
 
9853
  if (verbose)
 
9854
  {
 
9855
    QUICK_RANGE *range;
 
9856
    QUICK_RANGE **pr= (QUICK_RANGE**)ranges.buffer;
 
9857
    QUICK_RANGE **end_range= pr + ranges.elements;
 
9858
    for (; pr != end_range; ++pr)
 
9859
    {
 
9860
      fprintf(DBUG_FILE, "%*s", indent + 2, "");
 
9861
      range= *pr;
 
9862
      if (!(range->flag & NO_MIN_RANGE))
 
9863
      {
 
9864
        print_key(key_parts, range->min_key, range->min_length);
 
9865
        if (range->flag & NEAR_MIN)
 
9866
          fputs(" < ",DBUG_FILE);
 
9867
        else
 
9868
          fputs(" <= ",DBUG_FILE);
 
9869
      }
 
9870
      fputs("X",DBUG_FILE);
 
9871
 
 
9872
      if (!(range->flag & NO_MAX_RANGE))
 
9873
      {
 
9874
        if (range->flag & NEAR_MAX)
 
9875
          fputs(" < ",DBUG_FILE);
 
9876
        else
 
9877
          fputs(" <= ",DBUG_FILE);
 
9878
        print_key(key_parts, range->max_key, range->max_length);
 
9879
      }
 
9880
      fputs("\n",DBUG_FILE);
 
9881
    }
 
9882
  }
 
9883
  /* purecov: end */    
 
9884
}
 
9885
 
 
9886
void QUICK_INDEX_MERGE_SELECT::dbug_dump(int indent, bool verbose)
 
9887
{
 
9888
  List_iterator_fast<QUICK_RANGE_SELECT> it(quick_selects);
 
9889
  QUICK_RANGE_SELECT *quick;
 
9890
  fprintf(DBUG_FILE, "%*squick index_merge select\n", indent, "");
 
9891
  fprintf(DBUG_FILE, "%*smerged scans {\n", indent, "");
 
9892
  while ((quick= it++))
 
9893
    quick->dbug_dump(indent+2, verbose);
 
9894
  if (pk_quick_select)
 
9895
  {
 
9896
    fprintf(DBUG_FILE, "%*sclustered PK quick:\n", indent, "");
 
9897
    pk_quick_select->dbug_dump(indent+2, verbose);
 
9898
  }
 
9899
  fprintf(DBUG_FILE, "%*s}\n", indent, "");
 
9900
}
 
9901
 
 
9902
void QUICK_ROR_INTERSECT_SELECT::dbug_dump(int indent, bool verbose)
 
9903
{
 
9904
  List_iterator_fast<QUICK_RANGE_SELECT> it(quick_selects);
 
9905
  QUICK_RANGE_SELECT *quick;
 
9906
  fprintf(DBUG_FILE, "%*squick ROR-intersect select, %scovering\n",
 
9907
          indent, "", need_to_fetch_row? "":"non-");
 
9908
  fprintf(DBUG_FILE, "%*smerged scans {\n", indent, "");
 
9909
  while ((quick= it++))
 
9910
    quick->dbug_dump(indent+2, verbose);
 
9911
  if (cpk_quick)
 
9912
  {
 
9913
    fprintf(DBUG_FILE, "%*sclustered PK quick:\n", indent, "");
 
9914
    cpk_quick->dbug_dump(indent+2, verbose);
 
9915
  }
 
9916
  fprintf(DBUG_FILE, "%*s}\n", indent, "");
 
9917
}
 
9918
 
 
9919
void QUICK_ROR_UNION_SELECT::dbug_dump(int indent, bool verbose)
 
9920
{
 
9921
  List_iterator_fast<QUICK_SELECT_I> it(quick_selects);
 
9922
  QUICK_SELECT_I *quick;
 
9923
  fprintf(DBUG_FILE, "%*squick ROR-union select\n", indent, "");
 
9924
  fprintf(DBUG_FILE, "%*smerged scans {\n", indent, "");
 
9925
  while ((quick= it++))
 
9926
    quick->dbug_dump(indent+2, verbose);
 
9927
  fprintf(DBUG_FILE, "%*s}\n", indent, "");
 
9928
}
 
9929
 
 
9930
 
 
9931
/*
 
9932
  Print quick select information to DBUG_FILE.
 
9933
 
 
9934
  SYNOPSIS
 
9935
    QUICK_GROUP_MIN_MAX_SELECT::dbug_dump()
 
9936
    indent  Indentation offset
 
9937
    verbose If true show more detailed output.
 
9938
 
 
9939
  DESCRIPTION
 
9940
    Print the contents of this quick select to DBUG_FILE. The method also
 
9941
    calls dbug_dump() for the used quick select if any.
 
9942
 
 
9943
  IMPLEMENTATION
 
9944
    Caller is responsible for locking DBUG_FILE before this call and unlocking
 
9945
    it afterwards.
 
9946
 
 
9947
  RETURN
 
9948
    None
 
9949
*/
 
9950
 
 
9951
void QUICK_GROUP_MIN_MAX_SELECT::dbug_dump(int indent, bool verbose)
 
9952
{
 
9953
  fprintf(DBUG_FILE,
 
9954
          "%*squick_group_min_max_select: index %s (%d), length: %d\n",
 
9955
          indent, "", index_info->name, index, max_used_key_length);
 
9956
  if (key_infix_len > 0)
 
9957
  {
 
9958
    fprintf(DBUG_FILE, "%*susing key_infix with length %d:\n",
 
9959
            indent, "", key_infix_len);
 
9960
  }
 
9961
  if (quick_prefix_select)
 
9962
  {
 
9963
    fprintf(DBUG_FILE, "%*susing quick_range_select:\n", indent, "");
 
9964
    quick_prefix_select->dbug_dump(indent + 2, verbose);
 
9965
  }
 
9966
  if (min_max_ranges.elements > 0)
 
9967
  {
 
9968
    fprintf(DBUG_FILE, "%*susing %d quick_ranges for MIN/MAX:\n",
 
9969
            indent, "", min_max_ranges.elements);
 
9970
  }
 
9971
}
 
9972
 
9785
9973
/*****************************************************************************
9786
9974
** Instantiate templates 
9787
9975
*****************************************************************************/