item_cmpfunc.cc 60.1 KB
Newer Older
1
/* Copyright (C) 2000-2003 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
unknown's avatar
unknown committed
2

unknown's avatar
unknown committed
3 4 5 6
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.
unknown's avatar
unknown committed
7

unknown's avatar
unknown committed
8 9 10 11
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
unknown's avatar
unknown committed
12

unknown's avatar
unknown committed
13 14 15 16 17 18 19 20 21 22 23 24 25
   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */


/* This file defines all compare functions */

#ifdef __GNUC__
#pragma implementation				// gcc: Class implementation
#endif

#include "mysql_priv.h"
#include <m_ctype.h>
26
#include "sql_select.h"
27

28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
static Item_result item_store_type(Item_result a,Item_result b)
{
  if (a == STRING_RESULT || b == STRING_RESULT)
    return STRING_RESULT;
  else if (a == REAL_RESULT || b == REAL_RESULT)
    return REAL_RESULT;
  else
    return INT_RESULT;
}

static void agg_result_type(Item_result *type, Item **items, uint nitems)
{
  uint i;
  type[0]= items[0]->result_type();
  for (i=1 ; i < nitems ; i++)
    type[0]= item_store_type(type[0], items[i]->result_type());
}

static void agg_cmp_type(Item_result *type, Item **items, uint nitems)
{
  uint i;
  type[0]= items[0]->result_type();
  for (i=1 ; i < nitems ; i++)
    type[0]= item_cmp_type(type[0], items[i]->result_type());
}

54 55
static void my_coll_agg_error(DTCollation &c1, DTCollation &c2, const char *fname)
{
56
  my_error(ER_CANT_AGGREGATE_2COLLATIONS,MYF(0),
57 58 59 60 61
  	   c1.collation->name,c1.derivation_name(),
	   c2.collation->name,c2.derivation_name(),
	   fname);
}

unknown's avatar
unknown committed
62 63

Item_bool_func2* Eq_creator::create(Item *a, Item *b) const
unknown's avatar
unknown committed
64 65 66
{
  return new Item_func_eq(a, b);
}
unknown's avatar
unknown committed
67 68 69


Item_bool_func2* Ne_creator::create(Item *a, Item *b) const
unknown's avatar
unknown committed
70 71 72
{
  return new Item_func_ne(a, b);
}
unknown's avatar
unknown committed
73 74 75


Item_bool_func2* Gt_creator::create(Item *a, Item *b) const
unknown's avatar
unknown committed
76 77 78
{
  return new Item_func_gt(a, b);
}
unknown's avatar
unknown committed
79 80 81


Item_bool_func2* Lt_creator::create(Item *a, Item *b) const
unknown's avatar
unknown committed
82 83 84
{
  return new Item_func_lt(a, b);
}
unknown's avatar
unknown committed
85 86 87


Item_bool_func2* Ge_creator::create(Item *a, Item *b) const
unknown's avatar
unknown committed
88 89 90
{
  return new Item_func_ge(a, b);
}
unknown's avatar
unknown committed
91 92 93


Item_bool_func2* Le_creator::create(Item *a, Item *b) const
unknown's avatar
unknown committed
94 95 96
{
  return new Item_func_le(a, b);
}
unknown's avatar
unknown committed
97

unknown's avatar
unknown committed
98
/*
99
  Test functions
100 101
  Most of these  returns 0LL if false and 1LL if true and
  NULL if some arg is NULL.
unknown's avatar
unknown committed
102 103 104 105
*/

longlong Item_func_not::val_int()
{
106
  DBUG_ASSERT(fixed == 1);
unknown's avatar
unknown committed
107 108 109 110 111
  double value=args[0]->val();
  null_value=args[0]->null_value;
  return !null_value && value == 0 ? 1 : 0;
}

112 113 114 115 116
/*
  special NOT for ALL subquery
*/

longlong Item_func_not_all::val_int()
117 118
{
  DBUG_ASSERT(fixed == 1);
119 120 121 122 123 124 125 126 127 128
  double value= args[0]->val();
  if (abort_on_null)
  {
    null_value= 0;
    return (args[0]->null_value || value == 0) ? 1 : 0;
  }
  null_value= args[0]->null_value;
  return (!null_value && value == 0) ? 1 : 0;
}

unknown's avatar
unknown committed
129 130 131 132 133 134 135 136
void Item_func_not_all::print(String *str)
{
  if (show)
    Item_func::print(str);
  else
    args[0]->print(str);
}

unknown's avatar
unknown committed
137 138 139 140 141
/*
  Convert a constant expression or string to an integer.
  This is done when comparing DATE's of different formats and
  also when comparing bigint to strings (in which case the string
  is converted once to a bigint).
unknown's avatar
unknown committed
142 143 144 145

  RESULT VALUES
  0	Can't convert item
  1	Item was replaced with an integer version of the item
unknown's avatar
unknown committed
146
*/
unknown's avatar
unknown committed
147 148 149

static bool convert_constant_item(Field *field, Item **item)
{
150
  if ((*item)->const_item())
unknown's avatar
unknown committed
151
  {
unknown's avatar
unknown committed
152
    if (!(*item)->save_in_field(field, 1) && !((*item)->null_value))
unknown's avatar
unknown committed
153
    {
154 155
      Item *tmp=new Item_int_with_ref(field->val_int(), *item);
      if (tmp)
unknown's avatar
unknown committed
156
	*item=tmp;
157
      return 1;					// Item was replaced
unknown's avatar
unknown committed
158 159 160 161 162
    }
  }
  return 0;
}

unknown's avatar
unknown committed
163

164 165 166 167 168 169 170 171 172 173
void Item_bool_func2::fix_length_and_dec()
{
  max_length= 1;				     // Function returns 0 or 1

  /*
    As some compare functions are generated after sql_yacc,
    we have to check for out of memory conditions here
  */
  if (!args[0] || !args[1])
    return;
174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191

  /* 
    We allow to convert to Unicode character sets in some cases.
    The conditions when conversion is possible are:
    - arguments A and B have different charsets
    - A wins according to coercibility rules
    - character set of A is superset for character set of B
   
    If all of the above is true, then it's possible to convert
    B into the character set of A, and then compare according
    to the collation of A.
  */

  if (args[0] && args[1])
  {
    uint strong= 0;
    uint weak= 0;

192 193 194 195
    if ((args[0]->collation.derivation < args[1]->collation.derivation) && 
	!my_charset_same(args[0]->collation.collation, 
			 args[1]->collation.collation) &&
        (args[0]->collation.collation->state & MY_CS_UNICODE))
196 197 198
    {
      weak= 1;
    }
199 200 201 202
    else if ((args[1]->collation.derivation < args[0]->collation.derivation) && 
	     !my_charset_same(args[0]->collation.collation,
			      args[1]->collation.collation) &&
             (args[1]->collation.collation->state & MY_CS_UNICODE))
203 204 205 206 207 208 209 210 211 212 213 214
    {
      strong= 1;
    }
    
    if (strong || weak)
    {
      Item* conv= 0;
      if (args[weak]->type() == STRING_ITEM)
      {
        String tmp, cstr;
        String *ostr= args[weak]->val_str(&tmp);
        cstr.copy(ostr->ptr(), ostr->length(), ostr->charset(), 
215
		  args[strong]->collation.collation);
216
        conv= new Item_string(cstr.ptr(),cstr.length(),cstr.charset(),
217
			      args[weak]->collation.derivation);
218 219 220 221
	((Item_string*)conv)->str_value.copy();
      }
      else
      {
222 223
	conv= new Item_func_conv_charset(args[weak],args[strong]->collation.collation);
        conv->collation.set(args[weak]->collation.derivation);
unknown's avatar
unknown committed
224
        conv->fix_fields(current_thd, 0, &conv);
225 226 227 228
      }
      args[weak]= conv ? conv : args[weak];
    }
  }
229
  
unknown's avatar
unknown committed
230
  // Make a special case of compare with fields to get nicer DATE comparisons
unknown's avatar
unknown committed
231 232 233 234 235 236 237

  if (functype() == LIKE_FUNC)  // Disable conversion in case of LIKE function.
  {
    set_cmp_func();
    return;
  }
    
unknown's avatar
unknown committed
238 239 240
  if (args[0]->type() == FIELD_ITEM)
  {
    Field *field=((Item_field*) args[0])->field;
241
    if (field->store_for_compare())
unknown's avatar
unknown committed
242 243 244
    {
      if (convert_constant_item(field,&args[1]))
      {
245
	cmp.set_cmp_func(this, tmp_arg, tmp_arg+1,
unknown's avatar
unknown committed
246
			 INT_RESULT);		// Works for all types.
unknown's avatar
unknown committed
247 248 249 250 251 252 253
	return;
      }
    }
  }
  if (args[1]->type() == FIELD_ITEM)
  {
    Field *field=((Item_field*) args[1])->field;
254
    if (field->store_for_compare())
unknown's avatar
unknown committed
255 256 257
    {
      if (convert_constant_item(field,&args[0]))
      {
258 259
	cmp.set_cmp_func(this, tmp_arg, tmp_arg+1,
			 INT_RESULT); // Works for all types.
unknown's avatar
unknown committed
260 261 262 263
	return;
      }
    }
  }
264
  set_cmp_func();
unknown's avatar
unknown committed
265 266
}

267

268
int Arg_comparator::set_compare_func(Item_bool_func2 *item, Item_result type)
unknown's avatar
unknown committed
269
{
270
  owner= item;
unknown's avatar
unknown committed
271 272
  func= comparator_matrix[type][(owner->functype() == Item_func::EQUAL_FUNC)?
				1:0];
unknown's avatar
unknown committed
273
  if (type == ROW_RESULT)
unknown's avatar
unknown committed
274
  {
275 276
    uint n= (*a)->cols();
    if (n != (*b)->cols())
277
    {
unknown's avatar
unknown committed
278
      my_error(ER_OPERAND_COLUMNS, MYF(0), n);
279 280 281
      comparators= 0;
      return 1;
    }
unknown's avatar
unknown committed
282 283 284 285 286
    if (!(comparators= (Arg_comparator *) sql_alloc(sizeof(Arg_comparator)*n)))
      return 1;
    for (uint i=0; i < n; i++)
    {
      if ((*a)->el(i)->cols() != (*b)->el(i)->cols())
unknown's avatar
unknown committed
287
      {
unknown's avatar
unknown committed
288
	my_error(ER_OPERAND_COLUMNS, MYF(0), (*a)->el(i)->cols());
unknown's avatar
unknown committed
289
	return 1;
unknown's avatar
unknown committed
290
      }
unknown's avatar
unknown committed
291 292
      comparators[i].set_cmp_func(owner, (*a)->addr(i), (*b)->addr(i));
    }
293
  }
294 295 296 297 298 299
  else if (type == STRING_RESULT)
  {
    /*
      We must set cmp_charset here as we may be called from for an automatic
      generated item, like in natural join
    */
300 301
    if (cmp_collation.set((*a)->collation, (*b)->collation) || 
	cmp_collation.derivation == DERIVATION_NONE)
302 303 304 305
    {
      my_coll_agg_error((*a)->collation, (*b)->collation, owner->func_name());
      return 1;
    }
unknown's avatar
unknown committed
306 307 308 309 310 311 312 313 314 315 316
    if (my_binary_compare(cmp_collation.collation))
    {
      /*
	We are using binary collation, change to compare byte by byte,
	without removing end space
      */
      if (func == &Arg_comparator::compare_string)
	func= &Arg_comparator::compare_binary_string;
      else if (func == &Arg_comparator::compare_e_string)
	func= &Arg_comparator::compare_e_binary_string;
    }
317
  }
318
  return 0;
unknown's avatar
unknown committed
319
}
unknown's avatar
unknown committed
320

unknown's avatar
unknown committed
321

322
int Arg_comparator::compare_string()
unknown's avatar
unknown committed
323 324
{
  String *res1,*res2;
325
  if ((res1= (*a)->val_str(&owner->tmp_value1)))
unknown's avatar
unknown committed
326
  {
327
    if ((res2= (*b)->val_str(&owner->tmp_value2)))
unknown's avatar
unknown committed
328
    {
unknown's avatar
unknown committed
329
      owner->null_value= 0;
330
      return sortcmp(res1,res2,cmp_collation.collation);
unknown's avatar
unknown committed
331 332
    }
  }
unknown's avatar
unknown committed
333
  owner->null_value= 1;
unknown's avatar
unknown committed
334 335 336
  return -1;
}

