~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/item/cmpfunc.cc

  • Committer: Brian Aker
  • Date: 2010-10-21 08:55:44 UTC
  • mto: (1866.1.1 merge)
  • mto: This revision was merged to the branch mainline in revision 1867.
  • Revision ID: brian@tangent.org-20101021085544-chpce06zm4tdaqdi
This creates a function for seeing which catalog you are in. It also
refactors some of the functions to be in the utility_function collect.

Show diffs side-by-side

added added

removed removed

Lines of Context:
570
570
{
571
571
  owner= item;
572
572
  func= comparator_matrix[type]
573
 
    [test(owner->functype() == Item_func::EQUAL_FUNC)];
574
 
 
 
573
                         [test(owner->functype() == Item_func::EQUAL_FUNC)];
575
574
  switch (type) {
576
575
  case ROW_RESULT:
577
 
    {
578
 
      uint32_t n= (*a)->cols();
579
 
      if (n != (*b)->cols())
580
 
      {
581
 
        my_error(ER_OPERAND_COLUMNS, MYF(0), n);
582
 
        comparators= 0;
583
 
        return 1;
584
 
      }
585
 
      if (!(comparators= new Arg_comparator[n]))
586
 
        return 1;
587
 
      for (uint32_t i=0; i < n; i++)
588
 
      {
589
 
        if ((*a)->element_index(i)->cols() != (*b)->element_index(i)->cols())
590
 
        {
591
 
          my_error(ER_OPERAND_COLUMNS, MYF(0), (*a)->element_index(i)->cols());
592
 
          return 1;
593
 
        }
594
 
        comparators[i].set_cmp_func(owner, (*a)->addr(i), (*b)->addr(i));
595
 
      }
596
 
      break;
597
 
    }
598
 
 
 
576
  {
 
577
    uint32_t n= (*a)->cols();
 
578
    if (n != (*b)->cols())
 
579
    {
 
580
      my_error(ER_OPERAND_COLUMNS, MYF(0), n);
 
581
      comparators= 0;
 
582
      return 1;
 
583
    }
 
584
    if (!(comparators= new Arg_comparator[n]))
 
585
      return 1;
 
586
    for (uint32_t i=0; i < n; i++)
 
587
    {
 
588
      if ((*a)->element_index(i)->cols() != (*b)->element_index(i)->cols())
 
589
      {
 
590
        my_error(ER_OPERAND_COLUMNS, MYF(0), (*a)->element_index(i)->cols());
 
591
        return 1;
 
592
      }
 
593
      comparators[i].set_cmp_func(owner, (*a)->addr(i), (*b)->addr(i));
 
594
    }
 
595
    break;
 
596
  }
599
597
  case STRING_RESULT:
 
598
  {
 
599
    /*
 
600
      We must set cmp_charset here as we may be called from for an automatic
 
601
      generated item, like in natural join
 
602
    */
 
603
    if (cmp_collation.set((*a)->collation, (*b)->collation) ||
 
604
        cmp_collation.derivation == DERIVATION_NONE)
 
605
    {
 
606
      my_coll_agg_error((*a)->collation, (*b)->collation, owner->func_name());
 
607
      return 1;
 
608
    }
 
609
    if (cmp_collation.collation == &my_charset_bin)
600
610
    {
601
611
      /*
602
 
        We must set cmp_charset here as we may be called from for an automatic
603
 
        generated item, like in natural join
 
612
        We are using BLOB/BINARY/VARBINARY, change to compare byte by byte,
 
613
        without removing end space
604
614
      */
605
 
      if (cmp_collation.set((*a)->collation, (*b)->collation) ||
606
 
          cmp_collation.derivation == DERIVATION_NONE)
607
 
      {
608
 
        my_coll_agg_error((*a)->collation, (*b)->collation, owner->func_name());
609
 
        return 1;
610
 
      }
611
 
      if (cmp_collation.collation == &my_charset_bin)
612
 
      {
613
 
        /*
614
 
          We are using BLOB/BINARY/VARBINARY, change to compare byte by byte,
615
 
          without removing end space
616
 
        */
617
 
        if (func == &Arg_comparator::compare_string)
618
 
          func= &Arg_comparator::compare_binary_string;
619
 
        else if (func == &Arg_comparator::compare_e_string)
620
 
          func= &Arg_comparator::compare_e_binary_string;
 
615
      if (func == &Arg_comparator::compare_string)
 
616
        func= &Arg_comparator::compare_binary_string;
 
617
      else if (func == &Arg_comparator::compare_e_string)
 
618
        func= &Arg_comparator::compare_e_binary_string;
621
619
 
622
 
        /*
623
 
          As this is binary compassion, mark all fields that they can't be
624
 
          transformed. Otherwise we would get into trouble with comparisons
625
 
like:
626
 
WHERE col= 'j' AND col LIKE BINARY 'j'
627
 
which would be transformed to:
628
 
WHERE col= 'j'
 
620
      /*
 
621
        As this is binary compassion, mark all fields that they can't be
 
622
        transformed. Otherwise we would get into trouble with comparisons
 
623
        like:
 
624
        WHERE col= 'j' AND col LIKE BINARY 'j'
 
625
        which would be transformed to:
 
626
        WHERE col= 'j'
629
627
      */
630
 
        (*a)->walk(&Item::set_no_const_sub, false, (unsigned char*) 0);
631
 
        (*b)->walk(&Item::set_no_const_sub, false, (unsigned char*) 0);
632
 
      }
633
 
      break;
 
628
      (*a)->walk(&Item::set_no_const_sub, false, (unsigned char*) 0);
 
629
      (*b)->walk(&Item::set_no_const_sub, false, (unsigned char*) 0);
634
630
    }
 
631
    break;
 
632
  }
635
633
  case INT_RESULT:
636
 
    {
637
 
      if (func == &Arg_comparator::compare_int_signed)
638
 
      {
639
 
        if ((*a)->unsigned_flag)
640
 
          func= (((*b)->unsigned_flag)?
641
 
                 &Arg_comparator::compare_int_unsigned :
642
 
                 &Arg_comparator::compare_int_unsigned_signed);
643
 
        else if ((*b)->unsigned_flag)
644
 
          func= &Arg_comparator::compare_int_signed_unsigned;
645
 
      }
646
 
      else if (func== &Arg_comparator::compare_e_int)
647
 
      {
648
 
        if ((*a)->unsigned_flag ^ (*b)->unsigned_flag)
649
 
          func= &Arg_comparator::compare_e_int_diff_signedness;
650
 
      }
651
 
      break;
652
 
    }
 
634
  {
 
635
    if (func == &Arg_comparator::compare_int_signed)
 
636
    {
 
637
      if ((*a)->unsigned_flag)
 
638
        func= (((*b)->unsigned_flag)?
 
639
               &Arg_comparator::compare_int_unsigned :
 
640
               &Arg_comparator::compare_int_unsigned_signed);
 
641
      else if ((*b)->unsigned_flag)
 
642
        func= &Arg_comparator::compare_int_signed_unsigned;
 
643
    }
 
644
    else if (func== &Arg_comparator::compare_e_int)
 
645
    {
 
646
      if ((*a)->unsigned_flag ^ (*b)->unsigned_flag)
 
647
        func= &Arg_comparator::compare_e_int_diff_signedness;
 
648
    }
 
649
    break;
 
650
  }
653
651
  case DECIMAL_RESULT:
654
652
    break;
655
653
  case REAL_RESULT:
 
654
  {
 
655
    if ((*a)->decimals < NOT_FIXED_DEC && (*b)->decimals < NOT_FIXED_DEC)
656
656
    {
657
 
      if ((*a)->decimals < NOT_FIXED_DEC && (*b)->decimals < NOT_FIXED_DEC)
658
 
      {
659
 
        precision= 5 / log_10[max((*a)->decimals, (*b)->decimals) + 1];
660
 
        if (func == &Arg_comparator::compare_real)
661
 
          func= &Arg_comparator::compare_real_fixed;
662
 
        else if (func == &Arg_comparator::compare_e_real)
663
 
          func= &Arg_comparator::compare_e_real_fixed;
664
 
      }
665
 
      break;
 
657
      precision= 5 / log_10[max((*a)->decimals, (*b)->decimals) + 1];
 
658
      if (func == &Arg_comparator::compare_real)
 
659
        func= &Arg_comparator::compare_real_fixed;
 
660
      else if (func == &Arg_comparator::compare_e_real)
 
661
        func= &Arg_comparator::compare_e_real_fixed;
666
662
    }
667
 
  }
668
 
 
 
663
    break;
 
664
  }
 
665
  default:
 
666
    assert(0);
 
667
  }
