~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to sql/opt_range.cc

Removed my_vsnprintf and my_snprintf.

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,
752
757
static
753
758
TRP_GROUP_MIN_MAX *get_best_group_min_max(PARAM *param, SEL_TREE *tree);
754
759
 
 
760
#ifndef DBUG_OFF
755
761
static void print_sel_tree(PARAM *param, SEL_TREE *tree, key_map *tree_map,
756
762
                           const char *msg);
757
 
static void print_ror_scans_arr(Table *table, const char *msg,
 
763
static void print_ror_scans_arr(TABLE *table, const char *msg,
758
764
                                struct st_ror_scan_info **start,
759
765
                                struct st_ror_scan_info **end);
 
766
static void print_quick(QUICK_SELECT_I *quick, const key_map *needed_reg);
 
767
#endif
760
768
 
761
769
static SEL_TREE *tree_and(RANGE_OPT_PARAM *param,SEL_TREE *tree1,SEL_TREE *tree2);
762
770
static SEL_TREE *tree_or(RANGE_OPT_PARAM *param,SEL_TREE *tree1,SEL_TREE *tree2);
763
771
static SEL_ARG *sel_add(SEL_ARG *key1,SEL_ARG *key2);
764
772
static SEL_ARG *key_or(RANGE_OPT_PARAM *param, SEL_ARG *key1, SEL_ARG *key2);
765
773
static SEL_ARG *key_and(RANGE_OPT_PARAM *param, SEL_ARG *key1, SEL_ARG *key2,
766
 
                        uint32_t clone_flag);
 
774
                        uint clone_flag);
767
775
static bool get_range(SEL_ARG **e1,SEL_ARG **e2,SEL_ARG *root1);
768
776
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);
 
777
                    SEL_ARG *key_tree, uchar *min_key,uint min_key_flag,
 
778
                    uchar *max_key,uint max_key_flag);
771
779
static bool eq_tree(SEL_ARG* a,SEL_ARG *b);
772
780
 
773
781
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);
 
782
static bool null_part_in_key(KEY_PART *key_part, const uchar *key,
 
783
                             uint length);
776
784
bool sel_trees_can_be_ored(SEL_TREE *tree1, SEL_TREE *tree2, RANGE_OPT_PARAM* param);
777
785
 
778
786
 
828
836
  if (trees_next == trees_end)
829
837
  {
830
838
    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;
 
839
    uint old_elements= (trees_end - trees);
 
840
    uint old_size= sizeof(SEL_TREE**) * old_elements;
 
841
    uint new_size= old_size * realloc_ratio;
834
842
    SEL_TREE **new_trees;
835
843
    if (!(new_trees= (SEL_TREE**)alloc_root(param->mem_root, new_size)))
836
844
      return -1;
999
1007
           1 = Got some error (out of memory?)
1000
1008
           */
1001
1009
 
1002
 
SQL_SELECT *make_select(Table *head, table_map const_tables,
 
1010
SQL_SELECT *make_select(TABLE *head, table_map const_tables,
1003
1011
                        table_map read_tables, COND *conds,
1004
1012
                        bool allow_null_cond,
1005
1013
                        int *error)
1006
1014
{
1007
1015
  SQL_SELECT *select;
 
1016
  DBUG_ENTER("make_select");
1008
1017
 
1009
1018
  *error=0;
1010
1019
 
1011
1020
  if (!conds && !allow_null_cond)
1012
 
    return(0);
 
1021
    DBUG_RETURN(0);
1013
1022
  if (!(select= new SQL_SELECT))
1014
1023
  {
1015
1024
    *error= 1;                  // out of memory
1016
 
    return(0);          /* purecov: inspected */
 
1025
    DBUG_RETURN(0);             /* purecov: inspected */
1017
1026
  }
1018
1027
  select->read_tables=read_tables;
1019
1028
  select->const_tables=const_tables;
1025
1034
    select->file= *head->sort.io_cache;
1026
1035
    select->records=(ha_rows) (select->file.end_of_file/
1027
1036
                               head->file->ref_length);
1028
 
    free(head->sort.io_cache);
 
1037
    my_free(head->sort.io_cache, MYF(0));
1029
1038
    head->sort.io_cache=0;
1030
1039
  }
1031
 
  return(select);
 
1040
  DBUG_RETURN(select);
1032
1041
}
1033
1042
 
1034
1043
 
1058
1067
  cleanup();
1059
1068
}
1060
1069
 
 
1070
#undef index                                    // Fix for Unixware 7
 
1071
 
1061
1072
QUICK_SELECT_I::QUICK_SELECT_I()
1062
1073
  :max_used_key_length(0),
1063
1074
   used_key_parts(0)
1064
1075
{}
1065
1076
 
1066
 
QUICK_RANGE_SELECT::QUICK_RANGE_SELECT(THD *thd, Table *table, uint32_t key_nr,
 
1077
QUICK_RANGE_SELECT::QUICK_RANGE_SELECT(THD *thd, TABLE *table, uint key_nr,
1067
1078
                                       bool no_alloc, MEM_ROOT *parent_alloc,
1068
1079
                                       bool *create_error)
1069
1080
  :free_file(0),cur_range(NULL),last_range(0),dont_free(0)
1070
1081
{
1071
1082
  my_bitmap_map *bitmap;
 
1083
  DBUG_ENTER("QUICK_RANGE_SELECT::QUICK_RANGE_SELECT");
1072
1084
 
1073
1085
  in_ror_merged_scan= 0;
1074
1086
  sorted= 0;
1088
1100
    thd->mem_root= &alloc;
1089
1101
  }
1090
1102
  else
1091
 
    memset(&alloc, 0, sizeof(alloc));
 
1103
    bzero((char*) &alloc,sizeof(alloc));
1092
1104
  file= head->file;
1093
1105
  record= head->record[0];
1094
1106
  save_read_set= head->read_set;
1103
1115
  }
1104
1116
  else
1105
1117
    bitmap_init(&column_bitmap, bitmap, head->s->fields, false);
1106
 
  return;
 
1118
  DBUG_VOID_RETURN;
1107
1119
}
1108
1120
 
1109
1121
 
1110
1122
int QUICK_RANGE_SELECT::init()
1111
1123
{
 
1124
  DBUG_ENTER("QUICK_RANGE_SELECT::init");
 
1125
 
1112
1126
  if (file->inited != handler::NONE)
1113
1127
    file->ha_index_or_rnd_end();
1114
 
  return(file->ha_index_init(index, 1));
 
1128
  DBUG_RETURN(file->ha_index_init(index, 1));
1115
1129
}
1116
1130
 
1117
1131
 
1124
1138
 
1125
1139
QUICK_RANGE_SELECT::~QUICK_RANGE_SELECT()
1126
1140
{
 
1141
  DBUG_ENTER("QUICK_RANGE_SELECT::~QUICK_RANGE_SELECT");
1127
1142
  if (!dont_free)
1128
1143
  {
1129
1144
    /* file is NULL for CPK scan on covering ROR-intersection */
1137
1152
      }
1138
1153
      if (free_file)
1139
1154
      {
 
1155
        DBUG_PRINT("info", ("Freeing separate handler 0x%lx (free: %d)", (long) file,
 
1156
                            free_file));
1140
1157
        file->ha_external_lock(current_thd, F_UNLCK);
1141
1158
        file->close();
1142
1159
        delete file;
1144
1161
    }
1145
1162
    delete_dynamic(&ranges); /* ranges are allocated in alloc */
1146
1163
    free_root(&alloc,MYF(0));
1147
 
    free((char*) column_bitmap.bitmap);
 
1164
    my_free((char*) column_bitmap.bitmap, MYF(MY_ALLOW_ZERO_PTR));
1148
1165
  }
1149
1166
  head->column_bitmaps_set(save_read_set, save_write_set);
1150
 
  if (mrr_buf_desc)
1151
 
    free(mrr_buf_desc);
1152
 
  return;
 
1167
  x_free(mrr_buf_desc);
 
1168
  DBUG_VOID_RETURN;
1153
1169
}
1154
1170
 
1155
1171
 
1156
1172
QUICK_INDEX_MERGE_SELECT::QUICK_INDEX_MERGE_SELECT(THD *thd_param,
1157
 
                                                   Table *table)
 
1173
                                                   TABLE *table)
1158
1174
  :pk_quick_select(NULL), thd(thd_param)
1159
1175
{
 
1176
  DBUG_ENTER("QUICK_INDEX_MERGE_SELECT::QUICK_INDEX_MERGE_SELECT");
1160
1177
  index= MAX_KEY;
1161
1178
  head= table;
1162
 
  memset(&read_record, 0, sizeof(read_record));
 
1179
  bzero(&read_record, sizeof(read_record));
1163
1180
  init_sql_alloc(&alloc, thd->variables.range_alloc_block_size, 0);
1164
 
  return;
 
1181
  DBUG_VOID_RETURN;
1165
1182
}
1166
1183
 
1167
1184
int QUICK_INDEX_MERGE_SELECT::init()
1168
1185
{
1169
 
  return(0);
 
1186
  DBUG_ENTER("QUICK_INDEX_MERGE_SELECT::init");
 
1187
  DBUG_RETURN(0);
1170
1188
}
1171
1189
 
1172
1190
int QUICK_INDEX_MERGE_SELECT::reset()
1173
1191
{
1174
 
  return(read_keys_and_merge());
 
1192
  DBUG_ENTER("QUICK_INDEX_MERGE_SELECT::reset");
 
1193
  DBUG_RETURN(read_keys_and_merge());
1175
1194
}
1176
1195
 
1177
1196
bool
1193
1212
{
1194
1213
  List_iterator_fast<QUICK_RANGE_SELECT> quick_it(quick_selects);
1195
1214
  QUICK_RANGE_SELECT* quick;
 
1215
  DBUG_ENTER("QUICK_INDEX_MERGE_SELECT::~QUICK_INDEX_MERGE_SELECT");
1196
1216
  quick_it.rewind();
1197
1217
  while ((quick= quick_it++))
1198
1218
    quick->file= NULL;
1199
1219
  quick_selects.delete_elements();
1200
1220
  delete pk_quick_select;
1201
1221
  free_root(&alloc,MYF(0));
1202
 
  return;
 
1222
  DBUG_VOID_RETURN;
1203
1223
}
1204
1224
 
1205
1225
 
1206
1226
QUICK_ROR_INTERSECT_SELECT::QUICK_ROR_INTERSECT_SELECT(THD *thd_param,
1207
 
                                                       Table *table,
 
1227
                                                       TABLE *table,
1208
1228
                                                       bool retrieve_full_rows,
1209
1229
                                                       MEM_ROOT *parent_alloc)
1210
1230
  : cpk_quick(NULL), thd(thd_param), need_to_fetch_row(retrieve_full_rows),
1216
1236
  if (!parent_alloc)
1217
1237
    init_sql_alloc(&alloc, thd->variables.range_alloc_block_size, 0);
1218
1238
  else
1219
 
    memset(&alloc, 0, sizeof(MEM_ROOT));
1220
 
  last_rowid= (unsigned char*) alloc_root(parent_alloc? parent_alloc : &alloc,
 
1239
    bzero(&alloc, sizeof(MEM_ROOT));
 
1240
  last_rowid= (uchar*) alloc_root(parent_alloc? parent_alloc : &alloc,
1221
1241
                                  head->file->ref_length);
1222
1242
}
1223
1243
 
1234
1254
 
1235
1255
int QUICK_ROR_INTERSECT_SELECT::init()
1236
1256
{
 
1257
  DBUG_ENTER("QUICK_ROR_INTERSECT_SELECT::init");
1237
1258
 /* Check if last_rowid was successfully allocated in ctor */
1238
 
  return(!last_rowid);
 
1259
  DBUG_RETURN(!last_rowid);
1239
1260
}
1240
1261
 
1241
1262
 