unknown's avatar
unknown committed
337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369

/*
  Compare strings byte by byte. End spaces are also compared.

  RETURN
   < 0	*a < *b
   0	*b == *b
   > 0	*a > *b
*/

int Arg_comparator::compare_binary_string()
{
  String *res1,*res2;
  if ((res1= (*a)->val_str(&owner->tmp_value1)))
  {
    if ((res2= (*b)->val_str(&owner->tmp_value2)))
    {
      owner->null_value= 0;
      uint res1_length= res1->length();
      uint res2_length= res2->length();
      int cmp= memcmp(res1->ptr(), res2->ptr(), min(res1_length,res2_length));
      return cmp ? cmp : (int) (res1_length - res2_length);
    }
  }
  owner->null_value= 1;
  return -1;
}


/*
  Compare strings, but take into account that NULL == NULL
*/

unknown's avatar
unknown committed
370 371 372
int Arg_comparator::compare_e_string()
{
  String *res1,*res2;
373 374
  res1= (*a)->val_str(&owner->tmp_value1);
  res2= (*b)->val_str(&owner->tmp_value2);
unknown's avatar
unknown committed
375 376
  if (!res1 || !res2)
    return test(res1 == res2);
377
  return test(sortcmp(res1, res2, cmp_collation.collation) == 0);
unknown's avatar
unknown committed
378 379 380
}


unknown's avatar
unknown committed
381 382 383 384 385 386 387 388 389 390 391
int Arg_comparator::compare_e_binary_string()
{
  String *res1,*res2;
  res1= (*a)->val_str(&owner->tmp_value1);
  res2= (*b)->val_str(&owner->tmp_value2);
  if (!res1 || !res2)
    return test(res1 == res2);
  return test(stringcmp(res1, res2) == 0);
}


392
int Arg_comparator::compare_real()
unknown's avatar
unknown committed
393
{
394 395
  double val1= (*a)->val();
  if (!(*a)->null_value)
unknown's avatar
unknown committed
396
  {
397 398
    double val2= (*b)->val();
    if (!(*b)->null_value)
unknown's avatar
unknown committed
399
    {
unknown's avatar
unknown committed
400
      owner->null_value= 0;
unknown's avatar
unknown committed
401 402 403 404 405
      if (val1 < val2)	return -1;
      if (val1 == val2) return 0;
      return 1;
    }
  }
unknown's avatar
unknown committed
406
  owner->null_value= 1;
unknown's avatar
unknown committed
407 408 409
  return -1;
}

unknown's avatar
unknown committed
410 411
int Arg_comparator::compare_e_real()
{
412 413 414 415
  double val1= (*a)->val();
  double val2= (*b)->val();
  if ((*a)->null_value || (*b)->null_value)
    return test((*a)->null_value && (*b)->null_value);
unknown's avatar
unknown committed
416 417
  return test(val1 == val2);
}
unknown's avatar
unknown committed
418

419
int Arg_comparator::compare_int()
unknown's avatar
unknown committed
420
{
421 422
  longlong val1= (*a)->val_int();
  if (!(*a)->null_value)
unknown's avatar
unknown committed
423
  {
424 425
    longlong val2= (*b)->val_int();
    if (!(*b)->null_value)
unknown's avatar
unknown committed
426
    {
unknown's avatar
unknown committed
427
      owner->null_value= 0;
unknown's avatar
unknown committed
428 429 430 431 432
      if (val1 < val2)	return -1;
      if (val1 == val2)   return 0;
      return 1;
    }
  }
unknown's avatar
unknown committed
433
  owner->null_value= 1;
unknown's avatar
unknown committed
434 435 436
  return -1;
}

unknown's avatar
unknown committed
437 438
int Arg_comparator::compare_e_int()
{
439 440 441 442
  longlong val1= (*a)->val_int();
  longlong val2= (*b)->val_int();
  if ((*a)->null_value || (*b)->null_value)
    return test((*a)->null_value && (*b)->null_value);
unknown's avatar
unknown committed
443 444 445 446
  return test(val1 == val2);
}


447
int Arg_comparator::compare_row()
unknown's avatar
unknown committed
448 449
{
  int res= 0;
450 451
  (*a)->bring_value();
  (*b)->bring_value();
452
  uint n= (*a)->cols();
unknown's avatar
unknown committed
453
  for (uint i= 0; i<n; i++)
unknown's avatar
unknown committed
454
  {
455
    if ((res= comparators[i].compare()))
unknown's avatar
unknown committed
456 457 458 459 460 461
      return res;
    if (owner->null_value)
      return -1;
  }
  return res;
}
unknown's avatar
unknown committed
462

unknown's avatar
unknown committed
463 464
int Arg_comparator::compare_e_row()
{
465 466
  (*a)->bring_value();
  (*b)->bring_value();
467
  uint n= (*a)->cols();
unknown's avatar
unknown committed
468 469
  for (uint i= 0; i<n; i++)
  {
unknown's avatar
unknown committed
470
    if (!comparators[i].compare())
471
      return 0;
unknown's avatar
unknown committed
472 473 474 475
  }
  return 1;
}

476 477 478 479

bool Item_in_optimizer::fix_left(THD *thd,
				 struct st_table_list *tables,
				 Item **ref)
unknown's avatar
unknown committed
480
{
unknown's avatar
unknown committed
481 482
  if (!args[0]->fixed && args[0]->fix_fields(thd, tables, args) ||
      !cache && !(cache= Item_cache::get_cache(args[0]->result_type())))
483
    return 1;
484

485
  cache->setup(args[0]);
486
  cache->store(args[0]);
487
  if (cache->cols() == 1)
488
  {
unknown's avatar
unknown committed
489
    if ((used_tables_cache= args[0]->used_tables()))
unknown's avatar
unknown committed
490
      cache->set_used_tables(OUTER_REF_TABLE_BIT);
491 492 493
    else
      cache->set_used_tables(0);
  }
494 495 496 497
  else
  {
    uint n= cache->cols();
    for (uint i= 0; i < n; i++)
498 499
    {
      if (args[0]->el(i)->used_tables())
unknown's avatar
unknown committed
500
	((Item_cache *)cache->el(i))->set_used_tables(OUTER_REF_TABLE_BIT);
501 502 503
      else
	((Item_cache *)cache->el(i))->set_used_tables(0);
    }
unknown's avatar
unknown committed
504
    used_tables_cache= args[0]->used_tables();
505
  }
unknown's avatar
unknown committed
506 507 508
  not_null_tables_cache= args[0]->not_null_tables();
  with_sum_func= args[0]->with_sum_func;
  const_item_cache= args[0]->const_item();
509 510 511 512 513 514 515
  return 0;
}


bool Item_in_optimizer::fix_fields(THD *thd, struct st_table_list *tables,
				   Item ** ref)
{
516
  DBUG_ASSERT(fixed == 0);
517
  if (fix_left(thd, tables, ref))
518 519 520 521
    return 1;
  if (args[0]->maybe_null)
    maybe_null=1;

522
  if (!args[1]->fixed && args[1]->fix_fields(thd, tables, args+1))
unknown's avatar
unknown committed
523 524 525 526
    return 1;
  Item_in_subselect * sub= (Item_in_subselect *)args[1];
  if (args[0]->cols() != sub->engine->cols())
  {
unknown's avatar
unknown committed
527
    my_error(ER_OPERAND_COLUMNS, MYF(0), args[0]->cols());
528
    return 1;
unknown's avatar
unknown committed
529
  }
530 531 532 533
  if (args[1]->maybe_null)
    maybe_null=1;
  with_sum_func= with_sum_func || args[1]->with_sum_func;
  used_tables_cache|= args[1]->used_tables();
unknown's avatar
unknown committed
534
  not_null_tables_cache|= args[1]->not_null_tables();
535
  const_item_cache&= args[1]->const_item();
536
  fixed= 1;
537 538 539
  return 0;
}

540

541 542
longlong Item_in_optimizer::val_int()
{
543
  DBUG_ASSERT(fixed == 1);
544 545
  cache->store(args[0]);
  if (cache->null_value)
546 547 548 549 550
  {
    null_value= 1;
    return 0;
  }
  longlong tmp= args[1]->val_int_result();
unknown's avatar
unknown committed
551
  null_value= args[1]->null_value;
552 553 554
  return tmp;
}

555 556 557 558 559 560 561 562

void Item_in_optimizer::keep_top_level_cache()
{
  cache->keep_array();
  save_cache= 1;
}


unknown's avatar
unknown committed
563 564 565 566
void Item_in_optimizer::cleanup()
{
  DBUG_ENTER("Item_in_optimizer::cleanup");
  Item_bool_func::cleanup();
567 568
  if (!save_cache)
    cache= 0;
unknown's avatar
unknown committed
569 570 571
  DBUG_VOID_RETURN;
}

572

573
bool Item_in_optimizer::is_null()
574
{
575 576
  cache->store(args[0]);
  return (null_value= (cache->null_value || args[1]->is_null()));
577
}
unknown's avatar
unknown committed
578

579

unknown's avatar
unknown committed
580 581
longlong Item_func_eq::val_int()
{
582
  DBUG_ASSERT(fixed == 1);
583
  int value= cmp.compare();
unknown's avatar
unknown committed
584 585 586
  return value == 0 ? 1 : 0;
}

587

unknown's avatar
unknown committed
588 589
/* Same as Item_func_eq, but NULL = NULL */

unknown's avatar
unknown committed
590 591 592 593 594 595
void Item_func_equal::fix_length_and_dec()
{
  Item_bool_func2::fix_length_and_dec();
  maybe_null=null_value=0;
}

unknown's avatar
unknown committed
596 597
longlong Item_func_equal::val_int()
{
598
  DBUG_ASSERT(fixed == 1);
599
  return cmp.compare();
unknown's avatar
unknown committed
600 601 602 603
}

longlong Item_func_ne::val_int()
{
604
  DBUG_ASSERT(fixed == 1);
605
  int value= cmp.compare();
606
  return value != 0 && !null_value ? 1 : 0;
unknown's avatar
unknown committed
607 608 609 610 611
}


longlong Item_func_ge::val_int()
{
612
  DBUG_ASSERT(fixed == 1);
613
  int value= cmp.compare();
unknown's avatar
unknown committed
614 615 616 617 618 619
  return value >= 0 ? 1 : 0;
}


longlong Item_func_gt::val_int()
{
620
  DBUG_ASSERT(fixed == 1);
621
  int value= cmp.compare();
unknown's avatar
unknown committed
622 623 624 625 626
  return value > 0 ? 1 : 0;
}

longlong Item_func_le::val_int()
{
627
  DBUG_ASSERT(fixed == 1);
628
  int value= cmp.compare();
unknown's avatar
unknown committed
629 630 631 632 633 634
  return value <= 0 && !null_value ? 1 : 0;
}


longlong Item_func_lt::val_int()
{
635
  DBUG_ASSERT(fixed == 1);
636
  int value= cmp.compare();
unknown's avatar
unknown committed
637 638 639 640 641 642
  return value < 0 && !null_value ? 1 : 0;
}


longlong Item_func_strcmp::val_int()
{
643
  DBUG_ASSERT(fixed == 1);
unknown's avatar
unknown committed
644 645 646 647 648 649 650
  String *a=args[0]->val_str(&tmp_value1);
  String *b=args[1]->val_str(&tmp_value2);
  if (!a || !b)
  {
    null_value=1;
    return 0;
  }
651
  int value= sortcmp(a,b,cmp.cmp_collation.collation);
unknown's avatar
unknown committed
652 653 654 655 656 657 658
  null_value=0;
  return !value ? 0 : (value < 0 ? (longlong) -1 : (longlong) 1);
}


void Item_func_interval::fix_length_and_dec()
{
659
  if (row->cols() > 8)
unknown's avatar
unknown committed
660
  {
661 662 663
    bool consts=1;

    for (uint i=1 ; consts && i < row->cols() ; i++)
unknown's avatar
unknown committed
664
    {
665
      consts&= row->el(i)->const_item();
unknown's avatar
unknown committed
666
    }
667 668 669

    if (consts &&
        (intervals=(double*) sql_alloc(sizeof(double)*(row->cols()-1))))
unknown's avatar
unknown committed
670
    {
671 672
      for (uint i=1 ; i < row->cols(); i++)
        intervals[i-1]=row->el(i)->val();
unknown's avatar
unknown committed
673 674
    }
  }
unknown's avatar
unknown committed
675 676
  maybe_null= 0;
  max_length= 2;
677
  used_tables_cache|= row->used_tables();
unknown's avatar
unknown committed
678
  not_null_tables_cache&= row->not_null_tables();
679
  with_sum_func= with_sum_func || row->with_sum_func;
unknown's avatar
unknown committed
680
  const_item_cache&= row->const_item();
unknown's avatar
unknown committed
681 682
}

