~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/optimizer/range.cc

Performed numerous style cleanups in range.[cc,h].

Mainly involved:
 * renaming classes to not be all upper case
 * initializing variables when they are declared
 * correcting wrong indentation
 * removing tabs where I found them
 * correctly lining up paramaters in function calls and delcarations

Show diffs side-by-side

added added

removed removed

Lines of Context:
432
432
  enum { MAX_SEL_ARGS = 16000 };
433
433
 
434
434
  SEL_ARG() {}
 
435
 
435
436
  SEL_ARG(SEL_ARG &);
 
437
 
436
438
  SEL_ARG(Field *,const unsigned char *, const unsigned char *);
437
 
  SEL_ARG(Field *field, uint8_t part, unsigned char *min_value, unsigned char *max_value,
438
 
          uint8_t min_flag, uint8_t max_flag, uint8_t maybe_flag);
 
439
 
 
440
  SEL_ARG(Field *field, 
 
441
          uint8_t part, 
 
442
          unsigned char *min_value, 
 
443
          unsigned char *max_value,
 
444
                uint8_t min_flag, 
 
445
          uint8_t max_flag, 
 
446
          uint8_t maybe_flag);
 
447
 
439
448
  SEL_ARG(enum Type type_arg)
440
 
    :min_flag(0),elements(1),use_count(1),left(0),right(0),next_key_part(0),
441
 
    color(BLACK), type(type_arg)
 
449
    :
 
450
      min_flag(0),
 
451
      elements(1),
 
452
      use_count(1),
 
453
      left(0),
 
454
      right(0),
 
455
      next_key_part(0),
 
456
      color(BLACK), 
 
457
      type(type_arg)
442
458
  {}
 
459
 
443
460
  inline bool is_same(SEL_ARG *arg)
444
461
  {
445
462
    if (type != arg->type || part != arg->part)
446
463
      return 0;
447
464
    if (type != KEY_RANGE)
448
465
      return 1;
449
 
    return cmp_min_to_min(arg) == 0 && cmp_max_to_max(arg) == 0;
450
 
  }
451
 
  inline void merge_flags(SEL_ARG *arg) { maybe_flag|=arg->maybe_flag; }
452
 
  inline void maybe_smaller() { maybe_flag=1; }
 
466
    return (cmp_min_to_min(arg) == 0 && cmp_max_to_max(arg) == 0);
 
467
  }
 
468
 
 
469
  inline void merge_flags(SEL_ARG *arg) 
 
470
  { 
 
471
    maybe_flag|= arg->maybe_flag; 
 
472
  }
 
473
 
 
474
  inline void maybe_smaller() 
 
475
  { 
 
476
    maybe_flag= 1; 
 
477
  }
 
478
 
453
479
  /* Return true iff it's a single-point null interval */
454
 
  inline bool is_null_interval() { return maybe_null && max_value[0] == 1; }
455
 
  inline int cmp_min_to_min(SEL_ARG* arg)
 
480
  inline bool is_null_interval() 
 
481
  { 
 
482
    return (maybe_null && max_value[0] == 1);
 
483
  }
 
484
 
 
485
  inline int cmp_min_to_min(SEL_ARG *arg)
456
486
  {
457
487
    return sel_cmp(field,min_value, arg->min_value, min_flag, arg->min_flag);
458
488
  }
459
 
  inline int cmp_min_to_max(SEL_ARG* arg)
 
489
 
 
490
  inline int cmp_min_to_max(SEL_ARG *arg)
460
491
  {
461
492
    return sel_cmp(field,min_value, arg->max_value, min_flag, arg->max_flag);
462
493
  }
463
 
  inline int cmp_max_to_max(SEL_ARG* arg)
 
494
 
 
495
  inline int cmp_max_to_max(SEL_ARG *arg)
464
496
  {
465
497
    return sel_cmp(field,max_value, arg->max_value, max_flag, arg->max_flag);
466
498
  }
467
 
  inline int cmp_max_to_min(SEL_ARG* arg)
 
499
 
 
500
  inline int cmp_max_to_min(SEL_ARG *arg)
468
501
  {
469
502
    return sel_cmp(field,max_value, arg->min_value, max_flag, arg->min_flag);
470
503
  }
471
 
  SEL_ARG *clone_and(SEL_ARG* arg)
 
504
 
 
505
  SEL_ARG *clone_and(SEL_ARG *arg)
472
506
  {                                             // Get overlapping range
473
 
    unsigned char *new_min,*new_max;
474
 
    uint8_t flag_min,flag_max;
 
507
    unsigned char *new_min= NULL;
 
508
    unsigned char *new_max= NULL;
 
509
    uint8_t flag_min;
 
510
    uint8_t flag_max;
 
511
 
475
512
    if (cmp_min_to_min(arg) >= 0)
476
513
    {
477
 
      new_min=min_value; flag_min=min_flag;
 
514
      new_min= min_value;
 
515
      flag_min= min_flag;
478
516
    }
479
517
    else
480
518
    {
482
520
    }
483
521
    if (cmp_max_to_max(arg) <= 0)
484
522
    {
485
 
      new_max=max_value; flag_max=max_flag;
 
523
      new_max= max_value; 
 
524
      flag_max= max_flag;
486
525
    }
487
526
    else
488
527
    {
489
 
      new_max=arg->max_value; flag_max=arg->max_flag;
 
528
      new_max= arg->max_value; 
 
529
      flag_max= arg->max_flag;
490
530
    }
491
 
    return new SEL_ARG(field, part, new_min, new_max, flag_min, flag_max,
492
 
                       test(maybe_flag && arg->maybe_flag));
 
531
    return (new SEL_ARG(field, 
 
532
                        part, 
 
533
                        new_min, 
 
534
                        new_max, 
 
535
                        flag_min, 
 
536
                        flag_max,
 
537
                                    test(maybe_flag && arg->maybe_flag)));
493
538
  }
 
539
 
494
540
  SEL_ARG *clone_first(SEL_ARG *arg)
495
541
  {                                             // min <= X < arg->min
496
 
    return new SEL_ARG(field,part, min_value, arg->min_value,
497
 
                       min_flag, arg->min_flag & NEAR_MIN ? 0 : NEAR_MAX,
498
 
                       maybe_flag | arg->maybe_flag);
 
542
    return (new SEL_ARG(field,part, 
 
543
                        min_value, 
 
544
                        arg->min_value,
 
545
                                    min_flag, 
 
546
                        arg->min_flag & NEAR_MIN ? 0 : NEAR_MAX,
 
547
                                    maybe_flag | arg->maybe_flag));
499
548
  }
 
549
 
500
550
  SEL_ARG *clone_last(SEL_ARG *arg)
501
551
  {                                             // min <= X <= key_max
502
 
    return new SEL_ARG(field, part, min_value, arg->max_value,
503
 
                       min_flag, arg->max_flag, maybe_flag | arg->maybe_flag);
 
552
    return (new SEL_ARG(field, 
 
553
                        part, 
 
554
                        min_value, 
 
555
                        arg->max_value,
 
556
                                    min_flag, 
 
557
                        arg->max_flag, 
 
558
                        maybe_flag | arg->maybe_flag));
504
559
  }
 
560
 
505
561
  SEL_ARG *clone(RANGE_OPT_PARAM *param, SEL_ARG *new_parent, SEL_ARG **next);
506
562
 
507
 
  bool copy_min(SEL_ARG* arg)
 
563
  bool copy_min(SEL_ARG *arg)
508
564
  {                                             // Get overlapping range
509
565
    if (cmp_min_to_min(arg) > 0)
510
566
    {
511
 
      min_value=arg->min_value; min_flag=arg->min_flag;
 
567
      min_value= arg->min_value;
 
568
      min_flag=arg->min_flag;
512
569
      if ((max_flag & (NO_MAX_RANGE | NO_MIN_RANGE)) ==
513
 
          (NO_MAX_RANGE | NO_MIN_RANGE))
514
 
        return 1;                               // Full range
 
570
          (NO_MAX_RANGE | NO_MIN_RANGE))
 
571
      {
 
572
        return 1;       // Full range
 
573
      }
515
574
    }
516
 
    maybe_flag|=arg->maybe_flag;
 
575
    maybe_flag|= arg->maybe_flag;
517
576
    return 0;
518
577
  }
519
 
  bool copy_max(SEL_ARG* arg)
 
578
 
 
579
  bool copy_max(SEL_ARG *arg)
520
580
  {                                             // Get overlapping range
521
581
    if (cmp_max_to_max(arg) <= 0)
522
582
    {
523
 
      max_value=arg->max_value; max_flag=arg->max_flag;
 
583
      max_value= arg->max_value;
 
584
      max_flag= arg->max_flag;
524
585
      if ((max_flag & (NO_MAX_RANGE | NO_MIN_RANGE)) ==
525
 
          (NO_MAX_RANGE | NO_MIN_RANGE))
526
 
        return 1;                               // Full range
 
586
          (NO_MAX_RANGE | NO_MIN_RANGE))
 
587
      {
 
588
        return 1;       // Full range
 
589
      }
527
590
    }
528
 
    maybe_flag|=arg->maybe_flag;
 
591
    maybe_flag|= arg->maybe_flag;
529
592
    return 0;
530
593
  }
531
594
 
532
595
  void copy_min_to_min(SEL_ARG *arg)
533
596
  {
534
 
    min_value=arg->min_value; min_flag=arg->min_flag;
 
597
    min_value= arg->min_value;
 
598
    min_flag= arg->min_flag;
535
599
  }
 
600
 
536
601
  void copy_min_to_max(SEL_ARG *arg)
537
602
  {
538
 
    max_value=arg->min_value;
539
 
    max_flag=arg->min_flag & NEAR_MIN ? 0 : NEAR_MAX;
 
603
    max_value= arg->min_value;
 
604
    max_flag= arg->min_flag & NEAR_MIN ? 0 : NEAR_MAX;
540
605
  }
 
606
 
541
607
  void copy_max_to_min(SEL_ARG *arg)
542
608
  {
543
 
    min_value=arg->max_value;
544
 
    min_flag=arg->max_flag & NEAR_MAX ? 0 : NEAR_MIN;
 
609
    min_value= arg->max_value;
 
610
    min_flag= arg->max_flag & NEAR_MAX ? 0 : NEAR_MIN;
545
611
  }
 
612
 
546
613
  /* returns a number of keypart values (0 or 1) appended to the key buffer */
547
 
  int store_min(uint32_t length, unsigned char **min_key,uint32_t min_key_flag)
 
614
  int store_min(uint32_t length, unsigned char **min_key, uint32_t min_key_flag)
548
615
  {
549
616
    /* "(kp1 > c1) AND (kp2 OP c2) AND ..." -> (kp1 > c1) */
550
 
    if ((!(min_flag & NO_MIN_RANGE) &&
551
 
        !(min_key_flag & (NO_MIN_RANGE | NEAR_MIN))))
 
617
    if ((! (min_flag & NO_MIN_RANGE) &&
 
618
         ! (min_key_flag & (NO_MIN_RANGE | NEAR_MIN))))
552
619
    {
553
620
      if (maybe_null && *min_value)
554
621
      {
555
 
        **min_key=1;
556
 
        memset(*min_key+1, 0, length-1);
 
622
        **min_key= 1;
 
623
        memset(*min_key+1, 0, length-1);
557
624
      }
558
625
      else
559
 
        memcpy(*min_key,min_value,length);
 
626
      {
 
627
        memcpy(*min_key,min_value,length);
 
628
      }
560
629
      (*min_key)+= length;
561
630
      return 1;
562
631
    }
563
632
    return 0;
564
633
  }
 
634
 
565
635
  /* returns a number of keypart values (0 or 1) appended to the key buffer */
566
636
  int store_max(uint32_t length, unsigned char **max_key, uint32_t max_key_flag)
567
637
  {
568
 
    if (!(max_flag & NO_MAX_RANGE) &&
569
 
        !(max_key_flag & (NO_MAX_RANGE | NEAR_MAX)))
 
638
    if (! (max_flag & NO_MAX_RANGE) &&
 
639
        ! (max_key_flag & (NO_MAX_RANGE | NEAR_MAX)))
570
640
    {
571
641
      if (maybe_null && *max_value)
572
642
      {
573
 
        **max_key=1;
574
 
        memset(*max_key+1, 0, length-1);
 
643
        **max_key= 1;
 
644
        memset(*max_key + 1, 0, length-1);
575
645
      }
576
646
      else
577
 
        memcpy(*max_key,max_value,length);
 
647
      {
 
648
        memcpy(*max_key,max_value,length);
 
649
      }
578
650
      (*max_key)+= length;
579
651
      return 1;
580
652
    }
586
658
  {
587
659
    SEL_ARG *key_tree= first();
588
660
    uint32_t res= key_tree->store_min(key[key_tree->part].store_length,
589
 
                                  range_key, *range_key_flag);
 
661
                                      range_key, 
 
662
                                      *range_key_flag);
590
663
    *range_key_flag|= key_tree->min_flag;
591
664
 
592
665
    if (key_tree->next_key_part &&
593
 
        key_tree->next_key_part->part == key_tree->part+1 &&
594
 
        !(*range_key_flag & (NO_MIN_RANGE | NEAR_MIN)) &&
595
 
        key_tree->next_key_part->type == SEL_ARG::KEY_RANGE)
596
 
      res+= key_tree->next_key_part->store_min_key(key, range_key,
 
666
        key_tree->next_key_part->part == key_tree->part+1 &&
 
667
        ! (*range_key_flag & (NO_MIN_RANGE | NEAR_MIN)) &&
 
668
        key_tree->next_key_part->type == SEL_ARG::KEY_RANGE)
 
669
    {
 
670
      res+= key_tree->next_key_part->store_min_key(key, 
 
671
                                                   range_key,
597
672
                                                   range_key_flag);
 
673
    }
598
674
    return res;
599
675
  }
600
676
 
602
678
  int store_max_key(KEY_PART *key, unsigned char **range_key, uint32_t *range_key_flag)
603
679
  {
604
680
    SEL_ARG *key_tree= last();
605
 
    uint32_t res=key_tree->store_max(key[key_tree->part].store_length,
606
 
                                 range_key, *range_key_flag);
 
681
    uint32_t res= key_tree->store_max(key[key_tree->part].store_length,
 
682
                                      range_key, 
 
683
                                      *range_key_flag);
607
684
    (*range_key_flag)|= key_tree->max_flag;
608
685
    if (key_tree->next_key_part &&
609
 
        key_tree->next_key_part->part == key_tree->part+1 &&
610
 
        !(*range_key_flag & (NO_MAX_RANGE | NEAR_MAX)) &&
611
 
        key_tree->next_key_part->type == SEL_ARG::KEY_RANGE)
612
 
      res+= key_tree->next_key_part->store_max_key(key, range_key,
 
686
        key_tree->next_key_part->part == key_tree->part+1 &&
 
687
        ! (*range_key_flag & (NO_MAX_RANGE | NEAR_MAX)) &&
 
688
        key_tree->next_key_part->type == SEL_ARG::KEY_RANGE)
 
689
      res+= key_tree->next_key_part->store_max_key(key, 
 
690
                                                   range_key,
613
691
                                                   range_key_flag);
614
692
    return res;
615
693
  }