1265
1286
{
1266
1287
  handler *save_file= file, *org_file;
1267
1288
  THD *thd;
 
1289
  DBUG_ENTER("QUICK_RANGE_SELECT::init_ror_merged_scan");
1268
1290
 
1269
1291
  in_ror_merged_scan= 1;
1270
1292
  if (reuse_handler)
1271
1293
  {
 
1294
    DBUG_PRINT("info", ("Reusing handler 0x%lx", (long) file));
1272
1295
    if (init() || reset())
1273
1296
    {
1274
 
      return(1);
 
1297
      DBUG_RETURN(1);
1275
1298
    }
1276
1299
    head->column_bitmaps_set(&column_bitmap, &column_bitmap);
1277
1300
    goto end;
1281
1304
  if (free_file)
1282
1305
  {
1283
1306
    /* already have own 'handler' object. */
1284
 
    return(0);
 
1307
    DBUG_RETURN(0);
1285
1308
  }
1286
1309
 
1287
1310
  thd= head->in_use;
1333
1356
  bitmap_copy(&column_bitmap, head->read_set);
1334
1357
  head->column_bitmaps_set(&column_bitmap, &column_bitmap);
1335
1358
 
1336
 
  return(0);
 
1359
  DBUG_RETURN(0);
1337
1360
 
1338
1361
failure:
1339
1362
  head->column_bitmaps_set(save_read_set, save_write_set);
1340
1363
  delete file;
1341
1364
  file= save_file;
1342
 
  return(1);
 
1365
  DBUG_RETURN(1);
1343
1366
}
1344
1367
 
1345
1368
 
1357
1380
{
1358
1381
  List_iterator_fast<QUICK_RANGE_SELECT> quick_it(quick_selects);
1359
1382
  QUICK_RANGE_SELECT* quick;
 
1383
  DBUG_ENTER("QUICK_ROR_INTERSECT_SELECT::init_ror_merged_scan");
1360
1384
 
1361
1385
  /* Initialize all merged "children" quick selects */
1362
 
  assert(!need_to_fetch_row || reuse_handler);
 
1386
  DBUG_ASSERT(!need_to_fetch_row || reuse_handler);
1363
1387
  if (!need_to_fetch_row && reuse_handler)
1364
1388
  {
1365
1389
    quick= quick_it++;
1368
1392
      selects.
1369
1393
    */
1370
1394
    if (quick->init_ror_merged_scan(true))
1371
 
      return(1);
 
1395
      DBUG_RETURN(1);
1372
1396
    quick->file->extra(HA_EXTRA_KEYREAD_PRESERVE_FIELDS);
1373
1397
  }
1374
1398
  while ((quick= quick_it++))
1375
1399
  {
1376
1400
    if (quick->init_ror_merged_scan(false))
1377
 
      return(1);
 
1401
      DBUG_RETURN(1);
1378
1402
    quick->file->extra(HA_EXTRA_KEYREAD_PRESERVE_FIELDS);
1379
1403
    /* All merged scans share the same record buffer in intersection. */
1380
1404
    quick->record= head->record[0];
1382
1406
 
1383
1407
  if (need_to_fetch_row && head->file->ha_rnd_init(1))
1384
1408
  {
1385
 
    return(1);
 
1409
    DBUG_PRINT("error", ("ROR index_merge rnd_init call failed"));
 
1410
    DBUG_RETURN(1);
1386
1411
  }
1387
 
  return(0);
 
1412
  DBUG_RETURN(0);
1388
1413
}
1389
1414
 
1390
1415
 
1399
1424
 
1400
1425
int QUICK_ROR_INTERSECT_SELECT::reset()
1401
1426
{
 
1427
  DBUG_ENTER("QUICK_ROR_INTERSECT_SELECT::reset");
1402
1428
  if (!scans_inited && init_ror_merged_scan(true))
1403
 
    return(1);
 
1429
    DBUG_RETURN(1);
1404
1430
  scans_inited= true;
1405
1431
  List_iterator_fast<QUICK_RANGE_SELECT> it(quick_selects);
1406
1432
  QUICK_RANGE_SELECT *quick;
1407
1433
  while ((quick= it++))
1408
1434
    quick->reset();
1409
 
  return(0);
 
1435
  DBUG_RETURN(0);
1410
1436
}
1411
1437
 
1412
1438
 
1433
1459
 
1434
1460
QUICK_ROR_INTERSECT_SELECT::~QUICK_ROR_INTERSECT_SELECT()
1435
1461
{
 
1462
  DBUG_ENTER("QUICK_ROR_INTERSECT_SELECT::~QUICK_ROR_INTERSECT_SELECT");
1436
1463
  quick_selects.delete_elements();
1437
1464
  delete cpk_quick;
1438
1465
  free_root(&alloc,MYF(0));
1439
1466
  if (need_to_fetch_row && head->file->inited != handler::NONE)
1440
1467
    head->file->ha_rnd_end();
1441
 
  return;
 
1468
  DBUG_VOID_RETURN;
1442
1469
}
1443
1470
 
1444
1471
 
1445
1472
QUICK_ROR_UNION_SELECT::QUICK_ROR_UNION_SELECT(THD *thd_param,
1446
 
                                               Table *table)
 
1473
                                               TABLE *table)
1447
1474
  : thd(thd_param), scans_inited(false)
1448
1475
{
1449
1476
  index= MAX_KEY;
1467
1494
 
1468
1495
int QUICK_ROR_UNION_SELECT::init()
1469
1496
{
 
1497
  DBUG_ENTER("QUICK_ROR_UNION_SELECT::init");
1470
1498
  if (init_queue(&queue, quick_selects.elements, 0,
1471
1499
                 false , QUICK_ROR_UNION_SELECT::queue_cmp,
1472
1500
                 (void*) this))
1473
1501
  {
1474
 
    memset(&queue, 0, sizeof(QUEUE));
1475
 
    return(1);
 
1502
    bzero(&queue, sizeof(QUEUE));
 
1503
    DBUG_RETURN(1);
1476
1504
  }
1477
1505
 
1478
 
  if (!(cur_rowid= (unsigned char*) alloc_root(&alloc, 2*head->file->ref_length)))
1479
 
    return(1);
 
1506
  if (!(cur_rowid= (uchar*) alloc_root(&alloc, 2*head->file->ref_length)))
 
1507
    DBUG_RETURN(1);
1480
1508
  prev_rowid= cur_rowid + head->file->ref_length;
1481
 
  return(0);
 
1509
  DBUG_RETURN(0);
1482
1510
}
1483
1511
 
1484
1512
 
1493
1521
      val2  Second merged select
1494
1522
*/
1495
1523
 
1496
 
int QUICK_ROR_UNION_SELECT::queue_cmp(void *arg, unsigned char *val1, unsigned char *val2)
 
1524
int QUICK_ROR_UNION_SELECT::queue_cmp(void *arg, uchar *val1, uchar *val2)
1497
1525
{
1498
1526
  QUICK_ROR_UNION_SELECT *self= (QUICK_ROR_UNION_SELECT*)arg;
1499
1527
  return self->head->file->cmp_ref(((QUICK_SELECT_I*)val1)->last_rowid,
1515
1543
{
1516
1544
  QUICK_SELECT_I *quick;
1517
1545
  int error;
 
1546
  DBUG_ENTER("QUICK_ROR_UNION_SELECT::reset");
1518
1547
  have_prev_rowid= false;
1519
1548
  if (!scans_inited)
1520
1549
  {
1522
1551
    while ((quick= it++))
1523
1552
    {
1524
1553
      if (quick->init_ror_merged_scan(false))
1525
 
        return(1);
 
1554
        DBUG_RETURN(1);
1526
1555
    }
1527
1556
    scans_inited= true;
1528
1557
  }
1535
1564
  while ((quick= it++))
1536
1565
  {
1537
1566
    if (quick->reset())
1538
 
      return(1);
 
1567
      DBUG_RETURN(1);
1539
1568
    if ((error= quick->get_next()))
1540
1569
    {
1541
1570
      if (error == HA_ERR_END_OF_FILE)
1542
1571
        continue;
1543
 
      return(error);
 
1572
      DBUG_RETURN(error);
1544
1573
    }
1545
1574
    quick->save_last_pos();
1546
 
    queue_insert(&queue, (unsigned char*)quick);
 
1575
    queue_insert(&queue, (uchar*)quick);
1547
1576
  }
1548
1577
 
1549
1578
  if (head->file->ha_rnd_init(1))
1550
1579
  {
1551
 
    return(1);
 
1580
    DBUG_PRINT("error", ("ROR index_merge rnd_init call failed"));
 
1581
    DBUG_RETURN(1);
1552
1582
  }
1553
1583
 
1554
 
  return(0);
 
1584
  DBUG_RETURN(0);
1555
1585
}
1556
1586
 
1557
1587
 
1563
1593
 
1564
1594
QUICK_ROR_UNION_SELECT::~QUICK_ROR_UNION_SELECT()
1565
1595
{
 
1596
  DBUG_ENTER("QUICK_ROR_UNION_SELECT::~QUICK_ROR_UNION_SELECT");
1566
1597
  delete_queue(&queue);
1567
1598
  quick_selects.delete_elements();
1568
1599
  if (head->file->inited != handler::NONE)
1569
1600
    head->file->ha_rnd_end();
1570
1601
  free_root(&alloc,MYF(0));
1571
 
  return;
 
1602
  DBUG_VOID_RETURN;
1572
1603
}
1573
1604
 
1574
1605
 
1602
1633
  use_count=0; elements=1;
1603
1634
}
1604
1635
 
1605
 
SEL_ARG::SEL_ARG(Field *f,const unsigned char *min_value_arg,
1606
 
                 const unsigned char *max_value_arg)
 
1636
SEL_ARG::SEL_ARG(Field *f,const uchar *min_value_arg,
 
1637
                 const uchar *max_value_arg)
1607
1638
  :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),
 
1639
   elements(1), use_count(1), field(f), min_value((uchar*) min_value_arg),
 
1640
   max_value((uchar*) max_value_arg), next(0),prev(0),
1610
1641
   next_key_part(0),color(BLACK),type(KEY_RANGE)
1611
1642
{
1612
1643
  left=right= &null_element;
1613
1644
}
1614
1645
 
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_)
 
1646
SEL_ARG::SEL_ARG(Field *field_,uint8 part_,
 
1647
                 uchar *min_value_, uchar *max_value_,
 
1648
                 uint8 min_flag_,uint8 max_flag_,uint8 maybe_flag_)
1618
1649
  :min_flag(min_flag_),max_flag(max_flag_),maybe_flag(maybe_flag_),
1619
1650
   part(part_),maybe_null(field_->real_maybe_null()), elements(1),use_count(1),
1620
1651
   field(field_), min_value(min_value_), max_value(max_value_),
1691
1722
  Returns -2 or 2 if the ranges where 'joined' like  < 2 and >= 2
1692
1723
*/
1693
1724
 
1694
 
static int sel_cmp(Field *field, unsigned char *a, unsigned char *b, uint8_t a_flag,
1695
 
                   uint8_t b_flag)
 
1725
static int sel_cmp(Field *field, uchar *a, uchar *b, uint8 a_flag,
 
1726
                   uint8 b_flag)
1696
1727
{
1697
1728
  int cmp;
1698
1729
  /* First check if there was a compare to a min or max element */
1778
1809
    MAX_KEY if no such index was found.
1779
1810
*/
1780
1811
 
1781
 
uint32_t get_index_for_order(Table *table, order_st *order, ha_rows limit)
 
1812
uint get_index_for_order(TABLE *table, ORDER *order, ha_rows limit)
1782
1813
{
1783
 
  uint32_t idx;
1784
 
  uint32_t match_key= MAX_KEY, match_key_len= MAX_KEY_LENGTH + 1;
1785
 
  order_st *ord;
 
1814
  uint idx;
 
1815
  uint match_key= MAX_KEY, match_key_len= MAX_KEY_LENGTH + 1;
 
1816
  ORDER *ord;
1786
1817
  
1787
1818
  for (ord= order; ord; ord= ord->next)
1788
1819
    if (!ord->asc)
1793
1824
    if (!(table->keys_in_use_for_query.is_set(idx)))
1794
1825
      continue;
1795
1826
    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;
 
1827
    uint n_parts=  table->key_info[idx].key_parts;
 
1828
    uint partno= 0;
1798
1829
    
1799
1830
    /* 
1800
1831
      The below check is sufficient considering we now have either BTREE 
1882
1913
  /* Table read plans are allocated on MEM_ROOT and are never deleted */
1883
1914
  static void *operator new(size_t size, MEM_ROOT *mem_root)
1884
1915
  { 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 */ }
 
1916
  static void operator delete(void *ptr,size_t size) { TRASH(ptr, size); }
 
1917
  static void operator delete(void *ptr, MEM_ROOT *mem_root) { /* Never called */ }
1891
1918
  virtual ~TABLE_READ_PLAN() {}               /* Remove gcc warning */
1892
1919
 
1893
1920
};
1908
1935
{
1909
1936
public:
1910
1937
  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;
 
1938
  uint     key_idx; /* key number in PARAM::key */
 
1939
  uint     mrr_flags; 
 
1940
  uint     mrr_buf_size;
1914
1941
 
1915
 
  TRP_RANGE(SEL_ARG *key_arg, uint32_t idx_arg, uint32_t mrr_flags_arg)
 
1942
  TRP_RANGE(SEL_ARG *key_arg, uint idx_arg, uint mrr_flags_arg)
1916
1943
   : key(key_arg), key_idx(idx_arg), mrr_flags(mrr_flags_arg)
1917
1944
  {}
1918
1945
  virtual ~TRP_RANGE() {}                     /* Remove gcc warning */
1919
1946
 
1920
 
  QUICK_SELECT_I *make_quick(PARAM *param,
1921
 
                             bool retrieve_full_rows __attribute__((unused)),
 
1947
  QUICK_SELECT_I *make_quick(PARAM *param, bool retrieve_full_rows,
1922
1948
                             MEM_ROOT *parent_alloc)
1923
1949
  {
 
1950
    DBUG_ENTER("TRP_RANGE::make_quick");
1924
1951
    QUICK_RANGE_SELECT *quick;
1925
1952
    if ((quick= get_quick_select(param, key_idx, key, mrr_flags, mrr_buf_size,
1926
1953
                                 parent_alloc)))
1928
1955
      quick->records= records;
1929
1956
      quick->read_time= read_cost;
1930
1957
    }
1931
 
    return(quick);
 
1958
    DBUG_RETURN(quick);
1932
1959
  }
1933
1960
};
1934
1961
 
1997
2024
private:
1998
2025
  bool have_min, have_max;
1999
2026
  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;
 
2027
  uint group_prefix_len;
 
2028
  uint used_key_parts;
 
2029
  uint group_key_parts;
2003
2030
  KEY *index_info;
2004
 
  uint32_t index;
2005
 
  uint32_t key_infix_len;
2006
 
  unsigned char key_infix[MAX_KEY_LENGTH];
 
2031
  uint index;
 
2032
  uint key_infix_len;
 
2033
  uchar key_infix[MAX_KEY_LENGTH];
2007
2034
  SEL_TREE *range_tree; /* Represents all range predicates in the query. */
2008
2035
  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. */
 
2036
  uint param_idx; /* Index of used key in param->key. */
2010
2037
  /* Number of records selected by the ranges in index_tree. */
2011
2038
public:
2012
2039
  ha_rows quick_prefix_records;
2013
2040
public:
2014
2041
  TRP_GROUP_MIN_MAX(bool have_min_arg, bool have_max_arg,
2015
2042
                    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,
 
2043
                    uint group_prefix_len_arg, uint used_key_parts_arg,
 
2044
                    uint group_key_parts_arg, KEY *index_info_arg,
 
2045
                    uint index_arg, uint key_infix_len_arg,
 
2046
                    uchar *key_infix_arg,
2020
2047
                    SEL_TREE *tree_arg, SEL_ARG *index_tree_arg,
2021
 
                    uint32_t param_idx_arg, ha_rows quick_prefix_records_arg)
 
2048
                    uint param_idx_arg, ha_rows quick_prefix_records_arg)
2022
2049
  : have_min(have_min_arg), have_max(have_max_arg),
2023
2050
    min_max_arg_part(min_max_arg_part_arg),
2024
2051
    group_prefix_len(group_prefix_len_arg), used_key_parts(used_key_parts_arg),
2053
2080
 
2054
2081
static int fill_used_fields_bitmap(PARAM *param)
2055
2082
{
2056
 
  Table *table= param->table;
 
2083
  TABLE *table= param->table;
2057
2084
  my_bitmap_map *tmp;
2058
 
  uint32_t pk;
 
2085
  uint pk;
2059
2086
  param->tmp_covered_fields.bitmap= 0;
2060
2087
  param->fields_bitmap_size= table->s->column_bitmap_size;
2061
2088
  if (!(tmp= (my_bitmap_map*) alloc_root(param->mem_root,
2151
2178
                                  ha_rows limit, bool force_quick_range, 
2152
2179
                                  bool ordered_output)
2153
2180
{
2154
 
  uint32_t idx;
 
2181
  uint idx;
2155
2182
  double scan_time;
 
2183
  DBUG_ENTER("SQL_SELECT::test_quick_select");
 
2184
  DBUG_PRINT("enter",("keys_to_use: %lu  prev_tables: %lu  const_tables: %lu",
 
2185
                      (ulong) keys_to_use.to_ulonglong(), (ulong) prev_tables,
 
2186
                      (ulong) const_tables));
 
2187
  DBUG_PRINT("info", ("records: %lu", (ulong) head->file->stats.records));
2156
2188
  delete quick;
2157
2189
  quick=0;
2158
2190
  needed_reg.clear_all();
2159
2191
  quick_keys.clear_all();
2160
2192
  if (keys_to_use.is_clear_all())
2161
 
    return(0);
 
2193
    DBUG_RETURN(0);
2162
2194
  records= head->file->stats.records;
2163
2195
  if (!records)
2164
2196
    records++;                                  /* purecov: inspected */
2169
2201
  if (limit < records)
2170
2202
    read_time= (double) records + scan_time + 1; // Force to use index
2171
2203
  else if (read_time <= 2.0 && !force_quick_range)
2172
 
    return(0);                          /* No need for quick select */
 
2204
    DBUG_RETURN(0);                             /* No need for quick select */
 
2205
 
 
2206
  DBUG_PRINT("info",("Time to scan table: %g", read_time));
2173
2207
 
2174
2208
  keys_to_use.intersect(head->keys_in_use_for_query);
2175
2209
  if (!keys_to_use.is_clear_all())
2181
2215
    PARAM param;
2182
2216
 
2183
2217
    if (check_stack_overrun(thd, 2*STACK_MIN_SIZE, NULL))
2184
 
      return(0);                           // Fatal error flag is set
 
2218
      DBUG_RETURN(0);                           // Fatal error flag is set
2185
2219
 
2186
2220
    /* set up parameter that is passed to all functions */
2187
2221
    param.thd= thd;
2208
2242
    {
2209
2243
      thd->no_errors=0;
2210
2244
      free_root(&alloc,MYF(0));                 // Return memory & allocator
2211
 
      return(0);                                // Can't use range
 
2245
      DBUG_RETURN(0);                           // Can't use range
2212
2246
    }
2213
2247
    key_parts= param.key_parts;
2214
2248
    thd->mem_root= &alloc;
2226
2260
 
2227
2261
      param.key[param.keys]=key_parts;
2228
2262
      key_part_info= key_info->key_part;
2229
 
      for (uint32_t part=0 ; part < key_info->key_parts ;
 
2263
      for (uint part=0 ; part < key_info->key_parts ;
2230
2264
           part++, key_parts++, key_part_info++)
2231
2265
      {
2232
2266
        key_parts->key=          param.keys;
2237
2271
        key_parts->null_bit=     key_part_info->null_bit;
2238
2272
        key_parts->image_type =  Field::itRAW;
2239
2273
        /* Only HA_PART_KEY_SEG is used */
2240
 
        key_parts->flag=         (uint8_t) key_part_info->key_part_flag;
 
2274
        key_parts->flag=         (uint8) key_part_info->key_part_flag;
2241
2275
      }
2242
2276
      param.real_keynr[param.keys++]=idx;
2243
2277
    }
2247
2281
    /* Calculate cost of full index read for the shortest covering index */
2248
2282
    if (!head->covering_keys.is_clear_all())
2249
2283
    {
2250
 
      int key_for_use= head->find_shortest_key(&head->covering_keys);
 
2284
      int key_for_use= find_shortest_key(head, &head->covering_keys);
2251
2285
      double key_read_time= 
2252
2286
        param.table->file->index_only_read_time(key_for_use, 
2253
2287
                                                rows2double(records)) +
2254
2288
        (double) records / TIME_FOR_COMPARE;
 
2289
      DBUG_PRINT("info",  ("'all'+'using index' scan will be using key %d, "
 
2290
                           "read time %g", key_for_use, key_read_time));
2255
2291
      if (key_read_time < read_time)
2256
2292
        read_time= key_read_time;
2257
2293
    }
2286
2322
    group_trp= get_best_group_min_max(&param, tree);
2287
2323
    if (group_trp)
2288
2324
    {
2289
 
      param.table->quick_condition_rows= cmin(group_trp->records,
 
2325
      param.table->quick_condition_rows= min(group_trp->records,
2290
2326
                                             head->file->stats.records);
2291
2327
      if (group_trp->read_cost < best_read_time)
2292
2328
      {
2347
2383
        /* Try creating index_merge/ROR-union scan. */
2348
2384
        SEL_IMERGE *imerge;
2349
2385
        TABLE_READ_PLAN *best_conj_trp= NULL, *new_conj_trp;
 
2386
        DBUG_PRINT("info",("No range reads possible,"
 
2387
                           " trying to construct index_merge"));
2350
2388
        List_iterator_fast<SEL_IMERGE> it(tree->merges);
2351
2389
        while ((imerge= it++))
2352
2390
        {
2382
2420
    thd->no_errors=0;
2383
2421
  }
2384
2422
 
 
2423
  DBUG_EXECUTE("info", print_quick(quick, &needed_reg););
 
2424
 
2385
2425
  /*
2386
2426
    Assume that if the user is using 'limit' we will only need to scan
2387
2427
    limit rows if we are using a key
2388
2428
  */
2389
 
  return(records ? test(quick) : -1);
 
2429
  DBUG_RETURN(records ? test(quick) : -1);
2390
2430
}
2391
2431
 
2392
2432
/*
2460
2500
{
2461
2501
  SEL_TREE **ptree;
2462
2502
  TRP_INDEX_MERGE *imerge_trp= NULL;
2463
 
  uint32_t n_child_scans= imerge->trees_next - imerge->trees;
 
2503
  uint n_child_scans= imerge->trees_next - imerge->trees;
2464
2504
  TRP_RANGE **range_scans;
2465
2505
  TRP_RANGE **cur_child;
2466
2506
  TRP_RANGE **cpk_scan= NULL;
2471
2511
  bool pk_is_clustered= param->table->file->primary_key_is_clustered();
2472
2512
  bool all_scans_ror_able= true;
2473
2513
  bool all_scans_rors= true;
2474
 
  uint32_t unique_calc_buff_size;
 
2514
  uint unique_calc_buff_size;
2475
2515
  TABLE_READ_PLAN **roru_read_plans;
2476
2516
  TABLE_READ_PLAN **cur_roru_plan;
2477
2517
  double roru_index_costs;
2478
2518
  ha_rows roru_total_records;
2479
2519
  double roru_intersect_part= 1.0;
 
2520
  DBUG_ENTER("get_best_disjunct_quick");
 
2521
  DBUG_PRINT("info", ("Full table scan cost: %g", read_time));
2480
2522
 
2481
2523
  if (!(range_scans= (TRP_RANGE**)alloc_root(param->mem_root,
2482
2524
                                             sizeof(TRP_RANGE*)*
2483
2525
                                             n_child_scans)))
2484
 
    return(NULL);
 
2526
    DBUG_RETURN(NULL);
2485
2527
  /*
2486
2528
    Collect best 'range' scan for each of disjuncts, and, while doing so,
2487
2529
    analyze possibility of ROR scans. Also calculate some values needed by
2491
2533
       ptree != imerge->trees_next;
2492
2534
       ptree++, cur_child++)
2493
2535
  {
2494
 
    print_sel_tree(param, *ptree, &(*ptree)->keys_map, "tree in SEL_IMERGE");
 
2536
    DBUG_EXECUTE("info", print_sel_tree(param, *ptree, &(*ptree)->keys_map,
 
2537
                                        "tree in SEL_IMERGE"););
2495
2538
    if (!(*cur_child= get_key_scans_params(param, *ptree, true, false, read_time)))
2496
2539
    {
2497
2540
      /*
2519
2562
      non_cpk_scan_records += (*cur_child)->records;
2520
2563
  }
2521
2564
 
 
2565
  DBUG_PRINT("info", ("index_merge scans cost %g", imerge_cost));
2522
2566
  if (imerge_too_expensive || (imerge_cost > read_time) ||
2523
2567
      ((non_cpk_scan_records+cpk_scan_records >= param->table->file->stats.records) && read_time != DBL_MAX))
2524
2568
  {
2526
2570
      Bail out if it is obvious that both index_merge and ROR-union will be
2527
2571
      more expensive
2528
2572
    */
2529
 
    return(NULL);
 
2573
    DBUG_PRINT("info", ("Sum of index_merge scans is more expensive than "
 
2574
                        "full table scan, bailing out"));
 
2575
    DBUG_RETURN(NULL);
2530
2576
  }
2531
2577
  if (all_scans_rors)
2532
2578
  {
2551
2597
                        &sweep_cost);
2552
2598
    imerge_cost += sweep_cost.total_cost();
2553
2599
  }
 
2600
  DBUG_PRINT("info",("index_merge cost with rowid-to-row scan: %g",
 
2601
                     imerge_cost));
2554
2602
  if (imerge_cost > read_time)
2555
2603
    goto build_ror_index_merge;
2556
2604
 
2563
2611
  {
2564
2612
    if (!(param->imerge_cost_buff= (uint*)alloc_root(param->mem_root,
2565
2613
                                                     unique_calc_buff_size)))
2566
 
      return(NULL);
 
2614
      DBUG_RETURN(NULL);
2567
2615
    param->imerge_cost_buff_size= unique_calc_buff_size;
2568
2616
  }
2569
2617
 
2571
2619
    Unique::get_use_cost(param->imerge_cost_buff, (uint)non_cpk_scan_records,
2572
2620
                         param->table->file->ref_length,
2573
2621
                         param->thd->variables.sortbuff_size);
 
2622
  DBUG_PRINT("info",("index_merge total cost: %g (wanted: less then %g)",
 
2623
                     imerge_cost, read_time));
2574
2624
  if (imerge_cost < read_time)
2575
2625
  {
2576
2626
    if ((imerge_trp= new (param->mem_root)TRP_INDEX_MERGE))
2577
2627
    {
2578
2628
      imerge_trp->read_cost= imerge_cost;
2579
2629
      imerge_trp->records= non_cpk_scan_records + cpk_scan_records;
2580
 
      imerge_trp->records= cmin(imerge_trp->records,
 
2630
      imerge_trp->records= min(imerge_trp->records,
2581
2631
                               param->table->file->stats.records);
2582
2632
      imerge_trp->range_scans= range_scans;
2583
2633
      imerge_trp->range_scans_end= range_scans + n_child_scans;
2587
2637
 
2588
2638
build_ror_index_merge:
2589
2639
  if (!all_scans_ror_able || param->thd->lex->sql_command == SQLCOM_DELETE)
2590
 
    return(imerge_trp);
 
2640
    DBUG_RETURN(imerge_trp);
2591
2641
 
2592
2642
  /* Ok, it is possible to build a ROR-union, try it. */
2593
2643
  bool dummy;
2595
2645
          (TABLE_READ_PLAN**)alloc_root(param->mem_root,
2596
2646
                                        sizeof(TABLE_READ_PLAN*)*
2597
2647
                                        n_child_scans)))
2598
 
    return(imerge_trp);
 
2648
    DBUG_RETURN(imerge_trp);
2599
2649
skip_to_ror_scan:
2600
2650
  roru_index_costs= 0.0;
2601
2651
  roru_total_records= 0;
2631
2681
      if (prev_plan->is_ror)
2632
2682
        *cur_roru_plan= prev_plan;
2633
2683
      else
2634
 
        return(imerge_trp);
 
2684
        DBUG_RETURN(imerge_trp);
2635
2685
      roru_index_costs += (*cur_roru_plan)->read_cost;
2636
2686
    }
2637
2687
    else
2671
2721
                     sweep_cost.total_cost();
2672
2722
  }
2673
2723
 
 
2724
  DBUG_PRINT("info", ("ROR-union: cost %g, %d members", roru_total_cost,
 
2725
                      n_child_scans));
2674
2726
  TRP_ROR_UNION* roru;
2675
2727
  if (roru_total_cost < read_time)
2676
2728
  {
2680
2732
      roru->last_ror= roru_read_plans + n_child_scans;
2681
2733
      roru->read_cost= roru_total_cost;
2682
2734
      roru->records= roru_total_records;
2683
 
      return(roru);
 
2735
      DBUG_RETURN(roru);
2684
2736
    }
2685
2737
  }
2686
 
  return(imerge_trp);
 
2738
  DBUG_RETURN(imerge_trp);
2687
2739
}
2688
2740
 
2689
2741
 
2690
2742
typedef struct st_ror_scan_info
2691
2743
{
2692
 
  uint32_t      idx;      /* # of used key in param->keys */
2693
 
  uint32_t      keynr;    /* # of used key in table */
 
2744
  uint      idx;      /* # of used key in param->keys */
 
2745
  uint      keynr;    /* # of used key in table */
2694
2746
  ha_rows   records;  /* estimate of # records this scan will return */
2695
2747
 
2696
2748
  /* Set of intervals over key fields that will be used for row retrieval. */
2698
2750
 
2699
2751
  /* Fields used in the query and covered by this ROR scan. */
2700
2752
  MY_BITMAP covered_fields;
2701
 
  uint32_t      used_fields_covered; /* # of set bits in covered_fields */
 
2753
  uint      used_fields_covered; /* # of set bits in covered_fields */
2702
2754
  int       key_rec_length; /* length of key record (including rowid) */
2703
2755
 
2704
2756
  /*
2706
2758
    (assuming there is no need to access full table records)
2707
2759
  */
2708
2760
  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 */
 
2761
  uint      first_uncovered_field; /* first unused bit in covered_fields */
 
2762
  uint      key_components; /* # of parts in the key */
2711
2763
} ROR_SCAN_INFO;
2712
2764
 
2713
2765
 
2731
2783
{
2732
2784
  ROR_SCAN_INFO *ror_scan;
2733
2785
  my_bitmap_map *bitmap_buf;
2734
 
  uint32_t keynr;
 
2786
  uint keynr;
 
2787
  DBUG_ENTER("make_ror_scan");
2735
2788
 
2736
2789
  if (!(ror_scan= (ROR_SCAN_INFO*)alloc_root(param->mem_root,
2737
2790
                                             sizeof(ROR_SCAN_INFO))))
2738
 
    return(NULL);
 
2791
    DBUG_RETURN(NULL);
2739
2792
 
2740
2793
  ror_scan->idx= idx;
2741
2794
  ror_scan->keynr= keynr= param->real_keynr[idx];
2746
2799
 
2747
2800
  if (!(bitmap_buf= (my_bitmap_map*) alloc_root(param->mem_root,
2748
2801
                                                param->fields_bitmap_size)))
2749
 
    return(NULL);
 
2802
    DBUG_RETURN(NULL);
2750
2803
 
2751
2804
  if (bitmap_init(&ror_scan->covered_fields, bitmap_buf,
2752
2805
                  param->table->s->fields, false))
2753
 
    return(NULL);
 
2806
    DBUG_RETURN(NULL);
2754
2807
  bitmap_clear_all(&ror_scan->covered_fields);
2755
2808
 
2756
2809
  KEY_PART_INFO *key_part= param->table->key_info[keynr].key_part;
2764
2817
  double rows= rows2double(param->table->quick_rows[ror_scan->keynr]);
2765
2818
  ror_scan->index_read_cost=
2766
2819
    param->table->file->index_only_read_time(ror_scan->keynr, rows);
2767
 
  return(ror_scan);
 
2820
  DBUG_RETURN(ror_scan);
2768
2821
}
2769
2822
 
2770
2823
 
2986
3039
{
2987
3040
  double selectivity_mult= 1.0;
2988
3041
  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;
 
3042
  uchar key_val[MAX_KEY_LENGTH+MAX_FIELD_WIDTH]; /* key values tuple */
 
3043
  uchar *key_ptr= key_val;
2991
3044
  SEL_ARG *sel_arg, *tuple_arg= NULL;
2992
3045
  key_part_map keypart_map= 0;
2993
3046
  bool cur_covered;
3000
3053
  max_range.key= key_val;
3001
3054
  max_range.flag= HA_READ_AFTER_KEY;
3002
3055
  ha_rows prev_records= info->param->table->file->stats.records;
 
3056
  DBUG_ENTER("ror_scan_selectivity");
3003
3057
 
3004
3058
  for (sel_arg= scan->sel_arg; sel_arg;
3005
3059
       sel_arg= sel_arg->next_key_part)
3006
3060
  {
 
3061
    DBUG_PRINT("info",("sel_arg step"));
3007
3062
    cur_covered= test(bitmap_is_set(&info->covered_fields,
3008
3063
                                    key_part[sel_arg->part].fieldnr-1));
3009
3064
    if (cur_covered != prev_covered)
3032
3087
      {
3033
3088
        /* uncovered -> covered */
3034
3089
        double tmp= rows2double(records)/rows2double(prev_records);
 
3090
        DBUG_PRINT("info", ("Selectivity multiplier: %g", tmp));
3035
3091
        selectivity_mult *= tmp;
3036
3092
        prev_records= HA_POS_ERROR;
3037
3093
      }
3047
3103
  {
3048
3104
    double tmp= rows2double(info->param->table->quick_rows[scan->keynr]) /
3049
3105
                rows2double(prev_records);
 
3106
    DBUG_PRINT("info", ("Selectivity multiplier: %g", tmp));
3050
3107
    selectivity_mult *= tmp;
3051
3108
  }
3052
 
  return(selectivity_mult);
 
3109
  DBUG_PRINT("info", ("Returning multiplier: %g", selectivity_mult));
 
3110
  DBUG_RETURN(selectivity_mult);
3053
3111
}
3054
3112
 
3055
3113
 
3094
3152
{
3095
3153
  double selectivity_mult= 1.0;
3096
3154
 
 
3155
  DBUG_ENTER("ror_intersect_add");
 
3156
  DBUG_PRINT("info", ("Current out_rows= %g", info->out_rows));
 
3157
  DBUG_PRINT("info", ("Adding scan on %s",
 
3158
                      info->param->table->key_info[ror_scan->keynr].name));
 
3159
  DBUG_PRINT("info", ("is_cpk_scan: %d",is_cpk_scan));
 
3160
 
3097
3161
  selectivity_mult = ror_scan_selectivity(info, ror_scan);
3098
3162
  if (selectivity_mult == 1.0)
3099
3163
  {
3100
3164
    /* Don't add this scan if it doesn't improve selectivity. */
3101
 
    return(false);
 
3165
    DBUG_PRINT("info", ("The scan doesn't improve selectivity."));
 
3166
    DBUG_RETURN(false);
3102
3167
  }
3103
3168
  
3104
3169
  info->out_rows *= selectivity_mult;
3121
3186
    if (!info->is_covering && bitmap_is_subset(&info->param->needed_fields,
3122
3187
                                               &info->covered_fields))
3123
3188
    {
 
3189
      DBUG_PRINT("info", ("ROR-intersect is covering now"));
3124
3190
      info->is_covering= true;
3125
3191
    }
3126
3192
  }
3127
3193
 
3128
3194
  info->total_cost= info->index_scan_costs;
 
3195
  DBUG_PRINT("info", ("info->total_cost: %g", info->total_cost));
3129
3196
  if (!info->is_covering)
3130
3197
  {
3131
3198
    COST_VECT sweep_cost;
3134
3201
    get_sweep_read_cost(info->param->table, double2rows(info->out_rows),
3135
3202
                        is_interrupted, &sweep_cost);
3136
3203
    info->total_cost += sweep_cost.total_cost();
 
3204
    DBUG_PRINT("info", ("info->total_cost= %g", info->total_cost));
3137
3205
  }
3138
 
  return(true);
 
3206
  DBUG_PRINT("info", ("New out_rows: %g", info->out_rows));
 
3207
  DBUG_PRINT("info", ("New cost: %g, %scovering", info->total_cost,
 
3208
                      info->is_covering?"" : "non-"));
 
3209
  DBUG_RETURN(true);
3139
3210
}
3140
3211
 
3141
3212
 
3208
3279
                                          double read_time,
3209
3280
                                          bool *are_all_covering)
3210
3281
{
3211
 
  uint32_t idx;
 
3282
  uint idx;
3212
3283
  double min_cost= DBL_MAX;
 
3284
  DBUG_ENTER("get_best_ror_intersect");
3213
3285
 
3214
3286
  if ((tree->n_ror_scans < 2) || !param->table->file->stats.records)
3215
 
    return(NULL);
 
3287
    DBUG_RETURN(NULL);
3216
3288
 
3217
3289
  /*
3218
3290
    Step1: Collect ROR-able SEL_ARGs and create ROR_SCAN_INFO for each of 
3220
3292
  */
3221
3293
  ROR_SCAN_INFO **cur_ror_scan;
3222
3294
  ROR_SCAN_INFO *cpk_scan= NULL;
3223
 
  uint32_t cpk_no;
 
3295
  uint cpk_no;
3224
3296
  bool cpk_scan_used= false;
3225
3297
 
3226
3298
  if (!(tree->ror_scans= (ROR_SCAN_INFO**)alloc_root(param->mem_root,
3247
3319
  }
3248
3320
 
3249
3321
  tree->ror_scans_end= cur_ror_scan;
3250
 
  print_ror_scans_arr(param->table, "original",
 
3322
  DBUG_EXECUTE("info",print_ror_scans_arr(param->table, "original",
3251
3323
                                          tree->ror_scans,
3252
 
                                          tree->ror_scans_end);
 
3324
                                          tree->ror_scans_end););
3253
3325
  /*
3254
3326
    Ok, [ror_scans, ror_scans_end) is array of ptrs to initialized
3255
3327
    ROR_SCAN_INFO's.
3257
3329
  */
3258
3330
  my_qsort(tree->ror_scans, tree->n_ror_scans, sizeof(ROR_SCAN_INFO*),
3259
3331
           (qsort_cmp)cmp_ror_scan_info);
3260
 
  print_ror_scans_arr(param->table, "ordered",
 
3332
  DBUG_EXECUTE("info",print_ror_scans_arr(param->table, "ordered",
3261
3333
                                          tree->ror_scans,
3262
 
                                          tree->ror_scans_end);
 
3334
                                          tree->ror_scans_end););
3263
3335
 
3264
3336
  ROR_SCAN_INFO **intersect_scans; /* ROR scans used in index intersection */
3265
3337
  ROR_SCAN_INFO **intersect_scans_end;
3301
3373
 
3302
3374
  if (intersect_scans_best == intersect_scans)
3303
3375
  {
3304
 
    return(NULL);
 
3376
    DBUG_PRINT("info", ("None of scans increase selectivity"));
 
3377
    DBUG_RETURN(NULL);
3305
3378
  }
3306
3379
    
3307
 
  print_ror_scans_arr(param->table,
 
3380
  DBUG_EXECUTE("info",print_ror_scans_arr(param->table,
3308
3381
                                          "best ROR-intersection",
3309
3382
                                          intersect_scans,
3310
 
                                          intersect_scans_best);
 
3383
                                          intersect_scans_best););
3311
3384
 
3312
3385
  *are_all_covering= intersect->is_covering;
3313
 
  uint32_t best_num= intersect_scans_best - intersect_scans;
 
3386
  uint best_num= intersect_scans_best - intersect_scans;
3314
3387
  ror_intersect_cpy(intersect, intersect_best);
3315
3388
 
3316
3389
  /*
3333
3406
  if (min_cost < read_time && (cpk_scan_used || best_num > 1))
3334
3407
  {
3335
3408
    if (!(trp= new (param->mem_root) TRP_ROR_INTERSECT))
3336
 
      return(trp);
 
3409
      DBUG_RETURN(trp);
3337
3410
    if (!(trp->first_scan=
3338
3411
           (ROR_SCAN_INFO**)alloc_root(param->mem_root,
3339
3412
                                       sizeof(ROR_SCAN_INFO*)*best_num)))
3340
 
      return(NULL);
 
3413
      DBUG_RETURN(NULL);
3341
3414
    memcpy(trp->first_scan, intersect_scans, best_num*sizeof(ROR_SCAN_INFO*));
3342
3415
    trp->last_scan=  trp->first_scan + best_num;
3343
3416
    trp->is_covering= intersect_best->is_covering;
3350
3423
    trp->records= best_rows;
3351
3424
    trp->index_scan_costs= intersect_best->index_scan_costs;
3352
3425
    trp->cpk_scan= cpk_scan_used? cpk_scan: NULL;
 
3426
    DBUG_PRINT("info", ("Returning non-covering ROR-intersect plan:"
 
3427
                        "cost %g, records %lu",
 
3428
                        trp->read_cost, (ulong) trp->records));
3353
3429
  }
3354
 
  return(trp);
 
3430
  DBUG_RETURN(trp);
3355
3431
}
3356
3432
 
3357
3433
 
3395
3471
{
3396
3472
  ROR_SCAN_INFO **ror_scan_mark;
3397
3473
  ROR_SCAN_INFO **ror_scans_end= tree->ror_scans_end;
 
3474
  DBUG_ENTER("get_best_covering_ror_intersect");
3398
3475
 
3399
3476
  for (ROR_SCAN_INFO **scan= tree->ror_scans; scan != ror_scans_end; ++scan)
3400
3477
    (*scan)->key_components=
3415
3492
  if (!covered_fields->bitmap ||
3416
3493
      bitmap_init(covered_fields, covered_fields->bitmap,
3417
3494
                  param->table->s->fields, false))
3418
 
    return(0);
 
3495
    DBUG_RETURN(0);
3419
3496
  bitmap_clear_all(covered_fields);
3420
3497
 
3421
3498
  double total_cost= 0.0f;
3422
3499
  ha_rows records=0;
3423
3500
  bool all_covered;
3424
3501
 
3425
 
  print_ror_scans_arr(param->table,
 
3502
  DBUG_PRINT("info", ("Building covering ROR-intersection"));
 
3503
  DBUG_EXECUTE("info", print_ror_scans_arr(param->table,
3426
3504
                                           "building covering ROR-I",
3427
 
                                           ror_scan_mark, ror_scans_end);
 
3505
                                           ror_scan_mark, ror_scans_end););
3428
3506
  do
3429
3507
  {
3430
3508
    /*
3445
3523
    my_qsort(ror_scan_mark, ror_scans_end-ror_scan_mark, sizeof(ROR_SCAN_INFO*),
3446
3524
             (qsort_cmp)cmp_ror_scan_info_covering);
3447
3525
 
3448
 
    print_ror_scans_arr(param->table,
 
3526
    DBUG_EXECUTE("info", print_ror_scans_arr(param->table,
3449
3527
                                             "remaining scans",
3450
 
                                             ror_scan_mark, ror_scans_end);
 
3528
                                             ror_scan_mark, ror_scans_end););
3451
3529
 
3452
3530
    /* I=I-first(I) */
3453
3531
    total_cost += (*ror_scan_mark)->index_read_cost;
3454
3532
    records += (*ror_scan_mark)->records;
 
3533
    DBUG_PRINT("info", ("Adding scan on %s",
 
3534
                        param->table->key_info[(*ror_scan_mark)->keynr].name));
3455
3535
    if (total_cost > read_time)
3456
 
      return(NULL);
 
3536
      DBUG_RETURN(NULL);
3457
3537
    /* F=F-covered by first(I) */
3458
3538
    bitmap_union(covered_fields, &(*ror_scan_mark)->covered_fields);
3459
3539
    all_covered= bitmap_is_subset(&param->needed_fields, covered_fields);
3460
3540
  } while ((++ror_scan_mark < ror_scans_end) && !all_covered);
3461
3541
  
3462
3542
  if (!all_covered || (ror_scan_mark - tree->ror_scans) == 1)
3463
 
    return(NULL);
 
3543
    DBUG_RETURN(NULL);
3464
3544
 
3465
3545
  /*
3466
3546
    Ok, [tree->ror_scans .. ror_scan) holds covering index_intersection with
3467
3547
    cost total_cost.
3468
3548
  */
3469
 
  print_ror_scans_arr(param->table,
 
3549
  DBUG_PRINT("info", ("Covering ROR-intersect scans cost: %g", total_cost));
 
3550
  DBUG_EXECUTE("info", print_ror_scans_arr(param->table,
3470
3551
                                           "creating covering ROR-intersect",
3471
 
                                           tree->ror_scans, ror_scan_mark);
 
3552
                                           tree->ror_scans, ror_scan_mark););
3472
3553
 
3473
3554
  /* Add priority queue use cost. */
3474
3555
  total_cost += rows2double(records)*
3475
3556
                log((double)(ror_scan_mark - tree->ror_scans)) /
3476
3557
                (TIME_FOR_COMPARE_ROWID * M_LN2);
 
3558
  DBUG_PRINT("info", ("Covering ROR-intersect full cost: %g", total_cost));
3477
3559
 
3478
3560
  if (total_cost > read_time)
3479
 
    return(NULL);
 
3561
    DBUG_RETURN(NULL);
3480
3562
 
3481
3563
  TRP_ROR_INTERSECT *trp;
3482
3564
  if (!(trp= new (param->mem_root) TRP_ROR_INTERSECT))
3483
 
    return(trp);
3484
 
  uint32_t best_num= (ror_scan_mark - tree->ror_scans);
 
3565
    DBUG_RETURN(trp);
 
3566
  uint best_num= (ror_scan_mark - tree->ror_scans);
3485
3567
  if (!(trp->first_scan= (ROR_SCAN_INFO**)alloc_root(param->mem_root,
3486
3568
                                                     sizeof(ROR_SCAN_INFO*)*
3487
3569
                                                     best_num)))
3488
 
    return(NULL);
 
3570
    DBUG_RETURN(NULL);
3489
3571
  memcpy(trp->first_scan, tree->ror_scans, best_num*sizeof(ROR_SCAN_INFO*));
3490
3572
  trp->last_scan=  trp->first_scan + best_num;
3491
3573
  trp->is_covering= true;
3494
3576
  trp->cpk_scan= NULL;
3495
3577
  set_if_smaller(param->table->quick_condition_rows, records); 
3496
3578
 
3497
 
  return(trp);
 
3579
  DBUG_PRINT("info",
 
3580
             ("Returning covering ROR-intersect plan: cost %g, records %lu",
 
3581
              trp->read_cost, (ulong) trp->records));
 
3582
  DBUG_RETURN(trp);
3498
3583
}
3499
3584
 
3500
3585
 
3529
3614
                                       bool update_tbl_stats,
3530
3615
                                       double read_time)
3531
3616
{
3532
 
  uint32_t idx;
 
3617
  uint idx;
3533
3618
  SEL_ARG **key,**end, **key_to_read= NULL;
3534
3619
  ha_rows best_records= 0;
3535
 
  uint32_t    best_mrr_flags= 0, best_buf_size= 0;
 
3620
  uint    best_mrr_flags= 0, best_buf_size= 0;
3536
3621
  TRP_RANGE* read_plan= NULL;
 
3622
  DBUG_ENTER("get_key_scans_params");
3537
3623
  /*
3538
3624
    Note that there may be trees that have type SEL_TREE::KEY but contain no
3539
3625
    key reads at all, e.g. tree for expression "key1 is not null" where key1
3540
3626
    is defined as "not null".
3541
3627
  */
3542
 
  print_sel_tree(param, tree, &tree->keys_map, "tree scans");
 
3628
  DBUG_EXECUTE("info", print_sel_tree(param, tree, &tree->keys_map,
 
3629
                                      "tree scans"););
3543
3630
  tree->ror_scans_map.clear_all();
3544
3631
  tree->n_ror_scans= 0;
3545
3632
  for (idx= 0,key=tree->keys, end=key+param->keys; key != end; key++,idx++)
3549
3636
      ha_rows found_records;
3550
3637
      COST_VECT cost;
3551
3638
      double found_read_time;
3552
 
      uint32_t mrr_flags, buf_size;
3553
 
      uint32_t keynr= param->real_keynr[idx];
 
3639
      uint mrr_flags, buf_size;
 
3640
      uint keynr= param->real_keynr[idx];
3554
3641
      if ((*key)->type == SEL_ARG::MAYBE_KEY ||
3555
3642
          (*key)->maybe_flag)
3556
3643
        param->needed_reg->set_bit(keynr);
3578
3665
    }
3579
3666
  }