unknown's avatar
unknown committed
683

unknown's avatar
unknown committed
684 685 686
/*
  return -1 if null value,
	  0 if lower than lowest
687 688
	  1 - arg_count-1 if between args[n] and args[n+1]
	  arg_count if higher than biggest argument
unknown's avatar
unknown committed
689 690 691 692
*/

longlong Item_func_interval::val_int()
{
693
  DBUG_ASSERT(fixed == 1);
unknown's avatar
unknown committed
694 695 696
  double value= row->el(0)->val();
  uint i;

697 698
  if (row->el(0)->null_value)
    return -1;				// -1 if null
unknown's avatar
unknown committed
699 700 701
  if (intervals)
  {					// Use binary search to find interval
    uint start,end;
702
    start= 0;
unknown's avatar
unknown committed
703
    end=   row->cols()-2;
unknown's avatar
unknown committed
704 705
    while (start != end)
    {
unknown's avatar
unknown committed
706
      uint mid= (start + end + 1) / 2;
unknown's avatar
unknown committed
707
      if (intervals[mid] <= value)
unknown's avatar
unknown committed
708
	start= mid;
unknown's avatar
unknown committed
709
      else
unknown's avatar
unknown committed
710
	end= mid - 1;
unknown's avatar
unknown committed
711
    }
unknown's avatar
unknown committed
712
    return (value < intervals[start]) ? 0 : start + 1;
unknown's avatar
unknown committed
713
  }
714 715

  for (i=1 ; i < row->cols() ; i++)
unknown's avatar
unknown committed
716
  {
717 718
    if (row->el(i)->val() > value)
      return i-1;
unknown's avatar
unknown committed
719
  }
720
  return i-1;
unknown's avatar
unknown committed
721 722
}

unknown's avatar
unknown committed
723 724
void Item_func_between::fix_length_and_dec()
{
unknown's avatar
unknown committed
725
   max_length= 1;
unknown's avatar
unknown committed
726

727 728 729 730
  /*
    As some compare functions are generated after sql_yacc,
    we have to check for out of memory conditons here
  */
unknown's avatar
unknown committed
731 732
  if (!args[0] || !args[1] || !args[2])
    return;
733
  agg_cmp_type(&cmp_type, args, 3);
unknown's avatar
unknown committed
734 735 736
  if (cmp_type == STRING_RESULT &&
      agg_arg_collations_for_comparison(cmp_collation, args, 3))
    return;
unknown's avatar
unknown committed
737

unknown's avatar
unknown committed
738 739 740 741 742
  /*
    Make a special case of compare with date/time and longlong fields.
    They are compared as integers, so for const item this time-consuming
    conversion can be done only once, not for every single comparison
  */
unknown's avatar
unknown committed
743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758
  if (args[0]->type() == FIELD_ITEM)
  {
    Field *field=((Item_field*) args[0])->field;
    if (field->store_for_compare())
    {
      if (convert_constant_item(field,&args[1]))
	cmp_type=INT_RESULT;			// Works for all types.
      if (convert_constant_item(field,&args[2]))
	cmp_type=INT_RESULT;			// Works for all types.
    }
  }
}


longlong Item_func_between::val_int()
{						// ANSI BETWEEN
759
  DBUG_ASSERT(fixed == 1);
unknown's avatar
unknown committed
760 761 762 763 764 765 766 767 768
  if (cmp_type == STRING_RESULT)
  {
    String *value,*a,*b;
    value=args[0]->val_str(&value0);
    if ((null_value=args[0]->null_value))
      return 0;
    a=args[1]->val_str(&value1);
    b=args[2]->val_str(&value2);
    if (!args[1]->null_value && !args[2]->null_value)
769 770
      return (sortcmp(value,a,cmp_collation.collation) >= 0 && 
	      sortcmp(value,b,cmp_collation.collation) <= 0) ? 1 : 0;
unknown's avatar
unknown committed
771 772 773 774
    if (args[1]->null_value && args[2]->null_value)
      null_value=1;
    else if (args[1]->null_value)
    {
unknown's avatar
unknown committed
775 776
      // Set to not null if false range.
      null_value= sortcmp(value,b,cmp_collation.collation) <= 0;
unknown's avatar
unknown committed
777 778 779
    }
    else
    {
unknown's avatar
unknown committed
780 781
      // Set to not null if false range.
      null_value= sortcmp(value,a,cmp_collation.collation) >= 0;
unknown's avatar
unknown committed
782 783 784 785 786 787
    }
  }
  else if (cmp_type == INT_RESULT)
  {
    longlong value=args[0]->val_int(),a,b;
    if ((null_value=args[0]->null_value))
788
      return 0;					/* purecov: inspected */
unknown's avatar
unknown committed
789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807
    a=args[1]->val_int();
    b=args[2]->val_int();
    if (!args[1]->null_value && !args[2]->null_value)
      return (value >= a && value <= b) ? 1 : 0;
    if (args[1]->null_value && args[2]->null_value)
      null_value=1;
    else if (args[1]->null_value)
    {
      null_value= value <= b;			// not null if false range.
    }
    else
    {
      null_value= value >= a;
    }
  }
  else
  {
    double value=args[0]->val(),a,b;
    if ((null_value=args[0]->null_value))
808
      return 0;					/* purecov: inspected */
unknown's avatar
unknown committed
809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826
    a=args[1]->val();
    b=args[2]->val();
    if (!args[1]->null_value && !args[2]->null_value)
      return (value >= a && value <= b) ? 1 : 0;
    if (args[1]->null_value && args[2]->null_value)
      null_value=1;
    else if (args[1]->null_value)
    {
      null_value= value <= b;			// not null if false range.
    }
    else
    {
      null_value= value >= a;
    }
  }
  return 0;
}

827 828 829 830 831

void Item_func_between::print(String *str)
{
  str->append('(');
  args[0]->print(str);
832
  str->append(" between ", 9);
833
  args[1]->print(str);
834
  str->append(" and ", 5);
835 836 837 838
  args[2]->print(str);
  str->append(')');
}

unknown's avatar
unknown committed
839 840 841 842 843 844
void
Item_func_ifnull::fix_length_and_dec()
{
  maybe_null=args[1]->maybe_null;
  max_length=max(args[0]->max_length,args[1]->max_length);
  decimals=max(args[0]->decimals,args[1]->decimals);
845
  agg_result_type(&cached_result_type, args, 2);
unknown's avatar
unknown committed
846 847
  if (cached_result_type == STRING_RESULT)
    agg_arg_collations(collation, args, arg_count);
848 849
  else if (cached_result_type != REAL_RESULT)
    decimals= 0;
850 851 852 853
  
  cached_field_type= args[0]->field_type();
  if (cached_field_type != args[1]->field_type())
    cached_field_type= Item_func::field_type();
unknown's avatar
unknown committed
854 855
}

856 857 858
enum_field_types Item_func_ifnull::field_type() const 
{
  return cached_field_type;
unknown's avatar
unknown committed
859 860
}

861 862 863 864
Field *Item_func_ifnull::tmp_table_field(TABLE *table)
{
  return tmp_table_field_from_field_type(table);
}
865

unknown's avatar
unknown committed
866 867 868
double
Item_func_ifnull::val()
{
869
  DBUG_ASSERT(fixed == 1);
unknown's avatar
unknown committed
870 871 872 873 874 875 876 877 878 879 880 881 882 883 884
  double value=args[0]->val();
  if (!args[0]->null_value)
  {
    null_value=0;
    return value;
  }
  value=args[1]->val();
  if ((null_value=args[1]->null_value))
    return 0.0;
  return value;
}

longlong
Item_func_ifnull::val_int()
{
885
  DBUG_ASSERT(fixed == 1);
unknown's avatar
unknown committed
886 887 888 889 890 891 892 893 894 895 896 897 898 899 900
  longlong value=args[0]->val_int();
  if (!args[0]->null_value)
  {
    null_value=0;
    return value;
  }
  value=args[1]->val_int();
  if ((null_value=args[1]->null_value))
    return 0;
  return value;
}

String *
Item_func_ifnull::val_str(String *str)
{
901
  DBUG_ASSERT(fixed == 1);
unknown's avatar
unknown committed
902 903 904 905
  String *res  =args[0]->val_str(str);
  if (!args[0]->null_value)
  {
    null_value=0;
906
    res->set_charset(collation.collation);
unknown's avatar
unknown committed
907 908 909 910 911
    return res;
  }
  res=args[1]->val_str(str);
  if ((null_value=args[1]->null_value))
    return 0;
912
  res->set_charset(collation.collation);
unknown's avatar
unknown committed
913 914 915
  return res;
}

916

unknown's avatar
unknown committed
917 918 919 920 921
void
Item_func_if::fix_length_and_dec()
{
  maybe_null=args[1]->maybe_null || args[2]->maybe_null;
  max_length=max(args[1]->max_length,args[2]->max_length);
922
  decimals=max(args[1]->decimals,args[2]->decimals);
unknown's avatar
unknown committed
923 924
  enum Item_result arg1_type=args[1]->result_type();
  enum Item_result arg2_type=args[2]->result_type();
925 926 927 928 929 930
  bool null1=args[1]->null_value;
  bool null2=args[2]->null_value;

  if (null1)
  {
    cached_result_type= arg2_type;
931
    collation.set(args[2]->collation.collation);
932 933 934
  }
  else if (null2)
  {
unknown's avatar
unknown committed
935
    cached_result_type= arg1_type;
936
    collation.set(args[1]->collation.collation);
937
  }
unknown's avatar
unknown committed
938
  else
939
  {
940 941 942 943 944 945
    agg_result_type(&cached_result_type, args+1, 2);
    if (cached_result_type == STRING_RESULT)
    {
      if (agg_arg_collations(collation, args+1, 2))
      return;
    }
946
    else
947
    {
948
      collation.set(&my_charset_bin);	// Number
949
    }
950
  }
unknown's avatar
unknown committed
951 952 953 954 955 956
}


double
Item_func_if::val()
{
957
  DBUG_ASSERT(fixed == 1);
unknown's avatar
unknown committed
958 959 960 961 962 963 964 965 966
  Item *arg= args[0]->val_int() ? args[1] : args[2];
  double value=arg->val();
  null_value=arg->null_value;
  return value;
}

longlong
Item_func_if::val_int()
{
967
  DBUG_ASSERT(fixed == 1);
unknown's avatar
unknown committed
968 969 970 971 972 973 974 975 976
  Item *arg= args[0]->val_int() ? args[1] : args[2];
  longlong value=arg->val_int();
  null_value=arg->null_value;
  return value;
}

String *
Item_func_if::val_str(String *str)
{
977
  DBUG_ASSERT(fixed == 1);
unknown's avatar
unknown committed
978 979
  Item *arg= args[0]->val_int() ? args[1] : args[2];
  String *res=arg->val_str(str);
980
  if (res)
981
    res->set_charset(collation.collation);
unknown's avatar
unknown committed
982 983 984 985 986 987 988 989 990 991 992 993 994 995
  null_value=arg->null_value;
  return res;
}


void
Item_func_nullif::fix_length_and_dec()
{
  Item_bool_func2::fix_length_and_dec();
  maybe_null=1;
  if (args[0])					// Only false if EOM
  {
    max_length=args[0]->max_length;
    decimals=args[0]->decimals;
996
    agg_result_type(&cached_result_type, args, 2);
unknown's avatar
unknown committed
997 998 999 1000
  }
}

/*
1001
  nullif () returns NULL if arguments are equal, else it returns the
unknown's avatar
unknown committed
1002 1003 1004 1005 1006 1007 1008 1009
  first argument.
  Note that we have to evaluate the first argument twice as the compare
  may have been done with a different type than return value
*/

double
Item_func_nullif::val()
{
1010
  DBUG_ASSERT(fixed == 1);
unknown's avatar
unknown committed
1011
  double value;
unknown's avatar
unknown committed
1012
  if (!cmp.compare())
unknown's avatar
unknown committed
1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024
  {
    null_value=1;
    return 0.0;
  }
  value=args[0]->val();
  null_value=args[0]->null_value;
  return value;
}

