~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/item/cmpfunc.cc

  • Committer: Eric Herman
  • Date: 2008-12-06 19:42:46 UTC
  • mto: (656.1.6 devel)
  • mto: This revision was merged to the branch mainline in revision 665.
  • Revision ID: eric@mysql.com-20081206194246-5cdexuu81i366eek
removed trailing whitespace with simple script:

for file in $(find . -name "*.c") $(find . -name "*.cc") $(find . -name "*.h"); do ruby -pe 'gsub(/\s+$/, $/)' < $file > $file.out; mv $file.out $file; done;

Show diffs side-by-side

added added

removed removed

Lines of Context:
96
96
  DESCRIPTION
97
97
    The function checks that two expressions have compatible row signatures
98
98
    i.e. that the number of columns they return are the same and that if they
99
 
    are both row expressions then each component from the first expression has 
 
99
    are both row expressions then each component from the first expression has
100
100
    a row signature compatible with the signature of the corresponding component
101
101
    of the second expression.
102
102
 
157
157
      of the first row expression has a compatible row signature with
158
158
      the signature of the corresponding component of the second row
159
159
      expression.
160
 
    */ 
 
160
    */
161
161
    if (type[0] == ROW_RESULT && cmp_row_type(items[0], items[i]))
162
162
      return 1;     // error found: invalid usage of rows
163
163
  }
220
220
  found_types= 0;
221
221
  for (i= 1; i < nitems ; i++)