3580
3667
 
3581
 
  print_sel_tree(param, tree, &tree->ror_scans_map, "ROR scans");
 
3668
  DBUG_EXECUTE("info", print_sel_tree(param, tree, &tree->ror_scans_map,
 
3669
                                      "ROR scans"););
3582
3670
  if (key_to_read)
3583
3671
  {
3584
3672
    idx= key_to_read - tree->keys;
3589
3677
      read_plan->is_ror= tree->ror_scans_map.is_set(idx);
3590
3678
      read_plan->read_cost= read_time;
3591
3679
      read_plan->mrr_buf_size= best_buf_size;
 
3680
      DBUG_PRINT("info",
 
3681
                 ("Returning range plan for key %s, cost %g, records %lu",
 
3682
                  param->table->key_info[param->real_keynr[idx]].name,
 
3683
                  read_plan->read_cost, (ulong) read_plan->records));
3592
3684
    }
3593
3685
  }
 
3686
  else
 
3687
    DBUG_PRINT("info", ("No 'range' table read plan found"));
3594
3688
 
3595
 
  return(read_plan);
 
3689
  DBUG_RETURN(read_plan);
3596
3690
}
3597
3691
 
3598
3692
 
3599
3693
QUICK_SELECT_I *TRP_INDEX_MERGE::make_quick(PARAM *param,
3600
 
                                            bool retrieve_full_rows __attribute__((unused)),
3601
 
                                            MEM_ROOT *parent_alloc __attribute__((unused)))
 
3694
                                            bool retrieve_full_rows,
 
3695
                                            MEM_ROOT *parent_alloc)
3602
3696
{
3603
3697
  QUICK_INDEX_MERGE_SELECT *quick_imerge;
3604
3698
  QUICK_RANGE_SELECT *quick;
3629
3723
{
3630
3724
  QUICK_ROR_INTERSECT_SELECT *quick_intrsect;
3631
3725
  QUICK_RANGE_SELECT *quick;
 
3726
  DBUG_ENTER("TRP_ROR_INTERSECT::make_quick");
3632
3727
  MEM_ROOT *alloc;
3633
3728
 
3634
3729
  if ((quick_intrsect=
3637
3732
                                         false),
3638
3733
                                        parent_alloc)))
3639
3734
  {
3640
 
    print_ror_scans_arr(param->table,
 
3735
    DBUG_EXECUTE("info", print_ror_scans_arr(param->table,
3641
3736
                                             "creating ROR-intersect",
3642
 
                                             first_scan, last_scan);
 
3737
                                             first_scan, last_scan););
3643
3738
    alloc= parent_alloc? parent_alloc: &quick_intrsect->alloc;
3644
3739
    for (; first_scan != last_scan;++first_scan)
3645
3740
    {
3650
3745
          quick_intrsect->push_quick_back(quick))
3651
3746
      {
3652
3747
        delete quick_intrsect;
3653
 
        return(NULL);
 
3748
        DBUG_RETURN(NULL);
3654
3749
      }
3655
3750
    }
3656
3751
    if (cpk_scan)
3661
3756
                                    0, alloc)))
3662
3757
      {
3663
3758
        delete quick_intrsect;
3664
 
        return(NULL);
 
3759
        DBUG_RETURN(NULL);
3665
3760
      }
3666
3761
      quick->file= NULL; 
3667
3762
      quick_intrsect->cpk_quick= quick;
3669
3764
    quick_intrsect->records= records;
3670
3765
    quick_intrsect->read_time= read_cost;
3671
3766
  }
3672
 
  return(quick_intrsect);
 
3767
  DBUG_RETURN(quick_intrsect);
3673
3768
}
3674
3769
 
3675
3770
 
3676
3771
QUICK_SELECT_I *TRP_ROR_UNION::make_quick(PARAM *param,
3677
 
                                          bool retrieve_full_rows __attribute__((unused)),
3678
 
                                          MEM_ROOT *parent_alloc __attribute__((unused)))
 
3772
                                          bool retrieve_full_rows,
 
3773
                                          MEM_ROOT *parent_alloc)
3679
3774
{
3680
3775
  QUICK_ROR_UNION_SELECT *quick_roru;
3681
3776
  TABLE_READ_PLAN **scan;
3682
3777
  QUICK_SELECT_I *quick;
 
3778
  DBUG_ENTER("TRP_ROR_UNION::make_quick");
3683
3779
  /*
3684
3780
    It is impossible to construct a ROR-union that will not retrieve full
3685
3781
    rows, ignore retrieve_full_rows parameter.
3690
3786
    {
3691
3787
      if (!(quick= (*scan)->make_quick(param, false, &quick_roru->alloc)) ||
3692
3788
          quick_roru->push_quick_back(quick))
3693
 
        return(NULL);
 
3789
        DBUG_RETURN(NULL);
3694
3790
    }
3695
3791
    quick_roru->records= records;
3696
3792
    quick_roru->read_time= read_cost;
3697
3793
  }
3698
 
  return(quick_roru);
 
3794
  DBUG_RETURN(quick_roru);
3699
3795
}
3700
3796
 
3701
3797
 
3756
3852
                                  Item_result cmp_type, bool inv)
3757
3853
{
3758
3854
  SEL_TREE *tree= 0;
 
3855
  DBUG_ENTER("get_func_mm_tree");
3759
3856
 
3760
3857
  switch (cond_func->functype()) {
3761
3858
 
3856
3953
          break;
3857
3954
 
3858
3955
        /* Get a SEL_TREE for "(-inf|NULL) < X < c_0" interval.  */
3859
 
        uint32_t i=0;
 
3956
        uint i=0;
3860
3957
        do 
3861
3958
        {
3862
3959
          func->array->value_to_item(i, value_item);
3889
3986
            }
3890
3987
 
3891
3988
            /* Change all intervals to be "c_{i-1} < X < c_i" */
3892
 
            for (uint32_t idx= 0; idx < param->keys; idx++)
 
3989
            for (uint idx= 0; idx < param->keys; idx++)
3893
3990
            {
3894
3991
              SEL_ARG *new_interval, *last_val;
3895
3992
              if (((new_interval= tree2->keys[idx])) &&
3970
4067
  }
3971
4068
  }
3972
4069
 
3973
 
  return(tree);
 
4070
  DBUG_RETURN(tree);
3974
4071
}
3975
4072
 
3976
4073
 
4054
4151
  table_map ref_tables= 0;
4055
4152
  table_map param_comp= ~(param->prev_tables | param->read_tables |
4056
4153
                          param->current_table);
 
4154
  DBUG_ENTER("get_full_func_mm_tree");
4057
4155
 
4058
 
  for (uint32_t i= 0; i < cond_func->arg_count; i++)
 
4156
  for (uint i= 0; i < cond_func->arg_count; i++)
4059
4157
  {
4060
4158
    Item *arg= cond_func->arguments()[i]->real_item();
4061
4159
    if (arg != field_item)
4082
4180
      }
4083
4181
    }
4084
4182
  }
4085
 
  return(ftree);
 
4183
  DBUG_RETURN(ftree);
4086
4184
}
4087
4185
 
4088
4186
        /* make a select tree of all keys in condition */
4094
4192
  Item_field *field_item= 0;
4095
4193
  bool inv= false;
4096
4194
  Item *value= 0;
 
4195
  DBUG_ENTER("get_mm_tree");
4097
4196
 
4098
4197
  if (cond->type() == Item::COND_ITEM)
