~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/item/cmpfunc.cc

  • Committer: Monty Taylor
  • Date: 2010-06-02 22:35:45 UTC
  • mto: This revision was merged to the branch mainline in revision 1586.
  • Revision ID: mordred@inaugust.com-20100602223545-q8ekf9b40a85nwuf
Rearragned unittests into a single exe because of how we need to link it
(thanks lifeless)
Link with server symbols without needing to build a library.
Added an additional atomics test which tests whatever version of the atomics
lib the running platform would actually use.

Show diffs side-by-side

added added

removed removed

Lines of Context:
11
11
 
12
12
   You should have received a copy of the GNU General Public License
13
13
   along with this program; if not, write to the Free Software
14
 
   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
 
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
15
 
16
16
 
17
17
/**
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
 
722
721
  }
723
722
 
724
723
  if (error > 0)
725
 
  {
726
724
    make_truncated_value_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
727
725
                                 str->ptr(), str->length(),
728
726
                                 warn_type, warn_name);
729
 
  }
730
727
 
731
728
  return value;
732
729
}
765
762
*/
766
763
 
767
764
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)
 
765
Arg_comparator::can_compare_as_dates(Item *a, Item *b, uint64_t *const_value)
770
766
{
771
767
  enum enum_date_cmp_type cmp_type= CMP_DATE_DFLT;
772
768
  Item *str_arg= 0, *date_arg= 0;
773
769
 
774
 
  if (in_a->type() == Item::ROW_ITEM || in_b->type() == Item::ROW_ITEM)
 
770
  if (a->type() == Item::ROW_ITEM || b->type() == Item::ROW_ITEM)
775
771
    return CMP_DATE_DFLT;
776
772
 
777
 
  if (in_a->is_datetime())
 
773
  if (a->is_datetime())
778
774
  {
779
 
    if (in_b->is_datetime())
 
775
    if (b->is_datetime())
780
776
      cmp_type= CMP_DATE_WITH_DATE;
781
 
    else if (in_b->result_type() == STRING_RESULT)
 
777
    else if (b->result_type() == STRING_RESULT)
782
778
    {
783
779
      cmp_type= CMP_DATE_WITH_STR;
784
 
      date_arg= in_a;
785
 
      str_arg= in_b;
 
780
      date_arg= a;
 
781
      str_arg= b;
786
782
    }
787
783
  }
788
 
  else if (in_b->is_datetime() && in_a->result_type() == STRING_RESULT)
 
784
  else if (b->is_datetime() && a->result_type() == STRING_RESULT)
789
785
  {
790
786
    cmp_type= CMP_STR_WITH_DATE;
791
 
    date_arg= in_b;
792
 
    str_arg= in_a;
 
787
    date_arg= b;
 
788
    str_arg= a;
793
789
  }
794
790
 
795
791
  if (cmp_type != CMP_DATE_DFLT)
2036
2032
    ge_cmp.set_datetime_cmp_func(args, args + 1);
2037
2033
    le_cmp.set_datetime_cmp_func(args, args + 2);
2038
2034
  }
2039
 
  else if (args[0]->real_item()->type() == FIELD_ITEM)
 
2035
  else if (args[0]->real_item()->type() == FIELD_ITEM &&
 
2036
           session->lex->sql_command != SQLCOM_SHOW_CREATE)
2040
2037
  {
2041
2038
    Item_field *field_item= (Item_field*) (args[0]->real_item());
2042
2039
    if (field_item->field->can_be_compared_as_int64_t())
2196
2193
    max_length= max(len0, len1) + decimals + (unsigned_flag ? 0 : 1);
2197
2194
  }
2198
2195
  else
2199
 
  {
2200
2196
    max_length= max(args[0]->max_length, args[1]->max_length);
2201
 
  }
2202
2197
 
2203
2198
  switch (hybrid_type)
2204
2199
  {
2205
2200
  case STRING_RESULT:
2206
2201
    agg_arg_charsets(collation, args, arg_count, MY_COLL_CMP_CONV, 1);
2207
2202
    break;
2208
 
 
2209
2203
  case DECIMAL_RESULT:
2210
2204
  case REAL_RESULT:
2211
2205
    break;
2212
 
 
2213
2206
  case INT_RESULT:
2214
2207
    decimals= 0;
2215
2208
    break;
2216
 
 
2217
2209
  case ROW_RESULT:
 
2210
  default:
2218
2211
    assert(0);
2219
2212
  }
2220
 
 
2221
2213
  cached_field_type= agg_field_type(args, 2);
2222
2214
}
2223
2215
 
2755
2747
  */
2756
2748
  if (first_expr_num != -1)