longlong
Item_func_nullif::val_int()
{
1025
  DBUG_ASSERT(fixed == 1);
unknown's avatar
unknown committed
1026
  longlong value;
unknown's avatar
unknown committed
1027
  if (!cmp.compare())
unknown's avatar
unknown committed
1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039
  {
    null_value=1;
    return 0;
  }
  value=args[0]->val_int();
  null_value=args[0]->null_value;
  return value;
}

String *
Item_func_nullif::val_str(String *str)
{
1040
  DBUG_ASSERT(fixed == 1);
unknown's avatar
unknown committed
1041
  String *res;
unknown's avatar
unknown committed
1042
  if (!cmp.compare())
unknown's avatar
unknown committed
1043 1044 1045 1046 1047 1048 1049 1050 1051 1052
  {
    null_value=1;
    return 0;
  }
  res=args[0]->val_str(str);
  null_value=args[0]->null_value;
  return res;
}

/*
1053 1054
  CASE expression 
  Return the matching ITEM or NULL if all compares (including else) failed
unknown's avatar
unknown committed
1055 1056 1057 1058 1059 1060 1061
*/

Item *Item_func_case::find_item(String *str)
{
  String *first_expr_str,*tmp;
  longlong first_expr_int;
  double   first_expr_real;
unknown's avatar
unknown committed
1062
  
unknown's avatar
unknown committed
1063 1064 1065 1066 1067
  /* These will be initialized later */
  LINT_INIT(first_expr_str);
  LINT_INIT(first_expr_int);
  LINT_INIT(first_expr_real);

unknown's avatar
unknown committed
1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094
  if (first_expr_num != -1)
  {
    switch (cmp_type)
    {
      case STRING_RESULT:
      	// We can't use 'str' here as this may be overwritten
	if (!(first_expr_str= args[first_expr_num]->val_str(&str_value)))
	  return else_expr_num != -1 ? args[else_expr_num] : 0;	// Impossible
        break;
      case INT_RESULT:
	first_expr_int= args[first_expr_num]->val_int();
	if (args[first_expr_num]->null_value)
	  return else_expr_num != -1 ? args[else_expr_num] : 0;
	break;
      case REAL_RESULT:
	first_expr_real= args[first_expr_num]->val();
	if (args[first_expr_num]->null_value)
	  return else_expr_num != -1 ? args[else_expr_num] : 0;
	break;
      case ROW_RESULT:
      default:
	// This case should never be choosen
	DBUG_ASSERT(0);
	break;
    }
  }

unknown's avatar
unknown committed
1095
  // Compare every WHEN argument with it and return the first match
1096
  for (uint i=0 ; i < ncases ; i+=2)
unknown's avatar
unknown committed
1097
  {
1098
    if (first_expr_num == -1)
unknown's avatar
unknown committed
1099
    {
unknown's avatar
unknown committed
1100
      // No expression between CASE and the first WHEN
unknown's avatar
unknown committed
1101 1102 1103 1104
      if (args[i]->val_int())
	return args[i+1];
      continue;
    }
unknown's avatar
unknown committed
1105
    switch (cmp_type) {
unknown's avatar
unknown committed
1106 1107
    case STRING_RESULT:
      if ((tmp=args[i]->val_str(str)))		// If not null
unknown's avatar
unknown committed
1108
	if (sortcmp(tmp,first_expr_str,cmp_collation.collation)==0)
unknown's avatar
unknown committed
1109 1110 1111 1112 1113 1114 1115 1116 1117
	  return args[i+1];
      break;
    case INT_RESULT:
      if (args[i]->val_int()==first_expr_int && !args[i]->null_value) 
        return args[i+1];
      break;
    case REAL_RESULT: 
      if (args[i]->val()==first_expr_real && !args[i]->null_value) 
        return args[i+1];
unknown's avatar
unknown committed
1118
      break;
1119
    case ROW_RESULT:
unknown's avatar
unknown committed
1120
    default:
unknown's avatar
unknown committed
1121 1122 1123
      // This case should never be choosen
      DBUG_ASSERT(0);
      break;
unknown's avatar
unknown committed
1124 1125 1126
    }
  }
  // No, WHEN clauses all missed, return ELSE expression
1127
  return else_expr_num != -1 ? args[else_expr_num] : 0;
unknown's avatar
unknown committed
1128 1129 1130 1131 1132 1133
}



String *Item_func_case::val_str(String *str)
{
1134
  DBUG_ASSERT(fixed == 1);
unknown's avatar
unknown committed
1135 1136 1137 1138 1139 1140 1141 1142
  String *res;
  Item *item=find_item(str);

  if (!item)
  {
    null_value=1;
    return 0;
  }
unknown's avatar
unknown committed
1143
  null_value= 0;
unknown's avatar
unknown committed
1144
  if (!(res=item->val_str(str)))
unknown's avatar
unknown committed
1145
    null_value= 1;
unknown's avatar
unknown committed
1146 1147 1148 1149 1150 1151
  return res;
}


longlong Item_func_case::val_int()
{
1152
  DBUG_ASSERT(fixed == 1);
unknown's avatar
unknown committed
1153
  char buff[MAX_FIELD_WIDTH];
1154
  String dummy_str(buff,sizeof(buff),default_charset());
unknown's avatar
unknown committed
1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169
  Item *item=find_item(&dummy_str);
  longlong res;

  if (!item)
  {
    null_value=1;
    return 0;
  }
  res=item->val_int();
  null_value=item->null_value;
  return res;
}

double Item_func_case::val()
{
1170
  DBUG_ASSERT(fixed == 1);
unknown's avatar
unknown committed
1171
  char buff[MAX_FIELD_WIDTH];
1172
  String dummy_str(buff,sizeof(buff),default_charset());
unknown's avatar
unknown committed
1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186
  Item *item=find_item(&dummy_str);
  double res;

  if (!item)
  {
    null_value=1;
    return 0;
  }
  res=item->val();
  null_value=item->null_value;
  return res;
}

void Item_func_case::fix_length_and_dec()
1187
{
1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208
  Item **agg;
  uint nagg;
  
  if (!(agg= (Item**) sql_alloc(sizeof(Item*)*(ncases+1))))
    return;
  
  // Aggregate all THEN and ELSE expression types
  // and collations when string result
  
  for (nagg= 0 ; nagg < ncases/2 ; nagg++)
    agg[nagg]= args[nagg*2+1];
  
  if (else_expr_num != -1)
    agg[nagg++]= args[else_expr_num];
  
  agg_result_type(&cached_result_type, agg, nagg);
  if ((cached_result_type == STRING_RESULT) &&
      agg_arg_collations(collation, agg, nagg))
    return;
  
  
unknown's avatar
unknown committed
1209 1210 1211 1212
  /*
    Aggregate first expression and all THEN expression types
    and collations when string comparison
  */
1213
  if (first_expr_num != -1)
1214
  {
1215 1216
    agg[0]= args[first_expr_num];
    for (nagg= 0; nagg < ncases/2 ; nagg++)
unknown's avatar
unknown committed
1217
      agg[nagg+1]= args[nagg*2];
1218 1219 1220 1221 1222
    nagg++;
    agg_cmp_type(&cmp_type, agg, nagg);
    if ((cmp_type == STRING_RESULT) &&
        agg_arg_collations_for_comparison(cmp_collation, agg, nagg))
    return;
1223
  }
1224
  
unknown's avatar
unknown committed
1225
  if (else_expr_num == -1 || args[else_expr_num]->maybe_null)
1226
    maybe_null=1;
1227
  
unknown's avatar
unknown committed
1228 1229
  max_length=0;
  decimals=0;
1230
  for (uint i=0 ; i < ncases ; i+=2)
unknown's avatar
unknown committed
1231 1232 1233 1234
  {
    set_if_bigger(max_length,args[i+1]->max_length);
    set_if_bigger(decimals,args[i+1]->decimals);
  }
1235
  if (else_expr_num != -1) 
unknown's avatar
unknown committed
1236
  {
1237 1238
    set_if_bigger(max_length,args[else_expr_num]->max_length);
    set_if_bigger(decimals,args[else_expr_num]->decimals);
unknown's avatar
unknown committed
1239 1240 1241
  }
}

unknown's avatar
unknown committed
1242

1243
/* TODO:  Fix this so that it prints the whole CASE expression */
unknown's avatar
unknown committed
1244 1245 1246

void Item_func_case::print(String *str)
{
1247
  str->append("(case ", 6);
1248 1249 1250 1251 1252 1253 1254
  if (first_expr_num != -1)
  {
    args[first_expr_num]->print(str);
    str->append(' ');
  }
  for (uint i=0 ; i < ncases ; i+=2)
  {
1255
    str->append("when ", 5);
1256
    args[i]->print(str);
1257
    str->append(" then ", 6);
1258 1259 1260 1261 1262
    args[i+1]->print(str);
    str->append(' ');
  }
  if (else_expr_num != -1)
  {
1263
    str->append("else ", 5);
1264 1265 1266
    args[else_expr_num]->print(str);
    str->append(' ');
  }
1267
  str->append("end)", 4);
unknown's avatar
unknown committed
1268 1269 1270
}

/*
1271
  Coalesce - return first not NULL argument.
unknown's avatar
unknown committed
1272 1273 1274 1275
*/

String *Item_func_coalesce::val_str(String *str)
{
1276
  DBUG_ASSERT(fixed == 1);
unknown's avatar
unknown committed
1277 1278 1279
  null_value=0;
  for (uint i=0 ; i < arg_count ; i++)
  {
unknown's avatar
unknown committed
1280 1281 1282
    String *res;
    if ((res=args[i]->val_str(str)))
      return res;
unknown's avatar
unknown committed
1283 1284 1285 1286 1287 1288 1289
  }
  null_value=1;
  return 0;
}

longlong Item_func_coalesce::val_int()
{
1290
  DBUG_ASSERT(fixed == 1);
unknown's avatar
unknown committed
1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303
  null_value=0;
  for (uint i=0 ; i < arg_count ; i++)
  {
    longlong res=args[i]->val_int();
    if (!args[i]->null_value)
      return res;
  }
  null_value=1;
  return 0;
}

double Item_func_coalesce::val()
{
1304
  DBUG_ASSERT(fixed == 1);
unknown's avatar
unknown committed
1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318
  null_value=0;
  for (uint i=0 ; i < arg_count ; i++)
  {
    double res=args[i]->val();
    if (!args[i]->null_value)
      return res;
  }
  null_value=1;
  return 0;
}


void Item_func_coalesce::fix_length_and_dec()
{
unknown's avatar
unknown committed
1319 1320
  max_length= 0;
  decimals= 0;
1321
  agg_result_type(&cached_result_type, args, arg_count);
unknown's avatar
unknown committed
1322 1323 1324 1325 1326
  for (uint i=0 ; i < arg_count ; i++)
  {
    set_if_bigger(max_length,args[i]->max_length);
    set_if_bigger(decimals,args[i]->decimals);
  }
1327 1328 1329 1330
  if (cached_result_type == STRING_RESULT)
    agg_arg_collations(collation, args, arg_count);
  else if (cached_result_type != REAL_RESULT)
    decimals= 0;
unknown's avatar
unknown committed
1331 1332 1333
}

/****************************************************************************
1334
 Classes and function for the IN operator
unknown's avatar
unknown committed
1335 1336
****************************************************************************/

1337
static int cmp_longlong(void *cmp_arg, longlong *a,longlong *b)
unknown's avatar
unknown committed
1338 1339 1340 1341
{
  return *a < *b ? -1 : *a == *b ? 0 : 1;
}

1342
static int cmp_double(void *cmp_arg, double *a,double *b)
unknown's avatar
unknown committed
1343 1344 1345 1346
{
  return *a < *b ? -1 : *a == *b ? 0 : 1;
}

1347
static int cmp_row(void *cmp_arg, cmp_item_row* a, cmp_item_row* b)
unknown's avatar
unknown committed
1348 1349 1350 1351
{
  return a->compare(b);
}