4099
4198
  {
4108
4207
        SEL_TREE *new_tree=get_mm_tree(param,item);
4109
4208
        if (param->thd->is_fatal_error || 
4110
4209
            param->alloced_sel_args > SEL_ARG::MAX_SEL_ARGS)
4111
 
          return(0);    // out of memory
 
4210
          DBUG_RETURN(0);       // out of memory
4112
4211
        tree=tree_and(param,tree,new_tree);
4113
4212
        if (tree && tree->type == SEL_TREE::IMPOSSIBLE)
4114
4213
          break;
4124
4223
        {
4125
4224
          SEL_TREE *new_tree=get_mm_tree(param,item);
4126
4225
          if (!new_tree)
4127
 
            return(0);  // out of memory
 
4226
            DBUG_RETURN(0);     // out of memory
4128
4227
          tree=tree_or(param,tree,new_tree);
4129
4228
          if (!tree || tree->type == SEL_TREE::ALWAYS)
4130
4229
            break;
4131
4230
        }
4132
4231
      }
4133
4232
    }
4134
 
    return(tree);
 
4233
    DBUG_RETURN(tree);
4135
4234
  }
4136
4235
  /* Here when simple cond */
4137
4236
  if (cond->const_item())
4147
4246
    tree= cond->val_int() ? new(tmp_root) SEL_TREE(SEL_TREE::ALWAYS) :
4148
4247
                            new(tmp_root) SEL_TREE(SEL_TREE::IMPOSSIBLE);
4149
4248
    param->thd->mem_root= tmp_root;
4150
 
    return(tree);
 
4249
    DBUG_RETURN(tree);
4151
4250
  }
4152
4251
 
4153
4252
  table_map ref_tables= 0;
4158
4257
    ref_tables= cond->used_tables();
4159
4258
    if ((ref_tables & param->current_table) ||
4160
4259
        (ref_tables & ~(param->prev_tables | param->read_tables)))
4161
 
      return(0);
4162
 
    return(new SEL_TREE(SEL_TREE::MAYBE));
 
4260
      DBUG_RETURN(0);
 
4261
    DBUG_RETURN(new SEL_TREE(SEL_TREE::MAYBE));
4163
4262
  }
4164
4263
 
4165
4264
  Item_func *cond_func= (Item_func*) cond;
4167
4266
      cond_func->functype() == Item_func::IN_FUNC)
4168
4267
    inv= ((Item_func_opt_neg *) cond_func)->negated;
4169
4268
  else if (cond_func->select_optimize() == Item_func::OPTIMIZE_NONE)
4170
 
    return(0);                         
 
4269
    DBUG_RETURN(0);                            
4171
4270
 
4172
4271
  param->cond= cond;
4173
4272
 
4183
4282
      Concerning the code below see the NOTES section in
4184
4283
      the comments for the function get_full_func_mm_tree()
4185
4284
    */
4186
 
    for (uint32_t i= 1 ; i < cond_func->arg_count ; i++)
 
4285
    for (uint i= 1 ; i < cond_func->arg_count ; i++)
4187
4286
    {
4188
4287
      if (cond_func->arguments()[i]->real_item()->type() == Item::FIELD_ITEM)
4189
4288
      {
4190
4289
        field_item= (Item_field*) (cond_func->arguments()[i]->real_item());
4191
4290
        SEL_TREE *tmp= get_full_func_mm_tree(param, cond_func, 
4192
 
                                    field_item, (Item*)(intptr_t)i, inv);
 
4291
                                    field_item, (Item*)(intptr)i, inv);
4193
4292
        if (inv)
4194
4293
          tree= !tree ? tmp : tree_or(param, tree, tmp);
4195
4294
        else 
4208
4307
  {
4209
4308
    Item_func_in *func=(Item_func_in*) cond_func;
4210
4309
    if (func->key_item()->real_item()->type() != Item::FIELD_ITEM)
4211
 
      return(0);
 
4310
      DBUG_RETURN(0);
4212
4311
    field_item= (Item_field*) (func->key_item()->real_item());
4213
4312
    ftree= get_full_func_mm_tree(param, cond_func, field_item, NULL, inv);
4214
4313
    break;
4217
4316
  {
4218
4317
    Item_equal *item_equal= (Item_equal *) cond;    
4219
4318
    if (!(value= item_equal->get_const()))
4220
 
      return(0);
 
4319
      DBUG_RETURN(0);
4221
4320
    Item_equal_iterator it(*item_equal);
4222
4321
    ref_tables= value->used_tables();
4223
4322
    while ((field_item= it++))
4232
4331
      }
4233
4332
    }
4234
4333
    
4235
 
    return(ftree);
 
4334
    DBUG_RETURN(ftree);
4236
4335
  }
4237
4336
  default:
4238
4337
    if (cond_func->arguments()[0]->real_item()->type() == Item::FIELD_ITEM)
4248
4347
      value= cond_func->arguments()[0];
4249
4348
    }
4250
4349
    else
4251
 
      return(0);
 
4350
      DBUG_RETURN(0);
4252
4351
    ftree= get_full_func_mm_tree(param, cond_func, field_item, value, inv);
4253
4352
  }
4254
4353
 
4255
 
  return(ftree);
 
4354
  DBUG_RETURN(ftree);
4256
4355
}
4257
4356
 
4258
4357
 
4259
4358
static SEL_TREE *
4260
4359
get_mm_parts(RANGE_OPT_PARAM *param, COND *cond_func, Field *field,
4261
4360
             Item_func::Functype type,
4262
 
             Item *value,
4263
 
             Item_result cmp_type __attribute__((unused)))
 
4361
             Item *value, Item_result cmp_type)
4264
4362
{
 
4363
  DBUG_ENTER("get_mm_parts");
4265
4364
  if (field->table != param->table)
4266
 
    return(0);
 
4365
    DBUG_RETURN(0);
4267
4366
 
4268
4367
  KEY_PART *key_part = param->key_parts;
4269
4368
  KEY_PART *end = param->key_parts_end;
4270
4369
  SEL_TREE *tree=0;
4271
4370
  if (value &&
4272
4371
      value->used_tables() & ~(param->prev_tables | param->read_tables))
4273
 
    return(0);
 
4372
    DBUG_RETURN(0);
4274
4373
  for (; key_part != end ; key_part++)
4275
4374
  {
4276
4375
    if (field->eq(key_part->field))
4277
4376
    {
4278
4377
      SEL_ARG *sel_arg=0;
4279
4378
      if (!tree && !(tree=new SEL_TREE()))
4280
 
        return(0);                              // OOM
 
4379
        DBUG_RETURN(0);                         // OOM
4281
4380
      if (!value || !(value->used_tables() & ~param->read_tables))
4282
4381
      {
4283
4382
        sel_arg=get_mm_leaf(param,cond_func,
4287
4386
        if (sel_arg->type == SEL_ARG::IMPOSSIBLE)
4288
4387
        {
4289
4388
          tree->type=SEL_TREE::IMPOSSIBLE;
4290
 
          return(tree);
 
4389
          DBUG_RETURN(tree);
4291
4390
        }
4292
4391
      }
4293
4392
      else
4294
4393
      {
4295
4394
        // This key may be used later
4296
4395
        if (!(sel_arg= new SEL_ARG(SEL_ARG::MAYBE_KEY)))
4297
 
          return(0);                    // OOM
 
4396
          DBUG_RETURN(0);                       // OOM
4298
4397
      }
4299
 
      sel_arg->part=(unsigned char) key_part->part;
 
4398
      sel_arg->part=(uchar) key_part->part;
4300
4399
      tree->keys[key_part->key]=sel_add(tree->keys[key_part->key],sel_arg);
4301
4400
      tree->keys_map.set_bit(key_part->key);
4302
4401
    }
4303
4402
  }
4304
4403
  
4305
 
  return(tree);
 
4404
  DBUG_RETURN(tree);
4306
4405
}
4307
4406
 
4308
4407
 
4310
4409
get_mm_leaf(RANGE_OPT_PARAM *param, COND *conf_func, Field *field,
4311
4410
            KEY_PART *key_part, Item_func::Functype type,Item *value)
4312
4411
{
4313
 
  uint32_t maybe_null=(uint) field->real_maybe_null();
 
4412
  uint maybe_null=(uint) field->real_maybe_null();
4314
4413
  bool optimize_range;
4315
4414
  SEL_ARG *tree= 0;
4316
4415
  MEM_ROOT *alloc= param->mem_root;
4317
 
  unsigned char *str;
 
4416
  uchar *str;
4318
4417
  ulong orig_sql_mode;
4319
4418
  int err;
 
4419
  DBUG_ENTER("get_mm_leaf");
4320
4420
 
4321
4421
  /*
4322
4422
    We need to restore the runtime mem_root of the thread in this
4376
4476
  {
4377
4477
    bool like_error;
4378
4478
    char buff1[MAX_FIELD_WIDTH];
4379
 
    unsigned char *min_str,*max_str;
 
4479
    uchar *min_str,*max_str;
4380
4480
    String tmp(buff1,sizeof(buff1),value->collation.collation),*res;
4381
4481
    size_t length, offset, min_length, max_length;
4382
 
    uint32_t field_length= field->pack_length()+maybe_null;
 
4482
    uint field_length= field->pack_length()+maybe_null;
4383
4483
 
4384
4484
    if (!optimize_range)
4385
4485
      goto end;
4425
4525
        field_length= length;
4426
4526
    }
4427
4527
    length+=offset;
4428
 
    if (!(min_str= (unsigned char*) alloc_root(alloc, length*2)))
 
4528
    if (!(min_str= (uchar*) alloc_root(alloc, length*2)))
4429
4529
      goto end;
4430
4530
 
4431
4531
    max_str=min_str+length;
4468
4568
  /* For comparison purposes allow invalid dates like 2000-01-32 */
4469
4569
  orig_sql_mode= field->table->in_use->variables.sql_mode;
4470
4570
  if (value->real_item()->type() == Item::STRING_ITEM &&
4471
 
      (field->type() == DRIZZLE_TYPE_NEWDATE ||
4472
 
       field->type() == DRIZZLE_TYPE_DATETIME))
 
4571
      (field->type() == MYSQL_TYPE_DATE ||
 
4572
       field->type() == MYSQL_TYPE_DATETIME))
4473
4573
    field->table->in_use->variables.sql_mode|= MODE_INVALID_DATES;
4474
4574
  err= value->save_in_field_no_warnings(field, 1);
4475
4575
  if (err > 0)
4491
4591
          for the cases like int_field > 999999999999999999999999 as well.
4492
4592
        */
4493
4593
        tree= 0;
4494
 
        if (err == 3 && field->type() == DRIZZLE_TYPE_NEWDATE &&
 
4594
        if (err == 3 && field->type() == FIELD_TYPE_DATE &&
4495
4595
            (type == Item_func::GT_FUNC || type == Item_func::GE_FUNC ||
4496
4596
             type == Item_func::LT_FUNC || type == Item_func::LE_FUNC) )
4497
4597
        {
4543
4643
    goto end;
4544
4644
  }
4545
4645
  field->table->in_use->variables.sql_mode= orig_sql_mode;
4546
 
  str= (unsigned char*) alloc_root(alloc, key_part->store_length+1);
 
4646
  str= (uchar*) alloc_root(alloc, key_part->store_length+1);
4547
4647
  if (!str)
4548
4648
    goto end;
4549
4649
  if (maybe_null)
4550
 
    *str= (unsigned char) field->is_real_null();        // Set to 1 if null
 
4650
    *str= (uchar) field->is_real_null();        // Set to 1 if null
4551
4651
  field->get_key_image(str+maybe_null, key_part->length,
4552
4652
                       key_part->image_type);
4553
4653
  if (!(tree= new (alloc) SEL_ARG(field, str, str)))
4568
4668
      value->result_type() == INT_RESULT &&
4569
4669
      ((Field_num*)field)->unsigned_flag && !((Item_int*)value)->unsigned_flag)
4570
4670
  {
4571
 
    int64_t item_val= value->val_int();
 
4671
    longlong item_val= value->val_int();
4572
4672
    if (item_val < 0)
4573
4673
    {
4574
4674
      if (type == Item_func::LT_FUNC || type == Item_func::LE_FUNC)
4613
4713
 
4614
4714
end:
4615
4715
  param->thd->mem_root= alloc;
4616
 
  return(tree);
 
4716
  DBUG_RETURN(tree);
4617
4717
}
4618
4718
 
4619
4719
 
4672
4772
static SEL_TREE *
4673
4773
tree_and(RANGE_OPT_PARAM *param,SEL_TREE *tree1,SEL_TREE *tree2)
4674
4774
{
 
4775
  DBUG_ENTER("tree_and");
4675
4776
  if (!tree1)
4676
 
    return(tree2);
 
4777
    DBUG_RETURN(tree2);
4677
4778
  if (!tree2)
4678
 
    return(tree1);
 
4779
    DBUG_RETURN(tree1);
4679
4780
  if (tree1->type == SEL_TREE::IMPOSSIBLE || tree2->type == SEL_TREE::ALWAYS)
4680
 
    return(tree1);
 
4781
    DBUG_RETURN(tree1);
4681
4782
  if (tree2->type == SEL_TREE::IMPOSSIBLE || tree1->type == SEL_TREE::ALWAYS)
4682
 
    return(tree2);
 
4783
    DBUG_RETURN(tree2);
4683
4784
  if (tree1->type == SEL_TREE::MAYBE)
4684
4785
  {
4685
4786
    if (tree2->type == SEL_TREE::KEY)
4686
4787
      tree2->type=SEL_TREE::KEY_SMALLER;
4687
 
    return(tree2);
 
4788
    DBUG_RETURN(tree2);
4688
4789
  }
4689
4790
  if (tree2->type == SEL_TREE::MAYBE)
4690
4791
  {
4691
4792
    tree1->type=SEL_TREE::KEY_SMALLER;
4692
 
    return(tree1);
 
4793
    DBUG_RETURN(tree1);
4693
4794
  }
4694
4795
  key_map  result_keys;
4695
4796
  result_keys.clear_all();
4699
4800
  for (key1= tree1->keys,key2= tree2->keys,end=key1+param->keys ;
4700
4801
       key1 != end ; key1++,key2++)
4701
4802
  {
4702
 
    uint32_t flag=0;
 
4803
    uint flag=0;
4703
4804
    if (*key1 || *key2)
4704
4805
    {
4705
4806
      if (*key1 && !(*key1)->simple_key())
4710
4811
      if (*key1 && (*key1)->type == SEL_ARG::IMPOSSIBLE)
4711
4812
      {
4712
4813
        tree1->type= SEL_TREE::IMPOSSIBLE;
4713
 
        return(tree1);
 
4814
        DBUG_RETURN(tree1);
4714
4815
      }
4715
4816
      result_keys.set_bit(key1 - tree1->keys);
4716
4817
#ifdef EXTRA_DEBUG
4724
4825
  if (!result_keys.is_clear_all())
4725
4826
  {
4726
4827
    tree1->merges.empty();
4727
 
    return(tree1);
 
4828
    DBUG_RETURN(tree1);
4728
4829
  }
4729
4830
 
4730
4831
  /* ok, both trees are index_merge trees */
4731
4832
  imerge_list_and_list(&tree1->merges, &tree2->merges);
4732
 
  return(tree1);
 
4833
  DBUG_RETURN(tree1);
4733
4834
}
4734
4835
 
4735
4836
 
4743
4844
                           RANGE_OPT_PARAM* param)
4744
4845
{
4745
4846
  key_map common_keys= tree1->keys_map;
 
4847
  DBUG_ENTER("sel_trees_can_be_ored");
4746
4848
  common_keys.intersect(tree2->keys_map);
4747
4849
 
4748
4850
  if (common_keys.is_clear_all())
4749
 
    return(false);
 
4851
    DBUG_RETURN(false);
4750
4852
 
4751
4853
  /* trees have a common key, check if they refer to same key part */
4752
4854
  SEL_ARG **key1,**key2;
4753
 
  for (uint32_t key_no=0; key_no < param->keys; key_no++)
 
4855
  for (uint key_no=0; key_no < param->keys; key_no++)
4754
4856
  {
4755
4857
    if (common_keys.is_set(key_no))
4756
4858
    {
4758
4860
      key2= tree2->keys + key_no;
4759
4861
      if ((*key1)->part == (*key2)->part)
4760
4862
      {
4761
 
        return(true);
 
4863
        DBUG_RETURN(true);
4762
4864
      }
4763
4865
    }
4764
4866
  }
4765
 
  return(false);
 
4867
  DBUG_RETURN(false);
4766
4868
}
4767
4869
 
4768
4870
 
4824
4926
static bool remove_nonrange_trees(RANGE_OPT_PARAM *param, SEL_TREE *tree)
4825
4927
{
4826
4928
  bool res= false;
4827
 
  for (uint32_t i=0; i < param->keys; i++)
 
4929
  for (uint i=0; i < param->keys; i++)
4828
4930
  {
4829
4931
    if (tree->keys[i])
4830
4932
    {
4844
4946
static SEL_TREE *
4845
4947
tree_or(RANGE_OPT_PARAM *param,SEL_TREE *tree1,SEL_TREE *tree2)
4846
4948
{
 
4949
  DBUG_ENTER("tree_or");
4847
4950
  if (!tree1 || !tree2)
4848
 
    return(0);
 
4951
    DBUG_RETURN(0);
4849
4952
  if (tree1->type == SEL_TREE::IMPOSSIBLE || tree2->type == SEL_TREE::ALWAYS)
4850
 
    return(tree2);
 
4953
    DBUG_RETURN(tree2);
4851
4954
  if (tree2->type == SEL_TREE::IMPOSSIBLE || tree1->type == SEL_TREE::ALWAYS)
4852
 
    return(tree1);
 
4955
    DBUG_RETURN(tree1);
4853
4956
  if (tree1->type == SEL_TREE::MAYBE)
4854
 
    return(tree1);                              // Can't use this
 
4957
    DBUG_RETURN(tree1);                         // Can't use this
4855
4958
  if (tree2->type == SEL_TREE::MAYBE)
4856
 
    return(tree2);
 
4959
    DBUG_RETURN(tree2);
4857
4960
 
4858
4961
  SEL_TREE *result= 0;
4859
4962
  key_map  result_keys;
4889
4992
        bool no_trees= remove_nonrange_trees(param, tree1);
4890
4993
        no_trees= no_trees || remove_nonrange_trees(param, tree2);
4891
4994
        if (no_trees)
4892
 
          return(new SEL_TREE(SEL_TREE::ALWAYS));
 
4995
          DBUG_RETURN(new SEL_TREE(SEL_TREE::ALWAYS));
4893
4996
      }
4894
4997
      SEL_IMERGE *merge;
4895
4998
      /* both trees are "range" trees, produce new index merge structure */
4912
5015
    {
4913
5016
      /* one tree is index merge tree and another is range tree */
4914
5017
      if (tree1->merges.is_empty())
4915
 
        std::swap(tree1, tree2);
 
5018
        swap_variables(SEL_TREE*, tree1, tree2);
4916
5019
      
4917
5020
      if (param->remove_jump_scans && remove_nonrange_trees(param, tree2))
4918
 
         return(new SEL_TREE(SEL_TREE::ALWAYS));
 
5021
         DBUG_RETURN(new SEL_TREE(SEL_TREE::ALWAYS));
4919
5022
      /* add tree2 to tree1->merges, checking if it collapses to ALWAYS */
4920
5023
      if (imerge_list_or_tree(param, &tree1->merges, tree2))
4921
5024
        result= new SEL_TREE(SEL_TREE::ALWAYS);
4923
5026
        result= tree1;
4924
5027
    }
4925
5028
  }
4926
 
  return(result);
 
5029
  DBUG_RETURN(result);
4927
5030
}
4928
5031
 
4929
5032
 
4931
5034
 
4932
5035
static SEL_ARG *
4933
5036
and_all_keys(RANGE_OPT_PARAM *param, SEL_ARG *key1, SEL_ARG *key2, 
4934
 
             uint32_t clone_flag)
 
5037
             uint clone_flag)
4935
5038
{
4936
5039
  SEL_ARG *next;
4937
5040
  ulong use_count=key1->use_count;
4988
5091
*/
4989
5092
 
4990
5093
static SEL_ARG *
4991
 
key_and(RANGE_OPT_PARAM *param, SEL_ARG *key1, SEL_ARG *key2, uint32_t clone_flag)
 
5094
key_and(RANGE_OPT_PARAM *param, SEL_ARG *key1, SEL_ARG *key2, uint clone_flag)
4992
5095
{
4993
5096
  if (!key1)
4994
5097
    return key2;
4998
5101
  {
4999
5102
    if (key1->part > key2->part)
5000
5103
    {
5001
 
      std::swap(key1, key2);
 
5104
      swap_variables(SEL_ARG *, key1, key2);
5002
5105
      clone_flag=swap_clone_flag(clone_flag);
5003
5106
    }
5004
5107
    // key1->part < key2->part
5014
5117
       key2->type != SEL_ARG::MAYBE_KEY) ||
5015
5118
      key1->type == SEL_ARG::MAYBE_KEY)
5016
5119
  {                                             // Put simple key in key2
5017
 
    std::swap(key1, key2);
 
5120
    swap_variables(SEL_ARG *, key1, key2);
5018
5121
    clone_flag=swap_clone_flag(clone_flag);
5019
5122
  }
5020
5123
 
5157
5260
  {
5158
5261
    if (key2->use_count == 0 || key1->elements > key2->elements)
5159
5262
    {
5160
 
      std::swap(key1,key2);
 
5263
      swap_variables(SEL_ARG *,key1,key2);
5161
5264
    }
5162
5265
    if (key1->use_count > 0 || !(key1=key1->clone_tree(param)))
5163
5266
      return 0;                                 // OOM
5242
5345
      }
5243
5346
    }
5244
5347
 
5245
 
    // tmp.max >= key2.min && tmp.min <= key.cmax(overlapping ranges)
 
5348
    // tmp.max >= key2.min && tmp.min <= key.max  (overlapping ranges)
5246
5349
    if (eq_tree(tmp->next_key_part,key2->next_key_part))
5247
5350
    {
5248
5351
      if (tmp->is_same(key2))
5485
5588
{
5486
5589
  enum leaf_color remove_color;
5487
5590
  SEL_ARG *root,*nod,**par,*fix_par;
 
5591
  DBUG_ENTER("tree_delete");
5488
5592
 
5489
5593
  root=this;
5490
5594
  this->parent= 0;
5534
5638
  }
5535
5639
 
5536
5640
  if (root == &null_element)
5537
 
    return(0);                          // Maybe root later
 
5641
    DBUG_RETURN(0);                             // Maybe root later
5538
5642
  if (remove_color == BLACK)
5539
5643
    root=rb_delete_fixup(root,nod,fix_par);
5540
5644
  test_rb_tree(root,root->parent);
5542
5646
  root->use_count=this->use_count;              // Fix root counters
5543
5647
  root->elements=this->elements-1;
5544
5648
  root->maybe_flag=this->maybe_flag;
5545
 
  return(root);
 
5649
  DBUG_RETURN(root);
5546
5650
}
5547
5651
 
5548
5652
 
5834
5938
 
5835
5939
void SEL_ARG::test_use_count(SEL_ARG *root)
5836
5940
{
5837
 
  uint32_t e_count=0;
 
5941
  uint e_count=0;
5838
5942
  if (this == root && use_count != 1)
5839
5943
  {
5840
5944
    sql_print_information("Use_count: Wrong count %lu for root",use_count);
5876
5980
    Pointers in min and max keys. They point to right-after-end of key
5877
5981
    images. The 0-th entry has these pointing to key tuple start.
5878
5982
  */
5879
 
  unsigned char *min_key, *max_key;
 
5983
  uchar *min_key, *max_key;
5880
5984
  
5881
5985
  /* 
5882
5986
    Flags, for {keypart0, keypart1, ... this_keypart} subtuple.
5883
5987
    min_key_flag may have NULL_RANGE set.
5884
5988
  */
5885
 
  uint32_t min_key_flag, max_key_flag;
 
5989
  uint min_key_flag, max_key_flag;
5886
5990
  
5887
5991
  /* Number of key parts */
5888
 
  uint32_t min_key_parts, max_key_parts;
 
5992
  uint min_key_parts, max_key_parts;
5889
5993
  SEL_ARG *key_tree;
5890
5994
} RANGE_SEQ_ENTRY;
5891
5995
 
5895
5999
*/
5896
6000
typedef struct st_sel_arg_range_seq
5897
6001
{
5898
 
  uint32_t keyno;      /* index of used tree in SEL_TREE structure */
5899
 
  uint32_t real_keyno; /* Number of the index in tables */
 
6002
  uint keyno;      /* index of used tree in SEL_TREE structure */
 
6003
  uint real_keyno; /* Number of the index in tables */
5900
6004
  PARAM *param;
5901
6005
  SEL_ARG *start; /* Root node of the traversed SEL_ARG* graph */
5902
6006
  
5920
6024
    Value of init_param
5921
6025
*/
5922
6026
 
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)))
 
6027
range_seq_t sel_arg_range_seq_init(void *init_param, uint n_ranges, uint flags)
5926
6028
{
5927
6029
  SEL_ARG_RANGE_SEQ *seq= (SEL_ARG_RANGE_SEQ*)init_param;
5928
6030
  seq->at_start= true;
5950
6052
  cur->min_key_parts= prev->min_key_parts;
5951
6053
  cur->max_key_parts= prev->max_key_parts;
5952
6054
 
5953
 
  uint16_t stor_length= arg->param->key[arg->keyno][key_tree->part].store_length;
 
6055
  uint16 stor_length= arg->param->key[arg->keyno][key_tree->part].store_length;
5954
6056
  cur->min_key_parts += key_tree->store_min(stor_length, &cur->min_key,
5955
6057
                                            prev->min_key_flag);
5956
6058
  cur->max_key_parts += key_tree->store_max(stor_length, &cur->max_key,
5989
6091
*/
5990
6092
 
5991
6093
//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)
 
6094
uint sel_arg_range_seq_next(range_seq_t rseq, KEY_MULTI_RANGE *range)
5993
6095
{
5994
6096
  SEL_ARG *key_tree;
5995
6097
  SEL_ARG_RANGE_SEQ *seq= (SEL_ARG_RANGE_SEQ*)rseq;
6045
6147
  {
6046
6148
    {
6047
6149
      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;
 
6150
      uint min_key_length= cur->min_key - seq->param->min_key;
 
6151
      uint max_key_length= cur->max_key - seq->param->max_key;
 
6152
      uint len= cur->min_key - cur[-1].min_key;
6051
6153
      if (!(min_key_length == max_key_length &&
6052
6154
            !memcmp(cur[-1].min_key, cur[-1].max_key, len) &&
6053
6155
            !key_tree->min_flag && !key_tree->max_flag))
6128
6230
    }
6129
6231
  }
6130
6232
  seq->param->range_count++;
6131
 
  seq->param->max_key_part=cmax(seq->param->max_key_part,(uint)key_tree->part);
 
6233
  seq->param->max_key_part=max(seq->param->max_key_part,key_tree->part);
6132
6234
  return 0;
6133
6235
}
6134
6236
 
6161
6263
*/
6162
6264
 
6163
6265
static
6164
 
ha_rows check_quick_select(PARAM *param, uint32_t idx, bool index_only,
 
6266
ha_rows check_quick_select(PARAM *param, uint idx, bool index_only,
6165
6267
                           SEL_ARG *tree, bool update_tbl_stats, 
6166
 
                           uint32_t *mrr_flags, uint32_t *bufsize, COST_VECT *cost)
 
6268
                           uint *mrr_flags, uint *bufsize, COST_VECT *cost)
6167
6269
{
6168
6270
  SEL_ARG_RANGE_SEQ seq;
6169
6271
  RANGE_SEQ_IF seq_if = {sel_arg_range_seq_init, sel_arg_range_seq_next};
6170
6272
  handler *file= param->table->file;
6171
6273
  ha_rows rows;
6172
 
  uint32_t keynr= param->real_keynr[idx];
 
6274
  uint keynr= param->real_keynr[idx];
 
6275
  DBUG_ENTER("check_quick_select");
6173
6276
  
6174
6277
  /* Handle cases when we don't have a valid non-empty list of range */
6175
6278
  if (!tree)
6176
 
    return(HA_POS_ERROR);
 
6279
    DBUG_RETURN(HA_POS_ERROR);
6177
6280
  if (tree->type == SEL_ARG::IMPOSSIBLE)
6178
 
    return(0L);
 
6281
    DBUG_RETURN(0L);
6179
6282
  if (tree->type != SEL_ARG::KEY_RANGE || tree->part != 0)
6180
 
    return(HA_POS_ERROR);
 
6283
    DBUG_RETURN(HA_POS_ERROR);
6181
6284
 
6182
6285
  seq.keyno= idx;
6183
6286
  seq.real_keyno= keynr;
6215
6318
      param->table->quick_key_parts[keynr]=param->max_key_part+1;
6216
6319
      param->table->quick_n_ranges[keynr]= param->range_count;
6217
6320
      param->table->quick_condition_rows=
6218
 
        cmin(param->table->quick_condition_rows, rows);
 
6321
        min(param->table->quick_condition_rows, rows);
6219
6322
    }
6220
6323
  }
6221
6324
  /* Figure out if the key scan is ROR (returns rows in ROWID order) or not */
6236
6339
      param->is_ror_scan= true;
6237
6340
  }
6238
6341
 
6239
 
  return(rows); //psergey-merge:todo: maintain first_null_comp.
 
6342
  DBUG_PRINT("exit", ("Records: %lu", (ulong) rows));
 
6343
  DBUG_RETURN(rows); //psergey-merge:todo: maintain first_null_comp.
6240
6344
}
6241
6345
 
6242
6346
 
6277
6381
    false  Otherwise
6278
6382
*/
6279
6383
 
6280
 
static bool is_key_scan_ror(PARAM *param, uint32_t keynr, uint8_t nparts)
 
6384
static bool is_key_scan_ror(PARAM *param, uint keynr, uint8 nparts)
6281
6385
{
6282
6386
  KEY *table_key= param->table->key_info + keynr;
6283
6387
  KEY_PART_INFO *key_part= table_key->key_part + nparts;
6284
6388
  KEY_PART_INFO *key_part_end= (table_key->key_part +
6285
6389
                                table_key->key_parts);
6286
 
  uint32_t pk_number;
 
6390
  uint pk_number;
6287
6391
  
6288
6392
  for (KEY_PART_INFO *kp= table_key->key_part; kp < key_part; kp++)
6289
6393
  {
6290
 
    uint16_t fieldnr= param->table->key_info[keynr].
 
6394
    uint16 fieldnr= param->table->key_info[keynr].
6291
6395
                    key_part[kp - table_key->key_part].fieldnr - 1;
6292
6396
    if (param->table->field[fieldnr]->key_length() != kp->length)
6293
6397
      return false;
6339
6443
*/
6340
6444
 
6341
6445
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)
 
6446
get_quick_select(PARAM *param,uint idx,SEL_ARG *key_tree, uint mrr_flags,
 
6447
                 uint mrr_buf_size, MEM_ROOT *parent_alloc)
6344
6448
{
6345
6449
  QUICK_RANGE_SELECT *quick;
6346
6450
  bool create_err= false;
 
6451
  DBUG_ENTER("get_quick_select");
6347
6452
 
6348
6453
  quick=new QUICK_RANGE_SELECT(param->thd, param->table,
6349
6454
                               param->real_keynr[idx],
6369
6474
                    param->table->key_info[param->real_keynr[idx]].key_parts);
6370
6475
    }
6371
6476
  }
6372
 
  return(quick);
 
6477
  DBUG_RETURN(quick);
6373
6478
}
6374
6479
 