2757
2749
  {
 
2750
    uint32_t i;
2758
2751
    agg[0]= args[first_expr_num];
2759
2752
    left_result_type= agg[0]->result_type();
2760
2753
 
2764
2757
    if (!(found_types= collect_cmp_types(agg, nagg)))
2765
2758
      return;
2766
2759
 
2767
 
    for (int i= STRING_RESULT; i <= DECIMAL_RESULT; i++)
 
2760
    for (i= 0; i <= (uint32_t)DECIMAL_RESULT; i++)
2768
2761
    {
2769
2762
      if (found_types & (1 << i) && !cmp_items[i])
2770
2763
      {
2850
2843
 
2851
2844
void Item_func_case::cleanup()
2852
2845
{
 
2846
  uint32_t i;
2853
2847
  Item_func::cleanup();
2854
 
  for (int i= STRING_RESULT; i <= DECIMAL_RESULT; i++)
 
2848
  for (i= 0; i <= (uint32_t)DECIMAL_RESULT; i++)
2855
2849
  {
2856
2850
    delete cmp_items[i];
2857
2851
    cmp_items[i]= 0;
2858
2852
  }
 
2853
  return;
2859
2854
}
2860
2855
 
2861
2856
 
2925
2920
{
2926
2921
  cached_field_type= agg_field_type(args, arg_count);
2927
2922
  agg_result_type(&hybrid_type, args, arg_count);
2928
 
 
2929
2923
  switch (hybrid_type) {
2930
2924
  case STRING_RESULT:
2931
2925
    count_only_length();
2932
2926
    decimals= NOT_FIXED_DEC;
2933
2927
    agg_arg_charsets(collation, args, arg_count, MY_COLL_ALLOW_CONV, 1);
2934
2928
    break;
2935
 
 
2936
2929
  case DECIMAL_RESULT:
2937
2930
    count_decimal_length();
2938
2931
    break;
2939
 
 
2940
2932
  case REAL_RESULT:
2941
2933
    count_real_length();
2942
2934
    break;
2943
 
 
2944
2935
  case INT_RESULT:
2945
2936
    count_only_length();
2946
2937
    decimals= 0;
2947
2938
    break;
2948
 
 
2949
2939
  case ROW_RESULT:
 
2940
  default:
2950
2941
    assert(0);
2951
2942
  }
2952
2943
}
3270
3261
  switch (type) {
3271
3262
  case STRING_RESULT:
3272
3263
    return new cmp_item_sort_string(cs);
3273
 
 
3274
3264
  case INT_RESULT:
3275
3265
    return new cmp_item_int;
3276
 
 
3277
3266
  case REAL_RESULT:
3278
3267
    return new cmp_item_real;
3279
 
 
3280
3268
  case ROW_RESULT:
3281
3269
    return new cmp_item_row;
3282
 
 
3283
3270
  case DECIMAL_RESULT:
3284
3271
    return new cmp_item_decimal;
 
3272
  default:
 
3273
    assert(0);
 
3274
    break;
3285
3275
  }
3286
 
 
3287
3276
  return 0; // to satisfy compiler :)
3288
3277
}
3289
3278
 
3554
3543
  bool compare_as_datetime= false;
3555
3544
  Item *date_arg= 0;
3556
3545
  uint32_t found_types= 0;
3557
 
  uint32_t type_cnt= 0;
 
3546
  uint32_t type_cnt= 0, i;
3558
3547
  Item_result cmp_type= STRING_RESULT;
3559
3548
  left_result_type= args[0]->result_type();
3560
3549
  if (!(found_types= collect_cmp_types(args, arg_count, true)))
3568
3557
      break;
3569
3558
    }
3570
3559
  }
3571
 
  for (int i= STRING_RESULT; i <= DECIMAL_RESULT; i++)
 
3560
  for (i= 0; i <= (uint32_t)DECIMAL_RESULT; i++)
3572
3561
  {
3573
3562
    if (found_types & 1 << i)
3574
3563
    {
3675
3664
  if (type_cnt == 1 && const_itm && !nulls_in_row())
3676
3665
  {
3677
3666
    if (compare_as_datetime)
3678
 
    {
3679
3667
      array= new in_datetime(date_arg, arg_count - 1);
3680
 
    }
3681
3668
    else
3682
3669
    {
3683
3670
      /*
3688
3675
        comparison type accordingly.
3689
3676
      */
3690
3677
      if (args[0]->real_item()->type() == FIELD_ITEM &&
 
3678
          session->lex->sql_command != SQLCOM_SHOW_CREATE &&
3691
3679
          cmp_type != INT_RESULT)
3692
3680
      {
3693
3681
        Item_field *field_item= (Item_field*) (args[0]->real_item());
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
        {
5114
5099
  while ((item_field= it++))
5115
5100
  {
5116
5101
    /* Skip fields of non-const tables. They haven't been read yet */
5117
 
    if (item_field->field->getTable()->const_table)
 
5102
    if (item_field->field->table->const_table)
5118
5103
    {
5119
5104
      if ((null_value= item_field->null_value) || eval_item->cmp(item_field))
5120
5105
        return 0;