unknown's avatar
unknown committed
1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363
int in_vector::find(Item *item)
{
  byte *result=get_value(item);
  if (!result || !used_count)
    return 0;				// Null value

  uint start,end;
  start=0; end=used_count-1;
  while (start != end)
  {
    uint mid=(start+end+1)/2;
    int res;
1364
    if ((res=(*compare)(collation, base+mid*size, result)) == 0)
unknown's avatar
unknown committed
1365 1366 1367 1368 1369 1370
      return 1;
    if (res < 0)
      start=mid;
    else
      end=mid-1;
  }
1371
  return (int) ((*compare)(collation, base+start*size, result) == 0);
unknown's avatar
unknown committed
1372 1373
}

1374 1375
in_string::in_string(uint elements,qsort2_cmp cmp_func, CHARSET_INFO *cs)
  :in_vector(elements, sizeof(String), cmp_func, cs),
1376
   tmp(buff, sizeof(buff), &my_charset_bin)
unknown's avatar
unknown committed
1377 1378 1379 1380
{}

in_string::~in_string()
{
1381
  if (base)
1382
  {
unknown's avatar
unknown committed
1383
    // base was allocated with help of sql_alloc => following is OK
1384 1385
    for (uint i=0 ; i < count ; i++)
      ((String*) base)[i].free();
1386
  }
unknown's avatar
unknown committed
1387 1388 1389 1390 1391 1392 1393 1394
}

void in_string::set(uint pos,Item *item)
{
  String *str=((String*) base)+pos;
  String *res=item->val_str(str);
  if (res && res != str)
    *str= *res;
1395
  if (!str->charset())
1396 1397
  {
    CHARSET_INFO *cs;
1398
    if (!(cs= item->collation.collation))
1399
      cs= &my_charset_bin;		// Should never happen for STR items
1400 1401
    str->set_charset(cs);
  }
unknown's avatar
unknown committed
1402 1403
}

1404

unknown's avatar
unknown committed
1405 1406 1407 1408 1409
byte *in_string::get_value(Item *item)
{
  return (byte*) item->val_str(&tmp);
}

unknown's avatar
unknown committed
1410 1411
in_row::in_row(uint elements, Item * item)
{
1412
  base= (char*) new cmp_item_row[count= elements];
unknown's avatar
unknown committed
1413
  size= sizeof(cmp_item_row);
1414
  compare= (qsort2_cmp) cmp_row;
unknown's avatar
unknown committed
1415
  tmp.store_value(item);
1416 1417 1418 1419 1420
}

in_row::~in_row()
{
  if (base)
1421
    delete [] (cmp_item_row*) base;
unknown's avatar
unknown committed
1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436
}

byte *in_row::get_value(Item *item)
{
  tmp.store_value(item);
  return (byte *)&tmp;
}

void in_row::set(uint pos, Item *item)
{
  DBUG_ENTER("in_row::set");
  DBUG_PRINT("enter", ("pos %u item 0x%lx", pos, (ulong) item));
  ((cmp_item_row*) base)[pos].store_value_by_template(&tmp, item);
  DBUG_VOID_RETURN;
}
unknown's avatar
unknown committed
1437 1438

in_longlong::in_longlong(uint elements)
1439
  :in_vector(elements,sizeof(longlong),(qsort2_cmp) cmp_longlong, 0)
unknown's avatar
unknown committed
1440 1441 1442 1443 1444 1445 1446 1447 1448
{}

void in_longlong::set(uint pos,Item *item)
{
  ((longlong*) base)[pos]=item->val_int();
}

byte *in_longlong::get_value(Item *item)
{
unknown's avatar
unknown committed
1449
  tmp= item->val_int();
unknown's avatar
unknown committed
1450
  if (item->null_value)
unknown's avatar
unknown committed
1451
    return 0;
unknown's avatar
unknown committed
1452 1453 1454 1455
  return (byte*) &tmp;
}

in_double::in_double(uint elements)
1456
  :in_vector(elements,sizeof(double),(qsort2_cmp) cmp_double, 0)
unknown's avatar
unknown committed
1457 1458 1459 1460 1461 1462 1463 1464 1465
{}

void in_double::set(uint pos,Item *item)
{
  ((double*) base)[pos]=item->val();
}

byte *in_double::get_value(Item *item)
{
unknown's avatar
unknown committed
1466
  tmp= item->val();
unknown's avatar
unknown committed
1467
  if (item->null_value)
1468
    return 0;					/* purecov: inspected */
unknown's avatar
unknown committed
1469 1470 1471
  return (byte*) &tmp;
}

1472
cmp_item* cmp_item::get_comparator(Item *item)
1473 1474 1475
{
  switch (item->result_type()) {
  case STRING_RESULT:
1476
    return new cmp_item_sort_string(item->collation.collation);
1477 1478 1479 1480 1481 1482
  case INT_RESULT:
    return new cmp_item_int;
  case REAL_RESULT:
    return new cmp_item_real;
  case ROW_RESULT:
    return new cmp_item_row;
unknown's avatar
unknown committed
1483 1484 1485
  default:
    DBUG_ASSERT(0);
    break;
1486 1487 1488 1489
  }
  return 0; // to satisfy compiler :)
}

1490

unknown's avatar
unknown committed
1491 1492
cmp_item* cmp_item_sort_string::make_same()
{
1493
  return new cmp_item_sort_string_in_static(cmp_charset);
unknown's avatar
unknown committed
1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510
}

cmp_item* cmp_item_int::make_same()
{
  return new cmp_item_int();
}

cmp_item* cmp_item_real::make_same()
{
  return new cmp_item_real();
}

cmp_item* cmp_item_row::make_same()
{
  return new cmp_item_row();
}

1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527

cmp_item_row::~cmp_item_row()
{
  DBUG_ENTER("~cmp_item_row");
  DBUG_PRINT("enter",("this: %lx", this));
  if (comparators)
  {
    for (uint i= 0; i < n; i++)
    {
      if (comparators[i])
	delete comparators[i];
    }
  }
  DBUG_VOID_RETURN;
}


1528 1529
void cmp_item_row::store_value(Item *item)
{
1530
  DBUG_ENTER("cmp_item_row::store_value");
1531
  n= item->cols();
1532
  if (!comparators)
unknown's avatar
unknown committed
1533
    comparators= (cmp_item **) current_thd->calloc(sizeof(cmp_item *)*n);
1534
  if (comparators)
1535
  {
1536
    item->bring_value();
unknown's avatar
unknown committed
1537
    item->null_value= 0;
1538
    for (uint i=0; i < n; i++)
1539
    {
unknown's avatar
unknown committed
1540 1541 1542
      if (!comparators[i])
	if (!(comparators[i]= cmp_item::get_comparator(item->el(i))))
	  break;					// new failed
1543 1544 1545
      comparators[i]->store_value(item->el(i));
      item->null_value|= item->el(i)->null_value;
    }
1546
  }
1547
  DBUG_VOID_RETURN;
1548 1549
}

1550

unknown's avatar
unknown committed
1551 1552 1553 1554 1555
void cmp_item_row::store_value_by_template(cmp_item *t, Item *item)
{
  cmp_item_row *tmpl= (cmp_item_row*) t;
  if (tmpl->n != item->cols())
  {
unknown's avatar
unknown committed
1556
    my_error(ER_OPERAND_COLUMNS, MYF(0), tmpl->n);
unknown's avatar
unknown committed
1557 1558 1559 1560 1561
    return;
  }
  n= tmpl->n;
  if ((comparators= (cmp_item **) sql_alloc(sizeof(cmp_item *)*n)))
  {
1562
    item->bring_value();
unknown's avatar
unknown committed
1563 1564
    item->null_value= 0;
    for (uint i=0; i < n; i++)
1565 1566 1567 1568 1569 1570 1571
    {
      if (!(comparators[i]= tmpl->comparators[i]->make_same()))
	break;					// new failed
      comparators[i]->store_value_by_template(tmpl->comparators[i],
					      item->el(i));
      item->null_value|= item->el(i)->null_value;
    }
unknown's avatar
unknown committed
1572 1573 1574
  }
}

1575

1576 1577
int cmp_item_row::cmp(Item *arg)
{
unknown's avatar
unknown committed
1578 1579 1580
  arg->null_value= 0;
  if (arg->cols() != n)
  {
unknown's avatar
unknown committed
1581
    my_error(ER_OPERAND_COLUMNS, MYF(0), n);
unknown's avatar
unknown committed
1582 1583
    return 1;
  }
unknown's avatar
unknown committed
1584
  bool was_null= 0;
1585
  arg->bring_value();
unknown's avatar
unknown committed
1586
  for (uint i=0; i < n; i++)
1587
  {
unknown's avatar
unknown committed
1588
    if (comparators[i]->cmp(arg->el(i)))
unknown's avatar
unknown committed
1589
    {
unknown's avatar
unknown committed
1590 1591 1592
      if (!arg->el(i)->null_value)
	return 1;
      was_null= 1;
unknown's avatar
unknown committed
1593
    }
1594
  }
unknown's avatar
unknown committed
1595
  return (arg->null_value= was_null);
unknown's avatar
unknown committed
1596 1597
}

1598

unknown's avatar
unknown committed
1599 1600 1601
int cmp_item_row::compare(cmp_item *c)
{
  cmp_item_row *cmp= (cmp_item_row *) c;
unknown's avatar
unknown committed
1602
  for (uint i=0; i < n; i++)
1603 1604
  {
    int res;
unknown's avatar
unknown committed
1605
    if ((res= comparators[i]->compare(cmp->comparators[i])))
unknown's avatar
unknown committed
1606
      return res;
1607
  }
1608 1609
  return 0;
}
unknown's avatar
unknown committed
1610

1611

unknown's avatar
unknown committed
1612 1613 1614
bool Item_func_in::nulls_in_row()
{
  Item **arg,**arg_end;
1615
  for (arg= args+1, arg_end= args+arg_count; arg != arg_end ; arg++)
unknown's avatar
unknown committed
1616 1617 1618 1619 1620 1621 1622
  {
    if ((*arg)->null_inside())
      return 1;
  }
  return 0;
}

1623

1624
static int srtcmp_in(CHARSET_INFO *cs, const String *x,const String *y)
1625
{
1626
  return cs->coll->strnncollsp(cs,
1627 1628 1629 1630
                        (unsigned char *) x->ptr(),x->length(),
			(unsigned char *) y->ptr(),y->length());
}

1631

unknown's avatar
unknown committed
1632 1633
void Item_func_in::fix_length_and_dec()
{
1634 1635 1636
  Item **arg, **arg_end;
  uint const_itm= 1;
  
1637 1638
  agg_cmp_type(&cmp_type, args, arg_count);
  if ((cmp_type == STRING_RESULT) &&
1639 1640 1641 1642 1643 1644
      (agg_arg_collations_for_comparison(cmp_collation, args, arg_count)))
    return;
  
  for (arg=args+1, arg_end=args+arg_count; arg != arg_end ; arg++)
    const_itm&= arg[0]->const_item();
  
unknown's avatar
unknown committed
1645 1646 1647 1648
  /*
    Row item with NULLs inside can return NULL or FALSE => 
    they can't be processed as static
  */
1649
  if (const_itm && !nulls_in_row())
unknown's avatar
unknown committed
1650
  {
1651
    switch (cmp_type) {
unknown's avatar
unknown committed
1652
    case STRING_RESULT:
1653
      array=new in_string(arg_count-1,(qsort2_cmp) srtcmp_in, 
1654
			  cmp_collation.collation);
unknown's avatar
unknown committed
1655 1656
      break;
    case INT_RESULT:
1657
      array= new in_longlong(arg_count-1);
unknown's avatar
unknown committed
1658 1659
      break;
    case REAL_RESULT:
1660
      array= new in_double(arg_count-1);
unknown's avatar
unknown committed
1661
      break;
unknown's avatar
unknown committed
1662
    case ROW_RESULT:
1663
      array= new in_row(arg_count-1, args[0]);
unknown's avatar
unknown committed
1664
      break;
unknown's avatar
unknown committed
1665 1666 1667
    default:
      DBUG_ASSERT(0);
      return;
unknown's avatar
unknown committed
1668
    }
unknown's avatar
unknown committed
1669
    if (array && !(current_thd->is_fatal_error))	// If not EOM
unknown's avatar
unknown committed
1670
    {
unknown's avatar
unknown committed
1671
      uint j=0;
unknown's avatar
unknown committed
1672
      for (uint i=1 ; i < arg_count ; i++)
unknown's avatar
unknown committed
1673 1674 1675 1676
      {
	array->set(j,args[i]);
	if (!args[i]->null_value)			// Skip NULL values
	  j++;
unknown's avatar
unknown committed
1677 1678
	else
	  have_null= 1;
unknown's avatar
unknown committed
1679 1680 1681
      }
      if ((array->used_count=j))
	array->sort();
unknown's avatar
unknown committed
1682 1683 1684 1685
    }
  }
  else
  {
1686
    in_item= cmp_item::get_comparator(args[0]);
1687
    if (cmp_type  == STRING_RESULT)
1688
      in_item->cmp_charset= cmp_collation.collation;
unknown's avatar
unknown committed
1689
  }
1690
  maybe_null= args[0]->maybe_null;
unknown's avatar
unknown committed
1691
  max_length= 1;
unknown's avatar
unknown committed
1692 1693 1694 1695 1696 1697
}