222
222
  {
223
 
    if ((left_result == ROW_RESULT || 
 
223
    if ((left_result == ROW_RESULT ||
224
224
         items[i]->result_type() == ROW_RESULT) &&
225
225
        cmp_row_type(items[0], items[i]))
226
226
      return 0;
435
435
    uint64_t orig_field_val= 0; /* original field value if valid */
436
436
 
437
437
    /* For comparison purposes allow invalid dates like 2000-01-32 */
438
 
    session->variables.sql_mode= (orig_sql_mode & ~MODE_NO_ZERO_DATE) | 
 
438
    session->variables.sql_mode= (orig_sql_mode & ~MODE_NO_ZERO_DATE) |
439
439
                             MODE_INVALID_DATES;
440
440
    session->count_cuted_fields= CHECK_FIELD_IGNORE;
441
441
 
479
479
  if (!args[0] || !args[1])
480
480
    return;
481
481
 
482
 
  /* 
 
482
  /*
483
483
    We allow to convert to Unicode character sets in some cases.
484
484
    The conditions when conversion is possible are:
485
485
    - arguments A and B have different charsets
486
486
    - A wins according to coercibility rules
487
487
    - character set of A is superset for character set of B
488
 
   
 
488
 
489
489
    If all of the above is true, then it's possible to convert
490
490
    B into the character set of A, and then compare according
491
491
    to the collation of A.
492
492
  */
493
493
 
494
 
  
 
494
 
495
495
  DTCollation coll;
496
496
  if (args[0]->result_type() == STRING_RESULT &&
497
497
      args[1]->result_type() == STRING_RESULT &&
498
498
      agg_arg_charsets(coll, args, 2, MY_COLL_CMP_CONV, 1))
499
499
    return;
500
 
    
 
500
 
501
501
  args[0]->cmp_context= args[1]->cmp_context=
502
502
    item_cmp_type(args[0]->result_type(), args[1]->result_type());
503
503
  // Make a special case of compare with fields to get nicer DATE comparisons
580
580
      We must set cmp_charset here as we may be called from for an automatic
581
581
      generated item, like in natural join
582
582
    */
583
 
    if (cmp_collation.set((*a)->collation, (*b)->collation) || 
 
583
    if (cmp_collation.set((*a)->collation, (*b)->collation) ||
584
584
        cmp_collation.derivation == DERIVATION_NONE)
585
585
    {
586
586
      my_coll_agg_error((*a)->collation, (*b)->collation, owner->func_name());
1552
1552
  bool tmp;
1553
1553
  assert(fixed == 1);
1554
1554
  cache->store(args[0]);
1555
 
  
 
1555
 
1556
1556
  if (cache->null_value)
1557
1557
  {
1558
1558
    if (((Item_in_subselect*)args[1])->is_top_level_item())
1580
1580
          We disable the predicates we've pushed down into subselect, run the
1581
1581
          subselect and see if it has produced any rows.
1582
1582
        */
1583
 
        Item_in_subselect *item_subs=(Item_in_subselect*)args[1]; 
 
1583
        Item_in_subselect *item_subs=(Item_in_subselect*)args[1];
1584
1584
        if (cache->cols() == 1)
1585
1585
        {
1586
1586
          item_subs->set_cond_guard_var(0, false);
1601
1601
            if (cache->element_index(i)->null_value)
1602
1602
              item_subs->set_cond_guard_var(i, false);
1603
1603
          }
1604
 
          
 
1604
 
1605
1605
          (void) args[1]->val_bool_result();
1606
1606
          result_for_null_param= null_value= !item_subs->engine->no_rows();
1607
 
          
 
1607
 
1608
1608
          /* Turn all predicates back on */
1609
1609
          for (i= 0; i < ncols; i++)
1610
1610
            item_subs->set_cond_guard_var(i, true);
1806
1806
void Item_func_interval::fix_length_and_dec()
1807
1807
{
1808
1808
  uint32_t rows= row->cols();
1809
 
  
 
1809
 
1810
1810
  use_decimal_comparison= ((row->element_index(0)->result_type() ==
1811
1811
                            DECIMAL_RESULT) ||
1812
1812
                           (row->element_index(0)->result_type() ==
1947
1947
      if (my_decimal_cmp(e_dec, dec) > 0)
1948
1948
        return i - 1;
1949
1949
    }
1950
 
    else 
 
1950
    else
1951
1951
    {
1952
1952
      double val= el->val_real();
1953
1953
      /* Skip NULL ranges. */
2212
2212
  decimals= cmax(args[0]->decimals, args[1]->decimals);
2213
2213
  unsigned_flag= args[0]->unsigned_flag && args[1]->unsigned_flag;
2214
2214
 
2215
 
  if (hybrid_type == DECIMAL_RESULT || hybrid_type == INT_RESULT) 
 
2215
  if (hybrid_type == DECIMAL_RESULT || hybrid_type == INT_RESULT)
2216
2216
  {
2217
2217
    int len0= args[0]->max_length - args[0]->decimals
2218
2218
      - (args[0]->unsigned_flag ? 0 : 1);
2250
2250
}
2251
2251
 
2252
2252
 
2253
 
enum_field_types Item_func_ifnull::field_type() const 
 
2253
enum_field_types Item_func_ifnull::field_type() const
2254
2254
{
2255
2255
  return cached_field_type;
2256
2256
}
2570
2570
bool
2571
2571
Item_func_nullif::is_null()
2572
2572
{
2573
 
  return (null_value= (!cmp.compare() ? 1 : args[0]->null_value)); 
 
2573
  return (null_value= (!cmp.compare() ? 1 : args[0]->null_value));
2574
2574
}
2575
2575
 
2576
2576
 
2738
2738
{
2739
2739
  uint32_t len= my_decimal_length_to_precision(arg->max_length, arg->decimals,
2740
2740
                                           arg->unsigned_flag) - arg->decimals;
2741
 
  set_if_bigger(max_length, len); 
 
2741
  set_if_bigger(max_length, len);
2742
2742
  set_if_bigger(decimals, arg->decimals);
2743
 
  unsigned_flag= unsigned_flag && arg->unsigned_flag; 
 
2743
  unsigned_flag= unsigned_flag && arg->unsigned_flag;
2744
2744
}
2745
2745
 
2746
2746
 
2751
2751
  uint32_t found_types= 0;
2752
2752
  if (!(agg= (Item**) sql_alloc(sizeof(Item*)*(ncases+1))))
2753
2753
    return;
2754
 
  
 
2754
 
2755
2755
  /*
2756
2756
    Aggregate all THEN and ELSE expression types
2757
2757
    and collations when string result
2758
2758
  */
2759
 
  
 
2759
 
2760
2760
  for (nagg= 0 ; nagg < ncases/2 ; nagg++)
2761
2761
    agg[nagg]= args[nagg*2+1];
2762
 
  
 
2762
 
2763
2763
  if (else_expr_num != -1)
2764
2764
    agg[nagg++]= args[else_expr_num];
2765
 
  
 
2765
 
2766
2766
  agg_result_type(&cached_result_type, agg, nagg);
2767
2767
  if ((cached_result_type == STRING_RESULT) &&
2768
2768
      agg_arg_charsets(collation, agg, nagg, MY_COLL_ALLOW_CONV, 1))
2769
2769
    return;
2770
 
  
 
2770
 
2771
2771
  cached_field_type= agg_field_type(agg, nagg);
2772
2772
  /*
2773
2773
    Aggregate first expression and all THEN expression types
2803
2803
 
2804
2804
  if (else_expr_num == -1 || args[else_expr_num]->maybe_null)
2805
2805
    maybe_null=1;
2806
 
  
 
2806
 
2807
2807
  max_length=0;
2808
2808
  decimals=0;
2809
2809
  unsigned_flag= true;
2818
2818
  {
2819
2819
    for (uint32_t i= 0; i < ncases; i+= 2)
2820
2820
      agg_num_lengths(args[i + 1]);
2821
 
    if (else_expr_num != -1) 
 
2821
    if (else_expr_num != -1)
2822
2822
      agg_num_lengths(args[else_expr_num]);
2823
2823
    max_length= my_decimal_precision_to_length(max_length + decimals, decimals,
2824
2824
                                               unsigned_flag);
2832
2832
  for (uint32_t i=0 ; i < ncases ; i+=2)
2833
2833
    set_if_bigger(max_int_part, args[i+1]->decimal_int_part());
2834
2834
 
2835
 
  if (else_expr_num != -1) 
 
2835
  if (else_expr_num != -1)
2836
2836
    set_if_bigger(max_int_part, args[else_expr_num]->decimal_int_part());
2837
2837
  return cmin(max_int_part + decimals, DECIMAL_MAX_PRECISION);
2838
2838
}
3023
3023
 
3024
3024
 
3025
3025
/*
3026
 
  Compare two integers in IN value list format (packed_int64_t) 
 
3026
  Compare two integers in IN value list format (packed_int64_t)
3027
3027
 
3028
3028
  SYNOPSIS
3029
3029
    cmp_int64_t()
3049
3049
                in_int64_t::packed_int64_t *b)
3050
3050
{
3051
3051
  if (a->unsigned_flag != b->unsigned_flag)
3052
 
  { 
3053
 
    /* 
3054
 
      One of the args is unsigned and is too big to fit into the 
 
3052
  {
 
3053
    /*
 
3054
      One of the args is unsigned and is too big to fit into the
3055
3055
      positive signed range. Report no match.
3056
 
    */  
 
3056
    */
3057
3057
    if ((a->unsigned_flag && ((uint64_t) a->val) > (uint64_t) INT64_MAX) ||
3058
3058
        (b->unsigned_flag && ((uint64_t) b->val) > (uint64_t) INT64_MAX))
3059
3059
      return a->unsigned_flag ? 1 : -1;
3060
3060
    /*
3061
 
      Although the signedness differs both args can fit into the signed 
 
3061
      Although the signedness differs both args can fit into the signed
3062
3062
      positive range. Make them signed and compare as usual.
3063
 
    */  
 
3063
    */
3064
3064
    return cmp_longs (a->val, b->val);
3065
3065
  }
3066
3066
  if (a->unsigned_flag)
3197
3197
void in_int64_t::set(uint32_t pos,Item *item)
3198
3198
{
3199
3199
  struct packed_int64_t *buff= &((packed_int64_t*) base)[pos];
3200
 
  
 
3200
 
3201
3201
  buff->val= item->val_int();
3202
3202
  buff->unsigned_flag= item->unsigned_flag;
3203
3203
}
3262
3262
  dec->len= DECIMAL_BUFF_LENGTH;
3263
3263
  dec->fix_buffer_pointer();
3264
3264
  my_decimal *res= item->val_decimal(dec);
3265
 
  /* if item->val_decimal() is evaluated to NULL then res == 0 */ 
 
3265
  /* if item->val_decimal() is evaluated to NULL then res == 0 */
3266
3266
  if (!item->null_value && res != dec)
3267
3267
    my_decimal2decimal(res, dec);
3268
3268
}
3570
3570
  left_result_type= args[0]->result_type();
3571
3571
  if (!(found_types= collect_cmp_types(args, arg_count)))
3572
3572
    return;
3573
 
  
 
3573
 
3574
3574
  for (arg= args + 1, arg_end= args + arg_count; arg != arg_end ; arg++)
3575
3575
  {
3576
3576
    if (!arg[0]->const_item())
3590
3590
 
3591
3591
  if (type_cnt == 1)
3592
3592
  {
3593
 
    if (cmp_type == STRING_RESULT && 
 
3593
    if (cmp_type == STRING_RESULT &&
3594
3594
        agg_arg_charsets(cmp_collation, args, arg_count, MY_COLL_CMP_CONV, 1))
3595
3595
      return;
3596
3596
    arg_types_compatible= true;
3692
3692
      /*
3693
3693
        IN must compare INT columns and constants as int values (the same
3694
3694
        way as equality does).
3695
 
        So we must check here if the column on the left and all the constant 
3696
 
        values on the right can be compared as integers and adjust the 
 
3695
        So we must check here if the column on the left and all the constant
 
3696
        values on the right can be compared as integers and adjust the
3697
3697
        comparison type accordingly.
3698
 
      */  
 
3698
      */
3699
3699
      if (args[0]->real_item()->type() == FIELD_ITEM &&
3700
3700
          session->lex->sql_command != SQLCOM_SHOW_CREATE &&
3701
3701
          cmp_type != INT_RESULT)
3715
3715
      }
3716
3716
      switch (cmp_type) {
3717
3717
      case STRING_RESULT:
3718
 
        array=new in_string(arg_count-1,(qsort2_cmp) srtcmp_in, 
 
3718
        array=new in_string(arg_count-1,(qsort2_cmp) srtcmp_in,
3719
3719
                            cmp_collation.collation);
3720
3720
        break;
3721
3721
      case INT_RESULT:
3975
3975
      not_null_tables_cache|= tmp_table_map;
3976
3976
      and_tables_cache&= tmp_table_map;
3977
3977
      const_item_cache= false;
3978
 
    }  
 
3978
    }
3979
3979
    with_sum_func=          with_sum_func || item->with_sum_func;
3980
3980
    with_subselect|=        item->with_subselect;
3981
3981
    if (item->maybe_null)
4016
4016
      not_null_tables_cache|= tmp_table_map;
4017
4017
      and_tables_cache&= tmp_table_map;
4018
4018
      const_item_cache= false;
4019
 
    }  
 
4019
    }
4020
4020
  }
4021
4021
}
4022
4022
 
4034
4034
 
4035
4035
/**
4036
4036
  Transform an Item_cond object with a transformer callback function.
4037
 
  
 
4037
 
4038
4038
    The function recursively applies the transform method to each
4039
4039
     member item of the condition list.
4040
4040
    If the call of the method for a member item returns a new item
4041
4041
    the old item is substituted for a new one.
4042
4042
    After this the transformer is applied to the root node
4043
 
    of the Item_cond object. 
4044
 
     
 
4043
    of the Item_cond object.
 
4044
 
4045
4045
  @param transformer   the transformer callback function to be applied to
4046
4046
                       the nodes of the tree of the object
4047
4047
  @param arg           parameter to be passed to the transformer
4048
4048
 
4049
4049
  @return
4050
 
    Item returned as the result of transformation of the root node 
 
4050
    Item returned as the result of transformation of the root node
4051
4051
*/
4052
4052
 
4053
4053
Item *Item_cond::transform(Item_transformer transformer, unsigned char *arg)
4076
4076
/**
4077
4077
  Compile Item_cond object with a processor and a transformer
4078
4078
  callback functions.
4079
 
  
 
4079
 
4080
4080
    First the function applies the analyzer to the root node of
4081
4081
    the Item_func object. Then if the analyzer succeeeds (returns true)
4082
4082
    the function recursively applies the compile method to member
4084
4084
    If the call of the method for a member item returns a new item
4085
4085
    the old item is substituted for a new one.
4086
4086
    After this the transformer is applied to the root node
4087
 
    of the Item_cond object. 
4088
 
     
 
4087
    of the Item_cond object.
 
4088
 
4089
4089
  @param analyzer      the analyzer callback function to be applied to the
4090
4090
                       nodes of the tree of the object
4091
4091
  @param[in,out] arg_p parameter to be passed to the analyzer
4094
4094
  @param arg_t         parameter to be passed to the transformer
4095
4095
 
4096
4096
  @return
4097
 
    Item returned as the result of transformation of the root node 
 
4097
    Item returned as the result of transformation of the root node
4098
4098
*/
4099
4099
 
4100
4100
Item *Item_cond::compile(Item_analyzer analyzer, unsigned char **arg_p,
4102
4102
{
4103
4103
  if (!(this->*analyzer)(arg_p))
4104
4104
    return 0;
4105
 
  
 
4105
 
4106
4106
  List_iterator<Item> li(list);
4107
4107
  Item *item;
4108
4108
  while ((item= li++))
4109
4109
  {
4110
 
    /* 
 
4110
    /*
4111
4111
      The same parameter value of arg_p must be passed
4112
4112
      to analyze any argument of the condition formula.
4113
 
    */   
 
4113
    */
4114
4114
    unsigned char *arg_v= *arg_p;
4115
4115
    Item *new_item= item->compile(analyzer, &arg_v, transformer, arg_t);
4116
4116
    if (new_item && new_item != item)
4453
4453
    my_error(ER_WRONG_ARGUMENTS,MYF(0),"ESCAPE");
4454
4454
    return true;
4455
4455
  }
4456
 
  
 
4456
 
4457
4457
  if (escape_item->const_item())
4458
4458
  {
4459
4459
    /* If we are on execution stage */
4506
4506
      We could also do boyer-more for non-const items, but as we would have to
4507
4507
      recompute the tables for each row it's not worth it.
4508
4508
    */
4509
 
    if (args[1]->const_item() && !use_strnxfrm(collation.collation)) 
 
4509
    if (args[1]->const_item() && !use_strnxfrm(collation.collation))
4510
4510
    {
4511
4511
      String* res2 = args[1]->val_str(&tmp_value2);
4512
4512
      if (!res2)
4513
4513
        return false;                           // Null argument
4514
 
      
 
4514
 
4515
4515
      const size_t len   = res2->length();
4516
4516
      const char*  first = res2->ptr();
4517
4517
      const char*  last  = first + len - 1;
4519
4519
        len must be > 2 ('%pattern%')
4520
4520
        heuristic: only do TurboBM for pattern_len > 2
4521
4521
      */
4522
 
      
 
4522
 
4523
4523
      if (len > MIN_TURBOBM_PATTERN_LEN + 2 &&
4524
4524
          *first == wild_many &&
4525
4525
          *last  == wild_many)
4792
4792
  assert(fixed == 1);
4793
4793
  List_iterator<Item> li(list);
4794
4794
  Item *item;
4795
 
  int result=0; 
 
4795
  int result=0;
4796
4796
  null_value=0;
4797
4797
  while ((item=li++))
4798
4798
  {
5017
5017
  @retval
5018
5018
    1       if nultiple equality contains a reference to field
5019
5019
  @retval
5020
 
    0       otherwise    
 
5020
    0       otherwise
5021
5021
*/
5022
5022
 
5023
5023
bool Item_equal::contains(Field *field)
5035
5035
 
5036
5036
/**
5037
5037
  Join members of another Item_equal object.
5038
 
  
 
5038
 
5039
5039
    The function actually merges two multiple equalities.
5040
5040
    After this operation the Item_equal object additionally contains
5041
5041
    the field items of another item of the type Item_equal.
5042
5042
    If the optional constant items are not equal the cond_false flag is
5043
 
    set to 1.  
 
5043
    set to 1.
5044
5044
  @param item    multiple equality whose members are to be joined
5045
5045
*/
5046
5046
 
5050
5050
  Item *c= item->const_item;
5051
5051
  if (c)
5052
5052
  {
5053
 
    /* 
5054
 
      The flag cond_false will be set to 1 after this, if 
5055
 
      the multiple equality already contains a constant and its 
 
5053
    /*
 
5054
      The flag cond_false will be set to 1 after this, if
 
5055
      the multiple equality already contains a constant and its
5056
5056
      value is  not equal to the value of c.
5057
5057
    */
5058
5058
    add(c);
5059
5059
  }
5060
5060
  cond_false|= item->cond_false;
5061
 
 
5061
}
5062
5062
 
5063
5063
 
5064
5064
/**