6375
6480
 
6378
6483
*/
6379
6484
bool
6380
6485
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)
 
6486
               SEL_ARG *key_tree, uchar *min_key,uint min_key_flag,
 
6487
               uchar *max_key, uint max_key_flag)
6383
6488
{
6384
6489
  QUICK_RANGE *range;
6385
 
  uint32_t flag;
 
6490
  uint flag;
6386
6491
  int min_part= key_tree->part-1, // # of keypart values in min_key buffer
6387
6492
      max_part= key_tree->part-1; // # of keypart values in max_key buffer
6388
6493
 
6392
6497
                       min_key,min_key_flag, max_key, max_key_flag))
6393
6498
      return 1;
6394
6499
  }
6395
 
  unsigned char *tmp_min_key=min_key,*tmp_max_key=max_key;
 
6500
  uchar *tmp_min_key=min_key,*tmp_max_key=max_key;
6396
6501
  min_part+= key_tree->store_min(key[key_tree->part].store_length,
6397
6502
                                 &tmp_min_key,min_key_flag);
6398
6503
  max_part+= key_tree->store_max(key[key_tree->part].store_length,
6413
6518
      goto end;                                 // Ugly, but efficient
6414
6519
    }
6415
6520
    {
6416
 
      uint32_t tmp_min_flag=key_tree->min_flag,tmp_max_flag=key_tree->max_flag;
 
6521
      uint tmp_min_flag=key_tree->min_flag,tmp_max_flag=key_tree->max_flag;
6417
6522
      if (!tmp_min_flag)
6418
6523
        min_part+= key_tree->next_key_part->store_min_key(key, &tmp_min_key,
6419
6524
                                                          &tmp_min_flag);
6444
6549
  }
6445
6550
  if (flag == 0)
6446
6551
  {
6447
 
    uint32_t length= (uint) (tmp_min_key - param->min_key);
 
6552
    uint length= (uint) (tmp_min_key - param->min_key);
6448
6553
    if (length == (uint) (tmp_max_key - param->max_key) &&
6449
6554
        !memcmp(param->min_key,param->max_key,length))
6450
6555
    {
6477
6582
  set_if_bigger(quick->max_used_key_length, range->min_length);
6478
6583
  set_if_bigger(quick->max_used_key_length, range->max_length);
6479
6584
  set_if_bigger(quick->used_key_parts, (uint) key_tree->part+1);
6480
 
  if (insert_dynamic(&quick->ranges, (unsigned char*) &range))
 
6585
  if (insert_dynamic(&quick->ranges, (uchar*) &range))
6481
6586
    return 1;
6482
6587
 
6483
6588
 end:
6523
6628
    false  Otherwise
6524
6629
*/
6525
6630
 
6526
 
static bool null_part_in_key(KEY_PART *key_part, const unsigned char *key, uint32_t length)
 
6631
static bool null_part_in_key(KEY_PART *key_part, const uchar *key, uint length)
6527
6632
{
6528
 
  for (const unsigned char *end=key+length ;
 
6633
  for (const uchar *end=key+length ;
6529
6634
       key < end;
6530
6635
       key+= key_part++->store_length)
6531
6636
  {
6597
6702
    NULL on error.
6598
6703
*/
6599
6704
 
6600
 
QUICK_RANGE_SELECT *get_quick_select_for_ref(THD *thd, Table *table,
 
6705
QUICK_RANGE_SELECT *get_quick_select_for_ref(THD *thd, TABLE *table,
6601
6706
                                             TABLE_REF *ref, ha_rows records)
6602
6707
{
6603
6708
  MEM_ROOT *old_root, *alloc;
6605
6710
  KEY *key_info = &table->key_info[ref->key];
6606
6711
  KEY_PART *key_part;
6607
6712
  QUICK_RANGE *range;
6608
 
  uint32_t part;
 
6713
  uint part;
6609
6714
  bool create_err= false;
6610
6715
  COST_VECT cost;
6611
6716
 
6626
6731
    goto err;
6627
6732
  quick->records= records;
6628
6733
 
6629
 
  if ((cp_buffer_from_ref(thd, ref) && thd->is_fatal_error) ||
 
6734
  if ((cp_buffer_from_ref(thd, table, ref) && thd->is_fatal_error) ||
6630
6735
      !(range= new(alloc) QUICK_RANGE()))
6631
6736
    goto err;                                   // out of memory
6632
6737
 
6648
6753
    key_part->length=       key_info->key_part[part].length;
6649
6754
    key_part->store_length= key_info->key_part[part].store_length;
6650
6755
    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;
 
6756
    key_part->flag=         (uint8) key_info->key_part[part].key_part_flag;
6652
6757
  }
6653
 
  if (insert_dynamic(&quick->ranges,(unsigned char*)&range))
 
6758
  if (insert_dynamic(&quick->ranges,(uchar*)&range))
6654
6759
    goto err;
6655
6760
 
6656
6761
  /*
6671
6776
                      make_prev_keypart_map(ref->key_parts), EQ_RANGE)))
6672
6777
      goto err;
6673
6778
    *ref->null_ref_key= 0;              // Clear null byte
6674
 
    if (insert_dynamic(&quick->ranges,(unsigned char*)&null_range))
 
6779
    if (insert_dynamic(&quick->ranges,(uchar*)&null_range))
6675
6780
      goto err;
6676
6781
  }
6677
6782
 
6718
6823
  int result;
6719
6824
  Unique *unique;
6720
6825
  handler *file= head->file;
 
6826
  DBUG_ENTER("QUICK_INDEX_MERGE_SELECT::read_keys_and_merge");
6721
6827
 
6722
6828
  file->extra(HA_EXTRA_KEYREAD);
6723
6829
  head->prepare_for_position();
6724
6830
 
6725
6831
  cur_quick_it.rewind();
6726
6832
  cur_quick= cur_quick_it++;
6727
 
  assert(cur_quick != 0);
 
6833
  DBUG_ASSERT(cur_quick != 0);
6728
6834
  
6729
6835
  /*
6730
6836
    We reuse the same instance of handler so we need to call both init and 
6731
6837
    reset here.
6732
6838
  */
6733
6839
  if (cur_quick->init() || cur_quick->reset())
6734
 
    return(1);
 
6840
    DBUG_RETURN(1);
6735
6841
 
6736
6842
  unique= new Unique(refpos_order_cmp, (void *)file,
6737
6843
                     file->ref_length,
6738
6844
                     thd->variables.sortbuff_size);
6739
6845
  if (!unique)
6740
 
    return(1);
 
6846
    DBUG_RETURN(1);
6741
6847
  for (;;)
6742
6848
  {
6743
6849
    while ((result= cur_quick->get_next()) == HA_ERR_END_OF_FILE)
6750
6856
      if (cur_quick->file->inited != handler::NONE) 
6751
6857
        cur_quick->file->ha_index_end();
6752
6858
      if (cur_quick->init() || cur_quick->reset())
6753
 
        return(1);
 
6859
        DBUG_RETURN(1);
6754
6860
    }
6755
6861
 
6756
6862
    if (result)
6758
6864
      if (result != HA_ERR_END_OF_FILE)
6759
6865
      {
6760
6866
        cur_quick->range_end();
6761
 
        return(result);
 
6867
        DBUG_RETURN(result);
6762
6868
      }
6763
6869
      break;
6764
6870
    }
6765
6871
 
6766
6872
    if (thd->killed)
6767
 
      return(1);
 
6873
      DBUG_RETURN(1);
6768
6874
 
6769
6875
    /* skip row if it will be retrieved by clustered PK scan */
6770
6876
    if (pk_quick_select && pk_quick_select->row_in_ranges())
6773
6879
    cur_quick->file->position(cur_quick->record);
6774
6880
    result= unique->unique_add((char*)cur_quick->file->ref);
6775
6881
    if (result)
6776
 
      return(1);
 
6882
      DBUG_RETURN(1);
6777
6883
 
6778
6884
  }
6779
6885
 
 
6886
  DBUG_PRINT("info", ("ok"));
6780
6887
  /* ok, all row ids are in Unique */
6781
6888
  result= unique->get(head);
6782
6889
  delete unique;
6785
6892
  file->extra(HA_EXTRA_NO_KEYREAD);
6786
6893
  /* start table scan */
6787
6894
  init_read_record(&read_record, thd, head, (SQL_SELECT*) 0, 1, 1);
6788
 
  return(result);
 
6895
  DBUG_RETURN(result);
6789
6896
}
6790
6897
 
6791
6898
 
6801
6908
int QUICK_INDEX_MERGE_SELECT::get_next()
6802
6909
{
6803
6910
  int result;
 
6911
  DBUG_ENTER("QUICK_INDEX_MERGE_SELECT::get_next");
6804
6912
 
6805
6913
  if (doing_pk_scan)
6806
 
    return(pk_quick_select->get_next());
 
6914
    DBUG_RETURN(pk_quick_select->get_next());
6807
6915
 
6808
6916
  if ((result= read_record.read_record(&read_record)) == -1)
6809
6917
  {
6815
6923
      doing_pk_scan= true;
6816
6924
      if ((result= pk_quick_select->init()) ||
6817
6925
          (result= pk_quick_select->reset()))
6818
 
        return(result);
6819
 
      return(pk_quick_select->get_next());
 
6926
        DBUG_RETURN(result);
 
6927
      DBUG_RETURN(pk_quick_select->get_next());
6820
6928
    }
6821
6929
  }
6822
6930
 
6823
 
  return(result);
 
6931
  DBUG_RETURN(result);
6824
6932
}
6825
6933
 
6826
6934
 
6849
6957
  List_iterator_fast<QUICK_RANGE_SELECT> quick_it(quick_selects);
6850
6958
  QUICK_RANGE_SELECT* quick;
6851
6959
  int error, cmp;
6852
 
  uint32_t last_rowid_count=0;
 
6960
  uint last_rowid_count=0;
 
6961
  DBUG_ENTER("QUICK_ROR_INTERSECT_SELECT::get_next");
6853
6962
 
6854
6963
  do
6855
6964
  {
6862
6971
        error= quick->get_next();
6863
6972
    }
6864
6973
    if (error)
6865
 
      return(error);
 
6974
      DBUG_RETURN(error);
6866
6975
 
6867
6976
    quick->file->position(quick->record);
6868
6977
    memcpy(last_rowid, quick->file->ref, head->file->ref_length);
6879
6988
      do
6880
6989
      {
6881
6990
        if ((error= quick->get_next()))
6882
 
          return(error);
 
6991
          DBUG_RETURN(error);
6883
6992
        quick->file->position(quick->record);
6884
6993
        cmp= head->file->cmp_ref(quick->file->ref, last_rowid);
6885
6994
      } while (cmp < 0);
6893
7002
          while (!cpk_quick->row_in_ranges())
6894
7003
          {
6895
7004
            if ((error= quick->get_next()))
6896
 
              return(error);
 
7005
              DBUG_RETURN(error);
6897
7006
          }
6898
7007
        }
6899
7008
        memcpy(last_rowid, quick->file->ref, head->file->ref_length);
6910
7019
    if (need_to_fetch_row)
6911
7020
      error= head->file->rnd_pos(head->record[0], last_rowid);
6912
7021
  } while (error == HA_ERR_RECORD_DELETED);
6913
 
  return(error);
 
7022
  DBUG_RETURN(error);
6914
7023
}
6915
7024
 
6916
7025
 
6933
7042
{
6934
7043
  int error, dup_row;
6935
7044
  QUICK_SELECT_I *quick;
6936
 
  unsigned char *tmp;
 
7045
  uchar *tmp;
 
7046
  DBUG_ENTER("QUICK_ROR_UNION_SELECT::get_next");
6937
7047
 
6938
7048
  do
6939
7049
  {
6940
7050
    do
6941
7051
    {
6942
7052
      if (!queue.elements)
6943
 
        return(HA_ERR_END_OF_FILE);
 
7053
        DBUG_RETURN(HA_ERR_END_OF_FILE);
6944
7054
      /* Ok, we have a queue with >= 1 scans */
6945
7055
 
6946
7056
      quick= (QUICK_SELECT_I*)queue_top(&queue);
6950
7060
      if ((error= quick->get_next()))
6951
7061
      {
6952
7062
        if (error != HA_ERR_END_OF_FILE)
6953
 
          return(error);
 
7063
          DBUG_RETURN(error);
6954
7064
        queue_remove(&queue, 0);
6955
7065
      }
6956
7066
      else
6975
7085
 
6976
7086
    error= head->file->rnd_pos(quick->record, prev_rowid);
6977
7087
  } while (error == HA_ERR_RECORD_DELETED);
6978
 
  return(error);
 
7088
  DBUG_RETURN(error);
6979
7089
}
6980
7090
 
6981
7091
 
6982
7092
int QUICK_RANGE_SELECT::reset()
6983
7093
{
6984
 
  uint32_t  buf_size;
6985
 
  unsigned char *mrange_buff;
 
7094
  uint  buf_size;
 
7095
  uchar *mrange_buff;
6986
7096
  int   error;
6987
7097
  HANDLER_BUFFER empty_buf;
 
7098
  DBUG_ENTER("QUICK_RANGE_SELECT::reset");
6988
7099
  last_range= NULL;
6989
7100
  cur_range= (QUICK_RANGE**) ranges.buffer;
6990
7101
 
6991
7102
  if (file->inited == handler::NONE && (error= file->ha_index_init(index,1)))
6992
 
    return(error);
 
7103
    DBUG_RETURN(error);
6993
7104
 
6994
7105
  /* Allocate buffer if we need one but haven't allocated it yet */
6995
7106
  if (mrr_buf_size && !mrr_buf_desc)
6998
7109
    while (buf_size && !my_multi_malloc(MYF(MY_WME),
6999
7110
                                        &mrr_buf_desc, sizeof(*mrr_buf_desc),
7000
7111
                                        &mrange_buff, buf_size,
7001
 
                                        NULL))
 
7112
                                        NullS))
7002
7113
    {
7003
7114
      /* Try to shrink the buffers until both are 0. */
7004
7115
      buf_size/= 2;
7005
7116
    }
7006
7117
    if (!mrr_buf_desc)
7007
 
      return(HA_ERR_OUT_OF_MEM);
 
7118
      DBUG_RETURN(HA_ERR_OUT_OF_MEM);
7008
7119
 
7009
7120
    /* Initialize the handler buffer. */
