~ubuntu-branches/ubuntu/hardy/mysql-dfsg-5.0/hardy-updates

« back to all changes in this revision

Viewing changes to libmysqld/item_cmpfunc.cc

  • Committer: Bazaar Package Importer
  • Author(s): Martin Pitt
  • Date: 2007-04-02 16:10:53 UTC
  • mfrom: (1.1.9 upstream)
  • Revision ID: james.westby@ubuntu.com-20070402161053-zkil9hjq9k5p1uzv
Tags: 5.0.37-0ubuntu1
* New upstream bugfix release.
  - Fixes replication failure with auto-increment and on duplicate key
    update, a regression introduced into 5.0.24. (LP: #95821)
* debian/control: Set Ubuntu maintainer.
* debian/rules: Change comments from 'Debian etch' to 'Ubuntu 7.04'.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* Copyright (C) 2000-2003 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
 
1
/* Copyright (C) 2000-2006 MySQL AB
2
2
 
3
3
   This program is free software; you can redistribute it and/or modify
4
4
   it under the terms of the GNU General Public License as published by
5
 
   the Free Software Foundation; either version 2 of the License, or
6
 
   (at your option) any later version.
 
5
   the Free Software Foundation; version 2 of the License.
7
6
 
8
7
   This program is distributed in the hope that it will be useful,
9
8
   but WITHOUT ANY WARRANTY; without even the implied warranty of
27
26
 
28
27
static bool convert_constant_item(THD *thd, Field *field, Item **item);
29
28
 
30
 
static Item_result item_store_type(Item_result a,Item_result b)
 
29
static Item_result item_store_type(Item_result a, Item *item,
 
30
                                   my_bool unsigned_flag)
31
31
{
 
32
  Item_result b= item->result_type();
 
33
 
32
34
  if (a == STRING_RESULT || b == STRING_RESULT)
33
35
    return STRING_RESULT;
34
36
  else if (a == REAL_RESULT || b == REAL_RESULT)
35
37
    return REAL_RESULT;
36
 
  else if (a == DECIMAL_RESULT || b == DECIMAL_RESULT)
 
38
  else if (a == DECIMAL_RESULT || b == DECIMAL_RESULT ||
 
39
           unsigned_flag != item->unsigned_flag)
37
40
    return DECIMAL_RESULT;
38
41
  else
39
42
    return INT_RESULT;
42
45
static void agg_result_type(Item_result *type, Item **items, uint nitems)
43
46
{
44
47
  Item **item, **item_end;
 
48
  my_bool unsigned_flag= 0;
45
49
 
46
50
  *type= STRING_RESULT;
47
51
  /* Skip beginning NULL items */
50
54
    if ((*item)->type() != Item::NULL_ITEM)
51
55
    {
52
56
      *type= (*item)->result_type();
 
57
      unsigned_flag= (*item)->unsigned_flag;
53
58
      item++;
54
59
      break;
55
60
    }
58
63
  for (; item < item_end; item++)
59
64
  {
60
65
    if ((*item)->type() != Item::NULL_ITEM)
61
 
      *type= item_store_type(type[0], (*item)->result_type());
 
66
      *type= item_store_type(*type, *item, unsigned_flag);
62
67
  }
63
68
}
64
69
 
148
153
}
149
154
 
150
155
/*
 
156
  We put any NOT expression into parenthesis to avoid
 
157
  possible problems with internal view representations where
 
158
  any '!' is converted to NOT. It may cause a problem if
 
159
  '!' is used in an expression together with other operators
 
160
  whose precedence is lower than the precedence of '!' yet
 
161
  higher than the precedence of NOT.
 
162
*/
 
163
 
 
164
void Item_func_not::print(String *str)
 
165
{
 
166
  str->append('(');
 
167
  Item_func::print(str);
 
168
  str->append(')');
 
169
}
 
170
 
 
171
/*
151
172
  special NOT for ALL subquery
152
173
*/
153
174
 
418
439
    break;
419
440
  }
420
441
  case DECIMAL_RESULT:
 
442
    break;
421
443
  case REAL_RESULT:
 
444
  {
 
445
    if ((*a)->decimals < NOT_FIXED_DEC && (*b)->decimals < NOT_FIXED_DEC)
 
446
    {
 
447
      precision= 5 * log_01[max((*a)->decimals, (*b)->decimals)];
 
448
      if (func == &Arg_comparator::compare_real)
 
449
        func= &Arg_comparator::compare_real_fixed;
 
450
      else if (func == &Arg_comparator::compare_e_real)
 
451
        func= &Arg_comparator::compare_e_real_fixed;
 
452
    }
422
453
    break;
 
454
  }
423
455
  default:
424
456
    DBUG_ASSERT(0);
425
457
  }
558
590
  return test(my_decimal_cmp(val1, val2) == 0);
559
591
}
560
592
 
 
593
 
 
594
int Arg_comparator::compare_real_fixed()
 
595
{
 
596
  /*
 
597
    Fix yet another manifestation of Bug#2338. 'Volatile' will instruct
 
598
    gcc to flush double values out of 80-bit Intel FPU registers before
 
599
    performing the comparison.
 
600
  */
 
601
  volatile double val1, val2;
 
602
  val1= (*a)->val_real();
 
603
  if (!(*a)->null_value)
 
604
  {
 
605
    val2= (*b)->val_real();
 
606
    if (!(*b)->null_value)
 
607
    {
 
608
      owner->null_value= 0;
 
609
      if (val1 == val2 || fabs(val1 - val2) < precision)
 
610
        return 0;
 
611
      if (val1 < val2)
 
612
        return -1;
 
613
      return 1;
 
614
    }
 
615
  }
 
616
  owner->null_value= 1;
 
617
  return -1;
 
618
}
 