void Item_func_in::print(String *str)
{
  str->append('(');
1698
  args[0]->print(str);
1699
  str->append(" in (", 5);
unknown's avatar
unknown committed
1700
  print_args(str, 1);
1701
  str->append("))", 2);
unknown's avatar
unknown committed
1702 1703 1704 1705 1706
}


longlong Item_func_in::val_int()
{
1707
  DBUG_ASSERT(fixed == 1);
unknown's avatar
unknown committed
1708 1709
  if (array)
  {
1710 1711
    int tmp=array->find(args[0]);
    null_value=args[0]->null_value || (!tmp && have_null);
unknown's avatar
unknown committed
1712 1713
    return tmp;
  }
1714 1715
  in_item->store_value(args[0]);
  if ((null_value=args[0]->null_value))
unknown's avatar
unknown committed
1716
    return 0;
1717
  have_null= 0;
1718
  for (uint i=1 ; i < arg_count ; i++)
unknown's avatar
unknown committed
1719 1720 1721
  {
    if (!in_item->cmp(args[i]) && !args[i]->null_value)
      return 1;					// Would maybe be nice with i ?
1722
    have_null|= args[i]->null_value;
unknown's avatar
unknown committed
1723
  }
1724
  null_value= have_null;
unknown's avatar
unknown committed
1725 1726 1727 1728 1729 1730
  return 0;
}


longlong Item_func_bit_or::val_int()
{
1731
  DBUG_ASSERT(fixed == 1);
unknown's avatar
unknown committed
1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750
  ulonglong arg1= (ulonglong) args[0]->val_int();
  if (args[0]->null_value)
  {
    null_value=1; /* purecov: inspected */
    return 0; /* purecov: inspected */
  }
  ulonglong arg2= (ulonglong) args[1]->val_int();
  if (args[1]->null_value)
  {
    null_value=1;
    return 0;
  }
  null_value=0;
  return (longlong) (arg1 | arg2);
}


longlong Item_func_bit_and::val_int()
{
1751
  DBUG_ASSERT(fixed == 1);
unknown's avatar
unknown committed
1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767
  ulonglong arg1= (ulonglong) args[0]->val_int();
  if (args[0]->null_value)
  {
    null_value=1; /* purecov: inspected */
    return 0; /* purecov: inspected */
  }
  ulonglong arg2= (ulonglong) args[1]->val_int();
  if (args[1]->null_value)
  {
    null_value=1; /* purecov: inspected */
    return 0; /* purecov: inspected */
  }
  null_value=0;
  return (longlong) (arg1 & arg2);
}

1768
Item_cond::Item_cond(THD *thd, Item_cond *item)
1769
  :Item_bool_func(thd, item),
1770 1771
   abort_on_null(item->abort_on_null),
   and_tables_cache(item->and_tables_cache)
1772 1773
{
  /*
unknown's avatar
unknown committed
1774
    item->list will be copied by copy_andor_arguments() call
1775 1776 1777
  */
}

unknown's avatar
unknown committed
1778

1779 1780 1781
void Item_cond::copy_andor_arguments(THD *thd, Item_cond *item)
{
  List_iterator_fast<Item> li(item->list);
unknown's avatar
unknown committed
1782
  while (Item *it= li++)
1783 1784
    list.push_back(it->copy_andor_structure(thd));
}
unknown's avatar
unknown committed
1785

unknown's avatar
unknown committed
1786

unknown's avatar
unknown committed
1787
bool
unknown's avatar
unknown committed
1788
Item_cond::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
unknown's avatar
unknown committed
1789
{
1790
  DBUG_ASSERT(fixed == 0);
unknown's avatar
unknown committed
1791 1792
  List_iterator<Item> li(list);
  Item *item;
1793
#ifndef EMBEDDED_LIBRARY
unknown's avatar
unknown committed
1794
  char buff[sizeof(char*)];			// Max local vars in function
1795
#endif
1796 1797
  not_null_tables_cache= used_tables_cache= 0;
  const_item_cache= 0;
1798 1799 1800 1801 1802
  /*
    and_table_cache is the value that Item_cond_or() returns for
    not_null_tables()
  */
  and_tables_cache= ~(table_map) 0;
unknown's avatar
unknown committed
1803

unknown's avatar
unknown committed
1804
  if (check_stack_overrun(thd, buff))
1805
    return 1;					// Fatal error flag is set!
unknown's avatar
unknown committed
1806 1807
  while ((item=li++))
  {
1808
    table_map tmp_table_map;
unknown's avatar
unknown committed
1809 1810 1811 1812 1813 1814 1815
    while (item->type() == Item::COND_ITEM &&
	   ((Item_cond*) item)->functype() == functype())
    {						// Identical function
      li.replace(((Item_cond*) item)->list);
      ((Item_cond*) item)->list.empty();
      item= *li.ref();				// new current item
    }
1816 1817
    if (abort_on_null)
      item->top_level_item();
1818 1819

    // item can be substituted in fix_fields
1820
    if ((!item->fixed &&
1821 1822
	 item->fix_fields(thd, tables, li.ref())) ||
	(item= *li.ref())->check_cols(1))
unknown's avatar
unknown committed
1823
      return 1; /* purecov: inspected */
1824 1825 1826 1827 1828 1829
    used_tables_cache|=     item->used_tables();
    tmp_table_map=	    item->not_null_tables();
    not_null_tables_cache|= tmp_table_map;
    and_tables_cache&=      tmp_table_map;
    const_item_cache&=	    item->const_item();
    with_sum_func=	    with_sum_func || item->with_sum_func;
unknown's avatar
unknown committed
1830 1831
    if (item->maybe_null)
      maybe_null=1;
unknown's avatar
unknown committed
1832
  }
1833
  thd->lex->current_select->cond_count+= list.elements;
unknown's avatar
unknown committed
1834
  fix_length_and_dec();
1835
  fixed= 1;
unknown's avatar
unknown committed
1836 1837 1838
  return 0;
}

unknown's avatar
unknown committed
1839 1840 1841 1842 1843 1844 1845 1846 1847 1848
bool Item_cond::walk(Item_processor processor, byte *arg)
{
  List_iterator_fast<Item> li(list);
  Item *item;
  while ((item= li++))
    if (item->walk(processor, arg))
      return 1;
  return Item_func::walk(processor, arg);
}

1849
void Item_cond::split_sum_func(Item **ref_pointer_array, List<Item> &fields)
unknown's avatar
unknown committed
1850 1851 1852 1853 1854 1855 1856 1857
{
  List_iterator<Item> li(list);
  Item *item;
  used_tables_cache=0;
  const_item_cache=0;
  while ((item=li++))
  {
    if (item->with_sum_func && item->type() != SUM_FUNC_ITEM)
1858
      item->split_sum_func(ref_pointer_array, fields);
unknown's avatar
unknown committed
1859 1860
    else if (item->used_tables() || item->type() == SUM_FUNC_ITEM)
    {
1861
      uint el= fields.elements;
unknown's avatar
unknown committed
1862
      fields.push_front(item);
1863
      ref_pointer_array[el]= item;
unknown's avatar
unknown committed
1864
      li.replace(new Item_ref(ref_pointer_array + el, li.ref(), 0, item->name));
unknown's avatar
unknown committed
1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878
    }
    item->update_used_tables();
    used_tables_cache|=item->used_tables();
    const_item_cache&=item->const_item();
  }
}


table_map
Item_cond::used_tables() const
{						// This caches used_tables
  return used_tables_cache;
}

1879

unknown's avatar
unknown committed
1880 1881
void Item_cond::update_used_tables()
{
unknown's avatar
unknown committed
1882
  List_iterator_fast<Item> li(list);
unknown's avatar
unknown committed
1883
  Item *item;
1884 1885 1886

  used_tables_cache=0;
  const_item_cache=1;
unknown's avatar
unknown committed
1887 1888 1889
  while ((item=li++))
  {
    item->update_used_tables();
1890 1891
    used_tables_cache|= item->used_tables();
    const_item_cache&=  item->const_item();
unknown's avatar
unknown committed
1892 1893 1894 1895 1896 1897 1898
  }
}


void Item_cond::print(String *str)
{
  str->append('(');
unknown's avatar
unknown committed
1899
  List_iterator_fast<Item> li(list);
unknown's avatar
unknown committed
1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912
  Item *item;
  if ((item=li++))
    item->print(str);
  while ((item=li++))
  {
    str->append(' ');
    str->append(func_name());
    str->append(' ');
    item->print(str);
  }
  str->append(')');
}

1913

1914
void Item_cond::neg_arguments(THD *thd)
1915 1916 1917 1918 1919
{
  List_iterator<Item> li(list);
  Item *item;
  while ((item= li++))		/* Apply not transformation to the arguments */
  {
1920 1921 1922
    Item *new_item= item->neg_transformer(thd);
    if (!new_item)
    {
unknown's avatar
unknown committed
1923 1924
      if (!(new_item= new Item_func_not(item)))
	return;					// Fatal OEM error
1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935
      /*
	We can use 0 as tables list because Item_func_not do not use it
	on fix_fields and its arguments are already fixed.

	We do not check results of fix_fields, because there are not way
	to return error in this functions interface, thd->net.report_error
	will be checked on upper level call.
      */
      new_item->fix_fields(thd, 0, &new_item);
    }
    VOID(li.replace(new_item));
1936 1937 1938 1939
  }
}


1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956
/*
  Evalution of AND(expr, expr, expr ...)

  NOTES:
    abort_if_null is set for AND expressions for which we don't care if the
    result is NULL or 0. This is set for:
    - WHERE clause
    - HAVING clause
    - IF(expression)

  RETURN VALUES
    1  If all expressions are true
    0  If all expressions are false or if we find a NULL expression and
       'abort_on_null' is set.
    NULL if all expression are either 1 or NULL
*/

unknown's avatar
unknown committed
1957 1958 1959

longlong Item_cond_and::val_int()
{
1960
  DBUG_ASSERT(fixed == 1);
unknown's avatar
unknown committed
1961
  List_iterator_fast<Item> li(list);
unknown's avatar
unknown committed
1962
  Item *item;
1963
  null_value= 0;
unknown's avatar
unknown committed
1964 1965 1966 1967
  while ((item=li++))
  {
    if (item->val_int() == 0)
    {
1968 1969
      if (abort_on_null || !(null_value= item->null_value))
	return 0;				// return FALSE
unknown's avatar
unknown committed
1970 1971
    }
  }
1972
  return null_value ? 0 : 1;
unknown's avatar
unknown committed
1973 1974
}

1975

unknown's avatar
unknown committed
1976 1977
longlong Item_cond_or::val_int()
{
1978
  DBUG_ASSERT(fixed == 1);
unknown's avatar
unknown committed
1979
  List_iterator_fast<Item> li(list);
unknown's avatar
unknown committed
1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994
  Item *item;
  null_value=0;
  while ((item=li++))
  {
    if (item->val_int() != 0)
    {
      null_value=0;
      return 1;
    }
    if (item->null_value)
      null_value=1;
  }
  return 0;
}

1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018
/*
  Create an AND expression from two expressions

  SYNOPSIS
   and_expressions()
   a		expression or NULL
   b    	expression.
   org_item	Don't modify a if a == *org_item
		If a == NULL, org_item is set to point at b,
		to ensure that future calls will not modify b.

  NOTES
    This will not modify item pointed to by org_item or b
    The idea is that one can call this in a loop and create and
    'and' over all items without modifying any of the original items.

  RETURN
    NULL	Error
    Item
*/