7010
7121
    mrr_buf_desc->buffer= mrange_buff;
7021
7132
  error= file->multi_range_read_init(&seq_funcs, (void*)this, ranges.elements,
7022
7133
                                     mrr_flags, mrr_buf_desc? mrr_buf_desc: 
7023
7134
                                                              &empty_buf);
7024
 
  return(error);
 
7135
  DBUG_RETURN(error);
7025
7136
}
7026
7137
 
7027
7138
 
7038
7149
    Opaque value to be passed to quick_range_seq_next
7039
7150
*/
7040
7151
 
7041
 
range_seq_t quick_range_seq_init(void *init_param,
7042
 
                                 uint32_t n_ranges __attribute__((unused)),
7043
 
                                 uint32_t flags __attribute__((unused)))
 
7152
range_seq_t quick_range_seq_init(void *init_param, uint n_ranges, uint flags)
7044
7153
{
7045
7154
  QUICK_RANGE_SELECT *quick= (QUICK_RANGE_SELECT*)init_param;
7046
7155
  quick->qr_traversal_ctx.first=  (QUICK_RANGE**)quick->ranges.buffer;
7047
7156
  quick->qr_traversal_ctx.cur=    (QUICK_RANGE**)quick->ranges.buffer;
7048
 
  quick->qr_traversal_ctx.last=   quick->qr_traversal_ctx.cur +
 
7157
  quick->qr_traversal_ctx.last=   quick->qr_traversal_ctx.cur + 
7049
7158
                                  quick->ranges.elements;
7050
7159
  return &quick->qr_traversal_ctx;
7051
7160
}
7064
7173
    1  No more ranges in the sequence
7065
7174
*/
7066
7175
 
7067
 
uint32_t quick_range_seq_next(range_seq_t rseq, KEY_MULTI_RANGE *range)
 
7176
uint quick_range_seq_next(range_seq_t rseq, KEY_MULTI_RANGE *range)
7068
7177
{
7069
7178
  QUICK_RANGE_SEQ_CTX *ctx= (QUICK_RANGE_SEQ_CTX*)rseq;
7070
7179
 
7116
7225
    Reference to range_flag associated with range number #idx
7117
7226
*/
7118
7227
 
7119
 
uint16_t &mrr_persistent_flag_storage(range_seq_t seq, uint32_t idx)
 
7228
uint16 &mrr_persistent_flag_storage(range_seq_t seq, uint idx)
7120
7229
{
7121
7230
  QUICK_RANGE_SEQ_CTX *ctx= (QUICK_RANGE_SEQ_CTX*)seq;
7122
7231
  return ctx->first[idx]->flag;
7148
7257
    Reference to range-associated data
7149
7258
*/
7150
7259
 
7151
 
char* &mrr_get_ptr_by_idx(range_seq_t seq __attribute__((unused)),
7152
 
                          uint32_t idx __attribute__((unused)))
 
7260
char* &mrr_get_ptr_by_idx(range_seq_t seq, uint idx)
7153
7261
{
7154
7262
  static char *dummy;
7155
7263
  return dummy;
7174
7282
int QUICK_RANGE_SELECT::get_next()
7175
7283
{
7176
7284
  char *dummy;
 
7285
  DBUG_ENTER("QUICK_RANGE_SELECT::get_next");
7177
7286
  if (in_ror_merged_scan)
7178
7287
  {
7179
7288
    /*
7190
7299
    /* Restore bitmaps set on entry */
7191
7300
    head->column_bitmaps_set_no_signal(save_read_set, save_write_set);
7192
7301
  }
7193
 
  return(result);
 
7302
  DBUG_RETURN(result);
7194
7303
}
7195
7304
 
7196
7305
 
7222
7331
    other              if some error occurred
7223
7332
*/
7224
7333
 
7225
 
int QUICK_RANGE_SELECT::get_next_prefix(uint32_t prefix_length,
 
7334
int QUICK_RANGE_SELECT::get_next_prefix(uint prefix_length,
7226
7335
                                        key_part_map keypart_map,
7227
 
                                        unsigned char *cur_prefix)
 
7336
                                        uchar *cur_prefix)
7228
7337
{
 
7338
  DBUG_ENTER("QUICK_RANGE_SELECT::get_next_prefix");
 
7339
 
7229
7340
  for (;;)
7230
7341
  {
7231
7342
    int result;
7233
7344
    if (last_range)
7234
7345
    {
7235
7346
      /* Read the next record in the same range with prefix after cur_prefix. */
7236
 
      assert(cur_prefix != 0);
 
7347
      DBUG_ASSERT(cur_prefix != 0);
7237
7348
      result= file->index_read_map(record, cur_prefix, keypart_map,
7238
7349
                                   HA_READ_AFTER_KEY);
7239
7350
      if (result || (file->compare_key(file->end_range) <= 0))
7240
 
        return(result);
 
7351
        DBUG_RETURN(result);
7241
7352
    }
7242
7353
 
7243
 
    uint32_t count= ranges.elements - (cur_range - (QUICK_RANGE**) ranges.buffer);
 
7354
    uint count= ranges.elements - (cur_range - (QUICK_RANGE**) ranges.buffer);
7244
7355
    if (count == 0)
7245
7356
    {
7246
7357
      /* Ranges have already been used up before. None is left for read. */
7247
7358
      last_range= 0;
7248
 
      return(HA_ERR_END_OF_FILE);
 
7359
      DBUG_RETURN(HA_ERR_END_OF_FILE);
7249
7360
    }
7250
7361
    last_range= *(cur_range++);
7251
7362
 
7252
 
    start_key.key=    (const unsigned char*) last_range->min_key;
7253
 
    start_key.length= cmin(last_range->min_length, (uint16_t)prefix_length);
 
7363
    start_key.key=    (const uchar*) last_range->min_key;
 
7364
    start_key.length= min(last_range->min_length, prefix_length);
7254
7365
    start_key.keypart_map= last_range->min_keypart_map & keypart_map;
7255
7366
    start_key.flag=   ((last_range->flag & NEAR_MIN) ? HA_READ_AFTER_KEY :
7256
7367
                       (last_range->flag & EQ_RANGE) ?
7257
7368
                       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);
 
7369
    end_key.key=      (const uchar*) last_range->max_key;
 
7370
    end_key.length=   min(last_range->max_length, prefix_length);
7260
7371
    end_key.keypart_map= last_range->max_keypart_map & keypart_map;
7261
7372
    /*
7262
7373
      We use READ_AFTER_KEY here because if we are reading on a key
7273
7384
      last_range= 0;                    // Stop searching
7274
7385
 
7275
7386
    if (result != HA_ERR_END_OF_FILE)
7276
 
      return(result);
 
7387
      DBUG_RETURN(result);
7277
7388
    last_range= 0;                      // No matching rows; go to next range
7278
7389
  }
7279
7390
}
7300
7411
bool QUICK_RANGE_SELECT::row_in_ranges()
7301
7412
{
7302
7413
  QUICK_RANGE *res;
7303
 
  uint32_t min= 0;
7304
 
  uint32_t max= ranges.elements - 1;
7305
 
  uint32_t mid= (max + min)/2;
 
7414
  uint min= 0;
 
7415
  uint max= ranges.elements - 1;
 
7416
  uint mid= (max + min)/2;
7306
7417
 
7307
7418
  while (min != max)
7308
7419
  {
7330
7441
 */
7331
7442
 
7332
7443
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)))
 
7444
                                     uint used_key_parts_arg,
 
7445
                                     bool *create_err)
7335
7446
 :QUICK_RANGE_SELECT(*q), rev_it(rev_ranges)
7336
7447
{
7337
7448
  QUICK_RANGE *r;
7356
7467
 
7357
7468
int QUICK_SELECT_DESC::get_next()
7358
7469
{
 
7470
  DBUG_ENTER("QUICK_SELECT_DESC::get_next");
 
7471
 
7359
7472
  /* The max key is handled as follows:
7360
7473
   *   - if there is NO_MAX_RANGE, start at the end and move backwards
7361
7474
   *   - if it is an EQ_RANGE, which means that max key covers the entire
7379
7492
      if (!result)
7380
7493
      {
7381
7494
        if (cmp_prev(*rev_it.ref()) == 0)
7382
 
          return(0);
 
7495
          DBUG_RETURN(0);
7383
7496
      }
7384
7497
      else if (result != HA_ERR_END_OF_FILE)
7385
 
        return(result);
 
7498
        DBUG_RETURN(result);
7386
7499
    }
7387
7500
 
7388
7501
    if (!(last_range= rev_it++))
7389
 
      return(HA_ERR_END_OF_FILE);               // All ranges used
 
7502
      DBUG_RETURN(HA_ERR_END_OF_FILE);          // All ranges used
7390
7503
 
7391
7504
    if (last_range->flag & NO_MAX_RANGE)        // Read last record
7392
7505
    {
7393
7506
      int local_error;
7394
7507
      if ((local_error=file->index_last(record)))
7395
 
        return(local_error);            // Empty table
 
7508
        DBUG_RETURN(local_error);               // Empty table
7396
7509
      if (cmp_prev(last_range) == 0)
7397
 
        return(0);
 
7510
        DBUG_RETURN(0);
7398
7511
      last_range= 0;                            // No match; go to next range
7399
7512
      continue;
7400
7513
    }
7407
7520
    }
7408
7521
    else
7409
7522
    {
7410
 
      assert(last_range->flag & NEAR_MAX ||
 
7523
      DBUG_ASSERT(last_range->flag & NEAR_MAX ||
7411
7524
                  range_reads_after_key(last_range));
7412
7525
      result=file->index_read_map(record, last_range->max_key,
7413
7526
                                  last_range->max_keypart_map,
7418
7531
    if (result)
7419
7532
    {
7420
7533
      if (result != HA_ERR_KEY_NOT_FOUND && result != HA_ERR_END_OF_FILE)
7421
 
        return(result);
 
7534
        DBUG_RETURN(result);
7422
7535
      last_range= 0;                            // Not found, to next range
7423
7536
      continue;
7424
7537
    }
7426
7539
    {
7427
7540
      if (last_range->flag == (UNIQUE_RANGE | EQ_RANGE))
7428
7541
        last_range= 0;                          // Stop searching
7429
 
      return(0);                                // Found key is in range
 
7542
      DBUG_RETURN(0);                           // Found key is in range
7430
7543
    }
7431
7544
    last_range= 0;                              // To next range
7432
7545
  }
7445
7558
    return 0;                                   /* key can't be to large */
7446
7559
 
7447
7560
  KEY_PART *key_part=key_parts;
7448
 
  uint32_t store_length;
 
7561
  uint store_length;
7449
7562
 
7450
 
  for (unsigned char *key=range_arg->max_key, *end=key+range_arg->max_length;
 
7563
  for (uchar *key=range_arg->max_key, *end=key+range_arg->max_length;
7451
7564
       key < end;
7452
7565
       key+= store_length, key_part++)
7453
7566
  {
7580
7693
                                              String *used_lengths)
7581
7694
{
7582
7695
  char buf[64];
7583
 
  uint32_t length;
 
7696
  uint length;
7584
7697
  KEY *key_info= head->key_info + index;
7585
7698
  key_names->append(key_info->name);
7586
 
  length= int64_t2str(max_used_key_length, buf, 10) - buf;
 
7699
  length= longlong2str(max_used_key_length, buf, 10) - buf;
7587
7700
  used_lengths->append(buf, length);
7588
7701
}
7589
7702
 
7591
7704
                                                    String *used_lengths)
7592
7705
{
7593
7706
  char buf[64];
7594
 
  uint32_t length;
 
7707
  uint length;
7595
7708
  bool first= true;
7596
7709
  QUICK_RANGE_SELECT *quick;
7597
7710
 
7608
7721
 
7609
7722
    KEY *key_info= head->key_info + quick->index;
7610
7723
    key_names->append(key_info->name);
7611
 
    length= int64_t2str(quick->max_used_key_length, buf, 10) - buf;
 
7724
    length= longlong2str(quick->max_used_key_length, buf, 10) - buf;
7612
7725
    used_lengths->append(buf, length);
7613
7726
  }
7614
7727
  if (pk_quick_select)
7616
7729
    KEY *key_info= head->key_info + pk_quick_select->index;
7617
7730
    key_names->append(',');
7618
7731
    key_names->append(key_info->name);
7619
 
    length= int64_t2str(pk_quick_select->max_used_key_length, buf, 10) - buf;
 
7732
    length= longlong2str(pk_quick_select->max_used_key_length, buf, 10) - buf;
7620
7733
    used_lengths->append(',');
7621
7734
    used_lengths->append(buf, length);
7622
7735
  }
7626
7739
                                                      String *used_lengths)
7627
7740
{
7628
7741
  char buf[64];
7629
 
  uint32_t length;
 
7742
  uint length;
7630
7743
  bool first= true;
7631
7744
  QUICK_RANGE_SELECT *quick;
7632
7745
  List_iterator_fast<QUICK_RANGE_SELECT> it(quick_selects);
7641
7754
      used_lengths->append(',');
7642
7755
    }
7643
7756
    key_names->append(key_info->name);
7644
 
    length= int64_t2str(quick->max_used_key_length, buf, 10) - buf;
 
7757
    length= longlong2str(quick->max_used_key_length, buf, 10) - buf;
7645
7758
    used_lengths->append(buf, length);
7646
7759
  }
7647
7760
 
7650
7763
    KEY *key_info= head->key_info + cpk_quick->index;
7651
7764
    key_names->append(',');
7652
7765
    key_names->append(key_info->name);
7653
 
    length= int64_t2str(cpk_quick->max_used_key_length, buf, 10) - buf;
 
7766
    length= longlong2str(cpk_quick->max_used_key_length, buf, 10) - buf;
7654
7767
    used_lengths->append(',');
7655
7768
    used_lengths->append(buf, length);
7656
7769
  }
7680
7793
* Implementation of QUICK_GROUP_MIN_MAX_SELECT
7681
7794
*******************************************************************************/
7682
7795
 
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);
 
7796
static inline uint get_field_keypart(KEY *index, Field *field);
 
7797
static inline SEL_ARG * get_index_range_tree(uint index, SEL_TREE* range_tree,
 
7798
                                             PARAM *param, uint *param_idx);
7686
7799
static bool get_constant_key_infix(KEY *index_info, SEL_ARG *index_range_tree,
7687
7800
                       KEY_PART_INFO *first_non_group_part,
7688
7801
                       KEY_PART_INFO *min_max_arg_part,
7689
7802
                       KEY_PART_INFO *last_part, THD *thd,
7690
 
                       unsigned char *key_infix, uint32_t *key_infix_len,
 
7803
                       uchar *key_infix, uint *key_infix_len,
7691
7804
                       KEY_PART_INFO **first_non_infix_part);
7692
7805
static bool
7693
7806
check_group_min_max_predicates(COND *cond, Item_field *min_max_arg_item,
7694
7807
                               Field::imagetype image_type);
7695
7808
 
7696
7809
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,
 
7810
cost_group_min_max(TABLE* table, KEY *index_info, uint used_key_parts,
 
7811
                   uint group_key_parts, SEL_TREE *range_tree,
7699
7812
                   SEL_ARG *index_tree, ha_rows quick_prefix_records,
7700
7813
                   bool have_min, bool have_max,
7701
7814
                   double *read_cost, ha_rows *records);
7834
7947
{
7835
7948
  THD *thd= param->thd;
7836
7949
  JOIN *join= thd->lex->current_select->join;
7837
 
  Table *table= param->table;
 
7950
  TABLE *table= param->table;
7838
7951
  bool have_min= false;              /* true if there is a MIN function. */
7839
7952
  bool have_max= false;              /* true if there is a MAX function. */
7840
7953
  Item_field *min_max_arg_item= NULL; // The argument of all MIN/MAX functions
7841
7954
  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. */
 
7955
  uint group_prefix_len= 0; /* Length (in bytes) of the key prefix. */
7843
7956
  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. */
 
7957
  uint index= 0;            /* The id of the chosen index. */
 
7958
  uint group_key_parts= 0;  // Number of index key parts in the group prefix.
 
7959
  uint used_key_parts= 0;   /* Number of index key parts used for access. */
 
7960
  uchar key_infix[MAX_KEY_LENGTH]; /* Constants from equality predicates.*/
 
7961
  uint key_infix_len= 0;          /* Length of key_infix. */
7849
7962
  TRP_GROUP_MIN_MAX *read_plan= NULL; /* The eventually constructed TRP. */
7850
 
  uint32_t key_part_nr;
7851
 
  order_st *tmp_group;
 
7963
  uint key_part_nr;
 
7964
  ORDER *tmp_group;
7852
7965
  Item *item;
7853
7966
  Item_field *item_field;
 
7967
  DBUG_ENTER("get_best_group_min_max");
7854
7968
 
7855
7969
  /* Perform few 'cheap' tests whether this access method is applicable. */
7856
7970
  if (!join)
7857
 
    return(NULL);        /* This is not a select statement. */
 
7971
    DBUG_RETURN(NULL);        /* This is not a select statement. */
7858
7972
  if ((join->tables != 1) ||  /* The query must reference one table. */
7859
7973
      ((!join->group_list) && /* Neither GROUP BY nor a DISTINCT query. */
7860
7974
       (!join->select_distinct)) ||
7861
7975
      (join->select_lex->olap == ROLLUP_TYPE)) /* Check (B3) for ROLLUP */
7862
 
    return(NULL);
 
7976
    DBUG_RETURN(NULL);
7863
7977
  if (table->s->keys == 0)        /* There are no indexes to use. */
7864
 
    return(NULL);
 
7978
    DBUG_RETURN(NULL);
7865
7979
 
7866
7980
  /* Analyze the query in more detail. */
7867
7981
  List_iterator<Item> select_items_it(join->fields_list);
7868
7982
 
7869
7983
  /* Check (SA1,SA4) and store the only MIN/MAX argument - the C attribute.*/
7870
7984
  if (join->make_sum_func_list(join->all_fields, join->fields_list, 1))
7871
 
    return(NULL);
 
7985
    DBUG_RETURN(NULL);
7872
7986
  if (join->sum_funcs[0])
7873
7987
  {
7874
7988
    Item_sum *min_max_item;
7880
7994
      else if (min_max_item->sum_func() == Item_sum::MAX_FUNC)
7881
7995
        have_max= true;
7882
7996
      else
7883
 
        return(NULL);
 
7997
        DBUG_RETURN(NULL);
7884
7998
 
7885
7999
      /* The argument of MIN/MAX. */
7886
8000
      Item *expr= min_max_item->args[0]->real_item();    
7889
8003
        if (! min_max_arg_item)
7890
8004
          min_max_arg_item= (Item_field*) expr;
7891
8005
        else if (! min_max_arg_item->eq(expr, 1))
7892
 
          return(NULL);
 
8006
          DBUG_RETURN(NULL);
7893
8007
      }
7894
8008
      else
7895
 
        return(NULL);
 
8009
        DBUG_RETURN(NULL);
7896
8010
    }
7897
8011
  }
7898
8012
 
7902
8016
    while ((item= select_items_it++))
7903
8017
    {
7904
8018
      if (item->type() != Item::FIELD_ITEM)
7905
 
        return(NULL);
 
8019
        DBUG_RETURN(NULL);
7906
8020
    }
7907
8021
  }
7908
8022
 
7910
8024
  for (tmp_group= join->group_list; tmp_group; tmp_group= tmp_group->next)
7911
8025
  {
7912
8026
    if ((*tmp_group->item)->type() != Item::FIELD_ITEM)
7913
 
      return(NULL);
 
8027
      DBUG_RETURN(NULL);
7914
8028
  }
7915
8029
 
7916
8030
  /*
7926
8040
  KEY_PART_INFO *last_part= NULL;
7927
8041
  KEY_PART_INFO *first_non_group_part= NULL;
7928
8042
  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;
 
8043
  uint key_infix_parts= 0;
 
8044
  uint cur_group_key_parts= 0;
 
8045
  uint cur_group_prefix_len= 0;
7932
8046
  /* Cost-related variables for the best index so far. */
7933
8047
  double best_read_cost= DBL_MAX;
7934
8048
  ha_rows best_records= 0;
7935
8049
  SEL_ARG *best_index_tree= NULL;
7936
8050
  ha_rows best_quick_prefix_records= 0;
7937
 
  uint32_t best_param_idx= 0;
 
8051
  uint best_param_idx= 0;
7938
8052
  double cur_read_cost= DBL_MAX;
7939
8053
  ha_rows cur_records;
7940
8054
  SEL_ARG *cur_index_tree= NULL;
7941
8055
  ha_rows cur_quick_prefix_records= 0;
7942
 
  uint32_t cur_param_idx=MAX_KEY;
 
8056
  uint cur_param_idx=MAX_KEY;
7943
8057
  key_map cur_used_key_parts;
7944
 
  uint32_t pk= param->table->s->primary_key;
 
8058
  uint pk= param->table->s->primary_key;
7945
8059
 