619
 
 
620
 
 
621
int Arg_comparator::compare_e_real_fixed()
 
622
{
 
623
  double val1= (*a)->val_real();
 
624
  double val2= (*b)->val_real();
 
625
  if ((*a)->null_value || (*b)->null_value)
 
626
    return test((*a)->null_value && (*b)->null_value);
 
627
  return test(val1 == val2 || fabs(val1 - val2) < precision);
 
628
}
 
629
 
 
630
 
561
631
int Arg_comparator::compare_int_signed()
562
632
{
563
633
  longlong val1= (*a)->val_int();
814
884
          We disable the predicates we've pushed down into subselect, run the
815
885
          subselect and see if it has produced any rows.
816
886
        */
817
 
        ((Item_in_subselect*)args[1])->enable_pushed_conds= FALSE;
818
 
        longlong tmp= args[1]->val_bool_result();
819
 
        result_for_null_param= null_value= 
820
 
          !((Item_in_subselect*)args[1])->engine->no_rows();
821
 
        ((Item_in_subselect*)args[1])->enable_pushed_conds= TRUE;
 
887
        Item_in_subselect *item_subs=(Item_in_subselect*)args[1]; 
 
888
        if (cache->cols() == 1)
 
889
        {
 
890
          item_subs->set_cond_guard_var(0, FALSE);
 
891
          longlong tmp= args[1]->val_bool_result();
 
892
          result_for_null_param= null_value= !item_subs->engine->no_rows();
 
893
          item_subs->set_cond_guard_var(0, TRUE);
 
894
        }
 
895
        else
 
896
        {
 
897
          uint i;
 
898
          uint ncols= cache->cols();
 
899
          /*
 
900
            Turn off the predicates that are based on column compares for
 
901
            which the left part is currently NULL
 
902
          */
 
903
          for (i= 0; i < ncols; i++)
 
904
          {
 
905
            if (cache->el(i)->null_value)
 
906
              item_subs->set_cond_guard_var(i, FALSE);
 
907
          }
 
908
          
 
909
          longlong tmp= args[1]->val_bool_result();
 
910
          result_for_null_param= null_value= !item_subs->engine->no_rows();
 
911
          
 
912
          /* Turn all predicates back on */
 
913
          for (i= 0; i < ncols; i++)
 
914
            item_subs->set_cond_guard_var(i, TRUE);
 
915
        }
822
916
      }
823
917
    }
824
918
    return 0;
1146
1240
    They are compared as integers, so for const item this time-consuming
1147
1241
    conversion can be done only once, not for every single comparison
1148
1242
  */
1149
 
  if (args[0]->type() == FIELD_ITEM &&
 
1243
  if (args[0]->real_item()->type() == FIELD_ITEM &&
1150
1244
      thd->lex->sql_command != SQLCOM_CREATE_VIEW &&
1151
1245
      thd->lex->sql_command != SQLCOM_SHOW_CREATE)
1152
1246
  {
1153
 
    Field *field=((Item_field*) args[0])->field;
 
1247
    Field *field=((Item_field*) (args[0]->real_item()))->field;
1154
1248
    if (field->can_be_compared_as_longlong())
1155
1249
    {
1156
1250
      /*
2990
3084
    Handle optimization if the argument can't be null
2991
3085
    This has to be here because of the test in update_used_tables().
2992
3086
  */
2993
 
  if (!used_tables_cache)
 
3087
  if (!used_tables_cache && !with_subselect)
2994
3088
    return cached_value;
2995
3089
  return args[0]->is_null() ? 1: 0;
2996
3090
}
2999
3093
{
3000
3094
  DBUG_ASSERT(fixed == 1);
3001
3095
  DBUG_ENTER("Item_is_not_null_test::val_int");
3002
 
  if (!used_tables_cache)
 
3096
  if (!used_tables_cache && !with_subselect)
3003
3097
  {
3004
3098
    owner->was_null|= (!cached_value);
3005
3099
    DBUG_PRINT("info", ("cached :%ld", (long) cached_value));
3007
3101
  }
3008
3102
  if (args[0]->is_null())
3009
3103
  {
3010
 
    DBUG_PRINT("info", ("null"))
 
3104
    DBUG_PRINT("info", ("null"));
3011
3105
    owner->was_null|= 1;
3012
3106
    DBUG_RETURN(0);
3013
3107
  }
3026
3120
  else
3027
3121
  {
3028
3122
    args[0]->update_used_tables();
3029
 
    if (!(used_tables_cache=args[0]->used_tables()))
 
3123
    if (!(used_tables_cache=args[0]->used_tables()) && !with_subselect)
3030
3124
    {
3031
3125
      /* Remember if the value is always NULL or never NULL */
3032
3126
      cached_value= (longlong) !args[0]->is_null();
3995
4089
 
3996
4090
void Item_equal::fix_length_and_dec()
3997
4091
{
3998
 
  Item *item= const_item ? const_item : get_first();
 
4092
  Item *item= get_first();
3999
4093
  eval_item= cmp_item::get_comparator(item->result_type(),
4000
4094
                                      item->collation.collation);
4001
 
  if (item->result_type() == STRING_RESULT)
4002
 
    eval_item->cmp_charset= cmp_collation.collation;
4003
4095
}
4004
4096
 
4005
4097
bool Item_equal::walk(Item_processor processor, byte *arg)