~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/item/cmpfunc.cc

  • Committer: Brian Aker
  • Date: 2010-12-16 04:01:22 UTC
  • mfrom: (1996.2.1 compare)
  • Revision ID: brian@tangent.org-20101216040122-eodh5shwsij35ybe
Merge in uuid tree.

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
 
2196
2195
    max_length= max(len0, len1) + decimals + (unsigned_flag ? 0 : 1);
2197
2196
  }
2198
2197
  else
2199
 
  {
2200
2198
    max_length= max(args[0]->max_length, args[1]->max_length);
2201
 
  }
2202
2199
 
2203
2200
  switch (hybrid_type)
2204
2201
  {
2205
2202
  case STRING_RESULT:
2206
2203
    agg_arg_charsets(collation, args, arg_count, MY_COLL_CMP_CONV, 1);
2207
2204
    break;
2208
 
 
2209
2205
  case DECIMAL_RESULT:
2210
2206
  case REAL_RESULT:
2211
2207
    break;
2212
 
 
2213
2208
  case INT_RESULT:
2214
2209
    decimals= 0;
2215
2210
    break;
2216
 
 
2217
2211
  case ROW_RESULT:
 
2212
  default:
2218
2213
    assert(0);
2219
2214
  }
2220
 
 
2221
2215
  cached_field_type= agg_field_type(args, 2);
2222
2216
}
2223
2217
 
2755
2749
  */
2756
2750
  if (first_expr_num != -1)
2757
2751
  {
 
2752
    uint32_t i;
2758
2753
    agg[0]= args[first_expr_num];
2759
2754
    left_result_type= agg[0]->result_type();
2760
2755
 
2764
2759
    if (!(found_types= collect_cmp_types(agg, nagg)))
2765
2760
      return;
2766
2761
 
2767
 
    for (int i= STRING_RESULT; i <= DECIMAL_RESULT; i++)
 
2762
    for (i= 0; i <= (uint32_t)DECIMAL_RESULT; i++)
2768
2763
    {
2769
2764
      if (found_types & (1 << i) && !cmp_items[i])
2770
2765
      {
2850
2845
 
2851
2846
void Item_func_case::cleanup()
2852
2847
{
 
2848
  uint32_t i;
2853
2849
  Item_func::cleanup();
2854
 
  for (int i= STRING_RESULT; i <= DECIMAL_RESULT; i++)
 
2850
  for (i= 0; i <= (uint32_t)DECIMAL_RESULT; i++)
2855
2851
  {
2856
2852
    delete cmp_items[i];
2857
2853
    cmp_items[i]= 0;
2858
2854
  }
 
2855
  return;
2859
2856
}
2860
2857
 
2861
2858
 
2925
2922
{
2926
2923
  cached_field_type= agg_field_type(args, arg_count);
2927
2924
  agg_result_type(&hybrid_type, args, arg_count);
2928
 
 
2929
2925
  switch (hybrid_type) {
2930
2926
  case STRING_RESULT:
2931
2927
    count_only_length();
2932
2928
    decimals= NOT_FIXED_DEC;
2933
2929
    agg_arg_charsets(collation, args, arg_count, MY_COLL_ALLOW_CONV, 1);
2934
2930
    break;
2935
 
 
2936
2931
  case DECIMAL_RESULT:
2937
2932
    count_decimal_length();
2938
2933
    break;
2939
 
 
2940
2934
  case REAL_RESULT:
2941
2935
    count_real_length();
2942
2936
    break;
2943
 
 
2944
2937
  case INT_RESULT:
2945
2938
    count_only_length();
2946
2939
    decimals= 0;
2947
2940
    break;
2948
 
 
2949
2941
  case ROW_RESULT:
 
2942
  default:
2950
2943
    assert(0);
2951
2944
  }
2952
2945
}
3270
3263
  switch (type) {
3271
3264
  case STRING_RESULT:
3272
3265
    return new cmp_item_sort_string(cs);
3273
 
 
3274
3266
  case INT_RESULT:
3275
3267
    return new cmp_item_int;
3276
 
 
3277
3268
  case REAL_RESULT:
3278
3269
    return new cmp_item_real;
3279
 
 
3280
3270
  case ROW_RESULT:
3281
3271
    return new cmp_item_row;
3282
 
 
3283
3272
  case DECIMAL_RESULT:
3284
3273
    return new cmp_item_decimal;
 
3274
  default:
 
3275
    assert(0);
 
3276
    break;
3285
3277
  }
3286
 
 
3287
3278
  return 0; // to satisfy compiler :)
3288
3279
}
3289
3280
 
3554
3545
  bool compare_as_datetime= false;
3555
3546
  Item *date_arg= 0;
3556
3547
  uint32_t found_types= 0;
3557
 
  uint32_t type_cnt= 0;
 
3548
  uint32_t type_cnt= 0, i;
3558
3549
  Item_result cmp_type= STRING_RESULT;
3559
3550
  left_result_type= args[0]->result_type();
3560
3551
  if (!(found_types= collect_cmp_types(args, arg_count, true)))
3568
3559
      break;
3569
3560
    }
3570
3561
  }