7946
 
  for (uint32_t cur_index= 0 ; cur_index_info != cur_index_info_end ;
 
8060
  for (uint cur_index= 0 ; cur_index_info != cur_index_info_end ;
7947
8061
       cur_index_info++, cur_index++)
7948
8062
  {
7949
8063
    /* Check (B1) - if current index is covering. */
7963
8077
        (table->file->ha_table_flags() & HA_PRIMARY_KEY_IN_READ_INDEX))
7964
8078
    {
7965
8079
      /* For each table field */
7966
 
      for (uint32_t i= 0; i < table->s->fields; i++)
 
8080
      for (uint i= 0; i < table->s->fields; i++)
7967
8081
      {
7968
8082
        Field *cur_field= table->field[i];
7969
8083
        /*
7993
8107
          first Item? If so, then why? What is the array for?
7994
8108
        */
7995
8109
        /* Above we already checked that all group items are fields. */
7996
 
        assert((*tmp_group->item)->type() == Item::FIELD_ITEM);
 
8110
        DBUG_ASSERT((*tmp_group->item)->type() == Item::FIELD_ITEM);
7997
8111
        Item_field *group_field= (Item_field *) (*tmp_group->item);
7998
8112
        if (group_field->field->eq(cur_part->field))
7999
8113
        {
8006
8120
    }
8007
8121
    /*
8008
8122
      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
 
8123
      If GA2, then Store a new ORDER object in group_fields_array at the
 
8124
      position of the key part of item_field->field. Thus we get the ORDER
8011
8125
      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
 
8126
      Later group_fields_array of ORDER objects is used to convert the query
8013
8127
      to a GROUP query.
8014
8128
    */
8015
8129
    else if (join->select_distinct)
8016
8130
    {
8017
8131
      select_items_it.rewind();
8018
8132
      cur_used_key_parts.clear_all();
8019
 
      uint32_t max_key_part= 0;
 
8133
      uint max_key_part= 0;
8020
8134
      while ((item= select_items_it++))
8021
8135
      {
8022
8136
        item_field= (Item_field*) item; /* (SA5) already checked above. */
8034
8148
        cur_group_prefix_len+= cur_part->store_length;
8035
8149
        cur_used_key_parts.set_bit(key_part_nr);
8036
8150
        ++cur_group_key_parts;
8037
 
        max_key_part= cmax(max_key_part,key_part_nr);
 
8151
        max_key_part= max(max_key_part,key_part_nr);
8038
8152
      }
8039
8153
      /*
8040
8154
        Check that used key parts forms a prefix of the index.
8042
8156
        all_parts have all bits set from 0 to (max_key_part-1).
8043
8157
        cur_parts have bits set for only used keyparts.
8044
8158
      */
8045
 
      uint64_t all_parts, cur_parts;
 
8159
      ulonglong all_parts, cur_parts;
8046
8160
      all_parts= (1<<max_key_part) - 1;
8047
 
      cur_parts= cur_used_key_parts.to_uint64_t() >> 1;
 
8161
      cur_parts= cur_used_key_parts.to_ulonglong() >> 1;
8048
8162
      if (all_parts != cur_parts)
8049
8163
        goto next_index;
8050
8164
    }
8051
8165
    else
8052
 
      assert(false);
 
8166
      DBUG_ASSERT(false);
8053
8167
 
8054
8168
    /* Check (SA2). */
8055
8169
    if (min_max_arg_item)
8089
8203
    {
8090
8204
      if (tree)
8091
8205
      {
8092
 
        uint32_t dummy;
 
8206
        uint dummy;
8093
8207
        SEL_ARG *index_range_tree= get_index_range_tree(cur_index, tree, param,
8094
8208
                                                        &dummy);
8095
8209
        if (!get_constant_key_infix(cur_index_info, index_range_tree,
8127
8241
 
8128
8242
        /* Check if cur_part is referenced in the WHERE clause. */
8129
8243
        if (join->conds->walk(&Item::find_item_in_field_list_processor, 0,
8130
 
                              (unsigned char*) key_part_range))
 
8244
                              (uchar*) key_part_range))
8131
8245
          goto next_index;
8132
8246
      }
8133
8247
    }
8160
8274
                                           &cur_param_idx);
8161
8275
      /* Check if this range tree can be used for prefix retrieval. */
8162
8276
      COST_VECT dummy_cost;
8163
 
      uint32_t mrr_flags= HA_MRR_USE_DEFAULT_IMPL;
8164
 
      uint32_t mrr_bufsize=0;
 
8277
      uint mrr_flags= HA_MRR_USE_DEFAULT_IMPL;
 
8278
      uint mrr_bufsize=0;
8165
8279
      cur_quick_prefix_records= check_quick_select(param, cur_param_idx, 
8166
8280
                                                   false /*don't care*/, 
8167
8281
                                                   cur_index_tree, true,
8179
8293
    */
8180
8294
    if (cur_read_cost < best_read_cost - (DBL_EPSILON * cur_read_cost))
8181
8295
    {
8182
 
      assert(tree != 0 || cur_param_idx == MAX_KEY);
 
8296
      DBUG_ASSERT(tree != 0 || cur_param_idx == MAX_KEY);
8183
8297
      index_info= cur_index_info;
8184
8298
      index= cur_index;
8185
8299
      best_read_cost= cur_read_cost;
8196
8310
    cur_group_prefix_len= 0;
8197
8311
  }
8198
8312
  if (!index_info) /* No usable index found. */
8199
 
    return(NULL);
 
8313
    DBUG_RETURN(NULL);
8200
8314
 
8201
8315
  /* Check (SA3) for the where clause. */
8202
8316
  if (join->conds && min_max_arg_item &&
8203
 
      !check_group_min_max_predicates(join->conds, min_max_arg_item, Field::itRAW))
8204
 
    return(NULL);
 
8317
      !check_group_min_max_predicates(join->conds, min_max_arg_item,
 
8318
                                      (index_info->flags & HA_SPATIAL) ?
 
8319
                                      Field::itMBR : Field::itRAW))
 
8320
    DBUG_RETURN(NULL);
8205
8321
 
8206
8322
  /* The query passes all tests, so construct a new TRP object. */
8207
8323
  read_plan= new (param->mem_root)
8215
8331
  if (read_plan)
8216
8332
  {
8217
8333
    if (tree && read_plan->quick_prefix_records == 0)
8218
 
      return(NULL);
 
8334
      DBUG_RETURN(NULL);
8219
8335
 
8220
8336
    read_plan->read_cost= best_read_cost;
8221
8337
    read_plan->records=   best_records;
 
8338
 
 
8339
    DBUG_PRINT("info",
 
8340
               ("Returning group min/max plan: cost: %g, records: %lu",
 
8341
                read_plan->read_cost, (ulong) read_plan->records));
8222
8342
  }
8223
8343
 
8224
 
  return(read_plan);
 
8344
  DBUG_RETURN(read_plan);
8225
8345
}
8226
8346
 
8227
8347
 
8251
8371
check_group_min_max_predicates(COND *cond, Item_field *min_max_arg_item,
8252
8372
                               Field::imagetype image_type)
8253
8373
{
8254
 
  assert(cond && min_max_arg_item);
 
8374
  DBUG_ENTER("check_group_min_max_predicates");
 
8375
  DBUG_ASSERT(cond && min_max_arg_item);
8255
8376
 
8256
8377
  cond= cond->real_item();
8257
8378
  Item::Type cond_type= cond->type();
8258
8379
  if (cond_type == Item::COND_ITEM) /* 'AND' or 'OR' */
8259
8380
  {
 
8381
    DBUG_PRINT("info", ("Analyzing: %s", ((Item_func*) cond)->func_name()));
8260
8382
    List_iterator_fast<Item> li(*((Item_cond*) cond)->argument_list());
8261
8383
    Item *and_or_arg;
8262
8384
    while ((and_or_arg= li++))
8263
8385
    {
8264
8386
      if (!check_group_min_max_predicates(and_or_arg, min_max_arg_item,
8265
8387
                                         image_type))
8266
 
        return(false);
 
8388
        DBUG_RETURN(false);
8267
8389
    }
8268
 
    return(true);
 
8390
    DBUG_RETURN(true);
8269
8391
  }
8270
8392
 
8271
8393
  /*
8278
8400
    so.
8279
8401
  */
8280
8402
  if (cond_type == Item::SUBSELECT_ITEM)
8281
 
    return(false);
 
8403
    DBUG_RETURN(false);
8282
8404
  
8283
8405
  /* We presume that at this point there are no other Items than functions. */
8284
 
  assert(cond_type == Item::FUNC_ITEM);
 
8406
  DBUG_ASSERT(cond_type == Item::FUNC_ITEM);
8285
8407
 
8286
8408
  /* Test if cond references only group-by or non-group fields. */
8287
8409
  Item_func *pred= (Item_func*) cond;
8288
8410
  Item **arguments= pred->arguments();
8289
8411
  Item *cur_arg;
8290
 
  for (uint32_t arg_idx= 0; arg_idx < pred->argument_count (); arg_idx++)
 
8412
  DBUG_PRINT("info", ("Analyzing: %s", pred->func_name()));
 
8413
  for (uint arg_idx= 0; arg_idx < pred->argument_count (); arg_idx++)
8291
8414
  {
8292
8415
    cur_arg= arguments[arg_idx]->real_item();
 
8416
    DBUG_PRINT("info", ("cur_arg: %s", cur_arg->full_name()));
8293
8417
    if (cur_arg->type() == Item::FIELD_ITEM)
8294
8418
    {
8295
8419
      if (min_max_arg_item->eq(cur_arg, 1)) 
8309
8433
            pred_type != Item_func::ISNOTNULL_FUNC &&
8310
8434
            pred_type != Item_func::EQ_FUNC        &&
8311
8435
            pred_type != Item_func::NE_FUNC)
8312
 
          return(false);
 
8436
          DBUG_RETURN(false);
8313
8437
 
8314
8438
        /* Check that pred compares min_max_arg_item with a constant. */
8315
8439
        Item *args[3];
8316
 
        memset(args, 0, 3 * sizeof(Item*));
 
8440
        bzero(args, 3 * sizeof(Item*));
8317
8441
        bool inv;
8318
8442
        /* Test if this is a comparison of a field and a constant. */
8319
8443
        if (!simple_pred(pred, args, &inv))
8320
 
          return(false);
 
8444
          DBUG_RETURN(false);
8321
8445
 
8322
8446
        /* Check for compatible string comparisons - similar to get_mm_leaf. */
8323
8447
        if (args[0] && args[1] && !args[2] && // this is a binary function
8336
8460
             */
8337
8461
             (args[1]->result_type() != STRING_RESULT &&
8338
8462
              min_max_arg_item->field->cmp_type() != args[1]->result_type())))
8339
 
          return(false);
 
8463
          DBUG_RETURN(false);
8340
8464
      }
8341
8465
    }
8342
8466
    else if (cur_arg->type() == Item::FUNC_ITEM)
8343
8467
    {
8344
8468
      if (!check_group_min_max_predicates(cur_arg, min_max_arg_item,
8345
8469
                                         image_type))
8346
 
        return(false);
 
8470
        DBUG_RETURN(false);
8347
8471
    }
8348
8472
    else if (cur_arg->const_item())
8349
8473
    {
8350
 
      return(true);
 
8474
      DBUG_RETURN(true);
8351
8475
    }
8352
8476
    else
8353
 
      return(false);
 
8477
      DBUG_RETURN(false);
8354
8478
  }
8355
8479
 
8356
 
  return(true);
 
8480
  DBUG_RETURN(true);
8357
8481
}
8358
8482
 
8359
8483
 
8389
8513
*/
8390
8514
 
8391
8515
static bool
8392
 