Item *and_expressions(Item *a, Item *b, Item **org_item)
{
  if (!a)
2019
    return (*org_item= (Item*) b);
2020 2021 2022
  if (a == *org_item)
  {
    Item_cond *res;
2023
    if ((res= new Item_cond_and(a, (Item*) b)))
2024
    {
2025
      res->used_tables_cache= a->used_tables() | b->used_tables();
2026 2027
      res->not_null_tables_cache= a->not_null_tables() | b->not_null_tables();
    }
2028 2029
    return res;
  }
2030
  if (((Item_cond_and*) a)->add((Item*) b))
2031 2032
    return 0;
  ((Item_cond_and*) a)->used_tables_cache|= b->used_tables();
2033
  ((Item_cond_and*) a)->not_null_tables_cache|= b->not_null_tables();
2034 2035 2036 2037
  return a;
}


unknown's avatar
unknown committed
2038 2039
longlong Item_func_isnull::val_int()
{
2040
  DBUG_ASSERT(fixed == 1);
2041 2042 2043 2044 2045
  /*
    Handle optimization if the argument can't be null
    This has to be here because of the test in update_used_tables().
  */
  if (!used_tables_cache)
unknown's avatar
unknown committed
2046
    return cached_value;
unknown's avatar
unknown committed
2047
  return args[0]->is_null() ? 1: 0;
unknown's avatar
unknown committed
2048 2049
}

2050 2051
longlong Item_is_not_null_test::val_int()
{
2052
  DBUG_ASSERT(fixed == 1);
2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087
  DBUG_ENTER("Item_is_not_null_test::val_int");
  if (!used_tables_cache)
  {
    owner->was_null|= (!cached_value);
    DBUG_PRINT("info", ("cached :%d", cached_value));
    DBUG_RETURN(cached_value);
  }
  if (args[0]->is_null())
  {
    DBUG_PRINT("info", ("null"))
    owner->was_null|= 1;
    DBUG_RETURN(0);
  }
  else
    DBUG_RETURN(1);
}

/* Optimize case of not_null_column IS NULL */
void Item_is_not_null_test::update_used_tables()
{
  if (!args[0]->maybe_null)
  {
    used_tables_cache= 0;			/* is always true */
    cached_value= (longlong) 1;
  }
  else
  {
    args[0]->update_used_tables();
    if (!(used_tables_cache=args[0]->used_tables()))
    {
      /* Remember if the value is always NULL or never NULL */
      cached_value= (longlong) !args[0]->is_null();
    }
  }
}
2088

2089

unknown's avatar
unknown committed
2090 2091
longlong Item_func_isnotnull::val_int()
{
2092
  DBUG_ASSERT(fixed == 1);
unknown's avatar
unknown committed
2093
  return args[0]->is_null() ? 0 : 1;
unknown's avatar
unknown committed
2094 2095 2096
}


2097 2098 2099 2100
void Item_func_isnotnull::print(String *str)
{
  str->append('(');
  args[0]->print(str);
2101
  str->append(" is not null)", 13);
2102 2103 2104
}


unknown's avatar
unknown committed
2105 2106
longlong Item_func_like::val_int()
{
2107
  DBUG_ASSERT(fixed == 1);
2108
  String* res = args[0]->val_str(&tmp_value1);
unknown's avatar
unknown committed
2109 2110 2111 2112 2113
  if (args[0]->null_value)
  {
    null_value=1;
    return 0;
  }
2114
  String* res2 = args[1]->val_str(&tmp_value2);
unknown's avatar
unknown committed
2115 2116 2117 2118 2119 2120
  if (args[1]->null_value)
  {
    null_value=1;
    return 0;
  }
  null_value=0;
2121 2122
  if (canDoTurboBM)
    return turboBM_matches(res->ptr(), res->length()) ? 1 : 0;
2123
  return my_wildcmp(cmp.cmp_collation.collation,
2124 2125 2126
		    res->ptr(),res->ptr()+res->length(),
		    res2->ptr(),res2->ptr()+res2->length(),
		    escape,wild_one,wild_many) ? 0 : 1;
unknown's avatar
unknown committed
2127 2128 2129 2130 2131 2132 2133
}


/* We can optimize a where if first character isn't a wildcard */

Item_func::optimize_type Item_func_like::select_optimize() const
{
2134
  if (args[1]->const_item())
unknown's avatar
unknown committed
2135
  {
2136 2137 2138 2139 2140 2141
    String* res2= args[1]->val_str((String *)&tmp_value2);

    if (!res2)
      return OPTIMIZE_NONE;

    if (*res2->ptr() != wild_many)
unknown's avatar
unknown committed
2142
    {
2143
      if (args[0]->result_type() != STRING_RESULT || *res2->ptr() != wild_one)
unknown's avatar
unknown committed
2144 2145 2146 2147 2148 2149
	return OPTIMIZE_OP;
    }
  }
  return OPTIMIZE_NONE;
}

2150

unknown's avatar
unknown committed
2151
bool Item_func_like::fix_fields(THD *thd, TABLE_LIST *tlist, Item ** ref)
2152
{
2153
  DBUG_ASSERT(fixed == 0);
unknown's avatar
unknown committed
2154
  if (Item_bool_func2::fix_fields(thd, tlist, ref))
2155 2156
    return 1;

2157 2158 2159
  /*
    We could also do boyer-more for non-const items, but as we would have to
    recompute the tables for each row it's not worth it.
2160
  */
2161
  if (args[1]->const_item() && !use_strnxfrm(collation.collation) &&
2162
      !(specialflag & SPECIAL_NO_NEW_FUNC))
2163 2164
  {
    String* res2 = args[1]->val_str(&tmp_value2);
unknown's avatar
unknown committed
2165 2166 2167
    if (!res2)
      return 0;					// Null argument

2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180
    const size_t len   = res2->length();
    const char*  first = res2->ptr();
    const char*  last  = first + len - 1;
    /*
      len must be > 2 ('%pattern%')
      heuristic: only do TurboBM for pattern_len > 2
    */

    if (len > MIN_TURBOBM_PATTERN_LEN + 2 &&
	*first == wild_many &&
	*last  == wild_many)
    {
      const char* tmp = first + 1;
2181
      for (; *tmp != wild_many && *tmp != wild_one && *tmp != escape; tmp++) ;
2182
      canDoTurboBM = (tmp == last) && !use_mb(args[0]->collation.collation);
2183 2184 2185 2186 2187 2188
    }

    if (canDoTurboBM)
    {
      pattern     = first + 1;
      pattern_len = len - 2;
2189 2190 2191 2192 2193
      DBUG_PRINT("info", ("Initializing pattern: '%s'", first));
      int *suff = (int*) thd->alloc(sizeof(int)*((pattern_len + 1)*2+
						 alphabet_size));
      bmGs      = suff + pattern_len + 1;
      bmBc      = bmGs + pattern_len + 1;
2194 2195
      turboBM_compute_good_suffix_shifts(suff);
      turboBM_compute_bad_character_shifts();
2196
      DBUG_PRINT("info",("done"));
2197 2198 2199 2200 2201
    }
  }
  return 0;
}

unknown's avatar
unknown committed
2202 2203 2204
#ifdef USE_REGEX

bool
unknown's avatar
unknown committed
2205
Item_func_regex::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
unknown's avatar
unknown committed
2206
{
2207
  DBUG_ASSERT(fixed == 0);
unknown's avatar
unknown committed
2208 2209
  if (args[0]->fix_fields(thd, tables, args) || args[0]->check_cols(1) ||
      args[1]->fix_fields(thd,tables, args + 1) || args[1]->check_cols(1))
unknown's avatar
unknown committed
2210 2211
    return 1;					/* purecov: inspected */
  with_sum_func=args[0]->with_sum_func || args[1]->with_sum_func;
unknown's avatar
unknown committed
2212 2213
  max_length= 1;
  decimals= 0;
2214

unknown's avatar
unknown committed
2215
  if (agg_arg_collations(cmp_collation, args, 2))
2216
    return 1;
2217

unknown's avatar
unknown committed
2218
  used_tables_cache=args[0]->used_tables() | args[1]->used_tables();
2219 2220
  not_null_tables_cache= (args[0]->not_null_tables() |
			  args[1]->not_null_tables());
unknown's avatar
unknown committed
2221 2222 2223 2224
  const_item_cache=args[0]->const_item() && args[1]->const_item();
  if (!regex_compiled && args[1]->const_item())
  {
    char buff[MAX_FIELD_WIDTH];
2225
    String tmp(buff,sizeof(buff),&my_charset_bin);
unknown's avatar
unknown committed
2226 2227 2228 2229 2230 2231 2232 2233
    String *res=args[1]->val_str(&tmp);
    if (args[1]->null_value)
    {						// Will always return NULL
      maybe_null=1;
      return 0;
    }
    int error;
    if ((error=regcomp(&preg,res->c_ptr(),
2234 2235
		       (cmp_collation.collation->state & MY_CS_BINSORT) ?
		       REG_EXTENDED | REG_NOSUB :
2236
		       REG_EXTENDED | REG_NOSUB | REG_ICASE,
2237
		       cmp_collation.collation)))
unknown's avatar
unknown committed
2238 2239 2240 2241 2242 2243 2244 2245 2246 2247
    {
      (void) regerror(error,&preg,buff,sizeof(buff));
      my_printf_error(ER_REGEXP_ERROR,ER(ER_REGEXP_ERROR),MYF(0),buff);
      return 1;
    }
    regex_compiled=regex_is_const=1;
    maybe_null=args[0]->maybe_null;
  }
  else
    maybe_null=1;
2248
  fixed= 1;
unknown's avatar
unknown committed
2249 2250 2251
  return 0;
}

2252

unknown's avatar
unknown committed
2253 2254
longlong Item_func_regex::val_int()
{
2255
  DBUG_ASSERT(fixed == 1);
unknown's avatar
unknown committed
2256
  char buff[MAX_FIELD_WIDTH];
2257
  String *res, tmp(buff,sizeof(buff),&my_charset_bin);
unknown's avatar
unknown committed
2258 2259 2260 2261 2262 2263 2264 2265 2266 2267

  res=args[0]->val_str(&tmp);
  if (args[0]->null_value)
  {
    null_value=1;
    return 0;
  }
  if (!regex_is_const)
  {
    char buff2[MAX_FIELD_WIDTH];
2268
    String *res2, tmp2(buff2,sizeof(buff2),&my_charset_bin);
unknown's avatar
unknown committed
2269 2270 2271 2272 2273 2274 2275

    res2= args[1]->val_str(&tmp2);
    if (args[1]->null_value)
    {
      null_value=1;
      return 0;
    }
unknown's avatar
unknown committed
2276
    if (!regex_compiled || stringcmp(res2,&prev_regexp))
unknown's avatar
unknown committed
2277 2278 2279 2280 2281 2282 2283 2284
    {
      prev_regexp.copy(*res2);
      if (regex_compiled)
      {
	regfree(&preg);
	regex_compiled=0;
      }
      if (regcomp(&preg,res2->c_ptr(),
2285 2286
		  (cmp_collation.collation->state & MY_CS_BINSORT) ?
		  REG_EXTENDED | REG_NOSUB :
2287
		  REG_EXTENDED | REG_NOSUB | REG_ICASE,
2288
		  cmp_collation.collation))
unknown's avatar
unknown committed
2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310
      {
	null_value=1;
	return 0;
      }
      regex_compiled=1;
    }
  }
  null_value=0;
  return regexec(&preg,res->c_ptr(),0,(regmatch_t*) 0,0) ? 0 : 1;
}


Item_func_regex::~Item_func_regex()
{
  if (regex_compiled)
  {
    regfree(&preg);
    regex_compiled=0;
  }
}

#endif /* USE_REGEX */
2311 2312 2313


#ifdef LIKE_CMP_TOUPPER
unknown's avatar
unknown committed
2314
#define likeconv(cs,A) (uchar) (cs)->toupper(A)
2315
#else
unknown's avatar
unknown committed
2316
#define likeconv(cs,A) (uchar) (cs)->sort_order[(uchar) (A)]
2317 2318 2319 2320 2321 2322 2323 2324
#endif


/**********************************************************************
  turboBM_compute_suffixes()
  Precomputation dependent only on pattern_len.
**********************************************************************/