669
668
  return 0;
670
669
}
671
670
 
765
764
*/
766
765
 
767
766
enum Arg_comparator::enum_date_cmp_type
768
 
Arg_comparator::can_compare_as_dates(Item *in_a, Item *in_b,
769
 
                                     uint64_t *const_value)
 
767
Arg_comparator::can_compare_as_dates(Item *a, Item *b, uint64_t *const_value)
770
768
{
771
769
  enum enum_date_cmp_type cmp_type= CMP_DATE_DFLT;
772
770
  Item *str_arg= 0, *date_arg= 0;
773
771
 
774
 
  if (in_a->type() == Item::ROW_ITEM || in_b->type() == Item::ROW_ITEM)
 
772
  if (a->type() == Item::ROW_ITEM || b->type() == Item::ROW_ITEM)
775
773
    return CMP_DATE_DFLT;
776
774
 
777
 
  if (in_a->is_datetime())
 
775
  if (a->is_datetime())
778
776
  {
779
 
    if (in_b->is_datetime())
 
777
    if (b->is_datetime())
780
778
      cmp_type= CMP_DATE_WITH_DATE;
781
 
    else if (in_b->result_type() == STRING_RESULT)
 
779
    else if (b->result_type() == STRING_RESULT)
782
780
    {
783
781
      cmp_type= CMP_DATE_WITH_STR;
784
 
      date_arg= in_a;
785
 
      str_arg= in_b;
 
782
      date_arg= a;
 
783
      str_arg= b;
786
784
    }
787
785
  }
788
 
  else if (in_b->is_datetime() && in_a->result_type() == STRING_RESULT)
 
786
  else if (b->is_datetime() && a->result_type() == STRING_RESULT)
789
787
  {
790
788
    cmp_type= CMP_STR_WITH_DATE;
791
 
    date_arg= in_b;
792
 
    str_arg= in_a;
 
789
    date_arg= b;
 
790
    str_arg= a;
793
791
  }
794
792
 
795
793
  if (cmp_type != CMP_DATE_DFLT)
2196
2194
    max_length= max(len0, len1) + decimals + (unsigned_flag ? 0 : 1);
2197
2195
  }