get_constant_key_infix(KEY *index_info __attribute__((unused)),
8393
 
                       SEL_ARG *index_range_tree,
 
8516
get_constant_key_infix(KEY *index_info, SEL_ARG *index_range_tree,
8394
8517
                       KEY_PART_INFO *first_non_group_part,
8395
8518
                       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,
 
8519
                       KEY_PART_INFO *last_part, THD *thd,
 
8520
                       uchar *key_infix, uint *key_infix_len,
8399
8521
                       KEY_PART_INFO **first_non_infix_part)
8400
8522
{
8401
8523
  SEL_ARG       *cur_range;
8404
8526
  KEY_PART_INFO *end_part= min_max_arg_part ? min_max_arg_part : last_part;
8405
8527
 
8406
8528
  *key_infix_len= 0;
8407
 
  unsigned char *key_ptr= key_infix;
 
8529
  uchar *key_ptr= key_infix;
8408
8530
  for (cur_part= first_non_group_part; cur_part != end_part; cur_part++)
8409
8531
  {
8410
8532
    /*
8436
8558
        (cur_range->min_flag & NEAR_MIN) || (cur_range->max_flag & NEAR_MAX))
8437
8559
      return false;
8438
8560
 
8439
 
    uint32_t field_length= cur_part->store_length;
 
8561
    uint field_length= cur_part->store_length;
8440
8562
    if ((cur_range->maybe_null &&
8441
8563
         cur_range->min_value[0] && cur_range->max_value[0]) ||
8442
8564
        !memcmp(cur_range->min_value, cur_range->max_value, field_length))
8511
8633
    Pointer to the SEL_ARG subtree that corresponds to index.
8512
8634
*/
8513
8635
 
8514
 
SEL_ARG * get_index_range_tree(uint32_t index, SEL_TREE* range_tree, PARAM *param,
8515
 
                               uint32_t *param_idx)
 
8636
SEL_ARG * get_index_range_tree(uint index, SEL_TREE* range_tree, PARAM *param,
 
8637
                               uint *param_idx)
8516
8638
{
8517
 
  uint32_t idx= 0; /* Index nr in param->key_parts */
 
8639
  uint idx= 0; /* Index nr in param->key_parts */
8518
8640
  while (idx < param->keys)
8519
8641
  {
8520
8642
    if (index == param->real_keynr[idx])
8586
8708
    None
8587
8709
*/
8588
8710
 
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,
 
8711
void cost_group_min_max(TABLE* table, KEY *index_info, uint used_key_parts,
 
8712
                        uint group_key_parts, SEL_TREE *range_tree,
 
8713
                        SEL_ARG *index_tree, ha_rows quick_prefix_records,
8593
8714
                        bool have_min, bool have_max,
8594
8715
                        double *read_cost, ha_rows *records)
8595
8716
{
8596
8717
  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 */
 
8718
  uint num_groups;
 
8719
  uint num_blocks;
 
8720
  uint keys_per_block;
 
8721
  uint keys_per_group;
 
8722
  uint keys_per_subgroup; /* Average number of keys in sub-groups */
8602
8723
                          /* formed by a key infix. */
8603
8724
  double p_overlap; /* Probability that a sub-group overlaps two blocks. */
8604
8725
  double quick_prefix_selectivity;
8605
8726
  double io_cost;
8606
8727
  double cpu_cost= 0; /* TODO: CPU cost of index_read calls? */
 
8728
  DBUG_ENTER("cost_group_min_max");
8607
8729
 
8608
8730
  table_records= table->file->stats.records;
8609
8731
  keys_per_block= (table->file->stats.block_size / 2 /
8639
8761
    {
8640
8762
      double blocks_per_group= (double) num_blocks / (double) num_groups;
8641
8763
      p_overlap= (blocks_per_group * (keys_per_subgroup - 1)) / keys_per_group;
8642
 
      p_overlap= cmin(p_overlap, 1.0);
 
8764
      p_overlap= min(p_overlap, 1.0);
8643
8765
    }
8644
 
    io_cost= (double) cmin(num_groups * (1 + p_overlap), (double)num_blocks);
 
8766
    io_cost= (double) min(num_groups * (1 + p_overlap), num_blocks);
8645
8767
  }
8646
8768
  else
8647
8769
    io_cost= (keys_per_group > keys_per_block) ?
8658
8780
 
8659
8781
  *read_cost= io_cost + cpu_cost;
8660
8782
  *records= num_groups;
8661
 
  return;
 
8783
 
 
8784
  DBUG_PRINT("info",
 
8785
             ("table rows: %lu  keys/block: %u  keys/group: %u  result rows: %lu  blocks: %u",
 
8786
              (ulong)table_records, keys_per_block, keys_per_group, 
 
8787
              (ulong) *records, num_blocks));
 
8788
  DBUG_VOID_RETURN;
8662
8789
}
8663
8790
 
8664
8791
 
8684
8811
*/
8685
8812
 
8686
8813
QUICK_SELECT_I *
8687
 
TRP_GROUP_MIN_MAX::make_quick(PARAM *param,
8688
 
                              bool retrieve_full_rows __attribute__((unused)),
 
8814
TRP_GROUP_MIN_MAX::make_quick(PARAM *param, bool retrieve_full_rows,
8689
8815
                              MEM_ROOT *parent_alloc)
8690
8816
{
8691
8817
  QUICK_GROUP_MIN_MAX_SELECT *quick;
 
8818
  DBUG_ENTER("TRP_GROUP_MIN_MAX::make_quick");
8692
8819
 
8693
8820
  quick= new QUICK_GROUP_MIN_MAX_SELECT(param->table,
8694
8821
                                        param->thd->lex->current_select->join,
8698
8825
                                        read_cost, records, key_infix_len,
8699
8826
                                        key_infix, parent_alloc);
8700
8827
  if (!quick)
8701
 
    return(NULL);
 
8828
    DBUG_RETURN(NULL);
8702
8829
 
8703
8830
  if (quick->init())
8704
8831
  {
8705
8832
    delete quick;
8706
 
    return(NULL);
 
8833
    DBUG_RETURN(NULL);
8707
8834
  }
8708
8835
 
8709
8836
  if (range_tree)
8710
8837
  {
8711
 
    assert(quick_prefix_records > 0);
 
8838
    DBUG_ASSERT(quick_prefix_records > 0);
8712
8839
    if (quick_prefix_records == HA_POS_ERROR)
8713
8840
      quick->quick_prefix_select= NULL; /* Can't construct a quick select. */
8714
8841
    else
8742
8869
        {
8743
8870
          delete quick;
8744
8871
          quick= NULL;
8745
 
          return(NULL);
 
8872
          DBUG_RETURN(NULL);
8746
8873
        }
8747
8874
        min_max_range= min_max_range->next;
8748
8875
      }
8754
8881
  quick->update_key_stat();
8755
8882
  quick->adjust_prefix_ranges();
8756
8883
 
8757
 
  return(quick);
 
8884
  DBUG_RETURN(quick);
8758
8885
}
8759
8886
 
8760
8887
 
8783
8910
*/
8784
8911
 
8785
8912
QUICK_GROUP_MIN_MAX_SELECT::
8786
 
QUICK_GROUP_MIN_MAX_SELECT(Table *table, JOIN *join_arg, bool have_min_arg,
 
8913
QUICK_GROUP_MIN_MAX_SELECT(TABLE *table, JOIN *join_arg, bool have_min_arg,
8787
8914
                           bool have_max_arg,
8788
8915
                           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)
 
8916
                           uint group_prefix_len_arg, uint group_key_parts_arg,
 
8917
                           uint used_key_parts_arg, KEY *index_info_arg,
 
8918
                           uint use_index, double read_cost_arg,
 
8919
                           ha_rows records_arg, uint key_infix_len_arg,
 
8920
                           uchar *key_infix_arg, MEM_ROOT *parent_alloc)
8794
8921
  :join(join_arg), index_info(index_info_arg),
8795
8922
   group_prefix_len(group_prefix_len_arg),
8796
8923
   group_key_parts(group_key_parts_arg), have_min(have_min_arg),
8816
8943
    We can't have parent_alloc set as the init function can't handle this case
8817
8944
    yet.
8818
8945
  */
8819
 
  assert(!parent_alloc);
 
8946
  DBUG_ASSERT(!parent_alloc);
8820
8947
  if (!parent_alloc)
8821
8948
  {
8822
8949
    init_sql_alloc(&alloc, join->thd->variables.range_alloc_block_size, 0);
8823
8950
    join->thd->mem_root= &alloc;
8824
8951
  }
8825
8952
  else
8826
 
    memset(&alloc, 0, sizeof(MEM_ROOT));  // ensure that it's not used
 
8953
    bzero(&alloc, sizeof(MEM_ROOT));            // ensure that it's not used
8827
8954
}
8828
8955
 
8829
8956
 
8849
8976
  if (group_prefix) /* Already initialized. */
8850
8977
    return 0;
8851
8978
 
8852
 
  if (!(last_prefix= (unsigned char*) alloc_root(&alloc, group_prefix_len)))
 
8979
  if (!(last_prefix= (uchar*) alloc_root(&alloc, group_prefix_len)))
8853
8980
      return 1;
8854
8981
  /*
8855
8982
    We may use group_prefix to store keys with all select fields, so allocate
8856
8983
    enough space for it.
8857
8984
  */
8858
 
  if (!(group_prefix= (unsigned char*) alloc_root(&alloc,
 
8985
  if (!(group_prefix= (uchar*) alloc_root(&alloc,
8859
8986
                                         real_prefix_len + min_max_arg_len)))
8860
8987
    return 1;
8861
8988
 
8865
8992
      The memory location pointed to by key_infix will be deleted soon, so
8866
8993
      allocate a new buffer and copy the key_infix into it.
8867
8994
    */
8868
 
    unsigned char *tmp_key_infix= (unsigned char*) alloc_root(&alloc, key_infix_len);
 
8995
    uchar *tmp_key_infix= (uchar*) alloc_root(&alloc, key_infix_len);
8869
8996
    if (!tmp_key_infix)
8870
8997
      return 1;
8871
8998
    memcpy(tmp_key_infix, this->key_infix, key_infix_len);
8923
9050
 
8924
9051
QUICK_GROUP_MIN_MAX_SELECT::~QUICK_GROUP_MIN_MAX_SELECT()
8925
9052
{
 
9053
  DBUG_ENTER("QUICK_GROUP_MIN_MAX_SELECT::~QUICK_GROUP_MIN_MAX_SELECT");
8926
9054
  if (file->inited != handler::NONE) 
8927
9055
    file->ha_index_end();
8928
9056
  if (min_max_arg_part)
8931
9059
  delete min_functions_it;
8932
9060
  delete max_functions_it;
8933
9061
  delete quick_prefix_select;
8934
 
  return; 
 
9062
  DBUG_VOID_RETURN; 
8935
9063
}
8936
9064
 
8937
9065
 
8956
9084
bool QUICK_GROUP_MIN_MAX_SELECT::add_range(SEL_ARG *sel_range)
8957
9085
{
8958
9086
  QUICK_RANGE *range;
8959
 
  uint32_t range_flag= sel_range->min_flag | sel_range->max_flag;
 
9087
  uint range_flag= sel_range->min_flag | sel_range->max_flag;
8960
9088
 
8961
9089
  /* Skip (-inf,+inf) ranges, e.g. (x < 5 or x > 4). */
8962
9090
  if ((range_flag & NO_MIN_RANGE) && (range_flag & NO_MAX_RANGE))
8979
9107
                         range_flag);
8980
9108
  if (!range)
8981
9109
    return true;
8982
 
  if (insert_dynamic(&min_max_ranges, (unsigned char*)&range))
 
9110
  if (insert_dynamic(&min_max_ranges, (uchar*)&range))
8983
9111
    return true;
8984
9112
  return false;
8985
9113
}
9008
9136
      group_prefix_len < quick_prefix_select->max_used_key_length)
9009
9137
  {
9010
9138
    DYNAMIC_ARRAY *arr;
9011
 
    uint32_t inx;
 
9139
    uint inx;
9012
9140
 
9013
9141
    for (inx= 0, arr= &quick_prefix_select->ranges; inx < arr->elements; inx++)
9014
9142
    {
9015
9143
      QUICK_RANGE *range;
9016
9144
 
9017
 
      get_dynamic(arr, (unsigned char*)&range, inx);
 
9145
      get_dynamic(arr, (uchar*)&range, inx);
9018
9146
      range->flag &= ~(NEAR_MIN | NEAR_MAX);
9019
9147
    }
9020
9148
  }
9050
9178
    QUICK_RANGE *cur_range;
9051
9179
    if (have_min)
9052
9180
    { /* Check if the right-most range has a lower boundary. */
9053
 
      get_dynamic(&min_max_ranges, (unsigned char*)&cur_range,
 
9181
      get_dynamic(&min_max_ranges, (uchar*)&cur_range,
9054
9182
                  min_max_ranges.elements - 1);
9055
9183
      if (!(cur_range->flag & NO_MIN_RANGE))
9056
9184
      {
9061
9189
    }
9062
9190
    if (have_max)
9063
9191
    { /* Check if the left-most range has an upper boundary. */
9064
 
      get_dynamic(&min_max_ranges, (unsigned char*)&cur_range, 0);
 
9192
      get_dynamic(&min_max_ranges, (uchar*)&cur_range, 0);
9065
9193
      if (!(cur_range->flag & NO_MAX_RANGE))
9066
9194
      {
9067
9195
        max_used_key_length+= min_max_arg_len;
9105
9233
int QUICK_GROUP_MIN_MAX_SELECT::reset(void)
9106
9234
{
9107
9235
  int result;
 
9236
  DBUG_ENTER("QUICK_GROUP_MIN_MAX_SELECT::reset");
9108
9237
 
9109
9238
  file->extra(HA_EXTRA_KEYREAD); /* We need only the key attributes */
9110
9239
  if ((result= file->ha_index_init(index,1)))
9111
 
    return(result);
 
9240
    DBUG_RETURN(result);
9112
9241
  if (quick_prefix_select && quick_prefix_select->reset())
9113
 
    return(1);
 
9242
    DBUG_RETURN(1);
9114
9243
  result= file->index_last(record);
9115
9244
  if (result == HA_ERR_END_OF_FILE)
9116
 
    return(0);
 
9245
    DBUG_RETURN(0);
9117
9246
  /* Save the prefix of the last group. */
9118
9247
  key_copy(last_prefix, record, index_info, group_prefix_len);
9119
9248
 
9120
 
  return(0);
 
9249
  DBUG_RETURN(0);
9121
9250
}
9122
9251
 
9123
9252
 
9156
9285
  int result;
9157
9286
  int is_last_prefix= 0;
9158
9287
 
 
9288
  DBUG_ENTER("QUICK_GROUP_MIN_MAX_SELECT::get_next");
 
9289
 
9159
9290
  /*
9160
9291
    Loop until a group is found that satisfies all query conditions or the last
9161
9292
    group is reached.
9171
9302
    {
9172
9303
      is_last_prefix= key_cmp(index_info->key_part, last_prefix,
9173
9304
                              group_prefix_len);
9174
 
      assert(is_last_prefix <= 0);
 
9305
      DBUG_ASSERT(is_last_prefix <= 0);
9175
9306
    }
9176
9307
    else 
9177
9308
    {
9194
9325
      if (max_res == 0)
9195
9326
        update_max_result();
9196
9327
      /* If a MIN was found, a MAX must have been found as well. */
9197
 
      assert((have_max && !have_min) ||
 
9328
      DBUG_ASSERT((have_max && !have_min) ||
9198
9329
                  (have_max && have_min && (max_res == 0)));
9199
9330
    }
9200
9331
    /*
9224
9355
  else if (result == HA_ERR_KEY_NOT_FOUND)
9225
9356
    result= HA_ERR_END_OF_FILE;
9226
9357
 
9227
 
  return(result);
 
9358
  DBUG_RETURN(result);
9228
9359
}
9229
9360
 
9230
9361
 
9254
9385
int QUICK_GROUP_MIN_MAX_SELECT::next_min()
9255
9386
{
9256
9387
  int result= 0;
 
9388
  DBUG_ENTER("QUICK_GROUP_MIN_MAX_SELECT::next_min");
9257
9389
 
9258
9390
  /* Find the MIN key using the eventually extended group prefix. */
9259
9391
  if (min_max_ranges.elements > 0)
9260
9392
  {
9261
9393
    if ((result= next_min_in_range()))
9262
 
      return(result);
 
9394
      DBUG_RETURN(result);
9263
9395
  }
9264
9396
  else
9265
9397
  {
9269
9401
      if ((result= file->index_read_map(record, group_prefix,
9270
9402
                                        make_prev_keypart_map(real_key_parts),
9271
9403
                                        HA_READ_KEY_EXACT)))
9272
 
        return(result);
 
9404
        DBUG_RETURN(result);
9273
9405
    }
9274
9406
 
9275
9407
    /*
9310
9442
    If the MIN attribute is non-nullable, this->record already contains the
9311
9443
    MIN key in the group, so just return.
9312
9444
  */
9313
 
  return(result);
 
9445
  DBUG_RETURN(result);
9314
9446
}
9315
9447
 
9316
9448
 
9334
9466
{
9335
9467
  int result;
9336
9468
 
 
9469
  DBUG_ENTER("QUICK_GROUP_MIN_MAX_SELECT::next_max");
 
9470
 
9337
9471
  /* Get the last key in the (possibly extended) group. */
9338
9472
  if (min_max_ranges.elements > 0)
9339
9473
    result= next_max_in_range();
9341
9475
    result= file->index_read_map(record, group_prefix,
9342
9476
                                 make_prev_keypart_map(real_key_parts),
9343
9477
                                 HA_READ_PREFIX_LAST);
9344
 
  return(result);
 
9478
  DBUG_RETURN(result);
9345
9479
}
9346
9480
 
9347
9481
 
9369
9503
int QUICK_GROUP_MIN_MAX_SELECT::next_prefix()
9370
9504
{
9371
9505
  int result;
 
9506
  DBUG_ENTER("QUICK_GROUP_MIN_MAX_SELECT::next_prefix");
9372
9507
 
9373
9508
  if (quick_prefix_select)
9374
9509
  {
9375
 
    unsigned char *cur_prefix= seen_first_key ? group_prefix : NULL;
 
9510
    uchar *cur_prefix= seen_first_key ? group_prefix : NULL;
9376
9511
    if ((result= quick_prefix_select->get_next_prefix(group_prefix_len,
9377
9512
                         make_prev_keypart_map(group_key_parts), cur_prefix)))
9378
 
      return(result);
 
9513
      DBUG_RETURN(result);
9379
9514
    seen_first_key= true;
9380
9515
  }
9381
9516
  else
9384
9519
    {
9385
9520
      result= file->index_first(record);
9386
9521
      if (result)
9387
 
        return(result);
 
9522
        DBUG_RETURN(result);
9388
9523
      seen_first_key= true;
9389
9524
    }
9390
9525
    else
9394
9529
                                   make_prev_keypart_map(group_key_parts),
9395
9530
                                   HA_READ_AFTER_KEY);
9396
9531
      if (result)
9397
 
        return(result);
 
9532
        DBUG_RETURN(result);
9398
9533
    }
9399
9534
  }
9400
9535
 
9405
9540
    memcpy(group_prefix + group_prefix_len,
9406
9541
           key_infix, key_infix_len);
9407
9542
 
9408
 
  return(0);
 
9543
  DBUG_RETURN(0);
9409
9544
}
9410
9545
 
9411
9546
 
9438
9573
  bool found_null= false;
9439
9574
  int result= HA_ERR_KEY_NOT_FOUND;
9440
9575
 
9441
 
  assert(min_max_ranges.elements > 0);
 
9576
  DBUG_ASSERT(min_max_ranges.elements > 0);
9442
9577
 
9443
 
  for (uint32_t range_idx= 0; range_idx < min_max_ranges.elements; range_idx++)
 
9578
  for (uint range_idx= 0; range_idx < min_max_ranges.elements; range_idx++)
9444
9579
  { /* Search from the left-most range to the right. */
9445
 
    get_dynamic(&min_max_ranges, (unsigned char*)&cur_range, range_idx);
 
9580
    get_dynamic(&min_max_ranges, (uchar*)&cur_range, range_idx);
9446
9581
 
9447
9582
    /*
9448
9583
      If the current value for the min/max argument is bigger than the right
9449
9584
      boundary of cur_range, there is no need to check this range.
9450
9585
    */
9451
9586
    if (range_idx != 0 && !(cur_range->flag & NO_MAX_RANGE) &&
9452
 
        (key_cmp(min_max_arg_part, (const unsigned char*) cur_range->max_key,
 
9587
        (key_cmp(min_max_arg_part, (const uchar*) cur_range->max_key,
9453
9588
                 min_max_arg_len) == 1))
9454
9589
      continue;
9455
9590
 
9510
9645
    if ( !(cur_range->flag & NO_MAX_RANGE) )
9511
9646
    {
9512
9647
      /* Compose the MAX key for the range. */
9513
 
      unsigned char *max_key= (unsigned char*) my_alloca(real_prefix_len + min_max_arg_len);
 
9648
      uchar *max_key= (uchar*) my_alloca(real_prefix_len + min_max_arg_len);
9514
9649
      memcpy(max_key, group_prefix, real_prefix_len);
9515
9650
      memcpy(max_key + real_prefix_len, cur_range->max_key,
9516
9651
             cur_range->max_length);
9524
9659
      }
9525
9660
    }
9526
9661
    /* If we got to this point, the current key qualifies as MIN. */
9527
 
    assert(result == 0);
 
9662
    DBUG_ASSERT(result == 0);
9528
9663
    break;
9529
9664
  }
9530
9665
  /*
9569
9704
  QUICK_RANGE *cur_range;
9570
9705
  int result;
9571
9706
 
9572
 
  assert(min_max_ranges.elements > 0);
 
9707
  DBUG_ASSERT(min_max_ranges.elements > 0);
9573
9708
 
9574
 
  for (uint32_t range_idx= min_max_ranges.elements; range_idx > 0; range_idx--)
 
9709
  for (uint range_idx= min_max_ranges.elements; range_idx > 0; range_idx--)
9575
9710
  { /* Search from the right-most range to the left. */
9576
 
    get_dynamic(&min_max_ranges, (unsigned char*)&cur_range, range_idx - 1);
 
9711
    get_dynamic(&min_max_ranges, (uchar*)&cur_range, range_idx - 1);
9577
9712
 
9578
9713
    /*
9579
9714
      If the current value for the min/max argument is smaller than the left
9581
9716
    */
9582
9717
    if (range_idx != min_max_ranges.elements &&
9583
9718
        !(cur_range->flag & NO_MIN_RANGE) &&
9584
 
        (key_cmp(min_max_arg_part, (const unsigned char*) cur_range->min_key,
 
9719
        (key_cmp(min_max_arg_part, (const uchar*) cur_range->min_key,
9585
9720
                 min_max_arg_len) == -1))
9586
9721
      continue;
9587
9722
 
9627
9762
    if ( !(cur_range->flag & NO_MIN_RANGE) )
9628
9763
    {
9629
9764
      /* Compose the MIN key for the range. */
9630
 
      unsigned char *min_key= (unsigned char*) my_alloca(real_prefix_len + min_max_arg_len);
 
9765
      uchar *min_key= (uchar*) my_alloca(real_prefix_len + min_max_arg_len);
9631
9766
      memcpy(min_key, group_prefix, real_prefix_len);
9632
9767
      memcpy(min_key + real_prefix_len, cur_range->min_key,
9633
9768
             cur_range->min_length);
9729
9864
                                                      String *used_lengths)
9730
9865
{
9731
9866
  char buf[64];
9732
 
  uint32_t length;
 
9867
  uint length;
9733
9868
  key_names->append(index_info->name);
9734
 
  length= int64_t2str(max_used_key_length, buf, 10) - buf;
 
9869
  length= longlong2str(max_used_key_length, buf, 10) - buf;
9735
9870
  used_lengths->append(buf, length);
9736
9871
}
9737
9872
 
 
9873
 
 
9874
#ifndef DBUG_OFF
 
9875
 
9738
9876
static void print_sel_tree(PARAM *param, SEL_TREE *tree, key_map *tree_map,
9739
 
                           const char *msg __attribute__((unused)))
 
9877
                           const char *msg)
9740
9878
{
9741
9879
  SEL_ARG **key,**end;
9742
9880
  int idx;
9743
9881
  char buff[1024];
 
9882
  DBUG_ENTER("print_sel_tree");
9744
9883
 
9745
9884
  String tmp(buff,sizeof(buff),&my_charset_bin);
9746
9885
  tmp.length(0);
9750
9889
  {
9751
9890
    if (tree_map->is_set(idx))
9752
9891
    {
9753
 
      uint32_t keynr= param->real_keynr[idx];
 
9892
      uint keynr= param->real_keynr[idx];
9754
9893
      if (tmp.length())
9755
9894
        tmp.append(',');
9756
9895
      tmp.append(param->table->key_info[keynr].name);
9759
9898
  if (!tmp.length())
9760
9899
    tmp.append(STRING_WITH_LEN("(empty)"));
9761
9900
 
9762
 
  return;
 
9901
  DBUG_PRINT("info", ("SEL_TREE: 0x%lx (%s)  scans: %s", (long) tree, msg, tmp.ptr()));
 
9902
 
 
9903
  DBUG_VOID_RETURN;
9763
9904
}
9764
9905
 
9765
9906
 
9766
 
static void print_ror_scans_arr(Table *table,
9767
 
                                const char *msg __attribute__((unused)),
 
9907
static void print_ror_scans_arr(TABLE *table, const char *msg,
9768
9908
                                struct st_ror_scan_info **start,
9769
9909
                                struct st_ror_scan_info **end)
9770
9910
{
 
9911
  DBUG_ENTER("print_ror_scans_arr");
 
9912
 
9771
9913
  char buff[1024];
9772
9914
  String tmp(buff,sizeof(buff),&my_charset_bin);
9773
9915
  tmp.length(0);
9779
9921
  }
9780
9922
  if (!tmp.length())
9781
9923
    tmp.append(STRING_WITH_LEN("(empty)"));
9782
 
  return;
9783
 
}
 
9924
  DBUG_PRINT("info", ("ROR key scans (%s): %s", msg, tmp.ptr()));
 
9925
  DBUG_VOID_RETURN;
 
9926
}
 
9927
 
 
9928
 
 
9929
/*****************************************************************************
 
9930
** Print a quick range for debugging
 
9931
** TODO:
 
9932
** This should be changed to use a String to store each row instead
 
9933
** of locking the DEBUG stream !
 
9934
*****************************************************************************/
 
9935
 
 
9936
static void
 
9937
print_key(KEY_PART *key_part, const uchar *key, uint used_length)
 
9938
{
 
9939
  char buff[1024];
 
9940
  const uchar *key_end= key+used_length;
 
9941
  String tmp(buff,sizeof(buff),&my_charset_bin);
 
9942
  uint store_length;
 
9943
  TABLE *table= key_part->field->table;
 
9944
  my_bitmap_map *old_write_set, *old_read_set;
 
9945
  old_write_set= dbug_tmp_use_all_columns(table, table->write_set);
 
9946
  old_read_set=  dbug_tmp_use_all_columns(table, table->read_set);
 
9947
 
 
9948
  for (; key < key_end; key+=store_length, key_part++)
 
9949
  {
 
9950
    Field *field=      key_part->field;
 
9951
    store_length= key_part->store_length;
 
9952
 
 
9953
    if (field->real_maybe_null())
 
9954
    {
 
9955
      if (*key)
 
9956
      {
 
9957
        fwrite("NULL",sizeof(char),4,DBUG_FILE);
 
9958
        continue;
 
9959
      }
 
9960
      key++;                                    // Skip null byte
 
9961
      store_length--;
 
9962
    }
 
9963
    field->set_key_image(key, key_part->length);
 
9964
    field->val_str(&tmp);
 
9965
    fwrite(tmp.ptr(),sizeof(char),tmp.length(),DBUG_FILE);
 
9966
    if (key+store_length < key_end)
 
9967
      fputc('/',DBUG_FILE);
 
9968
  }
 
9969
  dbug_tmp_restore_column_map(table->write_set, old_write_set);
 
9970
  dbug_tmp_restore_column_map(table->read_set, old_read_set);
 
9971
}
 
9972
 
 
9973
 
 
9974
static void print_quick(QUICK_SELECT_I *quick, const key_map *needed_reg)
 
9975
{
 
9976
  char buf[MAX_KEY/8+1];
 
9977
  TABLE *table;
 
9978
  my_bitmap_map *old_read_map, *old_write_map;
 
9979
  DBUG_ENTER("print_quick");
 
9980
  if (!quick)
 
9981
    DBUG_VOID_RETURN;
 
9982
  DBUG_LOCK_FILE;
 
9983
 
 
9984
  table= quick->head;
 
9985
  old_read_map=  dbug_tmp_use_all_columns(table, table->read_set);
 
9986
  old_write_map= dbug_tmp_use_all_columns(table, table->write_set);
 
9987
  quick->dbug_dump(0, true);
 
9988
  dbug_tmp_restore_column_map(table->read_set, old_read_map);
 
9989
  dbug_tmp_restore_column_map(table->write_set, old_write_map);
 
9990
 
 
9991
  fprintf(DBUG_FILE,"other_keys: 0x%s:\n", needed_reg->print(buf));
 
9992
 
 
9993
  DBUG_UNLOCK_FILE;
 
9994
  DBUG_VOID_RETURN;
 
9995
}
 
9996
 
 
9997
 
 
9998
void QUICK_RANGE_SELECT::dbug_dump(int indent, bool verbose)
 
9999
{
 
10000
  /* purecov: begin inspected */
 
10001
  fprintf(DBUG_FILE, "%*squick range select, key %s, length: %d\n",
 
10002
          indent, "", head->key_info[index].name, max_used_key_length);
 
10003
 
 
10004
  if (verbose)
 
10005
  {
 
10006
    QUICK_RANGE *range;
 
10007
    QUICK_RANGE **pr= (QUICK_RANGE**)ranges.buffer;
 
10008
    QUICK_RANGE **end_range= pr + ranges.elements;
 
10009
    for (; pr != end_range; ++pr)
 
10010
    {
 
10011
      fprintf(DBUG_FILE, "%*s", indent + 2, "");
 
10012
      range= *pr;
 
10013
      if (!(range->flag & NO_MIN_RANGE))
 
10014
      {
 
10015
        print_key(key_parts, range->min_key, range->min_length);
 
10016
        if (range->flag & NEAR_MIN)
 
10017
          fputs(" < ",DBUG_FILE);
 
10018
        else
 
10019
          fputs(" <= ",DBUG_FILE);
 
10020
      }
 
10021
      fputs("X",DBUG_FILE);
 
10022
 
 
10023
      if (!(range->flag & NO_MAX_RANGE))
 
10024
      {
 
10025
        if (range->flag & NEAR_MAX)
 
10026
          fputs(" < ",DBUG_FILE);
 
10027
        else
 
10028
          fputs(" <= ",DBUG_FILE);
 
10029
        print_key(key_parts, range->max_key, range->max_length);
 
10030
      }
 
10031
      fputs("\n",DBUG_FILE);
 
10032
    }
 
10033
  }
 
10034
  /* purecov: end */    
 
10035
}
 
10036
 
 
10037
void QUICK_INDEX_MERGE_SELECT::dbug_dump(int indent, bool verbose)
 
10038
{
 
10039
  List_iterator_fast<QUICK_RANGE_SELECT> it(quick_selects);
 
10040
  QUICK_RANGE_SELECT *quick;
 
10041
  fprintf(DBUG_FILE, "%*squick index_merge select\n", indent, "");
 
10042
  fprintf(DBUG_FILE, "%*smerged scans {\n", indent, "");
 
10043
  while ((quick= it++))
 
10044
    quick->dbug_dump(indent+2, verbose);
 
10045
  if (pk_quick_select)
 
10046
  {
 
10047
    fprintf(DBUG_FILE, "%*sclustered PK quick:\n", indent, "");
 
10048
    pk_quick_select->dbug_dump(indent+2, verbose);
 
10049
  }
 
10050
  fprintf(DBUG_FILE, "%*s}\n", indent, "");
 
10051
}
 
10052
 
 
10053
void QUICK_ROR_INTERSECT_SELECT::dbug_dump(int indent, bool verbose)
 
10054
{
 
10055
  List_iterator_fast<QUICK_RANGE_SELECT> it(quick_selects);
 
10056
  QUICK_RANGE_SELECT *quick;
 
10057
  fprintf(DBUG_FILE, "%*squick ROR-intersect select, %scovering\n",
 
10058
          indent, "", need_to_fetch_row? "":"non-");
 
10059
  fprintf(DBUG_FILE, "%*smerged scans {\n", indent, "");
 
10060
  while ((quick= it++))
 
10061
    quick->dbug_dump(indent+2, verbose);
 
10062
  if (cpk_quick)
 
10063
  {
 
10064
    fprintf(DBUG_FILE, "%*sclustered PK quick:\n", indent, "");
 
10065
    cpk_quick->dbug_dump(indent+2, verbose);
 
10066
  }
 
10067
  fprintf(DBUG_FILE, "%*s}\n", indent, "");
 
10068
}
 
10069
 
 
10070
void QUICK_ROR_UNION_SELECT::dbug_dump(int indent, bool verbose)
 
10071
{
 
10072
  List_iterator_fast<QUICK_SELECT_I> it(quick_selects);
 
10073
  QUICK_SELECT_I *quick;
 
10074
  fprintf(DBUG_FILE, "%*squick ROR-union select\n", indent, "");
 
10075
  fprintf(DBUG_FILE, "%*smerged scans {\n", indent, "");
 
10076
  while ((quick= it++))
 
10077
    quick->dbug_dump(indent+2, verbose);
 
10078
  fprintf(DBUG_FILE, "%*s}\n", indent, "");
 
10079
}
 
10080
 
 
10081
 
 
10082
/*
 
10083
  Print quick select information to DBUG_FILE.
 
10084
 
 
10085
  SYNOPSIS
 
10086
    QUICK_GROUP_MIN_MAX_SELECT::dbug_dump()
 
10087
    indent  Indentation offset
 
10088
    verbose If true show more detailed output.
 
10089
 
 
10090
  DESCRIPTION
 
10091
    Print the contents of this quick select to DBUG_FILE. The method also
 
10092
    calls dbug_dump() for the used quick select if any.
 
10093
 
 
10094
  IMPLEMENTATION
 
10095
    Caller is responsible for locking DBUG_FILE before this call and unlocking
 
10096
    it afterwards.
 
10097
 
 
10098
  RETURN
 
10099
    None
 
10100
*/
 
10101
 
 
10102
void QUICK_GROUP_MIN_MAX_SELECT::dbug_dump(int indent, bool verbose)
 
10103
{
 
10104
  fprintf(DBUG_FILE,
 
10105
          "%*squick_group_min_max_select: index %s (%d), length: %d\n",
 
10106
          indent, "", index_info->name, index, max_used_key_length);
 
10107
  if (key_infix_len > 0)
 
10108
  {
 
10109
    fprintf(DBUG_FILE, "%*susing key_infix with length %d:\n",
 
10110
            indent, "", key_infix_len);
 
10111
  }
 
10112
  if (quick_prefix_select)
 
10113
  {
 
10114
    fprintf(DBUG_FILE, "%*susing quick_range_select:\n", indent, "");
 
10115
    quick_prefix_select->dbug_dump(indent + 2, verbose);
 
10116
  }
 
10117
  if (min_max_ranges.elements > 0)
 
10118
  {
 
10119
    fprintf(DBUG_FILE, "%*susing %d quick_ranges for MIN/MAX:\n",
 
10120
            indent, "", min_max_ranges.elements);
 
10121
  }
 
10122
}
 
10123
 
 
10124
 
 
10125
#endif /* NOT_USED */
9784
10126
 
9785
10127
/*****************************************************************************
9786
10128
** Instantiate templates