2325
void Item_func_like::turboBM_compute_suffixes(int *suff)
2326 2327 2328 2329
{
  const int   plm1 = pattern_len - 1;
  int            f = 0;
  int            g = plm1;
unknown's avatar
unknown committed
2330
  int *const splm1 = suff + plm1;
2331
  CHARSET_INFO	*cs= cmp.cmp_collation.collation;
2332 2333 2334

  *splm1 = pattern_len;

2335
  if (cs == &my_charset_bin)
2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366
  {
    int i;
    for (i = pattern_len - 2; i >= 0; i--)
    {
      int tmp = *(splm1 + i - f);
      if (g < i && tmp < i - g)
	suff[i] = tmp;
      else
      {
	if (i < g)
	  g = i; // g = min(i, g)
	f = i;
	while (g >= 0 && pattern[g] == pattern[g + plm1 - f])
	  g--;
	suff[i] = f - g;
      }
    }
  }
  else
  {
    int i;
    for (i = pattern_len - 2; 0 <= i; --i)
    {
      int tmp = *(splm1 + i - f);
      if (g < i && tmp < i - g)
	suff[i] = tmp;
      else
      {
	if (i < g)
	  g = i; // g = min(i, g)
	f = i;
2367
	while (g >= 0 &&
unknown's avatar
unknown committed
2368
	       likeconv(cs, pattern[g]) == likeconv(cs, pattern[g + plm1 - f]))
2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381
	  g--;
	suff[i] = f - g;
      }
    }
  }
}


/**********************************************************************
   turboBM_compute_good_suffix_shifts()
   Precomputation dependent only on pattern_len.
**********************************************************************/

2382
void Item_func_like::turboBM_compute_good_suffix_shifts(int *suff)
2383 2384 2385
{
  turboBM_compute_suffixes(suff);

2386 2387
  int *end = bmGs + pattern_len;
  int *k;
2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400
  for (k = bmGs; k < end; k++)
    *k = pattern_len;

  int tmp;
  int i;
  int j          = 0;
  const int plm1 = pattern_len - 1;
  for (i = plm1; i > -1; i--)
  {
    if (suff[i] == i + 1)
    {
      for (tmp = plm1 - i; j < tmp; j++)
      {
2401
	int *tmp2 = bmGs + j;
2402 2403 2404 2405 2406 2407
	if (*tmp2 == pattern_len)
	  *tmp2 = tmp;
      }
    }
  }

2408
  int *tmp2;
2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428
  for (tmp = plm1 - i; j < tmp; j++)
  {
    tmp2 = bmGs + j;
    if (*tmp2 == pattern_len)
      *tmp2 = tmp;
  }

  tmp2 = bmGs + plm1;
  for (i = 0; i <= pattern_len - 2; i++)
    *(tmp2 - suff[i]) = plm1 - i;
}


/**********************************************************************
   turboBM_compute_bad_character_shifts()
   Precomputation dependent on pattern_len.
**********************************************************************/

void Item_func_like::turboBM_compute_bad_character_shifts()
{
unknown's avatar
unknown committed
2429 2430 2431 2432
  int *i;
  int *end = bmBc + alphabet_size;
  int j;
  const int plm1 = pattern_len - 1;
2433
  CHARSET_INFO	*cs= cmp.cmp_collation.collation;
unknown's avatar
unknown committed
2434

2435 2436 2437
  for (i = bmBc; i < end; i++)
    *i = pattern_len;

2438
  if (cs == &my_charset_bin)
unknown's avatar
unknown committed
2439
  {
2440
    for (j = 0; j < plm1; j++)
2441
      bmBc[(uint) (uchar) pattern[j]] = plm1 - j;
unknown's avatar
unknown committed
2442
  }
2443
  else
unknown's avatar
unknown committed
2444
  {
2445
    for (j = 0; j < plm1; j++)
unknown's avatar
unknown committed
2446
      bmBc[(uint) likeconv(cs,pattern[j])] = plm1 - j;
unknown's avatar
unknown committed
2447
  }
2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462
}


/**********************************************************************
  turboBM_matches()
  Search for pattern in text, returns true/false for match/no match
**********************************************************************/

bool Item_func_like::turboBM_matches(const char* text, int text_len) const
{
  register int bcShift;
  register int turboShift;
  int shift = pattern_len;
  int j     = 0;
  int u     = 0;
2463
  CHARSET_INFO	*cs= cmp.cmp_collation.collation;
2464

2465 2466
  const int plm1=  pattern_len - 1;
  const int tlmpl= text_len - pattern_len;
2467 2468

  /* Searching */
2469
  if (cs == &my_charset_bin)
2470 2471 2472
  {
    while (j <= tlmpl)
    {
2473
      register int i= plm1;
2474 2475 2476 2477
      while (i >= 0 && pattern[i] == text[i + j])
      {
	i--;
	if (i == plm1 - shift)
2478
	  i-= u;
2479 2480
      }
      if (i < 0)
unknown's avatar
unknown committed
2481
	return 1;
2482 2483 2484

      register const int v = plm1 - i;
      turboShift = u - v;
2485
      bcShift    = bmBc[(uint) (uchar) text[i + j]] - plm1 + i;
2486 2487 2488 2489 2490 2491 2492 2493 2494 2495
      shift      = max(turboShift, bcShift);
      shift      = max(shift, bmGs[i]);
      if (shift == bmGs[i])
	u = min(pattern_len - shift, v);
      else
      {
	if (turboShift < bcShift)
	  shift = max(shift, u + 1);
	u = 0;
      }
2496
      j+= shift;
2497
    }
unknown's avatar
unknown committed
2498
    return 0;
2499 2500 2501 2502 2503 2504
  }
  else
  {
    while (j <= tlmpl)
    {
      register int i = plm1;
unknown's avatar
unknown committed
2505
      while (i >= 0 && likeconv(cs,pattern[i]) == likeconv(cs,text[i + j]))
2506 2507 2508
      {
	i--;
	if (i == plm1 - shift)
2509
	  i-= u;
2510 2511
      }
      if (i < 0)
unknown's avatar
unknown committed
2512
	return 1;
2513 2514 2515

      register const int v = plm1 - i;
      turboShift = u - v;
unknown's avatar
unknown committed
2516
      bcShift    = bmBc[(uint) likeconv(cs, text[i + j])] - plm1 + i;
2517 2518 2519 2520 2521 2522 2523 2524 2525 2526
      shift      = max(turboShift, bcShift);
      shift      = max(shift, bmGs[i]);
      if (shift == bmGs[i])
	u = min(pattern_len - shift, v);
      else
      {
	if (turboShift < bcShift)
	  shift = max(shift, u + 1);
	u = 0;
      }
2527
      j+= shift;
2528
    }
unknown's avatar
unknown committed
2529
    return 0;
2530 2531
  }
}
unknown's avatar
unknown committed
2532

2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553

/*
  Make a logical XOR of the arguments.

  SYNOPSIS
    val_int()

  DESCRIPTION
  If either operator is NULL, return NULL.

  NOTE
    As we don't do any index optimization on XOR this is not going to be
    very fast to use.

  TODO (low priority)
    Change this to be optimized as:
      A XOR B   ->  (A) == 1 AND (B) <> 1) OR (A <> 1 AND (B) == 1)
    To be able to do this, we would however first have to extend the MySQL
    range optimizer to handle OR better.
*/

unknown's avatar
unknown committed
2554 2555
longlong Item_cond_xor::val_int()
{
2556
  DBUG_ASSERT(fixed == 1);
unknown's avatar
unknown committed
2557 2558 2559
  List_iterator<Item> li(list);
  Item *item;
  int result=0;	
2560
  null_value=0;
unknown's avatar
unknown committed
2561 2562
  while ((item=li++))
  {
2563 2564 2565 2566 2567 2568
    result^= (item->val_int() != 0);
    if (item->null_value)
    {
      null_value=1;
      return 0;
    }
unknown's avatar
unknown committed
2569
  }
2570
  return (longlong) result;
unknown's avatar
unknown committed
2571
}
2572 2573 2574 2575 2576 2577

/*
  Apply NOT transformation to the item and return a new one.

  SYNPOSIS
    neg_transformer()
2578
    thd		thread handler
2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600 2601

  DESCRIPTION
    Transform the item using next rules:
       a AND b AND ...    -> NOT(a) OR NOT(b) OR ...
       a OR b OR ...      -> NOT(a) AND NOT(b) AND ...
       NOT(a)             -> a
       a = b              -> a != b
       a != b             -> a = b
       a < b              -> a >= b
       a >= b             -> a < b
       a > b              -> a <= b
       a <= b             -> a > b
       IS NULL(a)         -> IS NOT NULL(a)
       IS NOT NULL(a)     -> IS NULL(a)

  NOTE
    This method is used in the eliminate_not_funcs() function.

  RETURN
    New item or
    NULL if we cannot apply NOT transformation (see Item::neg_transformer()).
*/

2602
Item *Item_func_not::neg_transformer(THD *thd)	/* NOT(x)  ->  x */
2603
{
2604 2605
  // We should apply negation elimination to the argument of the NOT function
  return eliminate_not_funcs(thd, args[0]);
2606 2607
}

2608 2609

Item *Item_bool_rowready_func2::neg_transformer(THD *thd)
2610
{
2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624
  Item *item= negated_item();
  if (item)
  {
    /*
      We can use 0 as tables list because Item_func* family do not use it
      on fix_fields and its arguments are already fixed.
      
      We do not check results of fix_fields, because there are not way
      to return error in this functions interface, thd->net.report_error
      will be checked on upper level call.
    */
    item->fix_fields(thd, 0, &item);
  }
  return item;
2625 2626
}

2627 2628 2629

/* a IS NULL  ->  a IS NOT NULL */
Item *Item_func_isnull::neg_transformer(THD *thd)
2630
{
2631 2632 2633 2634 2635
  Item *item= new Item_func_isnotnull(args[0]);
  // see comment before fix_fields in Item_bool_rowready_func2::neg_transformer
  if (item)
    item->fix_fields(thd, 0, &item);
  return item;
2636 2637
}

2638 2639 2640

/* a IS NOT NULL  ->  a IS NULL */
Item *Item_func_isnotnull::neg_transformer(THD *thd)
2641
{
2642 2643 2644 2645 2646
  Item *item= new Item_func_isnull(args[0]);
  // see comment before fix_fields in Item_bool_rowready_func2::neg_transformer
  if (item)
    item->fix_fields(thd, 0, &item);
  return item;
2647 2648
}

2649 2650 2651

Item *Item_cond_and::neg_transformer(THD *thd)	/* NOT(a AND b AND ...)  -> */
					/* NOT a OR NOT b OR ... */
2652
{
2653 2654 2655 2656 2657 2658
  neg_arguments(thd);
  Item *item= new Item_cond_or(list);
  // see comment before fix_fields in Item_bool_rowready_func2::neg_transformer
  if (item)
    item->fix_fields(thd, 0, &item);
  return item;
2659 2660
}

2661 2662 2663

Item *Item_cond_or::neg_transformer(THD *thd)	/* NOT(a OR b OR ...)  -> */
					/* NOT a AND NOT b AND ... */
2664
{
2665 2666 2667 2668 2669 2670
  neg_arguments(thd);
  Item *item= new Item_cond_and(list);
  // see comment before fix_fields in Item_bool_rowready_func2::neg_transformer
  if (item)
    item->fix_fields(thd, 0, &item);
  return item;
2671 2672
}

2673 2674

Item *Item_func_eq::negated_item()		/* a = b  ->  a != b */
2675
{
2676
  return new Item_func_ne(args[0], args[1]);
2677 2678
}

2679 2680

Item *Item_func_ne::negated_item()		/* a != b  ->  a = b */
2681
{
2682
  return new Item_func_eq(args[0], args[1]);
2683 2684
}

2685 2686

Item *Item_func_lt::negated_item()		/* a < b  ->  a >= b */
2687
{
2688
  return new Item_func_ge(args[0], args[1]);
2689 2690
}

2691 2692

Item *Item_func_ge::negated_item()		/* a >= b  ->  a < b */
2693
{
2694
  return new Item_func_lt(args[0], args[1]);
2695 2696
}

2697 2698

Item *Item_func_gt::negated_item()		/* a > b  ->  a <= b */
2699
{
2700
  return new Item_func_le(args[0], args[1]);
2701 2702
}

2703 2704

Item *Item_func_le::negated_item()		/* a <= b  ->  a > b */
2705
{
2706
  return new Item_func_gt(args[0], args[1]);
2707 2708
}

2709 2710
// just fake method, should never be called
Item *Item_bool_rowready_func2::negated_item()
2711
{
2712 2713
  DBUG_ASSERT(0);
  return 0;
2714
}