2198
2196
  else
2199
 
  {
2200
2197
    max_length= max(args[0]->max_length, args[1]->max_length);
2201
 
  }
2202
2198
 
2203
2199
  switch (hybrid_type)
2204
2200
  {
2205
2201
  case STRING_RESULT:
2206
2202
    agg_arg_charsets(collation, args, arg_count, MY_COLL_CMP_CONV, 1);
2207
2203
    break;
2208
 
 
2209
2204
  case DECIMAL_RESULT:
2210
2205
  case REAL_RESULT:
2211
2206
    break;
2212
 
 
2213
2207
  case INT_RESULT:
2214
2208
    decimals= 0;
2215
2209
    break;
2216
 
 
2217
2210
  case ROW_RESULT:
 
2211
  default:
2218
2212
    assert(0);
2219
2213
  }
2220
 
 
2221
2214
  cached_field_type= agg_field_type(args, 2);
2222
2215
}
2223
2216
 
2755
2748
  */
2756
2749
  if (first_expr_num != -1)
2757
2750
  {
 
2751
    uint32_t i;
2758
2752
    agg[0]= args[first_expr_num];
2759
2753
    left_result_type= agg[0]->result_type();
2760
2754
 
2764
2758
    if (!(found_types= collect_cmp_types(agg, nagg)))
2765
2759
      return;
2766
2760
 
2767
 
    for (int i= STRING_RESULT; i <= DECIMAL_RESULT; i++)
 
2761
    for (i= 0; i <= (uint32_t)DECIMAL_RESULT; i++)
2768
2762
    {
2769
2763
      if (found_types & (1 << i) && !cmp_items[i])
2770
2764
      {
2850
2844
 
2851
2845
void Item_func_case::cleanup()
2852
2846
{
 
2847
  uint32_t i;
2853
2848
  Item_func::cleanup();
2854
 
  for (int i= STRING_RESULT; i <= DECIMAL_RESULT; i++)
 
2849
  for (i= 0; i <= (uint32_t)DECIMAL_RESULT; i++)
2855
2850
  {
2856
2851
    delete cmp_items[i];
2857
2852
    cmp_items[i]= 0;
2858
2853
  }
 
2854
  return;
2859
2855
}
2860
2856
 
2861
2857
 
2925
2921
{
2926
2922
  cached_field_type= agg_field_type(args, arg_count);
2927
2923
  agg_result_type(&hybrid_type, args, arg_count);
2928
 
 
2929
2924
  switch (hybrid_type) {
2930
2925
  case STRING_RESULT:
2931
2926
    count_only_length();
2932
2927
    decimals= NOT_FIXED_DEC;
2933
2928
    agg_arg_charsets(collation, args, arg_count, MY_COLL_ALLOW_CONV, 1);
2934
2929
    break;
2935
 
 
2936
2930
  case DECIMAL_RESULT:
2937
2931
    count_decimal_length();
2938
2932
    break;
2939
 
 
2940
2933
  case REAL_RESULT:
2941
2934
    count_real_length();
2942
2935
    break;
2943
 
 
2944
2936
  case INT_RESULT:
2945
2937
    count_only_length();
2946
2938
    decimals= 0;
2947
2939
    break;
2948
 
 
2949
2940
  case ROW_RESULT:
 
2941
  default:
2950
2942
    assert(0);
2951
2943
  }
2952
2944
}
3270
3262
  switch (type) {
3271
3263
  case STRING_RESULT:
3272
3264
    return new cmp_item_sort_string(cs);
3273
 
 
3274
3265
  case INT_RESULT:
3275
3266
    return new cmp_item_int;
3276
 
 
3277
3267
  case REAL_RESULT:
3278
3268
    return new cmp_item_real;
3279
 
 
3280
3269
  case ROW_RESULT:
3281
3270
    return new cmp_item_row;
3282
 
 
3283
3271
  case DECIMAL_RESULT:
3284
3272
    return new cmp_item_decimal;
 
3273
  default:
 
3274
    assert(0);
 
3275
    break;
3285
3276
  }
3286
 
 
3287
3277
  return 0; // to satisfy compiler :)
3288
3278
}
3289
3279
 
3554
3544
  bool compare_as_datetime= false;
3555
3545
  Item *date_arg= 0;
3556
3546
  uint32_t found_types= 0;
3557
 
  uint32_t type_cnt= 0;
 
3547
  uint32_t type_cnt= 0, i;
3558
3548
  Item_result cmp_type= STRING_RESULT;
3559
3549
  left_result_type= args[0]->result_type();
3560
3550
  if (!(found_types= collect_cmp_types(args, arg_count, true)))
3568
3558
      break;
3569
3559
    }
3570
3560
  }