618
696
  SEL_ARG *tree_delete(SEL_ARG *key);
619
697
  SEL_ARG *find_range(SEL_ARG *key);
620
698
  SEL_ARG *rb_insert(SEL_ARG *leaf);
 
699
 
621
700
  friend SEL_ARG *rb_delete_fixup(SEL_ARG *root,SEL_ARG *key, SEL_ARG *par);
622
701
#ifdef EXTRA_DEBUG
623
702
  friend int test_rb_tree(SEL_ARG *element,SEL_ARG *parent);
626
705
  SEL_ARG *first();
627
706
  SEL_ARG *last();
628
707
  void make_root();
 
708
 
629
709
  inline bool simple_key()
630
710
  {
631
 
    return !next_key_part && elements == 1;
 
711
    return (! next_key_part && elements == 1);
632
712
  }
 
713
 
633
714
  void increment_use_count(long count)
634
715
  {
635
716
    if (next_key_part)
636
717
    {
637
 
      next_key_part->use_count+=count;
638
 
      count*= (next_key_part->use_count-count);
639
 
      for (SEL_ARG *pos=next_key_part->first(); pos ; pos=pos->next)
640
 
        if (pos->next_key_part)
641
 
          pos->increment_use_count(count);
 
718
      next_key_part->use_count+= count;
 
719
      count*= (next_key_part->use_count - count);
 
720
      for (SEL_ARG *pos= next_key_part->first(); pos; pos= pos->next)
 
721
        if (pos->next_key_part)
 
722
          pos->increment_use_count(count);
642
723
    }
643
724
  }
 
725
 
644
726
  void free_tree()
645
727
  {
646
 
    for (SEL_ARG *pos=first(); pos ; pos=pos->next)
 
728
    for (SEL_ARG *pos= first(); pos; pos= pos->next)
647
729
      if (pos->next_key_part)
648
730
      {
649
 
        pos->next_key_part->use_count--;
650
 
        pos->next_key_part->free_tree();
 
731
        pos->next_key_part->use_count--;
 
732
        pos->next_key_part->free_tree();
651
733
      }
652
734
  }
653
735
 
695
777
      min_val++;
696
778
      max_val++;
697
779
    }
698
 
    return !field->key_cmp(min_val, max_val);
 
780
    return ! field->key_cmp(min_val, max_val);
699
781
  }
 
782
 
700
783
  SEL_ARG *clone_tree(RANGE_OPT_PARAM *param);
701
784
};
702
785
 
735
818
 
736
819
  /* The members below are filled/used only after get_mm_tree is done */
737
820
  key_map ror_scans_map;   /* bitmask of ROR scan-able elements in keys */
738
 
  uint32_t    n_ror_scans;     /* number of set bits in ror_scans_map */
 
821
  uint32_t n_ror_scans;     /* number of set bits in ror_scans_map */
739
822
 
740
823
  struct st_ror_scan_info **ror_scans;     /* list of ROR key scans */
741
824
  struct st_ror_scan_info **ror_scans_end; /* last ROR scan */
797
880
  MyBitmap needed_fields;    /* bitmask of fields needed by the query */
798
881
  MyBitmap tmp_covered_fields;
799
882
 
800
 
  key_map *needed_reg;        /* ptr to SQL_SELECT::needed_reg */
 
883
  key_map *needed_reg;        /* ptr to SqlSelect::needed_reg */
801
884
 
802
885
  uint32_t *imerge_cost_buff;     /* buffer for index_merge cost estimates */
803
886
  uint32_t imerge_cost_buff_size; /* size of the buffer */
817
900
 
818
901
struct st_ror_scan_info;
819
902
 
820
 
static SEL_TREE * get_mm_parts(RANGE_OPT_PARAM *param,COND *cond_func,Field *field,
821
 
                               Item_func::Functype type,Item *value,
822
 
                               Item_result cmp_type);
823
 
static SEL_ARG *get_mm_leaf(RANGE_OPT_PARAM *param,COND *cond_func,Field *field,
824
 
                            KEY_PART *key_part,
825
 
                            Item_func::Functype type,Item *value);
 
903
static SEL_TREE * get_mm_parts(RANGE_OPT_PARAM *param,
 
904
                               COND *cond_func,
 
905
                               Field *field,
 
906
                                                 Item_func::Functype type,
 
907
                               Item *value,
 
908
                                                 Item_result cmp_type);
 
909
 
 
910
static SEL_ARG *get_mm_leaf(RANGE_OPT_PARAM *param,
 
911
                            COND *cond_func,Field *field,
 
912
                            KEY_PART *key_part,
 
913
                                              Item_func::Functype type,Item *value);
 
914
 
826
915
static SEL_TREE *get_mm_tree(RANGE_OPT_PARAM *param,COND *cond);
827
916
 
828
917
static bool is_key_scan_ror(PARAM *param, uint32_t keynr, uint8_t nparts);
 
918
 
829
919
static ha_rows check_quick_select(PARAM *param, uint32_t idx, bool index_only,
830
920
                                  SEL_ARG *tree, bool update_tbl_stats,
831
921
                                  uint32_t *mrr_flags, uint32_t *bufsize,
835
925
                                       bool index_read_must_be_used,
836
926
                                       bool update_tbl_stats,
837
927
                                       double read_time);
 
928
 
838
929
static
839
930
TRP_ROR_INTERSECT *get_best_ror_intersect(const PARAM *param, SEL_TREE *tree,
840
931
                                          double read_time,
841
932
                                          bool *are_all_covering);
 
933
 
842
934
static
843
935
TRP_ROR_INTERSECT *get_best_covering_ror_intersect(PARAM *param,
844
936
                                                   SEL_TREE *tree,
845
937
                                                   double read_time);
 
938
 
846
939
static
847
 