3571
 
  for (int i= STRING_RESULT; i <= DECIMAL_RESULT; i++)
 
3562
  for (i= 0; i <= (uint32_t)DECIMAL_RESULT; i++)
3572
3563
  {
3573
3564
    if (found_types & 1 << i)
3574
3565
    {
3675
3666
  if (type_cnt == 1 && const_itm && !nulls_in_row())
3676
3667
  {
3677
3668
    if (compare_as_datetime)
3678
 
    {
3679
3669
      array= new in_datetime(date_arg, arg_count - 1);
3680
 
    }
3681
3670
    else
3682
3671
    {
3683
3672
      /*
3703
3692
            cmp_type= INT_RESULT;
3704
3693
        }
3705
3694
      }
3706
 
 
3707
3695
      switch (cmp_type) {
3708
3696
      case STRING_RESULT:
3709
3697
        array=new in_string(arg_count-1,(qsort2_cmp) srtcmp_in,
3710
3698
                            cmp_collation.collation);
3711
3699
        break;
3712
 
 
3713
3700
      case INT_RESULT:
3714
3701
        array= new in_int64_t(arg_count-1);
3715
3702
        break;
3716
 
 
3717
3703
      case REAL_RESULT:
3718
3704
        array= new in_double(arg_count-1);
3719
3705
        break;
3720
 
 
3721
3706
      case ROW_RESULT:
3722
3707
        /*
3723
3708
          The row comparator was created at the beginning but only DATETIME
3726
3711
        */
3727
3712
        ((in_row*)array)->tmp.store_value(args[0]);
3728
3713
        break;
3729
 
 
3730
3714
      case DECIMAL_RESULT:
3731
3715
        array= new in_decimal(arg_count - 1);
3732
3716
        break;
 
3717
      default:
 
3718
        assert(0);
 
3719
        return;
3733
3720
      }
3734
3721
    }
3735
 
 
3736
3722
    if (array && !(session->is_fatal_error))            // If not EOM
3737
3723
    {
3738
3724
      uint32_t j=0;
3739
3725
      for (uint32_t arg_num=1 ; arg_num < arg_count ; arg_num++)
3740
3726
      {
3741
 
        if (!args[arg_num]->null_value)                 // Skip NULL values
 
3727
        if (!args[arg_num]->null_value)                 // Skip NULL values
3742
3728
        {
3743
3729
          array->set(j,args[arg_num]);
3744
 
          j++;
 
3730
          j++;
3745
3731
        }
3746
 
        else
3747
 
          have_null= 1;
 
3732
        else
 
3733
          have_null= 1;
3748
3734
      }
3749
3735
      if ((array->used_count= j))
3750
 
        array->sort();
 
3736
        array->sort();
3751
3737
    }
3752
3738
  }
3753
3739
  else
3756
3742
      cmp_items[STRING_RESULT]= new cmp_item_datetime(date_arg);
3757
3743
    else
3758
3744
    {
3759
 
      for (int i= STRING_RESULT; i <= DECIMAL_RESULT; i++)
 
3745
      for (i= 0; i <= (uint32_t) DECIMAL_RESULT; i++)
3760
3746
      {
3761
3747
        if (found_types & (1 << i) && !cmp_items[i])
3762
3748
        {