3571
 
  for (int i= STRING_RESULT; i <= DECIMAL_RESULT; i++)
 
3561
  for (i= 0; i <= (uint32_t)DECIMAL_RESULT; i++)
3572
3562
  {
3573
3563
    if (found_types & 1 << i)
3574
3564
    {
3675
3665
  if (type_cnt == 1 && const_itm && !nulls_in_row())
3676
3666
  {
3677
3667
    if (compare_as_datetime)
3678
 
    {
3679
3668
      array= new in_datetime(date_arg, arg_count - 1);
3680
 
    }
3681
3669
    else
3682
3670
    {
3683
3671
      /*
3703
3691
            cmp_type= INT_RESULT;
3704
3692
        }
3705
3693
      }
3706
 
 
3707
3694
      switch (cmp_type) {
3708
3695
      case STRING_RESULT:
3709
3696
        array=new in_string(arg_count-1,(qsort2_cmp) srtcmp_in,
3710
3697
                            cmp_collation.collation);
3711
3698
        break;
3712
 
 
3713
3699
      case INT_RESULT:
3714
3700
        array= new in_int64_t(arg_count-1);
3715
3701
        break;
3716
 
 
3717
3702
      case REAL_RESULT:
3718
3703
        array= new in_double(arg_count-1);
3719
3704
        break;
3720
 
 
3721
3705
      case ROW_RESULT:
3722
3706
        /*
3723
3707
          The row comparator was created at the beginning but only DATETIME
3726
3710
        */
3727
3711
        ((in_row*)array)->tmp.store_value(args[0]);
3728
3712
        break;
3729
 
 
3730
3713
      case DECIMAL_RESULT:
3731
3714
        array= new in_decimal(arg_count - 1);
3732
3715
        break;
 
3716
      default:
 
3717
        assert(0);
 
3718
        return;
3733
3719
      }
3734
3720
    }
3735
 
 
3736
3721
    if (array && !(session->is_fatal_error))            // If not EOM
3737
3722
    {
3738
3723
      uint32_t j=0;
3739
3724
      for (uint32_t arg_num=1 ; arg_num < arg_count ; arg_num++)
3740
3725
      {
3741
 
        if (!args[arg_num]->null_value)                 // Skip NULL values
 
3726
        if (!args[arg_num]->null_value)                 // Skip NULL values
3742
3727
        {
3743
3728
          array->set(j,args[arg_num]);
3744
 
          j++;
 
3729
          j++;
3745
3730
        }
3746
 
        else
3747
 
          have_null= 1;
 
3731
        else
 
3732
          have_null= 1;
3748
3733
      }
3749
3734
      if ((array->used_count= j))
3750
 
        array->sort();
 
3735
        array->sort();
3751
3736
    }
3752
3737
  }
3753
3738
  else
3756
3741
      cmp_items[STRING_RESULT]= new cmp_item_datetime(date_arg);
3757
3742
    else
3758
3743
    {
3759
 
      for (int i= STRING_RESULT; i <= DECIMAL_RESULT; i++)
 
3744
      for (i= 0; i <= (uint32_t) DECIMAL_RESULT; i++)
3760
3745
      {
3761
3746
        if (found_types & (1 << i) && !cmp_items[i])
3762
3747
        {