TABLE_READ_PLAN *get_best_disjunct_quick(PARAM *param, SEL_IMERGE *imerge,
 
940
TABLE_READ_PLAN *get_best_disjunct_quick(PARAM *param, 
 
941
                                         SEL_IMERGE *imerge,
848
942
                                         double read_time);
 
943
 
849
944
static
850
945
TRP_GROUP_MIN_MAX *get_best_group_min_max(PARAM *param, SEL_TREE *tree);
851
946
 
852
 
static void print_sel_tree(PARAM *param, SEL_TREE *tree, key_map *tree_map,
 
947
static void print_sel_tree(PARAM *param, 
 
948
                           SEL_TREE *tree, 
 
949
                           key_map *tree_map,
853
950
                           const char *msg);
854
 
static void print_ror_scans_arr(Table *table, const char *msg,
 
951
 
 
952
static void print_ror_scans_arr(Table *table, 
 
953
                                const char *msg,
855
954
                                struct st_ror_scan_info **start,
856
955
                                struct st_ror_scan_info **end);
857
956
 
858
957
static SEL_TREE *tree_and(RANGE_OPT_PARAM *param,SEL_TREE *tree1,SEL_TREE *tree2);
 
958
 
859
959
static SEL_TREE *tree_or(RANGE_OPT_PARAM *param,SEL_TREE *tree1,SEL_TREE *tree2);
 
960
 
860
961
static SEL_ARG *sel_add(SEL_ARG *key1,SEL_ARG *key2);
 
962
 
861
963
static SEL_ARG *key_or(RANGE_OPT_PARAM *param, SEL_ARG *key1, SEL_ARG *key2);
862
 
static SEL_ARG *key_and(RANGE_OPT_PARAM *param, SEL_ARG *key1, SEL_ARG *key2,
 
964
 
 
965
static SEL_ARG *key_and(RANGE_OPT_PARAM *param, 
 
966
                        SEL_ARG *key1, 
 
967
                        SEL_ARG *key2,
863
968
                        uint32_t clone_flag);
 
969
 
864
970
static bool get_range(SEL_ARG **e1,SEL_ARG **e2,SEL_ARG *root1);
865
971
 
866
972
static bool eq_tree(SEL_ARG* a,SEL_ARG *b);
867
973
 
868
974
static SEL_ARG null_element(SEL_ARG::IMPOSSIBLE);
869
 
static bool null_part_in_key(KEY_PART *key_part, const unsigned char *key,
 
975
 
 
976
static bool null_part_in_key(KEY_PART *key_part, 
 
977
                             const unsigned char *key,
870
978
                             uint32_t length);
 
979
 
871
980
bool sel_trees_can_be_ored(SEL_TREE *tree1, SEL_TREE *tree2, RANGE_OPT_PARAM* param);
872
981
 
873
982
 
917
1026
     0 - OK
918
1027
    -1 - Out of memory.
919
1028
*/
920
 
 
921
1029
int SEL_IMERGE::or_sel_tree(RANGE_OPT_PARAM *param, SEL_TREE *tree)
922
1030
{
923
1031
  if (trees_next == trees_end)
930
1038
    if (!(new_trees= (SEL_TREE**)alloc_root(param->mem_root, new_size)))
931
1039
      return -1;
932
1040
    memcpy(new_trees, trees, old_size);
933
 
    trees=      new_trees;
 
1041
    trees= new_trees;
934
1042
    trees_next= trees + old_elements;
935
 
    trees_end=  trees + old_elements * realloc_ratio;
 
1043
    trees_end= trees + old_elements * realloc_ratio;
936
1044
  }
937
1045
  *(trees_next++)= tree;
938
1046
  return 0;
946
1054
 
947
1055
  SYNOPSIS
948
1056
    or_sel_tree_with_checks()
949
 
      param    PARAM from SQL_SELECT::test_quick_select
 
1057
      param    PARAM from SqlSelect::test_quick_select
950
1058
      new_tree SEL_TREE with type KEY or KEY_SMALLER.
951
1059
 
952
1060
  NOTES
968
1076
       and (*this) should be discarded.
969
1077
   -1  An error occurred.
970
1078
*/
971
 
 
972
1079
int SEL_IMERGE::or_sel_tree_with_checks(RANGE_OPT_PARAM *param, SEL_TREE *new_tree)
973
1080
{
974
1081
  for (SEL_TREE** tree = trees;
1085
1192
 
1086
1193
 
1087
1194
/***************************************************************************
1088
 
** Basic functions for SQL_SELECT and QuickRangeSelect
 
1195
** Basic functions for SqlSelect and QuickRangeSelect
1089
1196
***************************************************************************/
1090
1197
 
1091
1198
        /* make a select from mysql info
1094
1201
           1 = Got some error (out of memory?)
1095
1202
           */
1096
1203
 
1097
 
optimizer::SQL_SELECT *optimizer::make_select(Table *head, 
 
1204
optimizer::SqlSelect *optimizer::make_select(Table *head, 
1098
1205
                                              table_map const_tables,
1099
1206
                                              table_map read_tables, 
1100
1207
                                              COND *conds,
1101
1208
                                              bool allow_null_cond,
1102
1209
                                              int *error)
1103
1210
{
1104
 
  optimizer::SQL_SELECT *select= NULL;
 
1211
  optimizer::SqlSelect *select= NULL;
1105
1212
 
1106
1213
  *error= 0;
1107
1214
 
1109
1216
  {
1110
1217
    return 0;
1111
1218
  }
1112
 
  if (! (select= new optimizer::SQL_SELECT))
 
1219
  if (! (select= new optimizer::SqlSelect))
1113
1220
  {
1114
1221
    *error= 1;                  // out of memory
1115
1222
    return 0;
1131
1238
}
1132
1239
 
1133
1240
 
1134
 
optimizer::SQL_SELECT::SQL_SELECT() :quick(0),cond(0),free_cond(0)
 
1241
optimizer::SqlSelect::SqlSelect() :quick(0),cond(0),free_cond(0)
1135
1242
{
1136
1243
  quick_keys.reset(); 
1137
1244
  needed_reg.reset();
1139
1246
}
1140
1247
 
1141
1248
 
1142
 
void optimizer::SQL_SELECT::cleanup()
 
1249
void optimizer::SqlSelect::cleanup()
1143
1250
{
1144
1251
  delete quick;
1145
1252
  quick= 0;
1153
1260
}
1154
1261
 
1155
1262
 
1156
 
optimizer::SQL_SELECT::~SQL_SELECT()
 
1263
optimizer::SqlSelect::~SqlSelect()
1157
1264
{
1158
1265
  cleanup();
1159
1266
}
1160
1267
 
1161
1268
 
1162
 
bool optimizer::SQL_SELECT::check_quick(Session *session, bool force_quick_range,
 
1269
bool optimizer::SqlSelect::check_quick(Session *session, bool force_quick_range,
1163
1270
                             ha_rows limit)
1164
1271
{
1165
1272
  key_map tmp;
1169
1276
}
1170
1277
 
1171
1278
 
1172
 
bool optimizer::SQL_SELECT::skip_record()
 
1279
bool optimizer::SqlSelect::skip_record()
1173
1280
{
1174
1281
  return cond ? cond->val_int() == 0 : 0;
1175
1282
}
1176
1283
 
1177
1284
 
1178
 
optimizer::QUICK_SELECT_I::QUICK_SELECT_I()
 
1285
optimizer::QuickSelectInterface::QuickSelectInterface()
1179
1286
  :
1180
1287
    max_used_key_length(0),
1181
1288
    used_key_parts(0)
1627
1734
  public:
1628
1735
  compare_functor(optimizer::QUICK_ROR_UNION_SELECT *in_arg)
1629
1736
    : self(in_arg) { }
1630
 
  inline bool operator()(const optimizer::QUICK_SELECT_I *i, const optimizer::QUICK_SELECT_I *j) const
 
1737
  inline bool operator()(const optimizer::QuickSelectInterface *i, const optimizer::QuickSelectInterface *j) const
1631
1738
  {
1632
1739
    int val= self->head->cursor->cmp_ref(i->last_rowid,
1633
1740
                                         j->last_rowid);
1648
1755
int optimizer::QUICK_ROR_UNION_SELECT::init()
1649
1756
{
1650
1757
  queue= 
1651
 
    new priority_queue<optimizer::QUICK_SELECT_I *, 
1652
 
                       vector<optimizer::QUICK_SELECT_I *>, 
 
1758
    new priority_queue<optimizer::QuickSelectInterface *, 
 
1759
                       vector<optimizer::QuickSelectInterface *>, 
1653
1760
                       optimizer::compare_functor >(optimizer::compare_functor(this));
1654
1761
  if (! (cur_rowid= (unsigned char*) alloc_root(&alloc, 2*head->cursor->ref_length)))
1655
1762
  {
1672
1779
 
1673
1780
int optimizer::QUICK_ROR_UNION_SELECT::reset()
1674
1781
{
1675
 
  QUICK_SELECT_I *quick= NULL;
 
1782
  QuickSelectInterface *quick= NULL;
1676
1783
  int error;
1677
1784
  have_prev_rowid= false;
1678
1785
  if (! scans_inited)
1679
1786
  {
1680
 
    List_iterator_fast<QUICK_SELECT_I> it(quick_selects);
 
1787
    List_iterator_fast<QuickSelectInterface> it(quick_selects);
1681
1788
    while ((quick= it++))
1682
1789
    {
1683
1790
      if (quick->init_ror_merged_scan(false))
1695
1802
    Initialize scans for merged quick selects and put all merged quick
1696
1803
    selects into the queue.
1697
1804
  */
1698
 
  List_iterator_fast<QUICK_SELECT_I> it(quick_selects);
 
1805
  List_iterator_fast<QuickSelectInterface> it(quick_selects);
1699
1806
  while ((quick= it++))
1700
1807
  {
1701
1808
    if (quick->reset())
1724
1831
 
1725
1832
 
1726
1833
bool
1727
 
optimizer::QUICK_ROR_UNION_SELECT::push_quick_back(QUICK_SELECT_I *quick_sel_range)
 
1834
optimizer::QUICK_ROR_UNION_SELECT::push_quick_back(QuickSelectInterface *quick_sel_range)
1728
1835
{
1729
1836
  return quick_selects.push_back(quick_sel_range);
1730
1837
}
2019
2126
 
2020
2127
 
2021
2128
/*
2022
 
  Table rows retrieval plan. Range optimizer creates QUICK_SELECT_I-derived
 
2129
  Table rows retrieval plan. Range optimizer creates QuickSelectInterface-derived
2023
2130
  objects from table read plans.
2024
2131
*/
2025
2132
class TABLE_READ_PLAN
2054
2161
      created quick select
2055
2162
      NULL on any error.
2056
2163
  */
2057
 
  virtual optimizer::QUICK_SELECT_I *make_quick(PARAM *param,
 
2164
  virtual optimizer::QuickSelectInterface *make_quick(PARAM *param,
2058
2165
                                                bool retrieve_full_rows,
2059
2166
                                                MEM_ROOT *parent_alloc=NULL) = 0;
2060
2167
 
2094
2201
  {}
2095
2202
  virtual ~TRP_RANGE() {}                     /* Remove gcc warning */
2096
2203
 
2097
 
  optimizer::QUICK_SELECT_I *make_quick(PARAM *param, bool, MEM_ROOT *parent_alloc)
 
2204
  optimizer::QuickSelectInterface *make_quick(PARAM *param, bool, MEM_ROOT *parent_alloc)
2098
2205
  {
2099
 
    optimizer::QuickRangeSelect *quick;
 
2206
    optimizer::QuickRangeSelect *quick= NULL;
2100
2207
    if ((quick= optimizer::get_quick_select(param, 
2101
2208
                                            key_idx, 
2102
2209
                                            key, 
2119
2226
public:
2120
2227
  TRP_ROR_INTERSECT() {}                      /* Remove gcc warning */
2121
2228
  virtual ~TRP_ROR_INTERSECT() {}             /* Remove gcc warning */
2122
 
  optimizer::QUICK_SELECT_I *make_quick(PARAM *param, 
 
2229
  optimizer::QuickSelectInterface *make_quick(PARAM *param, 
2123
2230
                                        bool retrieve_full_rows,
2124
2231
                                        MEM_ROOT *parent_alloc);
2125
2232
 
2143
2250
public:
2144
2251
  TRP_ROR_UNION() {}                          /* Remove gcc warning */
2145
2252
  virtual ~TRP_ROR_UNION() {}                 /* Remove gcc warning */
2146
 
  optimizer::QUICK_SELECT_I *make_quick(PARAM *param, 
 
2253
  optimizer::QuickSelectInterface *make_quick(PARAM *param, 
2147
2254
                                        bool retrieve_full_rows,
2148
2255
                                        MEM_ROOT *parent_alloc);
2149
2256
  TABLE_READ_PLAN **first_ror; /* array of ptrs to plans for merged scans */
2162
2269
public:
2163
2270
  TRP_INDEX_MERGE() {}                        /* Remove gcc warning */
2164
2271
  virtual ~TRP_INDEX_MERGE() {}               /* Remove gcc warning */
2165
 
  optimizer::QUICK_SELECT_I *make_quick(PARAM *param, 
 
2272
  optimizer::QuickSelectInterface *make_quick(PARAM *param, 
2166
2273
                                        bool retrieve_full_rows,
2167
2274
                                        MEM_ROOT *parent_alloc);
2168
2275
  TRP_RANGE **range_scans; /* array of ptrs to plans of merged scans */
2214
2321
    }
2215
2322
  virtual ~TRP_GROUP_MIN_MAX() {}             /* Remove gcc warning */
2216
2323
 
2217
 
  optimizer::QUICK_SELECT_I *make_quick(PARAM *param, 
 
2324
  optimizer::QuickSelectInterface *make_quick(PARAM *param, 
2218
2325
                                        bool retrieve_full_rows,
2219
2326
                                        MEM_ROOT *parent_alloc);
2220
2327
};
2267
2374
  Test if a key can be used in different ranges
2268
2375
 
2269
2376
  SYNOPSIS
2270
 
    SQL_SELECT::test_quick_select()
 
2377
    SqlSelect::test_quick_select()
2271
2378
      session               Current thread
2272
2379
      keys_to_use       Keys to use for range retrieval
2273
2380
      prev_tables       Tables assumed to be already read when the scan is
2329
2436
    1 if found usable ranges and quick select has been successfully created.
2330
2437
*/
2331
2438
 
2332
 
int optimizer::SQL_SELECT::test_quick_select(Session *session, 
 
2439
int optimizer::SqlSelect::test_quick_select(Session *session, 
2333
2440
                                             key_map keys_to_use,
2334
2441
                                                                     table_map prev_tables,
2335
2442
                                                                     ha_rows limit, 
2682
2789
        One of index scans in this index_merge is more expensive than entire
2683
2790
        table read for another available option. The entire index_merge (and
2684
2791
        any possible ROR-union) will be more expensive then, too. We continue
2685
 
        here only to update SQL_SELECT members.
 
2792
        here only to update SqlSelect members.
2686
2793
      */
2687
2794
      imerge_too_expensive= true;
2688
2795
    }
3783
3890
}
3784
3891
 
3785
3892
 
3786
 
optimizer::QUICK_SELECT_I *TRP_INDEX_MERGE::make_quick(PARAM *param, bool, MEM_ROOT *)
 
3893
optimizer::QuickSelectInterface *TRP_INDEX_MERGE::make_quick(PARAM *param, bool, MEM_ROOT *)
3787
3894
{
3788
3895
  optimizer::QUICK_INDEX_MERGE_SELECT *quick_imerge;
3789
3896
  optimizer::QuickRangeSelect *quick;
3810
3917
  return quick_imerge;
3811
3918
}
3812
3919
 
3813
 
optimizer::QUICK_SELECT_I *TRP_ROR_INTERSECT::make_quick(PARAM *param,
 
3920
optimizer::QuickSelectInterface *TRP_ROR_INTERSECT::make_quick(PARAM *param,
3814
3921
                                                         bool retrieve_full_rows,
3815
3922
                                                         MEM_ROOT *parent_alloc)
3816
3923
{
3817
 
  optimizer::QUICK_ROR_INTERSECT_SELECT *quick_intrsect= NULL;
 
3924
  optimizer::QUICK_ROR_INTERSECT_SELECT *quick_intersect= NULL;
3818
3925
  optimizer::QuickRangeSelect *quick= NULL;
3819
3926
  MEM_ROOT *alloc= NULL;
3820
3927
 
3821
 
  if ((quick_intrsect=
3822
 
         new optimizer::QUICK_ROR_INTERSECT_SELECT(param->session, param->table,
3823
 
                                                   (retrieve_full_rows? (!is_covering) :
3824
 
                                                    false),
 
3928
  if ((quick_intersect=
 
3929
         new optimizer::QUICK_ROR_INTERSECT_SELECT(param->session, 
 
3930
                                                   param->table,
 
3931
                                                   (retrieve_full_rows? (! is_covering) : false),
3825
3932
                                                   parent_alloc)))
3826
3933
  {
3827
3934
    print_ror_scans_arr(param->table,
3828
 
                                             "creating ROR-intersect",
3829
 
                                             first_scan, last_scan);
3830
 
    alloc= parent_alloc? parent_alloc: &quick_intrsect->alloc;
3831
 
    for (; first_scan != last_scan;++first_scan)
 
3935
                        "creating ROR-intersect",
 
3936
                        first_scan, 
 
3937
                        last_scan);
 
3938
    alloc= parent_alloc ? parent_alloc : &quick_intersect->alloc;
 
3939
    for (; first_scan != last_scan; ++first_scan)
3832
3940
    {
3833
3941
      if (! (quick= optimizer::get_quick_select(param, 
3834
3942
                                                (*first_scan)->idx,
3836
3944
                                                HA_MRR_USE_DEFAULT_IMPL | HA_MRR_SORTED,
3837
3945
                                                0, 
3838
3946
                                                alloc)) ||
3839
 
          quick_intrsect->push_quick_back(quick))
 
3947
          quick_intersect->push_quick_back(quick))
3840
3948
      {
3841
 
        delete quick_intrsect;
 
3949
        delete quick_intersect;
3842
3950
        return NULL;
3843
3951
      }
3844
3952
    }
3851
3959
                                                0, 
3852
3960
                                                alloc)))
3853
3961
      {
3854
 
        delete quick_intrsect;
 
3962
        delete quick_intersect;
3855
3963
        return NULL;
3856
3964
      }
3857
3965
      quick->resetCursor();
3858
 
      quick_intrsect->cpk_quick= quick;
 
3966
      quick_intersect->cpk_quick= quick;
3859
3967
    }
3860
 
    quick_intrsect->records= records;
3861
 
    quick_intrsect->read_time= read_cost;
 
3968
    quick_intersect->records= records;
 
3969
    quick_intersect->read_time= read_cost;
3862
3970
  }
3863
 
  return quick_intrsect;
 
3971
  return quick_intersect;
3864
3972
}
3865
3973
 
3866
3974
 
3867
 
optimizer::QUICK_SELECT_I *TRP_ROR_UNION::make_quick(PARAM *param, bool, MEM_ROOT *)
 
3975
optimizer::QuickSelectInterface *TRP_ROR_UNION::make_quick(PARAM *param, bool, MEM_ROOT *)
3868
3976
{
3869
3977
  optimizer::QUICK_ROR_UNION_SELECT *quick_roru;
3870
3978
  TABLE_READ_PLAN **scan;
3871
 
  optimizer::QUICK_SELECT_I *quick;
 
3979
  optimizer::QuickSelectInterface *quick;
3872
3980
  /*
3873
3981
    It is impossible to construct a ROR-union that will not retrieve full
3874
3982
    rows, ignore retrieve_full_rows parameter.
3895
4003
 
3896
4004
  SYNOPSIS
3897
4005
    get_ne_mm_tree()
3898
 
      param       PARAM from SQL_SELECT::test_quick_select
 
4006
      param       PARAM from SqlSelect::test_quick_select
3899
4007
      cond_func   item for the predicate
3900
4008
      field       field in the predicate
3901
4009
      lt_value    constant that field should be smaller
3930
4038
 
3931
4039
  SYNOPSIS
3932
4040
    get_func_mm_tree()
3933
 
      param       PARAM from SQL_SELECT::test_quick_select
 
4041
      param       PARAM from SqlSelect::test_quick_select
3934
4042
      cond_func   item for the predicate
3935
4043
      field       field in the predicate
3936
4044
      value       constant in the predicate
4170
4278
 
4171
4279
  SYNOPSIS
4172
4280
    get_full_func_mm_tree()
4173
 
      param       PARAM from SQL_SELECT::test_quick_select
 
4281
      param       PARAM from SqlSelect::test_quick_select
4174
4282
      cond_func   item for the predicate
4175
4283
      field_item  field in the predicate
4176
4284
      value       constant in the predicate
6626
6734
  optimizer::QuickRangeSelect *quick= NULL;
6627
6735
  bool create_err= false;
6628
6736
 
6629
 
  quick=new optimizer::QuickRangeSelect(param->session, param->table,
6630
 
                               param->real_keynr[idx],
6631
 
                               test(parent_alloc), NULL, &create_err);
 
6737
  quick= new optimizer::QuickRangeSelect(param->session, 
 
6738
                                         param->table,
 
6739
                                         param->real_keynr[idx],
 
6740
                                         test(parent_alloc), 
 
6741
                                         NULL, 
 
6742
                                         &create_err);
6632
6743
 
6633
6744
  if (quick)
6634
6745
  {
6643
6754
                       0))
6644
6755
    {
6645
6756
      delete quick;
6646
 
      quick=0;
 
6757
      quick= NULL;
6647
6758
    }
6648
6759
    else
6649
6760
    {
6870
6981
}
6871
6982
 
6872
6983
 
6873
 
bool optimizer::QUICK_SELECT_I::is_keys_used(const MyBitmap *fields)
 
6984
bool optimizer::QuickSelectInterface::is_keys_used(const MyBitmap *fields)
6874
6985
{
6875
6986
  return is_key_used(head, index, fields);
6876
6987
}
6901
7012
 
6902
7013
bool optimizer::QUICK_ROR_UNION_SELECT::is_keys_used(const MyBitmap *fields)
6903
7014
{
6904
 
  optimizer::QUICK_SELECT_I *quick;
6905
 
  List_iterator_fast<optimizer::QUICK_SELECT_I> it(quick_selects);
 
7015
  optimizer::QuickSelectInterface *quick;
 
7016
  List_iterator_fast<optimizer::QuickSelectInterface> it(quick_selects);
6906
7017
  while ((quick= it++))
6907
7018
  {
6908
7019
    if (quick->is_keys_used(fields))
6932
7043
*/
6933
7044
 
6934
7045
optimizer::QuickRangeSelect *optimizer::get_quick_select_for_ref(Session *session, 
6935
 
                                                        Table *table,
6936
 
                                                        table_reference_st *ref, 
6937
 
                                                        ha_rows records)
 
7046
                                                                 Table *table,
 
7047
                                                                 table_reference_st *ref, 
 
7048
                                                                 ha_rows records)
6938
7049
{
6939
7050
  MEM_ROOT *old_root, *alloc;
6940
7051
  optimizer::QuickRangeSelect *quick= NULL;
7121
7232
  /* index_merge currently doesn't support "using index" at all */
7122
7233
  cursor->extra(HA_EXTRA_NO_KEYREAD);
7123
7234
  /* start table scan */
7124
 
  init_read_record(&read_record, session, head, (optimizer::SQL_SELECT*) 0, 1, 1);
 
7235
  init_read_record(&read_record, session, head, (optimizer::SqlSelect*) 0, 1, 1);
7125
7236
  return result;
7126
7237
}
7127
7238
 
7269
7380
int optimizer::QUICK_ROR_UNION_SELECT::get_next()
7270
7381
{
7271
7382
  int error, dup_row;
7272
 
  optimizer::QUICK_SELECT_I *quick;
 
7383
  optimizer::QuickSelectInterface *quick;
7273
7384
  unsigned char *tmp;
7274
7385
 
7275
7386
  do
7319
7430
 
7320
7431
int optimizer::QuickRangeSelect::reset()
7321
7432
{
7322
 
  uint32_t buf_size;
7323
 
  unsigned char *mrange_buff;
7324
 
  int error;
 
7433
  uint32_t buf_size= 0;
 
7434
  unsigned char *mrange_buff= NULL;
 
7435
  int error= 0;
7325
7436
  HANDLER_BUFFER empty_buf;
7326
7437
  last_range= NULL;
7327
7438
  cur_range= (optimizer::QuickRange**) ranges.buffer;
7328
7439
 
7329
 
  if (cursor->inited == Cursor::NONE && (error= cursor->ha_index_init(index,1)))
7330
 
    return(error);
 
7440
  if (cursor->inited == Cursor::NONE && (error= cursor->ha_index_init(index, 1)))
 
7441
  {
 
7442
    return error;
 
7443
  }
7331
7444
 
7332
7445
  /* Allocate buffer if we need one but haven't allocated it yet */
7333
 
  if (mrr_buf_size && !mrr_buf_desc)
 
7446
  if (mrr_buf_size && ! mrr_buf_desc)
7334
7447
  {
7335
7448
    buf_size= mrr_buf_size;
7336
7449
    while (buf_size && ! memory::multi_malloc(false,
7337
 
                                        &mrr_buf_desc, sizeof(*mrr_buf_desc),
7338
 
                                        &mrange_buff, buf_size,
7339
 
                                        NULL))
 
7450
                                              &mrr_buf_desc, 
 
7451
                                              sizeof(*mrr_buf_desc),
 
7452
                                              &mrange_buff, 
 
7453
                                              buf_size,
 
7454
                                              NULL))
7340
7455
    {
7341
7456
      /* Try to shrink the buffers until both are 0. */
7342
7457
      buf_size/= 2;
7343
7458
    }
7344
 
    if (!mrr_buf_desc)
7345
 
      return(HA_ERR_OUT_OF_MEM);
 
7459
    if (! mrr_buf_desc)
 
7460
    {
 
7461
      return HA_ERR_OUT_OF_MEM;
 
7462
    }
7346
7463
 
7347
7464
    /* Initialize the Cursor buffer. */
7348
7465
    mrr_buf_desc->buffer= mrange_buff;
7350
7467
    mrr_buf_desc->end_of_used_area= mrange_buff;
7351
7468
  }
7352
7469
 
7353
 
  if (!mrr_buf_desc)
7354
 
    empty_buf.buffer= empty_buf.buffer_end= empty_buf.end_of_used_area= NULL;
 
7470
  if (! mrr_buf_desc)
 
7471
  {
 
7472
    empty_buf.buffer= NULL;
 
7473
    empty_buf.buffer_end= NULL;
 
7474
    empty_buf.end_of_used_area= NULL;
 
7475
  }
7355
7476
 
7356
7477
  if (sorted)
7357
 
     mrr_flags |= HA_MRR_SORTED;
7358
 
  RANGE_SEQ_IF seq_funcs= {optimizer::quick_range_seq_init, optimizer::quick_range_seq_next};
7359
 
  error= cursor->multi_range_read_init(&seq_funcs, (void*)this, ranges.elements,
7360
 
                                     mrr_flags, mrr_buf_desc? mrr_buf_desc:
7361
 
                                                              &empty_buf);
7362
 
  return(error);
 
7478
  {
 
7479
     mrr_flags|= HA_MRR_SORTED;
 
7480
  }
 
7481
  RANGE_SEQ_IF seq_funcs= {
 
7482
    optimizer::quick_range_seq_init, 
 
7483
    optimizer::quick_range_seq_next
 
7484
  };
 
7485
  error= cursor->multi_range_read_init(&seq_funcs, 
 
7486
                                       (void*) this, 
 
7487
                                       ranges.elements,
 
7488
                                       mrr_flags, 
 
7489
                                       mrr_buf_desc ? mrr_buf_desc : &empty_buf);
 
7490
  return error;
7363
7491
}
7364
7492
 
7365
7493
 
7399
7527
    0  Ok
7400
7528
    1  No more ranges in the sequence
7401
7529
*/
7402
 
 
7403
7530
uint32_t optimizer::quick_range_seq_next(range_seq_t rseq, KEY_MULTI_RANGE *range)
7404
7531
{
7405
 
  QUICK_RANGE_SEQ_CTX *ctx= (QUICK_RANGE_SEQ_CTX*)rseq;
 
7532
  QuickRangeSequenceContext *ctx= (QuickRangeSequenceContext*) rseq;
7406
7533
 
7407
7534
  if (ctx->cur == ctx->last)
7408
7535
    return 1; /* no more ranges */
7409
7536
 
7410
7537
  optimizer::QuickRange *cur= *(ctx->cur);
7411
7538
  key_range *start_key= &range->start_key;
7412
 
  key_range *end_key=   &range->end_key;
 
7539
  key_range *end_key= &range->end_key;
7413
7540
 
7414
 
  start_key->key=    cur->min_key;
 
7541
  start_key->key= cur->min_key;
7415
7542
  start_key->length= cur->min_length;
7416
7543
  start_key->keypart_map= cur->min_keypart_map;
7417
 
  start_key->flag=   ((cur->flag & NEAR_MIN) ? HA_READ_AFTER_KEY :
7418
 
                      (cur->flag & EQ_RANGE) ?
7419
 
                      HA_READ_KEY_EXACT : HA_READ_KEY_OR_NEXT);
7420
 
  end_key->key=      cur->max_key;
7421
 
  end_key->length=   cur->max_length;
 
7544
  start_key->flag= ((cur->flag & NEAR_MIN) ? HA_READ_AFTER_KEY :
 
7545
                                             (cur->flag & EQ_RANGE) ?
 
7546
                                             HA_READ_KEY_EXACT : HA_READ_KEY_OR_NEXT);
 
7547
  end_key->key= cur->max_key;
 
7548
  end_key->length= cur->max_length;
7422
7549
  end_key->keypart_map= cur->max_keypart_map;
7423
7550
  /*
7424
7551
    We use HA_READ_AFTER_KEY here because if we are reading on a key
7425
7552
    prefix. We want to find all keys with this prefix.
7426
7553
  */
7427
 
  end_key->flag=     (cur->flag & NEAR_MAX ? HA_READ_BEFORE_KEY :
7428
 
                      HA_READ_AFTER_KEY);
 
7554
  end_key->flag= (cur->flag & NEAR_MAX ? HA_READ_BEFORE_KEY :
 
7555
                                         HA_READ_AFTER_KEY);
7429
7556
  range->range_flag= cur->flag;
7430
7557
  ctx->cur++;
7431
7558
  return 0;
7446
7573
    HA_ERR_END_OF_FILE  No (more) rows in range
7447
7574
    #                   Error code
7448
7575
*/
7449
 
 
7450
7576
int optimizer::QuickRangeSelect::get_next()
7451
7577
{
7452
 
  char *dummy;
 
7578
  char *dummy= NULL;
7453
7579
  if (in_ror_merged_scan)
7454
7580
  {
7455
7581
    /*
7497
7623
    HA_ERR_END_OF_FILE if returned all keys
7498
7624
    other              if some error occurred
7499
7625
*/
7500
 
 
7501
7626
int optimizer::QuickRangeSelect::get_next_prefix(uint32_t prefix_length,
7502
 
                                        key_part_map keypart_map,
7503
 
                                        unsigned char *cur_prefix)
 
7627
                                                 key_part_map keypart_map,
 
7628
                                                 unsigned char *cur_prefix)
7504
7629
{
7505
7630
  for (;;)
7506
7631
  {
7510
7635
    {
7511
7636
      /* Read the next record in the same range with prefix after cur_prefix. */
7512
7637
      assert(cur_prefix != 0);
7513
 
      result= cursor->index_read_map(record, cur_prefix, keypart_map,
7514
 
                                   HA_READ_AFTER_KEY);
 
7638
      result= cursor->index_read_map(record, 
 
7639
                                     cur_prefix, 
 
7640
                                     keypart_map,
 
7641
                                     HA_READ_AFTER_KEY);
7515
7642
      if (result || (cursor->compare_key(cursor->end_range) <= 0))
7516
7643
        return result;
7517
7644
    }
7525
7652
    }
7526
7653
    last_range= *(cur_range++);
7527
7654
 
7528
 
    start_key.key=    (const unsigned char*) last_range->min_key;
 
7655
    start_key.key= (const unsigned char*) last_range->min_key;
7529
7656
    start_key.length= min(last_range->min_length, (uint16_t)prefix_length);
7530
7657
    start_key.keypart_map= last_range->min_keypart_map & keypart_map;
7531
 
    start_key.flag=   ((last_range->flag & NEAR_MIN) ? HA_READ_AFTER_KEY :
7532
 
                       (last_range->flag & EQ_RANGE) ?
7533
 
                       HA_READ_KEY_EXACT : HA_READ_KEY_OR_NEXT);
7534
 
    end_key.key=      (const unsigned char*) last_range->max_key;
7535
 
    end_key.length=   min(last_range->max_length, (uint16_t)prefix_length);
 
7658
    start_key.flag= ((last_range->flag & NEAR_MIN) ? HA_READ_AFTER_KEY :
 
7659
                                                                (last_range->flag & EQ_RANGE) ?
 
7660
                                                                HA_READ_KEY_EXACT : HA_READ_KEY_OR_NEXT);
 
7661
    end_key.key= (const unsigned char*) last_range->max_key;
 
7662
    end_key.length= min(last_range->max_length, (uint16_t)prefix_length);
7536
7663
    end_key.keypart_map= last_range->max_keypart_map & keypart_map;
7537
7664
    /*
7538
7665
      We use READ_AFTER_KEY here because if we are reading on a key
7539
7666
      prefix we want to find all keys with this prefix
7540
7667
    */
7541
 
    end_key.flag=     (last_range->flag & NEAR_MAX ? HA_READ_BEFORE_KEY :
7542
 
                       HA_READ_AFTER_KEY);
 
7668
    end_key.flag= (last_range->flag & NEAR_MAX ? HA_READ_BEFORE_KEY :
 
7669
                                                             HA_READ_AFTER_KEY);
7543
7670
 
7544
7671
    result= cursor->read_range_first(last_range->min_keypart_map ? &start_key : 0,
7545
 
                                   last_range->max_keypart_map ? &end_key : 0,
7546
 
                                   test(last_range->flag & EQ_RANGE),
7547
 
                                   sorted);
 
7672
                                                             last_range->max_keypart_map ? &end_key : 0,
 
7673
                                     test(last_range->flag & EQ_RANGE),
 
7674
                                                             sorted);
7548
7675
    if (last_range->flag == (UNIQUE_RANGE | EQ_RANGE))
7549
 
      last_range= 0;                    // Stop searching
 
7676
      last_range= 0; // Stop searching
7550
7677
 
7551
7678
    if (result != HA_ERR_END_OF_FILE)
7552
7679
      return result;
7553
 
    last_range= 0;                      // No matching rows; go to next range
 
7680
    last_range= 0; // No matching rows; go to next range
7554
7681
  }
7555
7682
}
7556
7683
 
7572
7699
    true  if current row will be retrieved by this quick select
7573
7700
    false if not
7574
7701
*/
7575
 
 
7576
7702
bool optimizer::QuickRangeSelect::row_in_ranges()
7577
7703
{
7578
7704
  optimizer::QuickRange *res= NULL;
7579
7705
  uint32_t min= 0;
7580
7706
  uint32_t max= ranges.elements - 1;
7581
 
  uint32_t mid= (max + min)/2;
 
7707
  uint32_t mid= (max + min) / 2;
7582
7708
 
7583
7709
  while (min != max)
7584
7710
  {
7592
7718
    mid= (min + max) / 2;
7593
7719
  }
7594
7720
  res= *(optimizer::QuickRange**)dynamic_array_ptr(&ranges, mid);
7595
 
  return (!cmp_next(res) && !cmp_prev(res));
 
7721
  return (! cmp_next(res) && ! cmp_prev(res));
7596
7722
}
7597
7723
 
7598
7724
/*
7604
7730
  which handle the ranges and implement the get_next() function.  But
7605
7731
  for now, this seems to work right at least.
7606
7732
 */
7607
 
 
7608
7733
optimizer::QUICK_SELECT_DESC::QUICK_SELECT_DESC(optimizer::QuickRangeSelect *q, uint32_t, bool *)
7609
7734
  :
7610
7735
    optimizer::QuickRangeSelect(*q), 
7614
7739
 
7615
7740
  optimizer::QuickRange **pr= (optimizer::QuickRange**)ranges.buffer;
7616
7741
  optimizer::QuickRange **end_range= pr + ranges.elements;
7617
 
  for (; pr!=end_range; pr++)
 
7742
  for (; pr != end_range; pr++)
7618
7743
    rev_ranges.push_front(*pr);
7619
7744
 
7620
7745
  /* Remove EQ_RANGE flag for keys that are not using the full key */
7621
 
  for (r = rev_it++; r; r = rev_it++)
 
7746
  for (r = rev_it++; r; r= rev_it++)
7622
7747
  {
7623
7748
    if ((r->flag & EQ_RANGE) &&
7624
 
        head->key_info[index].key_length != r->max_length)
 
7749
        head->key_info[index].key_length != r->max_length)
7625
7750
      r->flag&= ~EQ_RANGE;
7626
7751
  }
7627
7752
  rev_it.rewind();
7628
 
  q->dont_free=1;                               // Don't free shared mem
 
7753
  q->dont_free= 1;                              // Don't free shared mem
7629
7754
  delete q;
7630
7755
}
7631
7756
 
7642
7767
   *   - otherwise (not NEAR_MAX == include the key), go after the key,
7643
7768
   *     step back once, and move backwards
7644
7769
   */
7645
 
 
7646
7770
  for (;;)
7647
7771
  {
7648
7772
    int result;
7649
7773
    if (last_range)
7650
7774
    {                                           // Already read through key
7651
 
      result = ((last_range->flag & EQ_RANGE)
7652
 
                ? cursor->index_next_same(record, last_range->min_key,
7653
 
                                        last_range->min_length) :
7654
 
                cursor->index_prev(record));
7655
 
      if (!result)
 
7775
      result= ((last_range->flag & EQ_RANGE) ?
 
7776
                           cursor->index_next_same(record, last_range->min_key,
 
7777
                                                                     last_range->min_length) :
 
7778
                           cursor->index_prev(record));
 
7779
      if (! result)
7656
7780
      {
7657
 
        if (cmp_prev(*rev_it.ref()) == 0)
7658
 
          return 0;
 
7781
        if (cmp_prev(*rev_it.ref()) == 0)
 
7782
          return 0;
7659
7783
      }
7660
7784
      else if (result != HA_ERR_END_OF_FILE)
7661
 
        return result;
 
7785
        return result;
7662
7786
    }
7663
7787
 
7664
 
    if (!(last_range= rev_it++))
 
7788
    if (! (last_range= rev_it++))
7665
7789
      return HA_ERR_END_OF_FILE;                // All ranges used
7666
7790
 
7667
7791
    if (last_range->flag & NO_MAX_RANGE)        // Read last record
7668
7792
    {
7669
7793
      int local_error;
7670
 
      if ((local_error=cursor->index_last(record)))
7671
 
        return(local_error);            // Empty table
 
7794
      if ((local_error= cursor->index_last(record)))
 
7795
        return local_error;     // Empty table
7672
7796
      if (cmp_prev(last_range) == 0)
7673
 
        return 0;
7674
 
      last_range= 0;                            // No match; go to next range
 
7797
        return 0;
 
7798
      last_range= 0; // No match; go to next range
7675
7799
      continue;
7676
7800
    }
7677
7801
 
7678
7802
    if (last_range->flag & EQ_RANGE)
7679
7803
    {
7680
 
      result = cursor->index_read_map(record, last_range->max_key,
7681
 
                                    last_range->max_keypart_map,
7682
 
                                    HA_READ_KEY_EXACT);
 
7804
      result = cursor->index_read_map(record, 
 
7805
                                      last_range->max_key,
 
7806
                                      last_range->max_keypart_map,
 
7807
                                      HA_READ_KEY_EXACT);
7683
7808
    }
7684
7809
    else
7685
7810
    {
7686
7811
      assert(last_range->flag & NEAR_MAX ||
7687
 
                  range_reads_after_key(last_range));
7688
 
      result=cursor->index_read_map(record, last_range->max_key,
7689
 
                                  last_range->max_keypart_map,
7690
 
                                  ((last_range->flag & NEAR_MAX) ?
7691
 
                                   HA_READ_BEFORE_KEY :
7692
 
                                   HA_READ_PREFIX_LAST_OR_PREV));
 
7812
             range_reads_after_key(last_range));
 
7813
      result= cursor->index_read_map(record, 
 
7814
                                     last_range->max_key,
 
7815
                                     last_range->max_keypart_map,
 
7816
                                     ((last_range->flag & NEAR_MAX) ?
 
7817
                                      HA_READ_BEFORE_KEY :
 
7818
                                      HA_READ_PREFIX_LAST_OR_PREV));
7693
7819
    }
7694
7820
    if (result)
7695
7821
    {
7696
7822
      if (result != HA_ERR_KEY_NOT_FOUND && result != HA_ERR_END_OF_FILE)
7697
 
        return result;
 
7823
        return result;
7698
7824
      last_range= 0;                            // Not found, to next range
7699
7825
      continue;
7700
7826
    }
7701
7827
    if (cmp_prev(last_range) == 0)
7702
7828
    {
7703
7829
      if (last_range->flag == (UNIQUE_RANGE | EQ_RANGE))
7704
 
        last_range= 0;                          // Stop searching
 
7830
        last_range= 0;                          // Stop searching
7705
7831
      return 0;                         // Found key is in range
7706
7832
    }
7707
7833
    last_range= 0;                              // To next range
7720
7846
  if (range_arg->flag & NO_MAX_RANGE)
7721
7847
    return 0;                                   /* key can't be to large */
7722
7848
 
7723
 
  KEY_PART *key_part=key_parts;
 
7849
  KEY_PART *key_part= key_parts;
7724
7850
  uint32_t store_length;
7725
7851
 
7726
7852
  for (unsigned char *key=range_arg->max_key, *end=key+range_arg->max_length;
7733
7859
    {
7734
7860
      if (*key)
7735
7861
      {
7736
 
        if (!key_part->field->is_null())
 
7862
        if (! key_part->field->is_null())
7737
7863
          return 1;
7738
7864
        continue;
7739
7865
      }
7742
7868
      key++;                                    // Skip null byte
7743
7869
      store_length--;
7744
7870
    }
7745
 
    if ((cmp=key_part->field->key_cmp(key, key_part->length)) < 0)
 
7871
    if ((cmp= key_part->field->key_cmp(key, key_part->length)) < 0)
7746
7872
      return 0;
7747
7873
    if (cmp > 0)
7748
7874
      return 1;
7754
7880
/*
7755
7881
  Returns 0 if found key is inside range (found key >= range->min_key).
7756
7882
*/
7757
 
 
7758
7883
int optimizer::QuickRangeSelect::cmp_prev(optimizer::QuickRange *range_arg)
7759
7884
{
7760
7885
  int cmp;
7761
7886
  if (range_arg->flag & NO_MIN_RANGE)
7762
7887
    return 0;                                   /* key can't be to small */
7763
7888
 
7764
 
  cmp= key_cmp(key_part_info, range_arg->min_key,
 
7889
  cmp= key_cmp(key_part_info, 
 
7890
               range_arg->min_key,
7765
7891
               range_arg->min_length);
7766
7892
  if (cmp > 0 || (cmp == 0 && (range_arg->flag & NEAR_MIN) == false))
7767
7893
    return 0;
7773
7899
 * true if this range will require using HA_READ_AFTER_KEY
7774
7900
   See comment in get_next() about this
7775
7901
 */
7776
 
 
7777
7902
bool optimizer::QUICK_SELECT_DESC::range_reads_after_key(optimizer::QuickRange *range_arg)
7778
7903
{
7779
7904
  return ((range_arg->flag & (NO_MAX_RANGE | NEAR_MAX)) ||
7780
 
          !(range_arg->flag & EQ_RANGE) ||
7781
 
          head->key_info[index].key_length != range_arg->max_length) ? 1 : 0;
 
7905
                ! (range_arg->flag & EQ_RANGE) ||
 
7906
                head->key_info[index].key_length != range_arg->max_length) ? 1 : 0;
7782
7907
}
7783
7908
 
7784
7909
 
7790
7915
 
7791
7916
void optimizer::QUICK_INDEX_MERGE_SELECT::add_info_string(String *str)
7792
7917
{
7793
 
  optimizer::QuickRangeSelect *quick;
 
7918
  optimizer::QuickRangeSelect *quick= NULL;
7794
7919
  bool first= true;
7795
7920
  List_iterator_fast<optimizer::QuickRangeSelect> it(quick_selects);
7796
7921
  str->append(STRING_WITH_LEN("sort_union("));
7797
7922
  while ((quick= it++))
7798
7923
  {
7799
 
    if (!first)
 
7924
    if (! first)
7800
7925
      str->append(',');
7801
7926
    else
7802
7927
      first= false;
7810
7935
  str->append(')');
7811
7936
}
7812
7937
 
 
7938
 
7813
7939
void optimizer::QUICK_ROR_INTERSECT_SELECT::add_info_string(String *str)
7814
7940
{
7815
7941
  bool first= true;
7819
7945
  while ((quick= it++))
7820
7946
  {
7821
7947
    KEY *key_info= head->key_info + quick->index;
7822
 
    if (!first)
 
7948
    if (! first)
7823
7949
      str->append(',');
7824
7950
    else
7825
7951
      first= false;
7834
7960
  str->append(')');
7835
7961
}
7836
7962
 
 
7963
 
7837
7964
void optimizer::QUICK_ROR_UNION_SELECT::add_info_string(String *str)
7838
7965
{
7839
7966
  bool first= true;
7840
 
  optimizer::QUICK_SELECT_I *quick;
7841
 
  List_iterator_fast<optimizer::QUICK_SELECT_I> it(quick_selects);
 
7967
  optimizer::QuickSelectInterface *quick;
 
7968
  List_iterator_fast<optimizer::QuickSelectInterface> it(quick_selects);
7842
7969
  str->append(STRING_WITH_LEN("union("));
7843
7970
  while ((quick= it++))
7844
7971
  {
7845
 
    if (!first)
 
7972
    if (! first)
7846
7973
      str->append(',');
7847
7974
    else
7848
7975
      first= false;
7853
7980
 
7854
7981
 
7855
7982
void optimizer::QuickRangeSelect::add_keys_and_lengths(String *key_names,
7856
 
                                              String *used_lengths)
 
7983
                                                       String *used_lengths)
7857
7984
{
7858
7985
  char buf[64];
7859
7986
  uint32_t length;
7863
7990
  used_lengths->append(buf, length);
7864
7991
}
7865
7992
 
 
7993
 
7866
7994
void optimizer::QUICK_INDEX_MERGE_SELECT::add_keys_and_lengths(String *key_names,
7867
7995
                                                               String *used_lengths)
7868
7996
{
7869
7997
  char buf[64];
7870
7998
  uint32_t length;
7871
7999
  bool first= true;
7872
 
  optimizer::QuickRangeSelect *quick;
 
8000
  optimizer::QuickRangeSelect *quick= NULL;
7873
8001
 
7874
8002
  List_iterator_fast<optimizer::QuickRangeSelect> it(quick_selects);
7875
8003
  while ((quick= it++))
7898
8026
  }
7899
8027
}
7900
8028
 
 
8029
 
7901
8030
void optimizer::QUICK_ROR_INTERSECT_SELECT::add_keys_and_lengths(String *key_names,
7902
8031
                                                                 String *used_lengths)
7903
8032
{
7932
8061
  }
7933
8062
}
7934
8063
 
 
8064
 
7935
8065
void optimizer::QUICK_ROR_UNION_SELECT::add_keys_and_lengths(String *key_names,
7936
8066
                                                             String *used_lengths)
7937
8067
{
7938
8068
  bool first= true;
7939
 
  optimizer::QUICK_SELECT_I *quick;
7940
 
  List_iterator_fast<optimizer::QUICK_SELECT_I> it(quick_selects);
 
8069
  optimizer::QuickSelectInterface *quick;
 
8070
  List_iterator_fast<optimizer::QuickSelectInterface> it(quick_selects);
7941
8071
  while ((quick= it++))
7942
8072
  {
7943
8073
    if (first)
7957
8087
*******************************************************************************/
7958
8088
 
7959
8089
static inline uint32_t get_field_keypart(KEY *index, Field *field);
7960
 
static inline SEL_ARG * get_index_range_tree(uint32_t index, SEL_TREE* range_tree,
7961
 
                                             PARAM *param, uint32_t *param_idx);
7962
 
static bool get_constant_key_infix(KEY *index_info, SEL_ARG *index_range_tree,
7963
 
                       KEY_PART_INFO *first_non_group_part,
7964
 
                       KEY_PART_INFO *min_max_arg_part,
7965
 
                       KEY_PART_INFO *last_part, Session *session,
7966
 
                       unsigned char *key_infix, uint32_t *key_infix_len,
7967
 
                       KEY_PART_INFO **first_non_infix_part);
 
8090
 
 
8091
static inline SEL_ARG * get_index_range_tree(uint32_t index, 
 
8092
                                             SEL_TREE* range_tree,
 
8093
                                             PARAM *param, 
 
8094
                                             uint32_t *param_idx);
 
8095
 
 
8096
static bool get_constant_key_infix(KEY *index_info, 
 
8097
                                   SEL_ARG *index_range_tree,
 
8098
                                   KEY_PART_INFO *first_non_group_part,
 
8099
                                   KEY_PART_INFO *min_max_arg_part,
 
8100
                                   KEY_PART_INFO *last_part, 
 
8101
                                   Session *session,
 
8102
                                   unsigned char *key_infix, 
 
8103
                                   uint32_t *key_infix_len,
 
8104
                                   KEY_PART_INFO **first_non_infix_part);
 
8105
 
7968
8106
static bool check_group_min_max_predicates(COND *cond, Item_field *min_max_arg_item);
7969
8107
 
7970
8108
static void
7971
 
cost_group_min_max(Table* table, KEY *index_info, uint32_t used_key_parts,
7972
 
                   uint32_t group_key_parts, SEL_TREE *range_tree,
7973
 
                   SEL_ARG *index_tree, ha_rows quick_prefix_records,
7974
 
                   bool have_min, bool have_max,
7975
 
                   double *read_cost, ha_rows *records);
 
8109
cost_group_min_max(Table* table, 
 
8110
                   KEY *index_info, 
 
8111
                   uint32_t used_key_parts,
 
8112
                   uint32_t group_key_parts, 
 
8113
                   SEL_TREE *range_tree,
 
8114
                   SEL_ARG *index_tree, 
 
8115
                   ha_rows quick_prefix_records,
 
8116
                   bool have_min, 
 
8117
                   bool have_max,
 
8118
                   double *read_cost, 
 
8119
                   ha_rows *records);
7976
8120
 
7977
8121
 
7978
8122
/*
8102
8246
    If mem_root == NULL
8103
8247
    - NULL
8104
8248
*/
8105
 
 
8106
8249
static TRP_GROUP_MIN_MAX *
8107
8250
get_best_group_min_max(PARAM *param, SEL_TREE *tree)
8108
8251
{
8122
8265
  uint32_t key_infix_len= 0;          /* Length of key_infix. */
8123
8266
  TRP_GROUP_MIN_MAX *read_plan= NULL; /* The eventually constructed TRP. */
8124
8267
  uint32_t key_part_nr;
8125
 
  order_st *tmp_group;
8126
 
  Item *item;
8127
 
  Item_field *item_field;
 
8268
  order_st *tmp_group= NULL;
 
8269
  Item *item= NULL;
 
8270
  Item_field *item_field= NULL;
8128
8271
 
8129
8272
  /* Perform few 'cheap' tests whether this access method is applicable. */
8130
 
  if (!join)
 
8273
  if (! join)
8131
8274
    return NULL;        /* This is not a select statement. */
 
8275
 
8132
8276
  if ((join->tables != 1) ||  /* The query must reference one table. */
8133
 
      ((!join->group_list) && /* Neither GROUP BY nor a DISTINCT query. */
8134
 
       (!join->select_distinct)) ||
 
8277
      ((! join->group_list) && /* Neither GROUP BY nor a DISTINCT query. */
 
8278
       (! join->select_distinct)) ||
8135
8279
      (join->select_lex->olap == ROLLUP_TYPE)) /* Check (B3) for ROLLUP */
8136
8280
    return NULL;
8137
8281
  if (table->s->keys == 0)        /* There are no indexes to use. */
8143
8287
  /* Check (SA1,SA4) and store the only MIN/MAX argument - the C attribute.*/
8144
8288
  if (join->make_sum_func_list(join->all_fields, join->fields_list, 1))
8145
8289
    return NULL;
 
8290
 
8146
8291
  if (join->sum_funcs[0])
8147
8292
  {
8148
 
    Item_sum *min_max_item;
 
8293
    Item_sum *min_max_item= NULL;
8149
8294
    Item_sum **func_ptr= join->sum_funcs;
8150
8295
    while ((min_max_item= *(func_ptr++)))
8151
8296
    {
8195
8340
  KEY *cur_index_info= table->key_info;
8196
8341
  KEY *cur_index_info_end= cur_index_info + table->s->keys;
8197
8342
  KEY_PART_INFO *cur_part= NULL;
8198
 
  KEY_PART_INFO *end_part; /* Last part for loops. */
 
8343
  KEY_PART_INFO *end_part= NULL; /* Last part for loops. */
8199
8344
  /* Last index part. */
8200
8345
  KEY_PART_INFO *last_part= NULL;
8201
8346
  KEY_PART_INFO *first_non_group_part= NULL;
8213
8358
  ha_rows cur_records;
8214
8359
  SEL_ARG *cur_index_tree= NULL;
8215
8360
  ha_rows cur_quick_prefix_records= 0;
8216
 
  uint32_t cur_param_idx=MAX_KEY;
 
8361
  uint32_t cur_param_idx= MAX_KEY;
8217
8362
  key_map used_key_parts_map;
8218
8363
  uint32_t cur_key_infix_len= 0;
8219
8364
  unsigned char cur_key_infix[MAX_KEY_LENGTH];
8220
8365
  uint32_t cur_used_key_parts= 0;
8221
8366
  uint32_t pk= param->table->s->primary_key;
8222
8367
 
8223
 
  for (uint32_t cur_index= 0 ; cur_index_info != cur_index_info_end ;
 
8368
  for (uint32_t cur_index= 0; 
 
8369
       cur_index_info != cur_index_info_end;
8224
8370
       cur_index_info++, cur_index++)
8225
8371
  {
8226
8372
    /* Check (B1) - if current index is covering. */
8227
 
    if (!table->covering_keys.test(cur_index))
 
8373
    if (! table->covering_keys.test(cur_index))
8228
8374
      goto next_index;
8229
8375
 
8230
8376
    /*
8248
8394
          part of 'cur_index'
8249
8395
        */
8250
8396
        if ((cur_field->isReadSet()) &&
8251
 
            !cur_field->part_of_key_not_clustered.test(cur_index))
 
8397
            ! cur_field->part_of_key_not_clustered.test(cur_index))
8252
8398
          goto next_index;                  // Field was not part of key
8253
8399
      }
8254
8400
    }
8261
8407
      cur_part= cur_index_info->key_part;
8262
8408
      end_part= cur_part + cur_index_info->key_parts;
8263
8409
      /* Iterate in parallel over the GROUP list and the index parts. */
8264
 
      for (tmp_group= join->group_list; tmp_group && (cur_part != end_part);
 
8410
      for (tmp_group= join->group_list; 
 
8411
           tmp_group && (cur_part != end_part);
8265
8412
           tmp_group= tmp_group->next, cur_part++)
8266
8413
      {
8267
8414
        /*
8319
8466
        all_parts have all bits set from 0 to (max_key_part-1).
8320
8467
        cur_parts have bits set for only used keyparts.
8321
8468
      */
8322
 
      key_map all_parts, cur_parts;
 
8469
      key_map all_parts;
 
8470
      key_map cur_parts;
8323
8471
      for (uint32_t pos= 0; pos < max_key_part; pos++)
8324
8472
        all_parts.set(pos);
8325
8473
      cur_parts= used_key_parts_map >> 1;
8363
8511
                             NULL :
8364
8512
                           NULL;
8365
8513
    if (first_non_group_part &&
8366
 
        (!min_max_arg_part || (min_max_arg_part - first_non_group_part > 0)))
 
8514
        (! min_max_arg_part || (min_max_arg_part - first_non_group_part > 0)))
8367
8515
    {
8368
8516
      if (tree)
8369
8517
      {
8370
8518
        uint32_t dummy;
8371
 
        SEL_ARG *index_range_tree= get_index_range_tree(cur_index, tree, param,
 
8519
        SEL_ARG *index_range_tree= get_index_range_tree(cur_index, 
 
8520
                                                        tree, 
 
8521
                                                        param,
8372
8522
                                                        &dummy);
8373
 
        if (!get_constant_key_infix(cur_index_info, index_range_tree,
8374
 
                                    first_non_group_part, min_max_arg_part,
8375
 
                                    last_part, session, cur_key_infix, 
8376
 
                                    &cur_key_infix_len,
8377
 
                                    &first_non_infix_part))
 
8523
        if (! get_constant_key_infix(cur_index_info, 
 
8524
                                     index_range_tree,
 
8525
                                     first_non_group_part, 
 
8526
                                     min_max_arg_part,
 
8527
                                     last_part, 
 
8528
                                     session, 
 
8529
                                     cur_key_infix, 
 
8530
                                     &cur_key_infix_len,
 
8531
                                     &first_non_infix_part))
 
8532
        {
8378
8533
          goto next_index;
 
8534
        }
8379
8535
      }
8380
8536
      else if (min_max_arg_part &&
8381
8537
               (min_max_arg_part - first_non_group_part > 0))
8405
8561
        key_part_range[1]= last_part;
8406
8562
 
8407
8563
        /* Check if cur_part is referenced in the WHERE clause. */
8408
 
        if (join->conds->walk(&Item::find_item_in_field_list_processor, 0,
 
8564
        if (join->conds->walk(&Item::find_item_in_field_list_processor,
 
8565
                              0,
8409
8566
                              (unsigned char*) key_part_range))
8410
8567
          goto next_index;
8411
8568
      }
8435
8592
    if (tree)
8436
8593
    {
8437
8594
      /* Find the SEL_ARG sub-tree that corresponds to the chosen index. */
8438
 
      cur_index_tree= get_index_range_tree(cur_index, tree, param,
 
8595
      cur_index_tree= get_index_range_tree(cur_index, 
 
8596
                                           tree, 
 
8597
                                           param,
8439
8598
                                           &cur_param_idx);
8440
8599
      /* Check if this range tree can be used for prefix retrieval. */
8441
8600
      COST_VECT dummy_cost;
8442
8601
      uint32_t mrr_flags= HA_MRR_USE_DEFAULT_IMPL;
8443
 
      uint32_t mrr_bufsize=0;
8444
 
      cur_quick_prefix_records= check_quick_select(param, cur_param_idx,
 
8602
      uint32_t mrr_bufsize= 0;
 
8603
      cur_quick_prefix_records= check_quick_select(param, 
 
8604
                                                   cur_param_idx,
8445
8605
                                                   false /*don't care*/,
8446
 
                                                   cur_index_tree, true,
8447
 
                                                   &mrr_flags, &mrr_bufsize,
 
8606
                                                   cur_index_tree, 
 
8607
                                                   true,
 
8608
                                                   &mrr_flags, 
 
8609
                                                   &mrr_bufsize,
8448
8610
                                                   &dummy_cost);
8449
8611
    }
8450
 
    cost_group_min_max(table, cur_index_info, cur_used_key_parts,
8451
 
                       cur_group_key_parts, tree, cur_index_tree,
8452
 
                       cur_quick_prefix_records, have_min, have_max,
8453
 
                       &cur_read_cost, &cur_records);
 
8612
    cost_group_min_max(table, 
 
8613
                       cur_index_info, 
 
8614
                       cur_used_key_parts,
 
8615
                       cur_group_key_parts, 
 
8616
                       tree, 
 
8617
                       cur_index_tree,
 
8618
                       cur_quick_prefix_records, 
 
8619
                       have_min, 
 
8620
                       have_max,
 
8621
                       &cur_read_cost, 
 
8622
                       &cur_records);
8454
8623
    /*
8455
8624
      If cur_read_cost is lower than best_read_cost use cur_index.
8456
8625
      Do not compare doubles directly because they may have different
8469
8638
      group_key_parts= cur_group_key_parts;
8470
8639
      group_prefix_len= cur_group_prefix_len;
8471
8640
      key_infix_len= cur_key_infix_len;
 
8641
 
8472
8642
      if (key_infix_len)
8473
 
        memcpy (key_infix, cur_key_infix, sizeof (key_infix));
 
8643
      {
 
8644
        memcpy(key_infix, cur_key_infix, sizeof (key_infix));
 
8645
      }
 
8646
 
8474
8647
      used_key_parts= cur_used_key_parts;
8475
8648
    }
8476
8649
 
8479
8652
    cur_group_prefix_len= 0;
8480
8653
    cur_key_infix_len= 0;
8481
8654
  }
8482
 
  if (!index_info) /* No usable index found. */
 
8655
  if (! index_info) /* No usable index found. */
8483
8656
    return NULL;
8484
8657
 
8485
8658
  /* Check (SA3) for the where clause. */
8488
8661
    return NULL;
8489
8662
 
8490
8663
  /* The query passes all tests, so construct a new TRP object. */
8491
 
  read_plan= new (param->mem_root)
8492
 
                 TRP_GROUP_MIN_MAX(have_min, have_max, min_max_arg_part,
8493
 
                                   group_prefix_len, used_key_parts,
8494
 
                                   group_key_parts, index_info, index,
8495
 
                                   key_infix_len,
8496
 
                                   (key_infix_len > 0) ? key_infix : NULL,
8497
 
                                   tree, best_index_tree, best_param_idx,
8498
 
                                   best_quick_prefix_records);
 
8664
  read_plan=
 
8665
    new(param->mem_root) TRP_GROUP_MIN_MAX(have_min, 
 
8666
                                           have_max, 
 
8667
                                           min_max_arg_part,
 
8668
                                           group_prefix_len, 
 
8669
                                           used_key_parts,
 
8670
                                           group_key_parts, 
 
8671
                                           index_info, 
 
8672
                                           index,
 
8673
                                           key_infix_len,
 
8674
                                           (key_infix_len > 0) ? key_infix : NULL,
 
8675
                                           tree, 
 
8676
                                           best_index_tree, 
 
8677
                                           best_param_idx,
 
8678
                                           best_quick_prefix_records);
8499
8679
  if (read_plan)
8500
8680
  {
8501
8681
    if (tree && read_plan->quick_prefix_records == 0)
8502
8682
      return NULL;
8503
8683
 
8504
8684
    read_plan->read_cost= best_read_cost;
8505
 
    read_plan->records=   best_records;
 
8685
    read_plan->records= best_records;
8506
8686
  }
8507
8687
 
8508
8688
  return read_plan;
8539
8719
  if (cond_type == Item::COND_ITEM) /* 'AND' or 'OR' */
8540
8720
  {
8541
8721
    List_iterator_fast<Item> li(*((Item_cond*) cond)->argument_list());
8542
 
    Item *and_or_arg;
 
8722
    Item *and_or_arg= NULL;
8543
8723
    while ((and_or_arg= li++))
8544
8724
    {
8545
 
      if (!check_group_min_max_predicates(and_or_arg, min_max_arg_item))
 
8725
      if (! check_group_min_max_predicates(and_or_arg, min_max_arg_item))
8546
8726
        return false;
8547
8727
    }
8548
8728
    return true;
8566
8746
  /* Test if cond references only group-by or non-group fields. */
8567
8747
  Item_func *pred= (Item_func*) cond;
8568
8748
  Item **arguments= pred->arguments();
8569
 
  Item *cur_arg;
 
8749
  Item *cur_arg= NULL;
8570
8750
  for (uint32_t arg_idx= 0; arg_idx < pred->argument_count (); arg_idx++)
8571
8751
  {
8572
8752
    cur_arg= arguments[arg_idx]->real_item();
8594
8774
        /* Check that pred compares min_max_arg_item with a constant. */
8595
8775
        Item *args[3];
8596
8776
        memset(args, 0, 3 * sizeof(Item*));
8597
 
        bool inv;
 
8777
        bool inv= false;
8598
8778
        /* Test if this is a comparison of a field and a constant. */
8599
8779
        if (! optimizer::simple_pred(pred, args, &inv))
8600
8780
          return false;
8615
8795
             */
8616
8796
             (args[1]->result_type() != STRING_RESULT &&
8617
8797
              min_max_arg_item->field->cmp_type() != args[1]->result_type())))
 
8798
        {
8618
8799
          return false;
 
8800
        }
8619
8801
      }
8620
8802
    }
8621
8803
    else if (cur_arg->type() == Item::FUNC_ITEM)
8665
8847
    true  if the index passes the test
8666
8848
    false o/w
8667
8849
*/
8668
 
 
8669
8850
static bool
8670
8851
get_constant_key_infix(KEY *, SEL_ARG *index_range_tree,
8671
8852
                       KEY_PART_INFO *first_non_group_part,
8672
8853
                       KEY_PART_INFO *min_max_arg_part,
8673
8854
                       KEY_PART_INFO *last_part,
8674
 
                       Session *, unsigned char *key_infix, uint32_t *key_infix_len,
 
8855
                       Session *, 
 
8856
                       unsigned char *key_infix, 
 
8857
                       uint32_t *key_infix_len,
8675
8858
                       KEY_PART_INFO **first_non_infix_part)
8676
8859
{
8677
 
  SEL_ARG       *cur_range;
8678
 
  KEY_PART_INFO *cur_part;
 
8860
  SEL_ARG *cur_range= NULL;
 
8861
  KEY_PART_INFO *cur_part= NULL;
8679
8862
  /* End part for the first loop below. */
8680
8863
  KEY_PART_INFO *end_part= min_max_arg_part ? min_max_arg_part : last_part;
8681
8864
 
8693
8876
      if (cur_range->field->eq(cur_part->field))
8694
8877
        break;
8695
8878
    }
8696
 
    if (!cur_range)
 
8879
    if (! cur_range)
8697
8880
    {
8698
8881
      if (min_max_arg_part)
8699
8882
        return false; /* The current keypart has no range predicates at all. */
8709
8892
      return false; /* This is not the only range predicate for the field. */
8710
8893
    if ((cur_range->min_flag & NO_MIN_RANGE) ||
8711
8894
        (cur_range->max_flag & NO_MAX_RANGE) ||
8712
 
        (cur_range->min_flag & NEAR_MIN) || (cur_range->max_flag & NEAR_MAX))
 
8895
        (cur_range->min_flag & NEAR_MIN) || 
 
8896
        (cur_range->max_flag & NEAR_MAX))
8713
8897
      return false;
8714
8898
 
8715
8899
    uint32_t field_length= cur_part->store_length;
8749
8933
    Positive number which is the consecutive number of the key part, or
8750
8934
    0 if field does not reference any index field.
8751
8935
*/
8752
 
 
8753
8936
static inline uint
8754
8937
get_field_keypart(KEY *index, Field *field)
8755
8938
{
8756
 
  KEY_PART_INFO *part, *end;
 
8939
  KEY_PART_INFO *part= NULL;
 
8940
  KEY_PART_INFO *end= NULL;
8757
8941
 
8758
8942
  for (part= index->key_part, end= part + index->key_parts; part < end; part++)
8759
8943
  {
8771
8955
    get_index_range_tree()
8772
8956
    index     [in]  The ID of the index being looked for
8773
8957
    range_tree[in]  Tree of ranges being searched
8774
 
    param     [in]  PARAM from SQL_SELECT::test_quick_select
 
8958
    param     [in]  PARAM from SqlSelect::test_quick_select
8775
8959
    param_idx [out] Index in the array PARAM::key that corresponds to 'index'
8776
8960
 
8777
8961
  DESCRIPTION
8786
8970
  RETURN
8787
8971
    Pointer to the SEL_ARG subtree that corresponds to index.
8788
8972
*/
8789
 
 
8790
 
SEL_ARG * get_index_range_tree(uint32_t index, SEL_TREE* range_tree, PARAM *param,
 
8973
SEL_ARG * get_index_range_tree(uint32_t index, 
 
8974
                               SEL_TREE* range_tree, 
 
8975
                               PARAM *param,
8791
8976
                               uint32_t *param_idx)
8792
8977
{
8793
8978
  uint32_t idx= 0; /* Index nr in param->key_parts */
8861
9046
  RETURN
8862
9047
    None
8863
9048
*/
8864
 
 
8865
 
void cost_group_min_max(Table* table, KEY *index_info, uint32_t used_key_parts,
8866
 
                        uint32_t group_key_parts, SEL_TREE *range_tree,
8867
 
                        SEL_ARG *, ha_rows quick_prefix_records,
8868
 
                        bool have_min, bool have_max,
8869
 
                        double *read_cost, ha_rows *records)
 
9049
void cost_group_min_max(Table* table, 
 
9050
                        KEY *index_info, 
 
9051
                        uint32_t used_key_parts,
 
9052
                        uint32_t group_key_parts, 
 
9053
                        SEL_TREE *range_tree,
 
9054
                        SEL_ARG *, 
 
9055
                        ha_rows quick_prefix_records,
 
9056
                        bool have_min, 
 
9057
                        bool have_max,
 
9058
                        double *read_cost, 
 
9059
                        ha_rows *records)
8870
9060
{
8871
9061
  ha_rows table_records;
8872
9062
  uint32_t num_groups;
8884
9074
  keys_per_block= (table->cursor->stats.block_size / 2 /
8885
9075
                   (index_info->key_length + table->cursor->ref_length)
8886
9076
                        + 1);
8887
 
  num_blocks= (uint32_t)(table_records / keys_per_block) + 1;
 
9077
  num_blocks= (uint32_t) (table_records / keys_per_block) + 1;
8888
9078
 
8889
9079
  /* Compute the number of keys in a group. */
8890
9080
  keys_per_group= index_info->rec_per_key[group_key_parts - 1];
8927
9117
  /*
8928
9118
    TODO: If there is no WHERE clause and no other expressions, there should be
8929
9119
    no CPU cost. We leave it here to make this cost comparable to that of index
8930
 
    scan as computed in SQL_SELECT::test_quick_select().
 
9120
    scan as computed in SqlSelect::test_quick_select().
8931
9121
  */
8932
9122
  cpu_cost= (double) num_groups / TIME_FOR_COMPARE;
8933
9123
 
8956
9146
    New QUICK_GROUP_MIN_MAX_SELECT object if successfully created,
8957
9147
    NULL otherwise.
8958
9148
*/
8959
 
 
8960
 
optimizer::QUICK_SELECT_I *
 
9149
optimizer::QuickSelectInterface *
8961
9150
TRP_GROUP_MIN_MAX::make_quick(PARAM *param, bool, MEM_ROOT *parent_alloc)
8962
9151
{
8963
 
  optimizer::QUICK_GROUP_MIN_MAX_SELECT *quick;
 
9152
  optimizer::QUICK_GROUP_MIN_MAX_SELECT *quick= NULL;
8964
9153
 
8965
9154
  quick= new optimizer::QUICK_GROUP_MIN_MAX_SELECT(param->table,
8966
9155
                                                   param->session->lex->current_select->join,
9069
9258
  RETURN
9070
9259
    None
9071
9260
*/
9072
 
 
9073
9261
optimizer::QUICK_GROUP_MIN_MAX_SELECT::
9074
9262
QUICK_GROUP_MIN_MAX_SELECT(Table *table, 
9075
9263
                           JOIN *join_arg, 
9089
9277
  :
9090
9278
    join(join_arg), 
9091
9279
    index_info(index_info_arg),
9092
 
   group_prefix_len(group_prefix_len_arg),
9093
 
   group_key_parts(group_key_parts_arg), 
9094
 
   have_min(have_min_arg),
9095
 
   have_max(have_max_arg), 
9096
 
   seen_first_key(false),
9097
 
   min_max_arg_part(min_max_arg_part_arg), 
9098
 
   key_infix(key_infix_arg),
9099
 
   key_infix_len(key_infix_len_arg), 
9100
 
   min_functions_it(NULL),
9101
 
   max_functions_it(NULL)
 
9280
    group_prefix_len(group_prefix_len_arg),
 
9281
    group_key_parts(group_key_parts_arg), 
 
9282
    have_min(have_min_arg),
 
9283
    have_max(have_max_arg), 
 
9284
    seen_first_key(false),
 
9285
    min_max_arg_part(min_max_arg_part_arg), 
 
9286
    key_infix(key_infix_arg),
 
9287
    key_infix_len(key_infix_len_arg), 
 
9288
    min_functions_it(NULL),
 
9289
    max_functions_it(NULL)
9102
9290
{
9103
 
  head=       table;
9104
 
  cursor=       head->cursor;
9105
 
  index=      use_index;
9106
 
  record=     head->record[0];
 
9291
  head= table;
 
9292
  cursor= head->cursor;
 
9293
  index= use_index;
 
9294
  record= head->record[0];
9107
9295
  tmp_record= head->record[1];
9108
9296
  read_time= read_cost_arg;
9109
9297
  records= records_arg;
9117
9305
    We can't have parent_alloc set as the init function can't handle this case
9118
9306
    yet.
9119
9307
  */
9120
 
  assert(!parent_alloc);
9121
 
  if (!parent_alloc)
 
9308
  assert(! parent_alloc);
 
9309
  if (! parent_alloc)
9122
9310
  {
9123
9311
    init_sql_alloc(&alloc, join->session->variables.range_alloc_block_size, 0);
9124
9312
    join->session->mem_root= &alloc;
9144
9332
    0      OK
9145
9333
    other  Error code
9146
9334
*/
9147
 
 
9148
9335
int optimizer::QUICK_GROUP_MIN_MAX_SELECT::init()
9149
9336
{
9150
9337
  if (group_prefix) /* Already initialized. */
9151
9338
    return 0;
9152
9339
 
9153
 
  if (!(last_prefix= (unsigned char*) alloc_root(&alloc, group_prefix_len)))
 
9340
  if (! (last_prefix= (unsigned char*) alloc_root(&alloc, group_prefix_len)))
9154
9341
      return 1;
9155
9342
  /*
9156
9343
    We may use group_prefix to store keys with all select fields, so allocate
9157
9344
    enough space for it.
9158
9345
  */
9159
 
  if (!(group_prefix= (unsigned char*) alloc_root(&alloc,
9160
 
                                         real_prefix_len + min_max_arg_len)))
 
9346
  if (! (group_prefix= (unsigned char*) alloc_root(&alloc,
 
9347
                                                   real_prefix_len + min_max_arg_len)))
9161
9348
    return 1;
9162
9349
 
9163
9350
  if (key_infix_len > 0)
9167
9354
      allocate a new buffer and copy the key_infix into it.
9168
9355
    */
9169
9356
    unsigned char *tmp_key_infix= (unsigned char*) alloc_root(&alloc, key_infix_len);
9170
 
    if (!tmp_key_infix)
 
9357
    if (! tmp_key_infix)
9171
9358
      return 1;
9172
9359
    memcpy(tmp_key_infix, this->key_infix, key_infix_len);
9173
9360
    this->key_infix= tmp_key_infix;
9180
9367
 
9181
9368
    if (have_min)
9182
9369
    {
9183
 
      if (!(min_functions= new List<Item_sum>))
 
9370
      if (! (min_functions= new List<Item_sum>))
9184
9371
        return 1;
9185
9372
    }
9186
9373
    else
9187
9374
      min_functions= NULL;
9188
9375
    if (have_max)
9189
9376
    {
9190
 
      if (!(max_functions= new List<Item_sum>))
 
9377
      if (! (max_functions= new List<Item_sum>))
9191
9378
        return 1;
9192
9379
    }
9193
9380
    else
9194
9381
      max_functions= NULL;
9195
9382
 
9196
 
    Item_sum *min_max_item;
 
9383
    Item_sum *min_max_item= NULL;
9197
9384
    Item_sum **func_ptr= join->sum_funcs;
9198
9385
    while ((min_max_item= *(func_ptr++)))
9199
9386
    {
9205
9392
 
9206
9393
    if (have_min)
9207
9394
    {
9208
 
      if (!(min_functions_it= new List_iterator<Item_sum>(*min_functions)))
 
9395
      if (! (min_functions_it= new List_iterator<Item_sum>(*min_functions)))
9209
9396
        return 1;
9210
9397
    }
9211
9398
 
9212
9399
    if (have_max)
9213
9400
    {
9214
 
      if (!(max_functions_it= new List_iterator<Item_sum>(*max_functions)))
 
9401
      if (! (max_functions_it= new List_iterator<Item_sum>(*max_functions)))
9215
9402
        return 1;
9216
9403
    }
9217
9404
  }
9256
9443
    false on success
9257
9444
    true  otherwise
9258
9445
*/
9259
 
 
9260
9446
bool optimizer::QUICK_GROUP_MIN_MAX_SELECT::add_range(SEL_ARG *sel_range)
9261
9447
{
9262
9448
  optimizer::QuickRange *range= NULL;
9266
9452
  if ((range_flag & NO_MIN_RANGE) && (range_flag & NO_MAX_RANGE))
9267
9453
    return false;
9268
9454
 
9269
 
  if (!(sel_range->min_flag & NO_MIN_RANGE) &&
9270
 
      !(sel_range->max_flag & NO_MAX_RANGE))
 
9455
  if (! (sel_range->min_flag & NO_MIN_RANGE) &&
 
9456
      ! (sel_range->max_flag & NO_MAX_RANGE))
9271
9457
  {
9272
9458
    if (sel_range->maybe_null &&
9273
9459
        sel_range->min_value[0] && sel_range->max_value[0])
9276
9462
                    min_max_arg_len) == 0)
9277
9463
      range_flag|= EQ_RANGE;  /* equality condition */
9278
9464
  }
9279
 
  range= new optimizer::QuickRange(sel_range->min_value, min_max_arg_len,
9280
 
                         make_keypart_map(sel_range->part),
9281
 
                         sel_range->max_value, min_max_arg_len,
9282
 
                         make_keypart_map(sel_range->part),
9283
 
                         range_flag);
9284
 
  if (!range)
 
9465
  range= new optimizer::QuickRange(sel_range->min_value, 
 
9466
                                   min_max_arg_len,
 
9467
                                   make_keypart_map(sel_range->part),
 
9468
                                   sel_range->max_value, 
 
9469
                                   min_max_arg_len,
 
9470
                                   make_keypart_map(sel_range->part),
 
9471
                                   range_flag);
 
9472
  if (! range)
9285
9473
    return true;
9286
9474
  if (insert_dynamic(&min_max_ranges, (unsigned char*)&range))
9287
9475
    return true;
9311
9499
  if (quick_prefix_select &&
9312
9500
      group_prefix_len < quick_prefix_select->max_used_key_length)
9313
9501
  {
9314
 
    DYNAMIC_ARRAY *arr;
 
9502
    DYNAMIC_ARRAY *arr= NULL;
9315
9503
    uint32_t inx;
9316
9504
 
9317
9505
    for (inx= 0, arr= &quick_prefix_select->ranges; inx < arr->elements; inx++)
9345
9533
  RETURN
9346
9534
    None
9347
9535
*/
9348
 
 
9349
9536
void optimizer::QUICK_GROUP_MIN_MAX_SELECT::update_key_stat()
9350
9537
{
9351
9538
  max_used_key_length= real_prefix_len;
9354
9541
    optimizer::QuickRange *cur_range= NULL;
9355
9542
    if (have_min)
9356
9543
    { /* Check if the right-most range has a lower boundary. */
9357
 
      get_dynamic(&min_max_ranges, (unsigned char*)&cur_range,
 
9544
      get_dynamic(&min_max_ranges, 
 
9545
                  (unsigned char*) &cur_range,
9358
9546
                  min_max_ranges.elements - 1);
9359
 
      if (!(cur_range->flag & NO_MIN_RANGE))
 
9547
      if (! (cur_range->flag & NO_MIN_RANGE))
9360
9548
      {
9361
9549
        max_used_key_length+= min_max_arg_len;
9362
9550
        used_key_parts++;
9366
9554
    if (have_max)
9367
9555
    { /* Check if the left-most range has an upper boundary. */
9368
9556
      get_dynamic(&min_max_ranges, (unsigned char*)&cur_range, 0);
9369
 
      if (!(cur_range->flag & NO_MAX_RANGE))
 
9557
      if (! (cur_range->flag & NO_MAX_RANGE))
9370
9558
      {
9371
9559
        max_used_key_length+= min_max_arg_len;
9372
9560
        used_key_parts++;
9405
9593
    0      OK
9406
9594
    other  Error code
9407
9595
*/
9408
 
 
9409
9596
int optimizer::QUICK_GROUP_MIN_MAX_SELECT::reset(void)
9410
9597
{
9411
9598
  int result;
9452
9639
    HA_ERR_END_OF_FILE if returned all keys
9453
9640
    other              if some error occurred
9454
9641
*/
9455
 
 
9456
9642
int optimizer::QUICK_GROUP_MIN_MAX_SELECT::get_next()
9457
9643
{
9458
9644
  int min_res= 0;
9459
9645
  int max_res= 0;
9460
 
  int result;
 
9646
  int result= 0;
9461
9647
  int is_last_prefix= 0;
9462
9648
 
9463
9649
  /*
9471
9657
      Check if this is the last group prefix. Notice that at this point
9472
9658
      this->record contains the current prefix in record format.
9473
9659
    */
9474
 
    if (!result)
 
9660
    if (! result)
9475
9661
    {
9476
9662
      is_last_prefix= key_cmp(index_info->key_part, last_prefix,
9477
9663
                              group_prefix_len);
9506
9692
      are equality predicates for the key parts after the group, find the
9507
9693
      first sub-group with the extended prefix.
9508
9694
    */
9509
 
    if (!have_min && !have_max && key_infix_len > 0)
9510
 
      result= cursor->index_read_map(record, group_prefix,
9511
 
                                   make_prev_keypart_map(real_key_parts),
9512
 
                                   HA_READ_KEY_EXACT);
 
9695
    if (! have_min && ! have_max && key_infix_len > 0)
 
9696
      result= cursor->index_read_map(record, 
 
9697
                                     group_prefix,
 
9698
                                     make_prev_keypart_map(real_key_parts),
 
9699
                                     HA_READ_KEY_EXACT);
9513
9700
 
9514
9701
    result= have_min ? min_res : have_max ? max_res : result;
9515
9702
  } while ((result == HA_ERR_KEY_NOT_FOUND || result == HA_ERR_END_OF_FILE) &&
9554
9741
    HA_ERR_END_OF_FILE   - "" -
9555
9742
    other                if some error occurred
9556
9743
*/
9557
 
 
9558
9744
int optimizer::QUICK_GROUP_MIN_MAX_SELECT::next_min()
9559
9745
{
9560
9746
  int result= 0;
9570
9756
    /* Apply the constant equality conditions to the non-group select fields */
9571
9757
    if (key_infix_len > 0)
9572
9758
    {
9573
 
      if ((result= cursor->index_read_map(record, group_prefix,
9574
 
                                        make_prev_keypart_map(real_key_parts),
9575
 
                                        HA_READ_KEY_EXACT)))
 
9759
      if ((result= cursor->index_read_map(record, 
 
9760
                                          group_prefix,
 
9761
                                          make_prev_keypart_map(real_key_parts),
 
9762
                                          HA_READ_KEY_EXACT)))
9576
9763
        return result;
9577
9764
    }
9578
9765
 
9587
9774
    {
9588
9775
      /* Find the first subsequent record without NULL in the MIN/MAX field. */
9589
9776
      key_copy(tmp_record, record, index_info, 0);
9590
 
      result= cursor->index_read_map(record, tmp_record,
9591
 
                                   make_keypart_map(real_key_parts),
9592
 
                                   HA_READ_AFTER_KEY);
 
9777
      result= cursor->index_read_map(record, 
 
9778
                                     tmp_record,
 
9779
                                     make_keypart_map(real_key_parts),
 
9780
                                     HA_READ_AFTER_KEY);
9593
9781
      /*
9594
9782
        Check if the new record belongs to the current group by comparing its
9595
9783
        prefix with the group's prefix. If it is from the next group, then the
9600
9788
        next call to next_min(), and to save one lookup in the next call. For
9601
9789
        this add a new member 'this->next_group_prefix'.
9602
9790
      */
9603
 
      if (!result)
 
9791
      if (! result)
9604
9792
      {
9605
9793
        if (key_cmp(index_info->key_part, group_prefix, real_prefix_len))
9606
9794
          key_restore(record, tmp_record, index_info, 0);
9633
9821
    HA_ERR_END_OF_FILE   - "" -
9634
9822
    other                if some error occurred
9635
9823
*/
9636
 
 
9637
9824
int optimizer::QUICK_GROUP_MIN_MAX_SELECT::next_max()
9638
9825
{
9639
 
  int result;
 
9826
  int result= 0;
9640
9827
 
9641
9828
  /* Get the last key in the (possibly extended) group. */
9642
9829
  if (min_max_ranges.elements > 0)
9643
9830
    result= next_max_in_range();
9644
9831
  else
9645
 
    result= cursor->index_read_map(record, group_prefix,
9646
 
                                 make_prev_keypart_map(real_key_parts),
9647
 
                                 HA_READ_PREFIX_LAST);
 
9832
    result= cursor->index_read_map(record, 
 
9833
                                   group_prefix,
 
9834
                                   make_prev_keypart_map(real_key_parts),
 
9835
                                   HA_READ_PREFIX_LAST);
9648
9836
  return result;
9649
9837
}
9650
9838
 
9672
9860
*/
9673
9861
int optimizer::QUICK_GROUP_MIN_MAX_SELECT::next_prefix()
9674
9862
{
9675
 
  int result;
 
9863
  int result= 0;
9676
9864
 
9677
9865
  if (quick_prefix_select)
9678
9866
  {
9679
9867
    unsigned char *cur_prefix= seen_first_key ? group_prefix : NULL;
9680
9868
    if ((result= quick_prefix_select->get_next_prefix(group_prefix_len,
9681
 
                         make_prev_keypart_map(group_key_parts), cur_prefix)))
 
9869
                                                      make_prev_keypart_map(group_key_parts), 
 
9870
                                                      cur_prefix)))
9682
9871
      return result;
9683
9872
    seen_first_key= true;
9684
9873
  }
9685
9874
  else
9686
9875
  {
9687
 
    if (!seen_first_key)
 
9876
    if (! seen_first_key)
9688
9877
    {
9689
9878
      result= cursor->index_first(record);
9690
9879
      if (result)
9694
9883
    else
9695
9884
    {
9696
9885
      /* Load the first key in this group into record. */
9697
 
      result= cursor->index_read_map(record, group_prefix,
9698
 
                                   make_prev_keypart_map(group_key_parts),
9699
 
                                   HA_READ_AFTER_KEY);
 
9886
      result= cursor->index_read_map(record, 
 
9887
                                     group_prefix,
 
9888
                                     make_prev_keypart_map(group_key_parts),
 
9889
                                     HA_READ_AFTER_KEY);
9700
9890
      if (result)
9701
9891
        return result;
9702
9892
    }
9707
9897
  /* Append key_infix to group_prefix. */
9708
9898
  if (key_infix_len > 0)
9709
9899
    memcpy(group_prefix + group_prefix_len,
9710
 
           key_infix, key_infix_len);
 
9900
           key_infix, 
 
9901
           key_infix_len);
9711
9902
 
9712
9903
  return 0;
9713
9904
}
9733
9924
    HA_ERR_END_OF_FILE   - "" -
9734
9925
    other                if some error
9735
9926
*/
9736
 
 
9737
9927
int optimizer::QUICK_GROUP_MIN_MAX_SELECT::next_min_in_range()
9738
9928
{
9739
9929
  ha_rkey_function find_flag;
9756
9946
      boundary of cur_range, there is no need to check this range.
9757
9947
    */
9758
9948
    if (range_idx != 0 && !(cur_range->flag & NO_MAX_RANGE) &&
9759
 
        (key_cmp(min_max_arg_part, (const unsigned char*) cur_range->max_key,
 
9949
        (key_cmp(min_max_arg_part, 
 
9950
                 (const unsigned char*) cur_range->max_key,
9760
9951
                 min_max_arg_len) == 1))
9761
9952
      continue;
9762
9953
 
9768
9959
    else
9769
9960
    {
9770
9961
      /* Extend the search key with the lower boundary for this range. */
9771
 
      memcpy(group_prefix + real_prefix_len, cur_range->min_key,
 
9962
      memcpy(group_prefix + real_prefix_len, 
 
9963
             cur_range->min_key,
9772
9964
             cur_range->min_length);
9773
9965
      keypart_map= make_keypart_map(real_key_parts);
9774
9966
      find_flag= (cur_range->flag & (EQ_RANGE | NULL_RANGE)) ?
9814
10006
    }
9815
10007
 
9816
10008
    /* If there is an upper limit, check if the found key is in the range. */
9817
 
    if ( !(cur_range->flag & NO_MAX_RANGE) )
 
10009
    if (! (cur_range->flag & NO_MAX_RANGE) )
9818
10010
    {
9819
10011
      /* Compose the MAX key for the range. */
9820
10012
      max_key.clear();
9824
10016
      int cmp_res= key_cmp(index_info->key_part,
9825
10017
                           max_key.data(),
9826
10018
                           real_prefix_len + min_max_arg_len);
9827
 
      if (!(((cur_range->flag & NEAR_MAX) && (cmp_res == -1)) ||
9828
 
            (cmp_res <= 0)))
 
10019
      if (! (((cur_range->flag & NEAR_MAX) && (cmp_res == -1)) ||
 
10020
          (cmp_res <= 0)))
9829
10021
      {
9830
10022
        result= HA_ERR_KEY_NOT_FOUND;
9831
10023
        continue;
9869
10061
    HA_ERR_END_OF_FILE   - "" -
9870
10062
    other                if some error
9871
10063
*/
9872
 
 
9873
10064
int optimizer::QUICK_GROUP_MIN_MAX_SELECT::next_max_in_range()
9874
10065
{
9875
10066
  ha_rkey_function find_flag;
9876
10067
  key_part_map keypart_map;
9877
10068
  optimizer::QuickRange *cur_range= NULL;
9878
 
  int result;
 
10069
  int result= 0;
9879
10070
  basic_string<unsigned char> min_key;
9880
10071
  min_key.reserve(real_prefix_len + min_max_arg_len);
9881
10072
 
9890
10081
      boundary of cur_range, there is no need to check this range.
9891
10082
    */
9892
10083
    if (range_idx != min_max_ranges.elements &&
9893
 
        !(cur_range->flag & NO_MIN_RANGE) &&
9894
 
        (key_cmp(min_max_arg_part, (const unsigned char*) cur_range->min_key,
 
10084
        ! (cur_range->flag & NO_MIN_RANGE) &&
 
10085
        (key_cmp(min_max_arg_part, 
 
10086
                 (const unsigned char*) cur_range->min_key,
9895
10087
                 min_max_arg_len) == -1))
9896
10088
      continue;
9897
10089
 
9903
10095
    else
9904
10096
    {
9905
10097
      /* Extend the search key with the upper boundary for this range. */
9906
 
      memcpy(group_prefix + real_prefix_len, cur_range->max_key,
 
10098
      memcpy(group_prefix + real_prefix_len, 
 
10099
             cur_range->max_key,
9907
10100
             cur_range->max_length);
9908
10101
      keypart_map= make_keypart_map(real_key_parts);
9909
10102
      find_flag= (cur_range->flag & EQ_RANGE) ?
9934
10127
      continue;                                 // Row not found
9935
10128
 
9936
10129
    /* If there is a lower limit, check if the found key is in the range. */
9937
 
    if ( !(cur_range->flag & NO_MIN_RANGE) )
 
10130
    if (! (cur_range->flag & NO_MIN_RANGE) )
9938
10131
    {
9939
10132
      /* Compose the MIN key for the range. */
9940
10133
      min_key.clear();
9945
10138
      int cmp_res= key_cmp(index_info->key_part,
9946
10139
                           min_key.data(),
9947
10140
                           real_prefix_len + min_max_arg_len);
9948
 
      if (!(((cur_range->flag & NEAR_MIN) && (cmp_res == 1)) ||
9949
 
            (cmp_res >= 0)))
 
10141
      if (! (((cur_range->flag & NEAR_MIN) && (cmp_res == 1)) ||
 
10142
          (cmp_res >= 0)))
9950
10143
        continue;
9951
10144
    }
9952
10145
    /* If we got to this point, the current key qualifies as MAX. */
9978
10171
  RETURN
9979
10172
    None
9980
10173
*/
9981
 
 
9982
10174
void optimizer::QUICK_GROUP_MIN_MAX_SELECT::update_min_result()
9983
10175
{
9984
 
  Item_sum *min_func;
 
10176
  Item_sum *min_func= NULL;
9985
10177
 
9986
10178
  min_functions_it->rewind();
9987
10179
  while ((min_func= (*min_functions_it)++))
10010
10202
  RETURN
10011
10203
    None
10012
10204
*/
10013
 
 
10014
10205
void optimizer::QUICK_GROUP_MIN_MAX_SELECT::update_max_result()
10015
10206
{
10016
 
  Item_sum *max_func;
 
10207
  Item_sum *max_func= NULL;
10017
10208
 
10018
10209
  max_functions_it->rewind();
10019
10210
  while ((max_func= (*max_functions_it)++))
10035
10226
    indexes used by a quick select.
10036
10227
 
10037
10228
*/
10038
 
 
10039
10229
void optimizer::QUICK_GROUP_MIN_MAX_SELECT::add_keys_and_lengths(String *key_names,
10040
10230
                                                                 String *used_lengths)
10041
10231
{
10048
10238
 
10049
10239
static void print_sel_tree(PARAM *param, SEL_TREE *tree, key_map *tree_map, const char *)
10050
10240
{
10051
 
  SEL_ARG **key,**end;
10052
 
  int idx;
 
10241
  SEL_ARG **key= NULL;
 
10242
  SEL_ARG **end= NULL;
 
10243
  int idx= 0;
10053
10244
  char buff[1024];
10054
10245
 
10055
10246
  String tmp(buff,sizeof(buff),&my_charset_bin);
10056
10247
  tmp.length(0);
10057
 
  for (idx= 0,key=tree->keys, end=key+param->keys ;
10058
 
       key != end ;
10059
 
       key++,idx++)
 
10248
  for (idx= 0, key=tree->keys, end= key + param->keys;
 
10249
       key != end;
 
10250
       key++, idx++)
10060
10251
  {
10061
10252
    if (tree_map->test(idx))
10062
10253
    {
10066
10257
      tmp.append(param->table->key_info[keynr].name);
10067
10258
    }
10068
10259
  }
10069
 
  if (!tmp.length())
 
10260
  if (! tmp.length())
10070
10261
    tmp.append(STRING_WITH_LEN("(empty)"));
10071
10262
}
10072
10263
 
10073
10264
 
10074
10265
static void print_ror_scans_arr(Table *table,
10075
 
                                const char *, struct st_ror_scan_info **start,
 
10266
                                const char *, 
 
10267
                                struct st_ror_scan_info **start,
10076
10268
                                struct st_ror_scan_info **end)
10077
10269
{
10078
10270
  char buff[1024];