item_cmpfunc.cc 121 KB
Newer Older
unknown's avatar
unknown committed
1
/* Copyright (C) 2000-2006 MySQL AB
unknown's avatar
unknown committed
2

unknown's avatar
unknown committed
3 4
   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
unknown's avatar
unknown committed
5
   the Free Software Foundation; version 2 of the License.
unknown's avatar
unknown committed
6

unknown's avatar
unknown committed
7 8 9 10
   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
11

unknown's avatar
unknown committed
12 13 14 15 16 17 18
   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 */

19
#ifdef USE_PRAGMA_IMPLEMENTATION
unknown's avatar
unknown committed
20 21 22 23 24
#pragma implementation				// gcc: Class implementation
#endif

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

27 28
static bool convert_constant_item(THD *thd, Field *field, Item **item);

29 30
static Item_result item_store_type(Item_result a, Item *item,
                                   my_bool unsigned_flag)
31
{
32 33
  Item_result b= item->result_type();

34 35 36 37
  if (a == STRING_RESULT || b == STRING_RESULT)
    return STRING_RESULT;
  else if (a == REAL_RESULT || b == REAL_RESULT)
    return REAL_RESULT;
38 39
  else if (a == DECIMAL_RESULT || b == DECIMAL_RESULT ||
           unsigned_flag != item->unsigned_flag)
unknown's avatar
unknown committed
40
    return DECIMAL_RESULT;
41 42 43 44 45 46
  else
    return INT_RESULT;
}

static void agg_result_type(Item_result *type, Item **items, uint nitems)
{
47
  Item **item, **item_end;
48
  my_bool unsigned_flag= 0;
49 50 51 52

  *type= STRING_RESULT;
  /* Skip beginning NULL items */
  for (item= items, item_end= item + nitems; item < item_end; item++)
53
  {
54 55 56
    if ((*item)->type() != Item::NULL_ITEM)
    {
      *type= (*item)->result_type();
57
      unsigned_flag= (*item)->unsigned_flag;
58 59 60
      item++;
      break;
    }
61 62
  }
  /* Combine result types. Note: NULL items don't affect the result */
63
  for (; item < item_end; item++)
64
  {
65
    if ((*item)->type() != Item::NULL_ITEM)
66
      *type= item_store_type(*type, *item, unsigned_flag);
67
  }
68 69
}

70

71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
/*
  Compare row signature of two expressions

  SYNOPSIS:
    cmp_row_type()
    item1          the first expression
    item2         the second expression

  DESCRIPTION
    The function checks that two expressions have compatible row signatures
    i.e. that the number of columns they return are the same and that if they
    are both row expressions then each component from the first expression has 
    a row signature compatible with the signature of the corresponding component
    of the second expression.

  RETURN VALUES
    1  type incompatibility has been detected
    0  otherwise
*/

static int cmp_row_type(Item* item1, Item* item2)
{
  uint n= item1->cols();
  if (item2->check_cols(n))
    return 1;
  for (uint i=0; i<n; i++)
  {
unknown's avatar
unknown committed
98 99 100
    if (item2->element_index(i)->check_cols(item1->element_index(i)->cols()) ||
        (item1->element_index(i)->result_type() == ROW_RESULT &&
         cmp_row_type(item1->element_index(i), item2->element_index(i))))
101 102 103 104 105 106
      return 1;
  }
  return 0;
}


107 108 109 110 111
/*
  Aggregates result types from the array of items.

  SYNOPSIS:
    agg_cmp_type()
112
    thd          thread handle
113 114 115 116 117 118 119 120
    type   [out] the aggregated type
    items        array of items to aggregate the type from
    nitems       number of items in the array

  DESCRIPTION
    This function aggregates result types from the array of items. Found type
    supposed to be used later for comparison of values of these items.
    Aggregation itself is performed by the item_cmp_type() function.
121 122 123 124 125 126
    The function also checks compatibility of row signatures for the
    submitted items (see the spec for the cmp_row_type function). 

  RETURN VALUES
    1  type incompatibility has been detected
    0  otherwise
127 128
*/

129
static int agg_cmp_type(THD *thd, Item_result *type, Item **items, uint nitems)
130 131
{
  uint i;
132 133
  type[0]= items[0]->result_type();
  for (i= 1 ; i < nitems ; i++)
134
  {
135
    type[0]= item_cmp_type(type[0], items[i]->result_type());
136 137 138 139 140 141 142 143 144 145 146
    /*
      When aggregating types of two row expressions we have to check
      that they have the same cardinality and that each component
      of the first row expression has a compatible row signature with
      the signature of the corresponding component of the second row
      expression.
    */ 
    if (type[0] == ROW_RESULT && cmp_row_type(items[0], items[i]))
      return 1;     // error found: invalid usage of rows
  }
  return 0;
147 148
}

149

unknown's avatar
unknown committed
150 151
static void my_coll_agg_error(DTCollation &c1, DTCollation &c2,
                              const char *fname)
152
{
153 154 155 156
  my_error(ER_CANT_AGGREGATE_2COLLATIONS, MYF(0),
           c1.collation->name,c1.derivation_name(),
           c2.collation->name,c2.derivation_name(),
           fname);
157 158
}

unknown's avatar
unknown committed
159 160

Item_bool_func2* Eq_creator::create(Item *a, Item *b) const
unknown's avatar
unknown committed
161 162 163
{
  return new Item_func_eq(a, b);
}
unknown's avatar
unknown committed
164 165 166


Item_bool_func2* Ne_creator::create(Item *a, Item *b) const
unknown's avatar
unknown committed
167 168 169
{
  return new Item_func_ne(a, b);
}
unknown's avatar
unknown committed
170 171 172


Item_bool_func2* Gt_creator::create(Item *a, Item *b) const
unknown's avatar
unknown committed
173 174 175
{
  return new Item_func_gt(a, b);
}
unknown's avatar
unknown committed
176 177 178


Item_bool_func2* Lt_creator::create(Item *a, Item *b) const
unknown's avatar
unknown committed
179 180 181
{
  return new Item_func_lt(a, b);
}
unknown's avatar
unknown committed
182 183 184


Item_bool_func2* Ge_creator::create(Item *a, Item *b) const
unknown's avatar
unknown committed
185 186 187
{
  return new Item_func_ge(a, b);
}
unknown's avatar
unknown committed
188 189 190


Item_bool_func2* Le_creator::create(Item *a, Item *b) const
unknown's avatar
unknown committed
191 192 193
{
  return new Item_func_le(a, b);
}
unknown's avatar
unknown committed
194

unknown's avatar
unknown committed
195
/*
196
  Test functions
197 198
  Most of these  returns 0LL if false and 1LL if true and
  NULL if some arg is NULL.
unknown's avatar
unknown committed
199 200 201 202
*/

longlong Item_func_not::val_int()
{
203
  DBUG_ASSERT(fixed == 1);
unknown's avatar
unknown committed
204
  bool value= args[0]->val_bool();
unknown's avatar
unknown committed
205
  null_value=args[0]->null_value;
206
  return ((!null_value && value == 0) ? 1 : 0);
unknown's avatar
unknown committed
207 208
}

209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224
/*
  We put any NOT expression into parenthesis to avoid
  possible problems with internal view representations where
  any '!' is converted to NOT. It may cause a problem if
  '!' is used in an expression together with other operators
  whose precedence is lower than the precedence of '!' yet
  higher than the precedence of NOT.
*/

void Item_func_not::print(String *str)
{
  str->append('(');
  Item_func::print(str);
  str->append(')');
}

225 226 227 228 229
/*
  special NOT for ALL subquery
*/

longlong Item_func_not_all::val_int()
230 231
{
  DBUG_ASSERT(fixed == 1);
unknown's avatar
unknown committed
232
  bool value= args[0]->val_bool();
233 234

  /*
unknown's avatar
unknown committed
235 236
    return TRUE if there was records in underlying select in max/min
    optimization (ALL subquery)
237 238 239 240
  */
  if (empty_underlying_subquery())
    return 1;

241
  null_value= args[0]->null_value;
242 243 244 245 246 247 248 249
  return ((!null_value && value == 0) ? 1 : 0);
}


bool Item_func_not_all::empty_underlying_subquery()
{
  return ((test_sum_item && !test_sum_item->any_value()) ||
          (test_sub_item && !test_sub_item->any_value()));
250 251
}

unknown's avatar
unknown committed
252 253 254 255 256 257 258 259
void Item_func_not_all::print(String *str)
{
  if (show)
    Item_func::print(str);
  else
    args[0]->print(str);
}

260 261

/*
unknown's avatar
unknown committed
262
  Special NOP (No OPeration) for ALL subquery it is like  Item_func_not_all
unknown's avatar
unknown committed
263
  (return TRUE if underlying subquery do not return rows) but if subquery
unknown's avatar
unknown committed
264
  returns some rows it return same value as argument (TRUE/FALSE).
265 266 267 268 269
*/

longlong Item_func_nop_all::val_int()
{
  DBUG_ASSERT(fixed == 1);
unknown's avatar
unknown committed
270
  longlong value= args[0]->val_int();
271 272

  /*
unknown's avatar
unknown committed
273 274
    return FALSE if there was records in underlying select in max/min
    optimization (SAME/ANY subquery)
275 276
  */
  if (empty_underlying_subquery())
unknown's avatar
unknown committed
277
    return 0;
278 279 280 281 282 283

  null_value= args[0]->null_value;
  return (null_value || value == 0) ? 0 : 1;
}


unknown's avatar
unknown committed
284
/*
285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306
  Convert a constant item to an int and replace the original item

  SYNOPSIS
    convert_constant_item()
    thd             thread handle
    field           item will be converted using the type of this field
    item  [in/out]  reference to the item to convert

  DESCRIPTION
    The function converts a constant expression or string to an integer.
    On successful conversion the original item is substituted for the
    result of the item evaluation.
    This is done when comparing DATE/TIME of different formats and
    also when comparing bigint to strings (in which case strings
    are converted to bigints).

  NOTES
    This function is called only at prepare stage.
    As all derived tables are filled only after all derived tables
    are prepared we do not evaluate items with subselects here because
    they can contain derived tables and thus we may attempt to use a
    table that has not been populated yet.
unknown's avatar
unknown committed
307 308 309 310

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

313
static bool convert_constant_item(THD *thd, Field *field, Item **item)
unknown's avatar
unknown committed
314
{
315
  if (!(*item)->with_subselect && (*item)->const_item())
unknown's avatar
unknown committed
316
  {
317
    /* For comparison purposes allow invalid dates like 2000-01-32 */
unknown's avatar
unknown committed
318
    ulong orig_sql_mode= thd->variables.sql_mode;
319 320
    thd->variables.sql_mode= (orig_sql_mode & ~MODE_NO_ZERO_DATE) | 
                             MODE_INVALID_DATES;
unknown's avatar
unknown committed
321
    if (!(*item)->save_in_field(field, 1) && !((*item)->null_value))
unknown's avatar
unknown committed
322
    {
unknown's avatar
unknown committed
323 324
      Item *tmp=new Item_int_with_ref(field->val_int(), *item,
                                      test(field->flags & UNSIGNED_FLAG));
unknown's avatar
unknown committed
325
      thd->variables.sql_mode= orig_sql_mode;
326
      if (tmp)
327
        thd->change_item_tree(item, tmp);
328
      return 1;					// Item was replaced
unknown's avatar
unknown committed
329
    }
unknown's avatar
unknown committed
330
    thd->variables.sql_mode= orig_sql_mode;
unknown's avatar
unknown committed
331 332 333 334
  }
  return 0;
}

unknown's avatar
unknown committed
335

336 337 338
void Item_bool_func2::fix_length_and_dec()
{
  max_length= 1;				     // Function returns 0 or 1
339
  THD *thd;
340 341 342 343 344 345 346

  /*
    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;
347 348 349 350 351 352 353 354 355 356 357 358 359

  /* 
    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.
  */

360
  
361 362 363
  DTCollation coll;
  if (args[0]->result_type() == STRING_RESULT &&
      args[1]->result_type() == STRING_RESULT &&
364
      agg_arg_charsets(coll, args, 2, MY_COLL_CMP_CONV, 1))
unknown's avatar
unknown committed
365
    return;
366
    
367 368
  args[0]->cmp_context= args[1]->cmp_context=
    item_cmp_type(args[0]->result_type(), args[1]->result_type());
unknown's avatar
unknown committed
369
  // Make a special case of compare with fields to get nicer DATE comparisons
unknown's avatar
unknown committed
370 371 372 373 374 375

  if (functype() == LIKE_FUNC)  // Disable conversion in case of LIKE function.
  {
    set_cmp_func();
    return;
  }
376

377
  thd= current_thd;
378
  if (!thd->is_context_analysis_only())
unknown's avatar
unknown committed
379
  {
380 381
    Item *arg_real_item= args[0]->real_item();
    if (arg_real_item->type() == FIELD_ITEM)
unknown's avatar
unknown committed
382
    {
383
      Field *field=((Item_field*) arg_real_item)->field;
384 385 386
      if (field->can_be_compared_as_longlong() &&
          !(arg_real_item->is_datetime() &&
            args[1]->result_type() == STRING_RESULT))
unknown's avatar
unknown committed
387
      {
388 389 390 391
        if (convert_constant_item(thd, field,&args[1]))
        {
          cmp.set_cmp_func(this, tmp_arg, tmp_arg+1,
                           INT_RESULT);		// Works for all types.
392
          args[0]->cmp_context= args[1]->cmp_context= INT_RESULT;
393 394
          return;
        }
unknown's avatar
unknown committed
395 396
      }
    }
397 398
    arg_real_item= args[1]->real_item();
    if (arg_real_item->type() == FIELD_ITEM)
unknown's avatar
unknown committed
399
    {
400
      Field *field=((Item_field*) arg_real_item)->field;
401 402 403
      if (field->can_be_compared_as_longlong() &&
          !(arg_real_item->is_datetime() &&
            args[0]->result_type() == STRING_RESULT))
unknown's avatar
unknown committed
404
      {
405 406 407 408
        if (convert_constant_item(thd, field,&args[0]))
        {
          cmp.set_cmp_func(this, tmp_arg, tmp_arg+1,
                           INT_RESULT); // Works for all types.
409
          args[0]->cmp_context= args[1]->cmp_context= INT_RESULT;
410 411
          return;
        }
unknown's avatar
unknown committed
412 413 414
      }
    }
  }
415
  set_cmp_func();
unknown's avatar
unknown committed
416 417
}

418

419
int Arg_comparator::set_compare_func(Item_bool_func2 *item, Item_result type)
unknown's avatar
unknown committed
420
{
421
  owner= item;
unknown's avatar
unknown committed
422 423
  func= comparator_matrix[type]
                         [test(owner->functype() == Item_func::EQUAL_FUNC)];
unknown's avatar
unknown committed
424
  switch (type) {
unknown's avatar
unknown committed
425
  case ROW_RESULT:
unknown's avatar
unknown committed
426
  {
427 428
    uint n= (*a)->cols();
    if (n != (*b)->cols())
429
    {
unknown's avatar
unknown committed
430
      my_error(ER_OPERAND_COLUMNS, MYF(0), n);
431 432 433
      comparators= 0;
      return 1;
    }
434
    if (!(comparators= new Arg_comparator[n]))
unknown's avatar
unknown committed
435 436 437
      return 1;
    for (uint i=0; i < n; i++)
    {
438
      if ((*a)->element_index(i)->cols() != (*b)->element_index(i)->cols())
unknown's avatar
unknown committed
439
      {
440
	my_error(ER_OPERAND_COLUMNS, MYF(0), (*a)->element_index(i)->cols());
unknown's avatar
unknown committed
441
	return 1;
unknown's avatar
unknown committed
442
      }
unknown's avatar
unknown committed
443 444
      comparators[i].set_cmp_func(owner, (*a)->addr(i), (*b)->addr(i));
    }
unknown's avatar
unknown committed
445
    break;
446
  }
unknown's avatar
unknown committed
447
  case STRING_RESULT:
448 449 450 451 452
  {
    /*
      We must set cmp_charset here as we may be called from for an automatic
      generated item, like in natural join
    */
453 454
    if (cmp_collation.set((*a)->collation, (*b)->collation) || 
	cmp_collation.derivation == DERIVATION_NONE)
455 456 457 458
    {
      my_coll_agg_error((*a)->collation, (*b)->collation, owner->func_name());
      return 1;
    }
459
    if (cmp_collation.collation == &my_charset_bin)
unknown's avatar
unknown committed
460 461
    {
      /*
462
	We are using BLOB/BINARY/VARBINARY, change to compare byte by byte,
unknown's avatar
unknown committed
463 464 465 466 467 468
	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;
unknown's avatar
unknown committed
469 470

      /*
unknown's avatar
unknown committed
471
        As this is binary compassion, mark all fields that they can't be
unknown's avatar
unknown committed
472 473 474 475 476 477
        transformed. Otherwise we would get into trouble with comparisons
        like:
        WHERE col= 'j' AND col LIKE BINARY 'j'
        which would be transformed to:
        WHERE col= 'j'
      */
478 479
      (*a)->walk(&Item::set_no_const_sub, (byte*) 0);
      (*b)->walk(&Item::set_no_const_sub, (byte*) 0);
unknown's avatar
unknown committed
480
    }
unknown's avatar
unknown committed
481
    break;
482
  }
unknown's avatar
unknown committed
483
  case INT_RESULT:
484
  {
485
    if (func == &Arg_comparator::compare_int_signed)
486 487
    {
      if ((*a)->unsigned_flag)
unknown's avatar
unknown committed
488 489 490
        func= (((*b)->unsigned_flag)?
               &Arg_comparator::compare_int_unsigned :
               &Arg_comparator::compare_int_unsigned_signed);
491 492 493
      else if ((*b)->unsigned_flag)
        func= &Arg_comparator::compare_int_signed_unsigned;
    }
494 495 496 497 498
    else if (func== &Arg_comparator::compare_e_int)
    {
      if ((*a)->unsigned_flag ^ (*b)->unsigned_flag)
        func= &Arg_comparator::compare_e_int_diff_signedness;
    }
unknown's avatar
unknown committed
499 500 501 502 503
    break;
  }
  case DECIMAL_RESULT:
    break;
  case REAL_RESULT:
504 505 506 507 508 509 510 511 512
  {
    if ((*a)->decimals < NOT_FIXED_DEC && (*b)->decimals < NOT_FIXED_DEC)
    {
      precision= 5 * log_01[max((*a)->decimals, (*b)->decimals)];
      if (func == &Arg_comparator::compare_real)
        func= &Arg_comparator::compare_real_fixed;
      else if (func == &Arg_comparator::compare_e_real)
        func= &Arg_comparator::compare_e_real_fixed;
    }
unknown's avatar
unknown committed
513
    break;
unknown's avatar
unknown committed
514
  }
unknown's avatar
unknown committed
515 516
  default:
    DBUG_ASSERT(0);
517
  }
518
  return 0;
unknown's avatar
unknown committed
519
}
unknown's avatar
unknown committed
520

unknown's avatar
unknown committed
521

522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547
/*
  Convert date provided in a string to the int representation.

  SYNOPSIS
    get_date_from_str()
    thd              Thread handle
    str              a string to convert
    warn_type        type of the timestamp for issuing the warning
    warn_name        field name for issuing the warning
    error_arg  [out] TRUE if string isn't a DATETIME or clipping occur

  DESCRIPTION
    Convert date provided in the string str to the int representation.
    if the string contains wrong date or doesn't contain it at all
    then the warning is issued and TRUE returned in the error_arg argument.
    The warn_type and the warn_name arguments are used as the name and the
    type of the field when issuing the warning.

  RETURN
    converted value.
*/

static ulonglong
get_date_from_str(THD *thd, String *str, timestamp_type warn_type,
                  char *warn_name, bool *error_arg)
{
unknown's avatar
unknown committed
548
  ulonglong value= 0;
549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635
  int error;
  MYSQL_TIME l_time;
  enum_mysql_timestamp_type ret;
  *error_arg= TRUE;

  ret= str_to_datetime(str->ptr(), str->length(), &l_time,
                       (TIME_FUZZY_DATE | MODE_INVALID_DATES |
                        (thd->variables.sql_mode &
                         (MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE))),
                       &error);
  if ((ret == MYSQL_TIMESTAMP_DATETIME || ret == MYSQL_TIMESTAMP_DATE))
  {
    value= TIME_to_ulonglong_datetime(&l_time);
    *error_arg= FALSE;
  }

  if (error || *error_arg)
  {
    make_truncated_value_warning(thd, str->ptr(), str->length(), warn_type,
                                 warn_name);
    *error_arg= TRUE;
  }
  return value;
}


/*
  Check whether compare_datetime() can be used to compare items.

  SYNOPSIS
    Arg_comparator::can_compare_as_dates()
    a, b          [in]  items to be compared
    const_value   [out] converted value of the string constant, if any

  DESCRIPTION
    Check several cases when the DATE/DATETIME comparator should be used.
    The following cases are checked:
      1. Both a and b is a DATE/DATETIME field/function returning string or
         int result.
      2. Only a or b is a DATE/DATETIME field/function returning string or
         int result and the other item (b or a) is an item with string result.
         If the second item is a constant one then it's checked to be
         convertible to the DATE/DATETIME type. If the constant can't be
         converted to a DATE/DATETIME then the compare_datetime() comparator
         isn't used and the warning about wrong DATE/DATETIME value is issued.
      In all other cases (date-[int|real|decimal]/[int|real|decimal]-date)
      the comparison is handled by other comparators.
    If the datetime comparator can be used and one the operands of the
    comparison is a string constant that was successfully converted to a
    DATE/DATETIME type then the result of the conversion is returned in the
    const_value if it is provided.  If there is no constant or
    compare_datetime() isn't applicable then the *const_value remains
    unchanged.

  RETURN
    the found type of date comparison
*/

enum Arg_comparator::enum_date_cmp_type
Arg_comparator::can_compare_as_dates(Item *a, Item *b, ulonglong *const_value)
{
  enum enum_date_cmp_type cmp_type= CMP_DATE_DFLT;
  Item *str_arg= 0, *date_arg= 0;

  if (a->type() == Item::ROW_ITEM || b->type() == Item::ROW_ITEM)
    return CMP_DATE_DFLT;

  if (a->is_datetime())
  {
    if (b->is_datetime())
      cmp_type= CMP_DATE_WITH_DATE;
    else if (b->result_type() == STRING_RESULT)
    {
      cmp_type= CMP_DATE_WITH_STR;
      date_arg= a;
      str_arg= b;
    }
  }
  else if (b->is_datetime() && a->result_type() == STRING_RESULT)
  {
    cmp_type= CMP_STR_WITH_DATE;
    date_arg= b;
    str_arg= a;
  }

  if (cmp_type != CMP_DATE_DFLT)
  {
636 637 638 639 640 641 642
    /*
      Do not cache GET_USER_VAR() function as its const_item() may return TRUE
      for the current thread but it still may change during the execution.
    */
    if (cmp_type != CMP_DATE_WITH_DATE && str_arg->const_item() &&
        (str_arg->type() != Item::FUNC_ITEM ||
        ((Item_func*)str_arg)->functype() != Item_func::GUSERVAR_FUNC))
643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669
    {
      THD *thd= current_thd;
      ulonglong value;
      bool error;
      String tmp, *str_val= 0;
      timestamp_type t_type= (date_arg->field_type() == MYSQL_TYPE_DATE ?
                              MYSQL_TIMESTAMP_DATE : MYSQL_TIMESTAMP_DATETIME);

      str_val= str_arg->val_str(&tmp);
      if (str_arg->null_value)
        return CMP_DATE_DFLT;
      value= get_date_from_str(thd, str_val, t_type, date_arg->name, &error);
      if (error)
        return CMP_DATE_DFLT;
      if (const_value)
        *const_value= value;
    }
  }
  return cmp_type;
}


int Arg_comparator::set_cmp_func(Item_bool_func2 *owner_arg,
                                        Item **a1, Item **a2,
                                        Item_result type)
{
  enum enum_date_cmp_type cmp_type;
670
  ulonglong const_value= (ulonglong)-1;
671 672 673 674 675 676 677 678 679 680 681 682
  a= a1;
  b= a2;

  if ((cmp_type= can_compare_as_dates(*a, *b, &const_value)))
  {
    thd= current_thd;
    owner= owner_arg;
    a_type= (*a)->field_type();
    b_type= (*b)->field_type();
    a_cache= 0;
    b_cache= 0;

683
    if (const_value != (ulonglong)-1)
684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700
    {
      Item_cache_int *cache= new Item_cache_int();
      /* Mark the cache as non-const to prevent re-caching. */
      cache->set_used_tables(1);
      if (!(*a)->is_datetime())
      {
        cache->store((*a), const_value);
        a_cache= cache;
        a= (Item **)&a_cache;
      }
      else
      {
        cache->store((*b), const_value);
        b_cache= cache;
        b= (Item **)&b_cache;
      }
    }
701
    is_nulls_eq= test(owner && owner->functype() == Item_func::EQUAL_FUNC);
702 703 704 705 706 707 708
    func= &Arg_comparator::compare_datetime;
    return 0;
  }
  return set_compare_func(owner_arg, type);
}


709 710 711 712 713 714 715 716 717 718 719 720 721 722 723
void Arg_comparator::set_datetime_cmp_func(Item **a1, Item **b1)
{
  thd= current_thd;
  /* A caller will handle null values by itself. */
  owner= NULL;
  a= a1;
  b= b1;
  a_type= (*a)->field_type();
  b_type= (*b)->field_type();
  a_cache= 0;
  b_cache= 0;
  is_nulls_eq= FALSE;
  func= &Arg_comparator::compare_datetime;
}

724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752
/*
  Retrieves correct DATETIME value from given item.

  SYNOPSIS
    get_datetime_value()
    thd                 thread handle
    item_arg   [in/out] item to retrieve DATETIME value from
    cache_arg  [in/out] pointer to place to store the caching item to
    warn_item  [in]     item for issuing the conversion warning
    is_null    [out]    TRUE <=> the item_arg is null

  DESCRIPTION
    Retrieves the correct DATETIME value from given item for comparison by the
    compare_datetime() function.
    If item's result can be compared as longlong then its int value is used
    and its string value is used otherwise. Strings are always parsed and
    converted to int values by the get_date_from_str() function.
    This allows us to compare correctly string dates with missed insignificant
    zeros. If an item is a constant one then its value is cached and it isn't
    get parsed again. An Item_cache_int object is used for caching values. It
    seamlessly substitutes the original item.  The cache item is marked as
    non-constant to prevent re-caching it again.  In order to compare
    correctly DATE and DATETIME items the result of the former are treated as
    a DATETIME with zero time (00:00:00).

  RETURN
    obtained value
*/

753
ulonglong
754 755 756
get_datetime_value(THD *thd, Item ***item_arg, Item **cache_arg,
                   Item *warn_item, bool *is_null)
{
unknown's avatar
unknown committed
757
  ulonglong value= 0;
758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788
  String buf, *str= 0;
  Item *item= **item_arg;

  if (item->result_as_longlong())
  {
    value= item->val_int();
    *is_null= item->null_value;
    if (item->field_type() == MYSQL_TYPE_DATE)
      value*= 1000000L;
  }
  else
  {
    str= item->val_str(&buf);
    *is_null= item->null_value;
  }
  if (*is_null)
    return -1;
  /*
    Convert strings to the integer DATE/DATETIME representation.
    Even if both dates provided in strings we can't compare them directly as
    strings as there is no warranty that they are correct and do not miss
    some insignificant zeros.
  */
  if (str)
  {
    bool error;
    enum_field_types f_type= warn_item->field_type();
    timestamp_type t_type= f_type ==
      MYSQL_TYPE_DATE ? MYSQL_TIMESTAMP_DATE : MYSQL_TIMESTAMP_DATETIME;
    value= get_date_from_str(thd, str, t_type, warn_item->name, &error);
  }
789 790 791 792 793 794
  /*
    Do not cache GET_USER_VAR() function as its const_item() may return TRUE
    for the current thread but it still may change during the execution.
  */
  if (item->const_item() && cache_arg && (item->type() != Item::FUNC_ITEM ||
      ((Item_func*)item)->functype() != Item_func::GUSERVAR_FUNC))
795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835
  {
    Item_cache_int *cache= new Item_cache_int();
    /* Mark the cache as non-const to prevent re-caching. */
    cache->set_used_tables(1);
    cache->store(item, value);
    *cache_arg= cache;
    *item_arg= cache_arg;
  }
  return value;
}

/*
  Compare items values as dates.

  SYNOPSIS
    Arg_comparator::compare_datetime()

  DESCRIPTION
    Compare items values as DATE/DATETIME for both EQUAL_FUNC and from other
    comparison functions. The correct DATETIME values are obtained
    with help of the get_datetime_value() function.

  RETURN
    If is_nulls_eq is TRUE:
       1    if items are equal or both are null
       0    otherwise
    If is_nulls_eq is FALSE:
      -1   a < b or one of items is null
       0   a == b
       1   a > b
*/

int Arg_comparator::compare_datetime()
{
  bool is_null= FALSE;
  ulonglong a_value, b_value;

  /* Get DATE/DATETIME value of the 'a' item. */
  a_value= get_datetime_value(thd, &a, &a_cache, *b, &is_null);
  if (!is_nulls_eq && is_null)
  {
836 837
    if (owner)
      owner->null_value= 1;
838 839 840 841 842 843 844
    return -1;
  }

  /* Get DATE/DATETIME value of the 'b' item. */
  b_value= get_datetime_value(thd, &b, &b_cache, *a, &is_null);
  if (is_null)
  {
845 846
    if (owner)
      owner->null_value= is_nulls_eq ? 0 : 1;
847 848 849
    return is_nulls_eq ? 1 : -1;
  }

850 851
  if (owner)
    owner->null_value= 0;
852 853 854 855 856 857 858 859

  /* Compare values. */
  if (is_nulls_eq)
    return (a_value == b_value);
  return a_value < b_value ? -1 : (a_value > b_value ? 1 : 0);
}


860
int Arg_comparator::compare_string()
unknown's avatar
unknown committed
861 862
{
  String *res1,*res2;
863
  if ((res1= (*a)->val_str(&owner->tmp_value1)))
unknown's avatar
unknown committed
864
  {
865
    if ((res2= (*b)->val_str(&owner->tmp_value2)))
unknown's avatar
unknown committed
866
    {
unknown's avatar
unknown committed
867
      owner->null_value= 0;
868
      return sortcmp(res1,res2,cmp_collation.collation);
unknown's avatar
unknown committed
869 870
    }
  }
unknown's avatar
unknown committed
871
  owner->null_value= 1;
unknown's avatar
unknown committed
872 873 874
  return -1;
}

unknown's avatar
unknown committed
875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907

/*
  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
908 909 910
int Arg_comparator::compare_e_string()
{
  String *res1,*res2;
911 912
  res1= (*a)->val_str(&owner->tmp_value1);
  res2= (*b)->val_str(&owner->tmp_value2);
unknown's avatar
unknown committed
913 914
  if (!res1 || !res2)
    return test(res1 == res2);
915
  return test(sortcmp(res1, res2, cmp_collation.collation) == 0);
unknown's avatar
unknown committed
916 917 918
}


unknown's avatar
unknown committed
919 920 921 922 923 924 925 926 927 928 929
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);
}


930
int Arg_comparator::compare_real()
unknown's avatar
unknown committed
931
{
932 933 934 935 936 937
  /*
    Fix yet another manifestation of Bug#2338. 'Volatile' will instruct
    gcc to flush double values out of 80-bit Intel FPU registers before
    performing the comparison.
  */
  volatile double val1, val2;
unknown's avatar
Merge  
unknown committed
938
  val1= (*a)->val_real();
939
  if (!(*a)->null_value)
unknown's avatar
unknown committed
940
  {
unknown's avatar
Merge  
unknown committed
941
    val2= (*b)->val_real();
942
    if (!(*b)->null_value)
unknown's avatar
unknown committed
943
    {
unknown's avatar
unknown committed
944
      owner->null_value= 0;
unknown's avatar
unknown committed
945 946 947 948 949
      if (val1 < val2)	return -1;
      if (val1 == val2) return 0;
      return 1;
    }
  }
unknown's avatar
unknown committed
950
  owner->null_value= 1;
unknown's avatar
unknown committed
951 952 953
  return -1;
}

unknown's avatar
unknown committed
954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971
int Arg_comparator::compare_decimal()
{
  my_decimal value1;
  my_decimal *val1= (*a)->val_decimal(&value1);
  if (!(*a)->null_value)
  {
    my_decimal value2;
    my_decimal *val2= (*b)->val_decimal(&value2);
    if (!(*b)->null_value)
    {
      owner->null_value= 0;
      return my_decimal_cmp(val1, val2);
    }
  }
  owner->null_value= 1;
  return -1;
}

unknown's avatar
unknown committed
972 973
int Arg_comparator::compare_e_real()
{
974 975
  double val1= (*a)->val_real();
  double val2= (*b)->val_real();
976 977
  if ((*a)->null_value || (*b)->null_value)
    return test((*a)->null_value && (*b)->null_value);
unknown's avatar
unknown committed
978 979
  return test(val1 == val2);
}
unknown's avatar
unknown committed
980

unknown's avatar
unknown committed
981 982 983 984 985 986 987 988 989 990
int Arg_comparator::compare_e_decimal()
{
  my_decimal value1, value2;
  my_decimal *val1= (*a)->val_decimal(&value1);
  my_decimal *val2= (*b)->val_decimal(&value2);
  if ((*a)->null_value || (*b)->null_value)
    return test((*a)->null_value && (*b)->null_value);
  return test(my_decimal_cmp(val1, val2) == 0);
}

991 992 993 994 995 996 997 998 999

int Arg_comparator::compare_real_fixed()
{
  /*
    Fix yet another manifestation of Bug#2338. 'Volatile' will instruct
    gcc to flush double values out of 80-bit Intel FPU registers before
    performing the comparison.
  */
  volatile double val1, val2;
unknown's avatar
unknown committed
1000
  val1= (*a)->val_real();
1001 1002
  if (!(*a)->null_value)
  {
unknown's avatar
unknown committed
1003
    val2= (*b)->val_real();
1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020
    if (!(*b)->null_value)
    {
      owner->null_value= 0;
      if (val1 == val2 || fabs(val1 - val2) < precision)
        return 0;
      if (val1 < val2)
        return -1;
      return 1;
    }
  }
  owner->null_value= 1;
  return -1;
}


int Arg_comparator::compare_e_real_fixed()
{
unknown's avatar
unknown committed
1021 1022
  double val1= (*a)->val_real();
  double val2= (*b)->val_real();
1023 1024 1025 1026 1027 1028
  if ((*a)->null_value || (*b)->null_value)
    return test((*a)->null_value && (*b)->null_value);
  return test(val1 == val2 || fabs(val1 - val2) < precision);
}


1029
int Arg_comparator::compare_int_signed()
unknown's avatar
unknown committed
1030
{
1031 1032
  longlong val1= (*a)->val_int();
  if (!(*a)->null_value)
unknown's avatar
unknown committed
1033
  {
1034 1035
    longlong val2= (*b)->val_int();
    if (!(*b)->null_value)
unknown's avatar
unknown committed
1036
    {
unknown's avatar
unknown committed
1037
      owner->null_value= 0;
unknown's avatar
unknown committed
1038 1039 1040 1041 1042
      if (val1 < val2)	return -1;
      if (val1 == val2)   return 0;
      return 1;
    }
  }
unknown's avatar
unknown committed
1043
  owner->null_value= 1;
unknown's avatar
unknown committed
1044 1045 1046
  return -1;
}

1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 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 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122

/*
  Compare values as BIGINT UNSIGNED.
*/

int Arg_comparator::compare_int_unsigned()
{
  ulonglong val1= (*a)->val_int();
  if (!(*a)->null_value)
  {
    ulonglong val2= (*b)->val_int();
    if (!(*b)->null_value)
    {
      owner->null_value= 0;
      if (val1 < val2)	return -1;
      if (val1 == val2)   return 0;
      return 1;
    }
  }
  owner->null_value= 1;
  return -1;
}


/*
  Compare signed (*a) with unsigned (*B)
*/

int Arg_comparator::compare_int_signed_unsigned()
{
  longlong sval1= (*a)->val_int();
  if (!(*a)->null_value)
  {
    ulonglong uval2= (ulonglong)(*b)->val_int();
    if (!(*b)->null_value)
    {
      owner->null_value= 0;
      if (sval1 < 0 || (ulonglong)sval1 < uval2)
        return -1;
      if ((ulonglong)sval1 == uval2)
        return 0;
      return 1;
    }
  }
  owner->null_value= 1;
  return -1;
}


/*
  Compare unsigned (*a) with signed (*B)
*/

int Arg_comparator::compare_int_unsigned_signed()
{
  ulonglong uval1= (ulonglong)(*a)->val_int();
  if (!(*a)->null_value)
  {
    longlong sval2= (*b)->val_int();
    if (!(*b)->null_value)
    {
      owner->null_value= 0;
      if (sval2 < 0)
        return 1;
      if (uval1 < (ulonglong)sval2)
        return -1;
      if (uval1 == (ulonglong)sval2)
        return 0;
      return 1;
    }
  }
  owner->null_value= 1;
  return -1;
}


unknown's avatar
unknown committed
1123 1124
int Arg_comparator::compare_e_int()
{
1125 1126 1127 1128
  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
1129 1130 1131
  return test(val1 == val2);
}

1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142
/*
  Compare unsigned *a with signed *b or signed *a with unsigned *b.
*/
int Arg_comparator::compare_e_int_diff_signedness()
{
  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);
  return (val1 >= 0) && test(val1 == val2);
}
unknown's avatar
unknown committed
1143

1144
int Arg_comparator::compare_row()
unknown's avatar
unknown committed
1145 1146
{
  int res= 0;
1147
  bool was_null= 0;
1148 1149
  (*a)->bring_value();
  (*b)->bring_value();
1150
  uint n= (*a)->cols();
unknown's avatar
unknown committed
1151
  for (uint i= 0; i<n; i++)
unknown's avatar
unknown committed
1152
  {
1153
    res= comparators[i].compare();
unknown's avatar
unknown committed
1154
    if (owner->null_value)
1155 1156
    {
      // NULL was compared
1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168
      switch (owner->functype()) {
      case Item_func::NE_FUNC:
        break; // NE never aborts on NULL even if abort_on_null is set
      case Item_func::LT_FUNC:
      case Item_func::LE_FUNC:
      case Item_func::GT_FUNC:
      case Item_func::GE_FUNC:
        return -1; // <, <=, > and >= always fail on NULL
      default: // EQ_FUNC
        if (owner->abort_on_null)
          return -1; // We do not need correct NULL returning
      }
1169 1170 1171 1172
      was_null= 1;
      owner->null_value= 0;
      res= 0;  // continue comparison (maybe we will meet explicit difference)
    }
1173
    else if (res)
1174
      return res;
unknown's avatar
unknown committed
1175
  }
1176 1177 1178
  if (was_null)
  {
    /*
1179 1180
      There was NULL(s) in comparison in some parts, but there was no
      explicit difference in other parts, so we have to return NULL.
1181 1182 1183 1184 1185
    */
    owner->null_value= 1;
    return -1;
  }
  return 0;
unknown's avatar
unknown committed
1186
}
unknown's avatar
unknown committed
1187

1188

unknown's avatar
unknown committed
1189 1190
int Arg_comparator::compare_e_row()
{
1191 1192
  (*a)->bring_value();
  (*b)->bring_value();
1193
  uint n= (*a)->cols();
unknown's avatar
unknown committed
1194 1195
  for (uint i= 0; i<n; i++)
  {
unknown's avatar
unknown committed
1196
    if (!comparators[i].compare())
1197
      return 0;
unknown's avatar
unknown committed
1198 1199 1200 1201
  }
  return 1;
}

1202

1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255
void Item_func_truth::fix_length_and_dec()
{
  maybe_null= 0;
  null_value= 0;
  decimals= 0;
  max_length= 1;
}


void Item_func_truth::print(String *str)
{
  str->append('(');
  args[0]->print(str);
  str->append(STRING_WITH_LEN(" is "));
  if (! affirmative)
    str->append(STRING_WITH_LEN("not "));
  if (value)
    str->append(STRING_WITH_LEN("true"));
  else
    str->append(STRING_WITH_LEN("false"));
  str->append(')');
}


bool Item_func_truth::val_bool()
{
  bool val= args[0]->val_bool();
  if (args[0]->null_value)
  {
    /*
      NULL val IS {TRUE, FALSE} --> FALSE
      NULL val IS NOT {TRUE, FALSE} --> TRUE
    */
    return (! affirmative);
  }

  if (affirmative)
  {
    /* {TRUE, FALSE} val IS {TRUE, FALSE} value */
    return (val == value);
  }

  /* {TRUE, FALSE} val IS NOT {TRUE, FALSE} value */
  return (val != value);
}


longlong Item_func_truth::val_int()
{
  return (val_bool() ? 1 : 0);
}


1256
bool Item_in_optimizer::fix_left(THD *thd, Item **ref)
unknown's avatar
unknown committed
1257
{
1258
  if (!args[0]->fixed && args[0]->fix_fields(thd, args) ||
unknown's avatar
unknown committed
1259
      !cache && !(cache= Item_cache::get_cache(args[0]->result_type())))
1260
    return 1;
1261

1262
  cache->setup(args[0]);
1263
  if (cache->cols() == 1)
1264
  {
unknown's avatar
unknown committed
1265
    if ((used_tables_cache= args[0]->used_tables()))
unknown's avatar
unknown committed
1266
      cache->set_used_tables(OUTER_REF_TABLE_BIT);
1267 1268 1269
    else
      cache->set_used_tables(0);
  }
1270 1271 1272 1273
  else
  {
    uint n= cache->cols();
    for (uint i= 0; i < n; i++)
1274
    {
1275 1276
      if (args[0]->element_index(i)->used_tables())
	((Item_cache *)cache->element_index(i))->set_used_tables(OUTER_REF_TABLE_BIT);
1277
      else
1278
	((Item_cache *)cache->element_index(i))->set_used_tables(0);
1279
    }
unknown's avatar
unknown committed
1280
    used_tables_cache= args[0]->used_tables();
1281
  }
unknown's avatar
unknown committed
1282 1283 1284
  not_null_tables_cache= args[0]->not_null_tables();
  with_sum_func= args[0]->with_sum_func;
  const_item_cache= args[0]->const_item();
1285 1286 1287 1288
  return 0;
}


1289
bool Item_in_optimizer::fix_fields(THD *thd, Item **ref)
1290
{
1291
  DBUG_ASSERT(fixed == 0);
1292
  if (fix_left(thd, ref))
unknown's avatar
unknown committed
1293
    return TRUE;
1294 1295 1296
  if (args[0]->maybe_null)
    maybe_null=1;

1297
  if (!args[1]->fixed && args[1]->fix_fields(thd, args+1))
unknown's avatar
unknown committed
1298
    return TRUE;
unknown's avatar
unknown committed
1299 1300 1301
  Item_in_subselect * sub= (Item_in_subselect *)args[1];
  if (args[0]->cols() != sub->engine->cols())
  {
unknown's avatar
unknown committed
1302
    my_error(ER_OPERAND_COLUMNS, MYF(0), args[0]->cols());
unknown's avatar
unknown committed
1303
    return TRUE;
unknown's avatar
unknown committed
1304
  }
1305 1306 1307 1308
  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
1309
  not_null_tables_cache|= args[1]->not_null_tables();
1310
  const_item_cache&= args[1]->const_item();
1311
  fixed= 1;
unknown's avatar
unknown committed
1312
  return FALSE;
1313 1314
}

1315

1316 1317
longlong Item_in_optimizer::val_int()
{
1318
  bool tmp;
1319
  DBUG_ASSERT(fixed == 1);
1320
  cache->store(args[0]);
1321
  
1322
  if (cache->null_value)
1323
  {
1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348
    if (((Item_in_subselect*)args[1])->is_top_level_item())
    {
      /*
        We're evaluating "NULL IN (SELECT ...)". The result can be NULL or
        FALSE, and we can return one instead of another. Just return NULL.
      */
      null_value= 1;
    }
    else
    {
      if (!((Item_in_subselect*)args[1])->is_correlated &&
          result_for_null_param != UNKNOWN)
      {
        /* Use cached value from previous execution */
        null_value= result_for_null_param;
      }
      else
      {
        /*
          We're evaluating "NULL IN (SELECT ...)". The result is:
             FALSE if SELECT produces an empty set, or
             NULL  otherwise.
          We disable the predicates we've pushed down into subselect, run the
          subselect and see if it has produced any rows.
        */
1349 1350 1351 1352
        Item_in_subselect *item_subs=(Item_in_subselect*)args[1]; 
        if (cache->cols() == 1)
        {
          item_subs->set_cond_guard_var(0, FALSE);
1353
          (void) args[1]->val_bool_result();
1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366
          result_for_null_param= null_value= !item_subs->engine->no_rows();
          item_subs->set_cond_guard_var(0, TRUE);
        }
        else
        {
          uint i;
          uint ncols= cache->cols();
          /*
            Turn off the predicates that are based on column compares for
            which the left part is currently NULL
          */
          for (i= 0; i < ncols; i++)
          {
unknown's avatar
unknown committed
1367
            if (cache->element_index(i)->null_value)
1368 1369 1370
              item_subs->set_cond_guard_var(i, FALSE);
          }
          
1371
          (void) args[1]->val_bool_result();
1372 1373 1374 1375 1376 1377
          result_for_null_param= null_value= !item_subs->engine->no_rows();
          
          /* Turn all predicates back on */
          for (i= 0; i < ncols; i++)
            item_subs->set_cond_guard_var(i, TRUE);
        }
1378 1379
      }
    }
1380 1381
    return 0;
  }
1382
  tmp= args[1]->val_bool_result();
unknown's avatar
unknown committed
1383
  null_value= args[1]->null_value;
1384 1385 1386
  return tmp;
}

1387 1388 1389 1390 1391 1392 1393 1394

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


unknown's avatar
unknown committed
1395 1396 1397 1398
void Item_in_optimizer::cleanup()
{
  DBUG_ENTER("Item_in_optimizer::cleanup");
  Item_bool_func::cleanup();
1399 1400
  if (!save_cache)
    cache= 0;
unknown's avatar
unknown committed
1401 1402 1403
  DBUG_VOID_RETURN;
}

1404

1405
bool Item_in_optimizer::is_null()
1406
{
1407 1408
  cache->store(args[0]);
  return (null_value= (cache->null_value || args[1]->is_null()));
1409
}
unknown's avatar
unknown committed
1410

1411

unknown's avatar
unknown committed
1412 1413
longlong Item_func_eq::val_int()
{
1414
  DBUG_ASSERT(fixed == 1);
1415
  int value= cmp.compare();
unknown's avatar
unknown committed
1416 1417 1418
  return value == 0 ? 1 : 0;
}

1419

unknown's avatar
unknown committed
1420 1421
/* Same as Item_func_eq, but NULL = NULL */

unknown's avatar
unknown committed
1422 1423 1424 1425 1426 1427
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
1428 1429
longlong Item_func_equal::val_int()
{
1430
  DBUG_ASSERT(fixed == 1);
1431
  return cmp.compare();
unknown's avatar
unknown committed
1432 1433 1434 1435
}

longlong Item_func_ne::val_int()
{
1436
  DBUG_ASSERT(fixed == 1);
1437
  int value= cmp.compare();
1438
  return value != 0 && !null_value ? 1 : 0;
unknown's avatar
unknown committed
1439 1440 1441 1442 1443
}


longlong Item_func_ge::val_int()
{
1444
  DBUG_ASSERT(fixed == 1);
1445
  int value= cmp.compare();
unknown's avatar
unknown committed
1446 1447 1448 1449 1450 1451
  return value >= 0 ? 1 : 0;
}


longlong Item_func_gt::val_int()
{
1452
  DBUG_ASSERT(fixed == 1);
1453
  int value= cmp.compare();
unknown's avatar
unknown committed
1454 1455 1456 1457 1458
  return value > 0 ? 1 : 0;
}

longlong Item_func_le::val_int()
{
1459
  DBUG_ASSERT(fixed == 1);
1460
  int value= cmp.compare();
unknown's avatar
unknown committed
1461 1462 1463 1464 1465 1466
  return value <= 0 && !null_value ? 1 : 0;
}


longlong Item_func_lt::val_int()
{
1467
  DBUG_ASSERT(fixed == 1);
1468
  int value= cmp.compare();
unknown's avatar
unknown committed
1469 1470 1471 1472 1473 1474
  return value < 0 && !null_value ? 1 : 0;
}


longlong Item_func_strcmp::val_int()
{
1475
  DBUG_ASSERT(fixed == 1);
unknown's avatar
unknown committed
1476 1477 1478 1479 1480 1481 1482
  String *a=args[0]->val_str(&tmp_value1);
  String *b=args[1]->val_str(&tmp_value2);
  if (!a || !b)
  {
    null_value=1;
    return 0;
  }
1483
  int value= sortcmp(a,b,cmp.cmp_collation.collation);
unknown's avatar
unknown committed
1484 1485 1486 1487 1488
  null_value=0;
  return !value ? 0 : (value < 0 ? (longlong) -1 : (longlong) 1);
}


1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508
bool Item_func_opt_neg::eq(const Item *item, bool binary_cmp) const
{
  /* Assume we don't have rtti */
  if (this == item)
    return 1;
  if (item->type() != FUNC_ITEM)
    return 0;
  Item_func *item_func=(Item_func*) item;
  if (arg_count != item_func->arg_count ||
      functype() != item_func->functype())
    return 0;
  if (negated != ((Item_func_opt_neg *) item_func)->negated)
    return 0;
  for (uint i=0; i < arg_count ; i++)
    if (!args[i]->eq(item_func->arguments()[i], binary_cmp))
      return 0;
  return 1;
}


unknown's avatar
unknown committed
1509 1510
void Item_func_interval::fix_length_and_dec()
{
1511 1512
  use_decimal_comparison= (row->element_index(0)->result_type() == DECIMAL_RESULT) ||
    (row->element_index(0)->result_type() == INT_RESULT);
1513
  if (row->cols() > 8)
unknown's avatar
unknown committed
1514
  {
1515 1516 1517
    bool consts=1;

    for (uint i=1 ; consts && i < row->cols() ; i++)
unknown's avatar
unknown committed
1518
    {
1519
      consts&= row->element_index(i)->const_item();
unknown's avatar
unknown committed
1520
    }
1521 1522

    if (consts &&
unknown's avatar
unknown committed
1523 1524
        (intervals=
          (interval_range*) sql_alloc(sizeof(interval_range)*(row->cols()-1))))
unknown's avatar
unknown committed
1525
    {
unknown's avatar
unknown committed
1526 1527 1528 1529
      if (use_decimal_comparison)
      {
        for (uint i=1 ; i < row->cols(); i++)
        {
1530
          Item *el= row->element_index(i);
unknown's avatar
unknown committed
1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554
          interval_range *range= intervals + (i-1);
          if ((el->result_type() == DECIMAL_RESULT) ||
              (el->result_type() == INT_RESULT))
          {
            range->type= DECIMAL_RESULT;
            range->dec.init();
            my_decimal *dec= el->val_decimal(&range->dec);
            if (dec != &range->dec)
            {
              range->dec= *dec;
              range->dec.fix_buffer_pointer();
            }
          }
          else
          {
            range->type= REAL_RESULT;
            range->dbl= el->val_real();
          }
        }
      }
      else
      {
        for (uint i=1 ; i < row->cols(); i++)
        {
1555
          intervals[i-1].dbl= row->element_index(i)->val_real();
unknown's avatar
unknown committed
1556 1557
        }
      }
unknown's avatar
unknown committed
1558 1559
    }
  }
unknown's avatar
unknown committed
1560 1561
  maybe_null= 0;
  max_length= 2;
1562
  used_tables_cache|= row->used_tables();
unknown's avatar
unknown committed
1563
  not_null_tables_cache= row->not_null_tables();
1564
  with_sum_func= with_sum_func || row->with_sum_func;
unknown's avatar
unknown committed
1565
  const_item_cache&= row->const_item();
unknown's avatar
unknown committed
1566 1567
}

unknown's avatar
unknown committed
1568

unknown's avatar
unknown committed
1569
/*
unknown's avatar
unknown committed
1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583
  Execute Item_func_interval()

  SYNOPSIS
    Item_func_interval::val_int()

  NOTES
    If we are doing a decimal comparison, we are
    evaluating the first item twice.

  RETURN
    -1 if null value,
    0 if lower than lowest
    1 - arg_count-1 if between args[n] and args[n+1]
    arg_count if higher than biggest argument
unknown's avatar
unknown committed
1584 1585 1586 1587
*/

longlong Item_func_interval::val_int()
{
1588
  DBUG_ASSERT(fixed == 1);
1589
  double value;
unknown's avatar
unknown committed
1590
  my_decimal dec_buf, *dec= NULL;
unknown's avatar
unknown committed
1591 1592
  uint i;

unknown's avatar
unknown committed
1593 1594
  if (use_decimal_comparison)
  {
1595 1596
    dec= row->element_index(0)->val_decimal(&dec_buf);
    if (row->element_index(0)->null_value)
1597 1598 1599 1600 1601
      return -1;
    my_decimal2double(E_DEC_FATAL_ERROR, dec, &value);
  }
  else
  {
1602 1603
    value= row->element_index(0)->val_real();
    if (row->element_index(0)->null_value)
1604
      return -1;
unknown's avatar
unknown committed
1605
  }
unknown's avatar
unknown committed
1606

unknown's avatar
unknown committed
1607 1608 1609
  if (intervals)
  {					// Use binary search to find interval
    uint start,end;
1610
    start= 0;
unknown's avatar
unknown committed
1611
    end=   row->cols()-2;
unknown's avatar
unknown committed
1612 1613
    while (start != end)
    {
unknown's avatar
unknown committed
1614
      uint mid= (start + end + 1) / 2;
unknown's avatar
unknown committed
1615 1616
      interval_range *range= intervals + mid;
      my_bool cmp_result;
unknown's avatar
unknown committed
1617 1618 1619 1620 1621
      /*
        The values in the range intervall may have different types,
        Only do a decimal comparision of the first argument is a decimal
        and we are comparing against a decimal
      */
unknown's avatar
unknown committed
1622 1623 1624 1625 1626
      if (dec && range->type == DECIMAL_RESULT)
        cmp_result= my_decimal_cmp(&range->dec, dec) <= 0;
      else
        cmp_result= (range->dbl <= value);
      if (cmp_result)
unknown's avatar
unknown committed
1627
	start= mid;
unknown's avatar
unknown committed
1628
      else
unknown's avatar
unknown committed
1629
	end= mid - 1;
unknown's avatar
unknown committed
1630
    }
unknown's avatar
unknown committed
1631 1632
    interval_range *range= intervals+start;
    return ((dec && range->type == DECIMAL_RESULT) ?
unknown's avatar
unknown committed
1633
            my_decimal_cmp(dec, &range->dec) < 0 :
unknown's avatar
unknown committed
1634
            value < range->dbl) ? 0 : start + 1;
unknown's avatar
unknown committed
1635
  }
1636 1637

  for (i=1 ; i < row->cols() ; i++)
unknown's avatar
unknown committed
1638
  {
1639
    Item *el= row->element_index(i);
unknown's avatar
unknown committed
1640 1641 1642 1643
    if (use_decimal_comparison &&
        ((el->result_type() == DECIMAL_RESULT) ||
         (el->result_type() == INT_RESULT)))
    {
1644
      my_decimal e_dec_buf, *e_dec= row->element_index(i)->val_decimal(&e_dec_buf);
unknown's avatar
unknown committed
1645 1646 1647
      if (my_decimal_cmp(e_dec, dec) > 0)
        return i-1;
    }
1648
    else if (row->element_index(i)->val_real() > value)
unknown's avatar
unknown committed
1649
      return i-1;
unknown's avatar
unknown committed
1650
  }
1651
  return i-1;
unknown's avatar
unknown committed
1652 1653
}

unknown's avatar
unknown committed
1654

unknown's avatar
unknown committed
1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683
/*
  Perform context analysis of a BETWEEN item tree

  SYNOPSIS:
    fix_fields()
    thd     reference to the global context of the query thread
    tables  list of all open tables involved in the query
    ref     pointer to Item* variable where pointer to resulting "fixed"
            item is to be assigned

  DESCRIPTION
    This function performs context analysis (name resolution) and calculates
    various attributes of the item tree with Item_func_between as its root.
    The function saves in ref the pointer to the item or to a newly created
    item that is considered as a replacement for the original one.

  NOTES
    Let T0(e)/T1(e) be the value of not_null_tables(e) when e is used on
    a predicate/function level. Then it's easy to show that:
      T0(e BETWEEN e1 AND e2)     = union(T1(e),T1(e1),T1(e2))
      T1(e BETWEEN e1 AND e2)     = union(T1(e),intersection(T1(e1),T1(e2)))
      T0(e NOT BETWEEN e1 AND e2) = union(T1(e),intersection(T1(e1),T1(e2)))
      T1(e NOT BETWEEN e1 AND e2) = union(T1(e),intersection(T1(e1),T1(e2)))

  RETURN
    0   ok
    1   got error
*/

unknown's avatar
unknown committed
1684
bool Item_func_between::fix_fields(THD *thd, Item **ref)
unknown's avatar
unknown committed
1685
{
1686
  if (Item_func_opt_neg::fix_fields(thd, ref))
unknown's avatar
unknown committed
1687 1688
    return 1;

1689 1690
  thd->lex->current_select->between_count++;

unknown's avatar
unknown committed
1691 1692 1693 1694 1695
  /* not_null_tables_cache == union(T1(e),T1(e1),T1(e2)) */
  if (pred_level && !negated)
    return 0;

  /* not_null_tables_cache == union(T1(e), intersection(T1(e1),T1(e2))) */
unknown's avatar
unknown committed
1696 1697 1698
  not_null_tables_cache= (args[0]->not_null_tables() |
                          (args[1]->not_null_tables() &
                           args[2]->not_null_tables()));
unknown's avatar
unknown committed
1699 1700 1701 1702 1703

  return 0;
}


unknown's avatar
unknown committed
1704 1705
void Item_func_between::fix_length_and_dec()
{
1706 1707 1708 1709 1710
  max_length= 1;
  THD *thd= current_thd;
  int i;
  bool datetime_found= FALSE;
  compare_as_dates= TRUE;
unknown's avatar
unknown committed
1711

1712 1713
  /*
    As some compare functions are generated after sql_yacc,
unknown's avatar
unknown committed
1714
    we have to check for out of memory conditions here
1715
  */
unknown's avatar
unknown committed
1716 1717
  if (!args[0] || !args[1] || !args[2])
    return;
1718 1719
  if ( agg_cmp_type(thd, &cmp_type, args, 3))
    return;
unknown's avatar
unknown committed
1720
  if (cmp_type == STRING_RESULT &&
1721
      agg_arg_charsets(cmp_collation, args, 3, MY_COLL_CMP_CONV, 1))
unknown's avatar
unknown committed
1722
   return;
1723

unknown's avatar
unknown committed
1724
  /*
1725 1726 1727
    Detect the comparison of DATE/DATETIME items.
    At least one of items should be a DATE/DATETIME item and other items
    should return the STRING result.
unknown's avatar
unknown committed
1728
  */
1729
  for (i= 0; i < 3; i++)
unknown's avatar
unknown committed
1730
  {
1731
    if (args[i]->is_datetime())
unknown's avatar
unknown committed
1732
    {
1733 1734
      datetime_found= TRUE;
      continue;
unknown's avatar
unknown committed
1735
    }
1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747
    if (args[i]->result_type() == STRING_RESULT)
      continue;
    compare_as_dates= FALSE;
    break;
  }
  if (!datetime_found)
    compare_as_dates= FALSE;

  if (compare_as_dates)
  {
    ge_cmp.set_datetime_cmp_func(args, args + 1);
    le_cmp.set_datetime_cmp_func(args, args + 2);
unknown's avatar
unknown committed
1748
  }
unknown's avatar
unknown committed
1749 1750 1751 1752 1753
}


longlong Item_func_between::val_int()
{						// ANSI BETWEEN
1754
  DBUG_ASSERT(fixed == 1);
1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775
  if (compare_as_dates)
  {
    int ge_res, le_res;

    ge_res= ge_cmp.compare();
    if ((null_value= args[0]->null_value))
      return 0;
    le_res= le_cmp.compare();

    if (!args[1]->null_value && !args[2]->null_value)
      return (longlong) ((ge_res >= 0 && le_res <=0) != negated);
    else if (args[1]->null_value)
    {
      null_value= le_res > 0;			// not null if false range.
    }
    else
    {
      null_value= ge_res < 0;
    }
  }
  else if (cmp_type == STRING_RESULT)
unknown's avatar
unknown committed
1776 1777 1778 1779 1780 1781 1782 1783
  {
    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)
unknown's avatar
unknown committed
1784 1785 1786
      return (longlong) ((sortcmp(value,a,cmp_collation.collation) >= 0 &&
                          sortcmp(value,b,cmp_collation.collation) <= 0) !=
                         negated);
unknown's avatar
unknown committed
1787 1788 1789 1790
    if (args[1]->null_value && args[2]->null_value)
      null_value=1;
    else if (args[1]->null_value)
    {
unknown's avatar
unknown committed
1791 1792
      // Set to not null if false range.
      null_value= sortcmp(value,b,cmp_collation.collation) <= 0;
unknown's avatar
unknown committed
1793 1794 1795
    }
    else
    {
unknown's avatar
unknown committed
1796 1797
      // Set to not null if false range.
      null_value= sortcmp(value,a,cmp_collation.collation) >= 0;
unknown's avatar
unknown committed
1798 1799 1800 1801
    }
  }
  else if (cmp_type == INT_RESULT)
  {
1802
    longlong value=args[0]->val_int(), a, b;
unknown's avatar
unknown committed
1803
    if ((null_value=args[0]->null_value))
1804
      return 0;					/* purecov: inspected */
unknown's avatar
unknown committed
1805 1806 1807
    a=args[1]->val_int();
    b=args[2]->val_int();
    if (!args[1]->null_value && !args[2]->null_value)
unknown's avatar
unknown committed
1808
      return (longlong) ((value >= a && value <= b) != negated);
unknown's avatar
unknown committed
1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819
    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;
    }
  }
unknown's avatar
unknown committed
1820 1821 1822 1823 1824 1825 1826 1827 1828
  else if (cmp_type == DECIMAL_RESULT)
  {
    my_decimal dec_buf, *dec= args[0]->val_decimal(&dec_buf),
               a_buf, *a_dec, b_buf, *b_dec;
    if ((null_value=args[0]->null_value))
      return 0;					/* purecov: inspected */
    a_dec= args[1]->val_decimal(&a_buf);
    b_dec= args[2]->val_decimal(&b_buf);
    if (!args[1]->null_value && !args[2]->null_value)
1829 1830
      return (longlong) ((my_decimal_cmp(dec, a_dec) >= 0 &&
                          my_decimal_cmp(dec, b_dec) <= 0) != negated);
unknown's avatar
unknown committed
1831 1832 1833 1834 1835 1836 1837
    if (args[1]->null_value && args[2]->null_value)
      null_value=1;
    else if (args[1]->null_value)
      null_value= (my_decimal_cmp(dec, b_dec) <= 0);
    else
      null_value= (my_decimal_cmp(dec, a_dec) >= 0);
  }
unknown's avatar
unknown committed
1838 1839
  else
  {
1840
    double value= args[0]->val_real(),a,b;
unknown's avatar
unknown committed
1841
    if ((null_value=args[0]->null_value))
1842
      return 0;					/* purecov: inspected */
1843 1844
    a= args[1]->val_real();
    b= args[2]->val_real();
unknown's avatar
unknown committed
1845
    if (!args[1]->null_value && !args[2]->null_value)
unknown's avatar
unknown committed
1846
      return (longlong) ((value >= a && value <= b) != negated);
unknown's avatar
unknown committed
1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857
    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;
    }
  }
unknown's avatar
unknown committed
1858
  return (longlong) (!null_value && negated);
unknown's avatar
unknown committed
1859 1860
}

1861 1862 1863 1864 1865

void Item_func_between::print(String *str)
{
  str->append('(');
  args[0]->print(str);
unknown's avatar
unknown committed
1866
  if (negated)
1867 1868
    str->append(STRING_WITH_LEN(" not"));
  str->append(STRING_WITH_LEN(" between "));
1869
  args[1]->print(str);
1870
  str->append(STRING_WITH_LEN(" and "));
1871 1872 1873 1874
  args[2]->print(str);
  str->append(')');
}

unknown's avatar
unknown committed
1875 1876 1877
void
Item_func_ifnull::fix_length_and_dec()
{
1878
  agg_result_type(&hybrid_type, args, 2);
unknown's avatar
unknown committed
1879
  maybe_null=args[1]->maybe_null;
unknown's avatar
unknown committed
1880
  decimals= max(args[0]->decimals, args[1]->decimals);
1881 1882 1883 1884 1885
  max_length= (hybrid_type == DECIMAL_RESULT || hybrid_type == INT_RESULT) ?
    (max(args[0]->max_length - args[0]->decimals,
         args[1]->max_length - args[1]->decimals) + decimals) :
    max(args[0]->max_length, args[1]->max_length);

unknown's avatar
unknown committed
1886
  switch (hybrid_type) {
unknown's avatar
unknown committed
1887
  case STRING_RESULT:
1888
    agg_arg_charsets(collation, args, arg_count, MY_COLL_CMP_CONV, 1);
unknown's avatar
unknown committed
1889 1890 1891 1892 1893
    break;
  case DECIMAL_RESULT:
  case REAL_RESULT:
    break;
  case INT_RESULT:
1894
    decimals= 0;
unknown's avatar
unknown committed
1895 1896 1897 1898 1899
    break;
  case ROW_RESULT:
  default:
    DBUG_ASSERT(0);
  }
1900 1901 1902
  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
1903 1904
}

unknown's avatar
unknown committed
1905 1906 1907 1908 1909 1910 1911 1912

uint Item_func_ifnull::decimal_precision() const
{
  int max_int_part=max(args[0]->decimal_int_part(),args[1]->decimal_int_part());
  return min(max_int_part + decimals, DECIMAL_MAX_PRECISION);
}


1913 1914 1915
enum_field_types Item_func_ifnull::field_type() const 
{
  return cached_field_type;
unknown's avatar
unknown committed
1916 1917
}

1918 1919 1920 1921
Field *Item_func_ifnull::tmp_table_field(TABLE *table)
{
  return tmp_table_field_from_field_type(table);
}
1922

unknown's avatar
unknown committed
1923
double
unknown's avatar
unknown committed
1924
Item_func_ifnull::real_op()
unknown's avatar
unknown committed
1925
{
1926
  DBUG_ASSERT(fixed == 1);
1927
  double value= args[0]->val_real();
unknown's avatar
unknown committed
1928 1929 1930 1931 1932
  if (!args[0]->null_value)
  {
    null_value=0;
    return value;
  }
1933
  value= args[1]->val_real();
unknown's avatar
unknown committed
1934 1935 1936 1937 1938 1939
  if ((null_value=args[1]->null_value))
    return 0.0;
  return value;
}

longlong
unknown's avatar
unknown committed
1940
Item_func_ifnull::int_op()
unknown's avatar
unknown committed
1941
{
1942
  DBUG_ASSERT(fixed == 1);
unknown's avatar
unknown committed
1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954
  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;
}

unknown's avatar
unknown committed
1955

unknown's avatar
unknown committed
1956
my_decimal *Item_func_ifnull::decimal_op(my_decimal *decimal_value)
unknown's avatar
unknown committed
1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971
{
  DBUG_ASSERT(fixed == 1);
  my_decimal *value= args[0]->val_decimal(decimal_value);
  if (!args[0]->null_value)
  {
    null_value= 0;
    return value;
  }
  value= args[1]->val_decimal(decimal_value);
  if ((null_value= args[1]->null_value))
    return 0;
  return value;
}


unknown's avatar
unknown committed
1972
String *
unknown's avatar
unknown committed
1973
Item_func_ifnull::str_op(String *str)
unknown's avatar
unknown committed
1974
{
1975
  DBUG_ASSERT(fixed == 1);
unknown's avatar
unknown committed
1976 1977 1978 1979
  String *res  =args[0]->val_str(str);
  if (!args[0]->null_value)
  {
    null_value=0;
1980
    res->set_charset(collation.collation);
unknown's avatar
unknown committed
1981 1982 1983 1984 1985
    return res;
  }
  res=args[1]->val_str(str);
  if ((null_value=args[1]->null_value))
    return 0;
1986
  res->set_charset(collation.collation);
unknown's avatar
unknown committed
1987 1988 1989
  return res;
}

1990

unknown's avatar
unknown committed
1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018
/*
  Perform context analysis of an IF item tree

  SYNOPSIS:
    fix_fields()
    thd     reference to the global context of the query thread
    tables  list of all open tables involved in the query
    ref     pointer to Item* variable where pointer to resulting "fixed"
            item is to be assigned

  DESCRIPTION
    This function performs context analysis (name resolution) and calculates
    various attributes of the item tree with Item_func_if as its root.
    The function saves in ref the pointer to the item or to a newly created
    item that is considered as a replacement for the original one.

  NOTES
    Let T0(e)/T1(e) be the value of not_null_tables(e) when e is used on
    a predicate/function level. Then it's easy to show that:
      T0(IF(e,e1,e2)  = T1(IF(e,e1,e2))
      T1(IF(e,e1,e2)) = intersection(T1(e1),T1(e2))

  RETURN
    0   ok
    1   got error
*/

bool
2019
Item_func_if::fix_fields(THD *thd, Item **ref)
unknown's avatar
unknown committed
2020 2021 2022 2023
{
  DBUG_ASSERT(fixed == 0);
  args[0]->top_level_item();

2024
  if (Item_func::fix_fields(thd, ref))
unknown's avatar
unknown committed
2025 2026
    return 1;

unknown's avatar
unknown committed
2027 2028
  not_null_tables_cache= (args[1]->not_null_tables() &
                          args[2]->not_null_tables());
unknown's avatar
unknown committed
2029 2030 2031 2032 2033

  return 0;
}


unknown's avatar
unknown committed
2034 2035 2036 2037
void
Item_func_if::fix_length_and_dec()
{
  maybe_null=args[1]->maybe_null || args[2]->maybe_null;
unknown's avatar
unknown committed
2038
  decimals= max(args[1]->decimals, args[2]->decimals);
2039
  unsigned_flag=args[1]->unsigned_flag && args[2]->unsigned_flag;
2040

unknown's avatar
unknown committed
2041 2042
  enum Item_result arg1_type=args[1]->result_type();
  enum Item_result arg2_type=args[2]->result_type();
unknown's avatar
unknown committed
2043 2044
  bool null1=args[1]->const_item() && args[1]->null_value;
  bool null2=args[2]->const_item() && args[2]->null_value;
2045 2046 2047 2048

  if (null1)
  {
    cached_result_type= arg2_type;
2049
    collation.set(args[2]->collation.collation);
2050 2051 2052
  }
  else if (null2)
  {
unknown's avatar
unknown committed
2053
    cached_result_type= arg1_type;
2054
    collation.set(args[1]->collation.collation);
2055
  }
unknown's avatar
unknown committed
2056
  else
2057
  {
2058 2059 2060
    agg_result_type(&cached_result_type, args+1, 2);
    if (cached_result_type == STRING_RESULT)
    {
2061
      if (agg_arg_charsets(collation, args+1, 2, MY_COLL_ALLOW_CONV, 1))
2062
        return;
2063
    }
2064
    else
2065
    {
2066
      collation.set(&my_charset_bin);	// Number
2067
    }
2068
  }
2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082

  if ((cached_result_type == DECIMAL_RESULT )
      || (cached_result_type == INT_RESULT))
  {
    int len1= args[1]->max_length - args[1]->decimals
      - (args[1]->unsigned_flag ? 0 : 1);

    int len2= args[2]->max_length - args[2]->decimals
      - (args[2]->unsigned_flag ? 0 : 1);

    max_length=max(len1, len2) + decimals + (unsigned_flag ? 0 : 1);
  }
  else
    max_length= max(args[1]->max_length, args[2]->max_length);
unknown's avatar
unknown committed
2083 2084 2085
}


unknown's avatar
unknown committed
2086 2087 2088 2089 2090 2091 2092 2093
uint Item_func_if::decimal_precision() const
{
  int precision=(max(args[1]->decimal_int_part(),args[2]->decimal_int_part())+
                 decimals);
  return min(precision, DECIMAL_MAX_PRECISION);
}


unknown's avatar
unknown committed
2094
double
2095
Item_func_if::val_real()
unknown's avatar
unknown committed
2096
{
2097
  DBUG_ASSERT(fixed == 1);
unknown's avatar
unknown committed
2098
  Item *arg= args[0]->val_bool() ? args[1] : args[2];
2099
  double value= arg->val_real();
unknown's avatar
unknown committed
2100 2101 2102 2103 2104 2105 2106
  null_value=arg->null_value;
  return value;
}

longlong
Item_func_if::val_int()
{
2107
  DBUG_ASSERT(fixed == 1);
unknown's avatar
unknown committed
2108
  Item *arg= args[0]->val_bool() ? args[1] : args[2];
unknown's avatar
unknown committed
2109 2110 2111 2112 2113 2114 2115 2116
  longlong value=arg->val_int();
  null_value=arg->null_value;
  return value;
}

String *
Item_func_if::val_str(String *str)
{
2117
  DBUG_ASSERT(fixed == 1);
unknown's avatar
unknown committed
2118
  Item *arg= args[0]->val_bool() ? args[1] : args[2];
unknown's avatar
unknown committed
2119
  String *res=arg->val_str(str);
2120
  if (res)
2121
    res->set_charset(collation.collation);
unknown's avatar
unknown committed
2122 2123 2124 2125 2126
  null_value=arg->null_value;
  return res;
}


unknown's avatar
unknown committed
2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137
my_decimal *
Item_func_if::val_decimal(my_decimal *decimal_value)
{
  DBUG_ASSERT(fixed == 1);
  Item *arg= args[0]->val_bool() ? args[1] : args[2];
  my_decimal *value= arg->val_decimal(decimal_value);
  null_value= arg->null_value;
  return value;
}


unknown's avatar
unknown committed
2138 2139 2140 2141 2142 2143 2144 2145 2146
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;
unknown's avatar
unknown committed
2147 2148
    unsigned_flag= args[0]->unsigned_flag;
    cached_result_type= args[0]->result_type();
2149
    if (cached_result_type == STRING_RESULT &&
2150
        agg_arg_charsets(collation, args, arg_count, MY_COLL_CMP_CONV, 1))
2151
      return;
unknown's avatar
unknown committed
2152 2153 2154
  }
}

unknown's avatar
unknown committed
2155

unknown's avatar
unknown committed
2156
/*
2157
  nullif () returns NULL if arguments are equal, else it returns the
unknown's avatar
unknown committed
2158 2159 2160 2161 2162 2163
  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
2164
Item_func_nullif::val_real()
unknown's avatar
unknown committed
2165
{
2166
  DBUG_ASSERT(fixed == 1);
unknown's avatar
unknown committed
2167
  double value;
unknown's avatar
unknown committed
2168
  if (!cmp.compare())
unknown's avatar
unknown committed
2169 2170 2171 2172
  {
    null_value=1;
    return 0.0;
  }
2173
  value= args[0]->val_real();
unknown's avatar
unknown committed
2174 2175 2176 2177 2178 2179 2180
  null_value=args[0]->null_value;
  return value;
}

longlong
Item_func_nullif::val_int()
{
2181
  DBUG_ASSERT(fixed == 1);
unknown's avatar
unknown committed
2182
  longlong value;
unknown's avatar
unknown committed
2183
  if (!cmp.compare())
unknown's avatar
unknown committed
2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195
  {
    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)
{
2196
  DBUG_ASSERT(fixed == 1);
unknown's avatar
unknown committed
2197
  String *res;
unknown's avatar
unknown committed
2198
  if (!cmp.compare())
unknown's avatar
unknown committed
2199 2200 2201 2202 2203 2204 2205 2206 2207
  {
    null_value=1;
    return 0;
  }
  res=args[0]->val_str(str);
  null_value=args[0]->null_value;
  return res;
}

2208

unknown's avatar
unknown committed
2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224
my_decimal *
Item_func_nullif::val_decimal(my_decimal * decimal_value)
{
  DBUG_ASSERT(fixed == 1);
  my_decimal *res;
  if (!cmp.compare())
  {
    null_value=1;
    return 0;
  }
  res= args[0]->val_decimal(decimal_value);
  null_value= args[0]->null_value;
  return res;
}


2225 2226 2227
bool
Item_func_nullif::is_null()
{
unknown's avatar
unknown committed
2228
  return (null_value= (!cmp.compare() ? 1 : args[0]->null_value)); 
2229 2230
}

unknown's avatar
unknown committed
2231
/*
2232 2233
  CASE expression 
  Return the matching ITEM or NULL if all compares (including else) failed
unknown's avatar
unknown committed
2234 2235 2236 2237
*/

Item *Item_func_case::find_item(String *str)
{
unknown's avatar
unknown committed
2238 2239
  String *first_expr_str, *tmp;
  my_decimal *first_expr_dec, first_expr_dec_val;
unknown's avatar
unknown committed
2240 2241
  longlong first_expr_int;
  double   first_expr_real;
2242 2243
  char buff[MAX_FIELD_WIDTH];
  String buff_str(buff,sizeof(buff),default_charset());
unknown's avatar
unknown committed
2244

unknown's avatar
unknown committed
2245 2246 2247 2248
  /* 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
2249
  LINT_INIT(first_expr_dec);
unknown's avatar
unknown committed
2250

unknown's avatar
unknown committed
2251 2252 2253 2254 2255 2256
  if (first_expr_num != -1)
  {
    switch (cmp_type)
    {
      case STRING_RESULT:
      	// We can't use 'str' here as this may be overwritten
2257
	if (!(first_expr_str= args[first_expr_num]->val_str(&buff_str)))
unknown's avatar
unknown committed
2258 2259 2260 2261 2262 2263 2264 2265
	  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:
2266
	first_expr_real= args[first_expr_num]->val_real();
unknown's avatar
unknown committed
2267 2268 2269
	if (args[first_expr_num]->null_value)
	  return else_expr_num != -1 ? args[else_expr_num] : 0;
	break;
unknown's avatar
unknown committed
2270 2271 2272 2273 2274
      case DECIMAL_RESULT:
        first_expr_dec= args[first_expr_num]->val_decimal(&first_expr_dec_val);
        if (args[first_expr_num]->null_value)
          return else_expr_num != -1 ? args[else_expr_num] : 0;
        break;
unknown's avatar
unknown committed
2275 2276
      case ROW_RESULT:
      default:
unknown's avatar
unknown committed
2277
        // This case should never be chosen
unknown's avatar
unknown committed
2278 2279 2280 2281 2282
	DBUG_ASSERT(0);
	break;
    }
  }

unknown's avatar
unknown committed
2283
  // Compare every WHEN argument with it and return the first match
2284
  for (uint i=0 ; i < ncases ; i+=2)
unknown's avatar
unknown committed
2285
  {
2286
    if (first_expr_num == -1)
unknown's avatar
unknown committed
2287
    {
unknown's avatar
unknown committed
2288
      // No expression between CASE and the first WHEN
unknown's avatar
unknown committed
2289
      if (args[i]->val_bool())
unknown's avatar
unknown committed
2290 2291 2292
	return args[i+1];
      continue;
    }
unknown's avatar
unknown committed
2293
    switch (cmp_type) {
unknown's avatar
unknown committed
2294 2295
    case STRING_RESULT:
      if ((tmp=args[i]->val_str(str)))		// If not null
unknown's avatar
unknown committed
2296
	if (sortcmp(tmp,first_expr_str,cmp_collation.collation)==0)
unknown's avatar
unknown committed
2297 2298 2299 2300 2301 2302 2303
	  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: 
2304
      if (args[i]->val_real() == first_expr_real && !args[i]->null_value)
unknown's avatar
unknown committed
2305
        return args[i+1];
unknown's avatar
unknown committed
2306
      break;
unknown's avatar
unknown committed
2307 2308 2309 2310 2311 2312 2313
    case DECIMAL_RESULT:
    {
      my_decimal value;
      if (my_decimal_cmp(args[i]->val_decimal(&value), first_expr_dec) == 0)
        return args[i+1];
      break;
    }
2314
    case ROW_RESULT:
unknown's avatar
unknown committed
2315
    default:
unknown's avatar
unknown committed
2316
      // This case should never be chosen
unknown's avatar
unknown committed
2317 2318
      DBUG_ASSERT(0);
      break;
unknown's avatar
unknown committed
2319 2320 2321
    }
  }
  // No, WHEN clauses all missed, return ELSE expression
2322
  return else_expr_num != -1 ? args[else_expr_num] : 0;
unknown's avatar
unknown committed
2323 2324 2325 2326 2327
}


String *Item_func_case::val_str(String *str)
{
2328
  DBUG_ASSERT(fixed == 1);
unknown's avatar
unknown committed
2329 2330 2331 2332 2333 2334 2335 2336
  String *res;
  Item *item=find_item(str);

  if (!item)
  {
    null_value=1;
    return 0;
  }
unknown's avatar
unknown committed
2337
  null_value= 0;
unknown's avatar
unknown committed
2338
  if (!(res=item->val_str(str)))
unknown's avatar
unknown committed
2339
    null_value= 1;
unknown's avatar
unknown committed
2340 2341 2342 2343 2344 2345
  return res;
}


longlong Item_func_case::val_int()
{
2346
  DBUG_ASSERT(fixed == 1);
unknown's avatar
unknown committed
2347
  char buff[MAX_FIELD_WIDTH];
2348
  String dummy_str(buff,sizeof(buff),default_charset());
unknown's avatar
unknown committed
2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361
  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;
}

2362
double Item_func_case::val_real()
unknown's avatar
unknown committed
2363
{
2364
  DBUG_ASSERT(fixed == 1);
unknown's avatar
unknown committed
2365
  char buff[MAX_FIELD_WIDTH];
2366
  String dummy_str(buff,sizeof(buff),default_charset());
unknown's avatar
unknown committed
2367 2368 2369 2370 2371 2372 2373 2374
  Item *item=find_item(&dummy_str);
  double res;

  if (!item)
  {
    null_value=1;
    return 0;
  }
2375
  res= item->val_real();
unknown's avatar
unknown committed
2376 2377 2378 2379
  null_value=item->null_value;
  return res;
}

unknown's avatar
unknown committed
2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400

my_decimal *Item_func_case::val_decimal(my_decimal *decimal_value)
{
  DBUG_ASSERT(fixed == 1);
  char buff[MAX_FIELD_WIDTH];
  String dummy_str(buff, sizeof(buff), default_charset());
  Item *item= find_item(&dummy_str);
  my_decimal *res;

  if (!item)
  {
    null_value=1;
    return 0;
  }

  res= item->val_decimal(decimal_value);
  null_value= item->null_value;
  return res;
}


unknown's avatar
unknown committed
2401
bool Item_func_case::fix_fields(THD *thd, Item **ref)
unknown's avatar
unknown committed
2402 2403 2404 2405 2406
{
  /*
    buff should match stack usage from
    Item_func_case::val_int() -> Item_func_case::find_item()
  */
2407
#ifndef EMBEDDED_LIBRARY
unknown's avatar
unknown committed
2408
  char buff[MAX_FIELD_WIDTH*2+sizeof(String)*2+sizeof(String*)*2+sizeof(double)*2+sizeof(longlong)*2];
2409
#endif
unknown's avatar
unknown committed
2410 2411 2412 2413 2414
  bool res= Item_func::fix_fields(thd, ref);
  /*
    Call check_stack_overrun after fix_fields to be sure that stack variable
    is not optimized away
  */
unknown's avatar
unknown committed
2415 2416
  if (check_stack_overrun(thd, STACK_MIN_SIZE, buff))
    return TRUE;				// Fatal error flag is set!
unknown's avatar
unknown committed
2417
  return res;
unknown's avatar
unknown committed
2418 2419 2420 2421
}



unknown's avatar
unknown committed
2422
void Item_func_case::fix_length_and_dec()
2423
{
2424 2425
  Item **agg;
  uint nagg;
2426
  THD *thd= current_thd;
2427 2428 2429 2430
  
  if (!(agg= (Item**) sql_alloc(sizeof(Item*)*(ncases+1))))
    return;
  
2431 2432 2433 2434
  /*
    Aggregate all THEN and ELSE expression types
    and collations when string result
  */
2435 2436 2437 2438 2439 2440 2441 2442 2443
  
  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) &&
2444
      agg_arg_charsets(collation, agg, nagg, MY_COLL_ALLOW_CONV, 1))
2445 2446 2447
    return;
  
  
unknown's avatar
unknown committed
2448 2449 2450 2451
  /*
    Aggregate first expression and all THEN expression types
    and collations when string comparison
  */
2452
  if (first_expr_num != -1)
2453
  {
2454 2455
    agg[0]= args[first_expr_num];
    for (nagg= 0; nagg < ncases/2 ; nagg++)
unknown's avatar
unknown committed
2456
      agg[nagg+1]= args[nagg*2];
2457
    nagg++;
2458
    if (agg_cmp_type(thd, &cmp_type, agg, nagg))
2459
      return;
2460
    if ((cmp_type == STRING_RESULT) &&
2461
        agg_arg_charsets(cmp_collation, agg, nagg, MY_COLL_CMP_CONV, 1))
unknown's avatar
unknown committed
2462
      return;
2463
  }
2464
  
unknown's avatar
unknown committed
2465
  if (else_expr_num == -1 || args[else_expr_num]->maybe_null)
2466
    maybe_null=1;
2467
  
unknown's avatar
unknown committed
2468 2469
  max_length=0;
  decimals=0;
2470
  for (uint i=0 ; i < ncases ; i+=2)
unknown's avatar
unknown committed
2471 2472 2473 2474
  {
    set_if_bigger(max_length,args[i+1]->max_length);
    set_if_bigger(decimals,args[i+1]->decimals);
  }
2475
  if (else_expr_num != -1) 
unknown's avatar
unknown committed
2476
  {
2477 2478
    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
2479 2480 2481
  }
}

unknown's avatar
unknown committed
2482

unknown's avatar
unknown committed
2483 2484 2485 2486 2487 2488 2489 2490 2491 2492 2493 2494
uint Item_func_case::decimal_precision() const
{
  int max_int_part=0;
  for (uint i=0 ; i < ncases ; i+=2)
    set_if_bigger(max_int_part, args[i+1]->decimal_int_part());

  if (else_expr_num != -1) 
    set_if_bigger(max_int_part, args[else_expr_num]->decimal_int_part());
  return min(max_int_part + decimals, DECIMAL_MAX_PRECISION);
}


2495
/* TODO:  Fix this so that it prints the whole CASE expression */
unknown's avatar
unknown committed
2496 2497 2498

void Item_func_case::print(String *str)
{
2499
  str->append(STRING_WITH_LEN("(case "));
2500 2501 2502 2503 2504 2505 2506
  if (first_expr_num != -1)
  {
    args[first_expr_num]->print(str);
    str->append(' ');
  }
  for (uint i=0 ; i < ncases ; i+=2)
  {
2507
    str->append(STRING_WITH_LEN("when "));
2508
    args[i]->print(str);
2509
    str->append(STRING_WITH_LEN(" then "));
2510 2511 2512 2513 2514
    args[i+1]->print(str);
    str->append(' ');
  }
  if (else_expr_num != -1)
  {
2515
    str->append(STRING_WITH_LEN("else "));
2516 2517 2518
    args[else_expr_num]->print(str);
    str->append(' ');
  }
2519
  str->append(STRING_WITH_LEN("end)"));
unknown's avatar
unknown committed
2520 2521 2522
}

/*
2523
  Coalesce - return first not NULL argument.
unknown's avatar
unknown committed
2524 2525
*/

unknown's avatar
unknown committed
2526
String *Item_func_coalesce::str_op(String *str)
unknown's avatar
unknown committed
2527
{
2528
  DBUG_ASSERT(fixed == 1);
unknown's avatar
unknown committed
2529 2530 2531
  null_value=0;
  for (uint i=0 ; i < arg_count ; i++)
  {
unknown's avatar
unknown committed
2532 2533 2534
    String *res;
    if ((res=args[i]->val_str(str)))
      return res;
unknown's avatar
unknown committed
2535 2536 2537 2538 2539
  }
  null_value=1;
  return 0;
}

unknown's avatar
unknown committed
2540
longlong Item_func_coalesce::int_op()
unknown's avatar
unknown committed
2541
{
2542
  DBUG_ASSERT(fixed == 1);
unknown's avatar
unknown committed
2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553
  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;
}

unknown's avatar
unknown committed
2554
double Item_func_coalesce::real_op()
unknown's avatar
unknown committed
2555
{
2556
  DBUG_ASSERT(fixed == 1);
unknown's avatar
unknown committed
2557 2558 2559
  null_value=0;
  for (uint i=0 ; i < arg_count ; i++)
  {
2560
    double res= args[i]->val_real();
unknown's avatar
unknown committed
2561 2562 2563 2564 2565 2566 2567 2568
    if (!args[i]->null_value)
      return res;
  }
  null_value=1;
  return 0;
}


unknown's avatar
unknown committed
2569
my_decimal *Item_func_coalesce::decimal_op(my_decimal *decimal_value)
unknown's avatar
unknown committed
2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 2583
{
  DBUG_ASSERT(fixed == 1);
  null_value= 0;
  for (uint i= 0; i < arg_count; i++)
  {
    my_decimal *res= args[i]->val_decimal(decimal_value);
    if (!args[i]->null_value)
      return res;
  }
  null_value=1;
  return 0;
}


unknown's avatar
unknown committed
2584 2585
void Item_func_coalesce::fix_length_and_dec()
{
unknown's avatar
unknown committed
2586 2587
  agg_result_type(&hybrid_type, args, arg_count);
  switch (hybrid_type) {
unknown's avatar
unknown committed
2588 2589 2590
  case STRING_RESULT:
    count_only_length();
    decimals= NOT_FIXED_DEC;
2591
    agg_arg_charsets(collation, args, arg_count, MY_COLL_ALLOW_CONV, 1);
unknown's avatar
unknown committed
2592 2593 2594 2595 2596 2597 2598 2599 2600
    break;
  case DECIMAL_RESULT:
    count_decimal_length();
    break;
  case REAL_RESULT:
    count_real_length();
    break;
  case INT_RESULT:
    count_only_length();
2601
    decimals= 0;
unknown's avatar
unknown committed
2602 2603
    break;
  case ROW_RESULT:
2604
  default:
unknown's avatar
unknown committed
2605 2606
    DBUG_ASSERT(0);
  }
unknown's avatar
unknown committed
2607 2608 2609
}

/****************************************************************************
2610
 Classes and function for the IN operator
unknown's avatar
unknown committed
2611 2612
****************************************************************************/

unknown's avatar
unknown committed
2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629 2630 2631
/*
  Determine which of the signed longlong arguments is bigger

  SYNOPSIS
    cmp_longs()
      a_val     left argument
      b_val     right argument

  DESCRIPTION
    This function will compare two signed longlong arguments
    and will return -1, 0, or 1 if left argument is smaller than,
    equal to or greater than the right argument.

  RETURN VALUE
    -1          left argument is smaller than the right argument.
    0           left argument is equal to the right argument.
    1           left argument is greater than the right argument.
*/
static inline int cmp_longs (longlong a_val, longlong b_val)
unknown's avatar
unknown committed
2632
{
unknown's avatar
unknown committed
2633 2634 2635 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 2651 2652 2653 2654 2655 2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693
  return a_val < b_val ? -1 : a_val == b_val ? 0 : 1;
}


/*
  Determine which of the unsigned longlong arguments is bigger

  SYNOPSIS
    cmp_ulongs()
      a_val     left argument
      b_val     right argument

  DESCRIPTION
    This function will compare two unsigned longlong arguments
    and will return -1, 0, or 1 if left argument is smaller than,
    equal to or greater than the right argument.

  RETURN VALUE
    -1          left argument is smaller than the right argument.
    0           left argument is equal to the right argument.
    1           left argument is greater than the right argument.
*/
static inline int cmp_ulongs (ulonglong a_val, ulonglong b_val)
{
  return a_val < b_val ? -1 : a_val == b_val ? 0 : 1;
}


/*
  Compare two integers in IN value list format (packed_longlong) 

  SYNOPSIS
    cmp_longlong()
      cmp_arg   an argument passed to the calling function (qsort2)
      a         left argument
      b         right argument

  DESCRIPTION
    This function will compare two integer arguments in the IN value list
    format and will return -1, 0, or 1 if left argument is smaller than,
    equal to or greater than the right argument.
    It's used in sorting the IN values list and finding an element in it.
    Depending on the signedness of the arguments cmp_longlong() will
    compare them as either signed (using cmp_longs()) or unsigned (using
    cmp_ulongs()).

  RETURN VALUE
    -1          left argument is smaller than the right argument.
    0           left argument is equal to the right argument.
    1           left argument is greater than the right argument.
*/
int cmp_longlong(void *cmp_arg, 
                 in_longlong::packed_longlong *a,
                 in_longlong::packed_longlong *b)
{
  if (a->unsigned_flag != b->unsigned_flag)
  { 
    /* 
      One of the args is unsigned and is too big to fit into the 
      positive signed range. Report no match.
    */  
2694 2695
    if (a->unsigned_flag && ((ulonglong) a->val) > (ulonglong) LONGLONG_MAX ||
        b->unsigned_flag && ((ulonglong) b->val) > (ulonglong) LONGLONG_MAX)
unknown's avatar
unknown committed
2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706
      return a->unsigned_flag ? 1 : -1;
    /*
      Although the signedness differs both args can fit into the signed 
      positive range. Make them signed and compare as usual.
    */  
    return cmp_longs (a->val, b->val);
  }
  if (a->unsigned_flag)
    return cmp_ulongs ((ulonglong) a->val, (ulonglong) b->val);
  else
    return cmp_longs (a->val, b->val);
unknown's avatar
unknown committed
2707 2708
}

2709
static int cmp_double(void *cmp_arg, double *a,double *b)
unknown's avatar
unknown committed
2710 2711 2712 2713
{
  return *a < *b ? -1 : *a == *b ? 0 : 1;
}

unknown's avatar
unknown committed
2714
static int cmp_row(void *cmp_arg, cmp_item_row *a, cmp_item_row *b)
unknown's avatar
unknown committed
2715 2716 2717 2718
{
  return a->compare(b);
}

unknown's avatar
unknown committed
2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731

static int cmp_decimal(void *cmp_arg, my_decimal *a, my_decimal *b)
{
  /*
    We need call of fixing buffer pointer, because fast sort just copy
    decimal buffers in memory and pointers left pointing on old buffer place
  */
  a->fix_buffer_pointer();
  b->fix_buffer_pointer();
  return my_decimal_cmp(a, b);
}


unknown's avatar
unknown committed
2732 2733 2734 2735 2736 2737 2738 2739 2740 2741 2742 2743
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;
2744
    if ((res=(*compare)(collation, base+mid*size, result)) == 0)
unknown's avatar
unknown committed
2745 2746 2747 2748 2749 2750
      return 1;
    if (res < 0)
      start=mid;
    else
      end=mid-1;
  }
2751
  return (int) ((*compare)(collation, base+start*size, result) == 0);
unknown's avatar
unknown committed
2752 2753
}

2754 2755
in_string::in_string(uint elements,qsort2_cmp cmp_func, CHARSET_INFO *cs)
  :in_vector(elements, sizeof(String), cmp_func, cs),
2756
   tmp(buff, sizeof(buff), &my_charset_bin)
unknown's avatar
unknown committed
2757 2758 2759 2760
{}

in_string::~in_string()
{
2761
  if (base)
2762
  {
unknown's avatar
unknown committed
2763
    // base was allocated with help of sql_alloc => following is OK
2764 2765
    for (uint i=0 ; i < count ; i++)
      ((String*) base)[i].free();
2766
  }
unknown's avatar
unknown committed
2767 2768 2769 2770 2771 2772 2773
}

void in_string::set(uint pos,Item *item)
{
  String *str=((String*) base)+pos;
  String *res=item->val_str(str);
  if (res && res != str)
2774 2775 2776
  {
    if (res->uses_buffer_owned_by(str))
      res->copy();
unknown's avatar
unknown committed
2777
    *str= *res;
2778
  }
2779
  if (!str->charset())
2780 2781
  {
    CHARSET_INFO *cs;
2782
    if (!(cs= item->collation.collation))
2783
      cs= &my_charset_bin;		// Should never happen for STR items
2784 2785
    str->set_charset(cs);
  }
unknown's avatar
unknown committed
2786 2787
}

2788

unknown's avatar
unknown committed
2789 2790 2791 2792 2793
byte *in_string::get_value(Item *item)
{
  return (byte*) item->val_str(&tmp);
}

unknown's avatar
unknown committed
2794 2795
in_row::in_row(uint elements, Item * item)
{
2796
  base= (char*) new cmp_item_row[count= elements];
unknown's avatar
unknown committed
2797
  size= sizeof(cmp_item_row);
2798
  compare= (qsort2_cmp) cmp_row;
2799 2800 2801 2802 2803 2804
  /*
    We need to reset these as otherwise we will call sort() with
    uninitialized (even if not used) elements
  */
  used_count= elements;
  collation= 0;
2805 2806 2807 2808 2809
}

in_row::~in_row()
{
  if (base)
2810
    delete [] (cmp_item_row*) base;
unknown's avatar
unknown committed
2811 2812 2813 2814 2815
}

byte *in_row::get_value(Item *item)
{
  tmp.store_value(item);
unknown's avatar
unknown committed
2816 2817
  if (item->is_null())
    return 0;
unknown's avatar
unknown committed
2818 2819 2820 2821 2822 2823
  return (byte *)&tmp;
}

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

in_longlong::in_longlong(uint elements)
unknown's avatar
unknown committed
2830
  :in_vector(elements,sizeof(packed_longlong),(qsort2_cmp) cmp_longlong, 0)
unknown's avatar
unknown committed
2831 2832 2833 2834
{}

void in_longlong::set(uint pos,Item *item)
{
unknown's avatar
unknown committed
2835 2836 2837 2838
  struct packed_longlong *buff= &((packed_longlong*) base)[pos];
  
  buff->val= item->val_int();
  buff->unsigned_flag= item->unsigned_flag;
unknown's avatar
unknown committed
2839 2840 2841 2842
}

byte *in_longlong::get_value(Item *item)
{
unknown's avatar
unknown committed
2843
  tmp.val= item->val_int();
unknown's avatar
unknown committed
2844
  if (item->null_value)
unknown's avatar
unknown committed
2845
    return 0;
unknown's avatar
unknown committed
2846
  tmp.unsigned_flag= item->unsigned_flag;
unknown's avatar
unknown committed
2847 2848 2849
  return (byte*) &tmp;
}

2850 2851 2852 2853 2854 2855 2856 2857 2858 2859 2860 2861 2862 2863 2864 2865 2866 2867 2868 2869 2870
void in_datetime::set(uint pos,Item *item)
{
  Item **tmp= &item;
  bool is_null;
  struct packed_longlong *buff= &((packed_longlong*) base)[pos];

  buff->val= get_datetime_value(thd, &tmp, 0, warn_item, &is_null);
  buff->unsigned_flag= 1L;
}

byte *in_datetime::get_value(Item *item)
{
  bool is_null;
  Item **tmp_item= lval_cache ? &lval_cache : &item;
  tmp.val= get_datetime_value(thd, &tmp_item, &lval_cache, warn_item, &is_null);
  if (item->null_value)
    return 0;
  tmp.unsigned_flag= 1L;
  return (byte*) &tmp;
}

unknown's avatar
unknown committed
2871
in_double::in_double(uint elements)
2872
  :in_vector(elements,sizeof(double),(qsort2_cmp) cmp_double, 0)
unknown's avatar
unknown committed
2873 2874 2875 2876
{}

void in_double::set(uint pos,Item *item)
{
2877
  ((double*) base)[pos]= item->val_real();
unknown's avatar
unknown committed
2878 2879 2880 2881
}

byte *in_double::get_value(Item *item)
{
2882
  tmp= item->val_real();
unknown's avatar
unknown committed
2883
  if (item->null_value)
2884
    return 0;					/* purecov: inspected */
unknown's avatar
unknown committed
2885 2886 2887
  return (byte*) &tmp;
}

unknown's avatar
unknown committed
2888 2889 2890 2891 2892 2893 2894 2895 2896 2897 2898 2899 2900

in_decimal::in_decimal(uint elements)
  :in_vector(elements, sizeof(my_decimal),(qsort2_cmp) cmp_decimal, 0)
{}


void in_decimal::set(uint pos, Item *item)
{
  /* as far as 'item' is constant, we can store reference on my_decimal */
  my_decimal *dec= ((my_decimal *)base) + pos;
  dec->len= DECIMAL_BUFF_LENGTH;
  dec->fix_buffer_pointer();
  my_decimal *res= item->val_decimal(dec);
2901 2902
  /* if item->val_decimal() is evaluated to NULL then res == 0 */ 
  if (!item->null_value && res != dec)
unknown's avatar
unknown committed
2903 2904 2905 2906 2907 2908 2909 2910 2911 2912 2913 2914 2915 2916 2917
    my_decimal2decimal(res, dec);
}


byte *in_decimal::get_value(Item *item)
{
  my_decimal *result= item->val_decimal(&val);
  if (item->null_value)
    return 0;
  return (byte *)result;
}


cmp_item* cmp_item::get_comparator(Item_result type,
                                   CHARSET_INFO *cs)
2918
{
unknown's avatar
unknown committed
2919
  switch (type) {
2920
  case STRING_RESULT:
unknown's avatar
unknown committed
2921
    return new cmp_item_sort_string(cs);
2922 2923 2924 2925 2926 2927
  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
2928 2929
  case DECIMAL_RESULT:
    return new cmp_item_decimal;
unknown's avatar
unknown committed
2930 2931 2932
  default:
    DBUG_ASSERT(0);
    break;
2933 2934 2935 2936
  }
  return 0; // to satisfy compiler :)
}

2937

unknown's avatar
unknown committed
2938 2939
cmp_item* cmp_item_sort_string::make_same()
{
2940
  return new cmp_item_sort_string_in_static(cmp_charset);
unknown's avatar
unknown committed
2941 2942 2943 2944 2945 2946 2947 2948 2949 2950 2951 2952 2953 2954 2955 2956 2957
}

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();
}

2958 2959 2960 2961

cmp_item_row::~cmp_item_row()
{
  DBUG_ENTER("~cmp_item_row");
unknown's avatar
unknown committed
2962
  DBUG_PRINT("enter",("this: 0x%lx", (long) this));
2963 2964 2965 2966 2967 2968 2969 2970 2971 2972 2973 2974
  if (comparators)
  {
    for (uint i= 0; i < n; i++)
    {
      if (comparators[i])
	delete comparators[i];
    }
  }
  DBUG_VOID_RETURN;
}


2975 2976 2977 2978 2979 2980 2981
void cmp_item_row::alloc_comparators()
{
  if (!comparators)
    comparators= (cmp_item **) current_thd->calloc(sizeof(cmp_item *)*n);
}


2982 2983
void cmp_item_row::store_value(Item *item)
{
2984
  DBUG_ENTER("cmp_item_row::store_value");
2985
  n= item->cols();
2986
  alloc_comparators();
2987
  if (comparators)
2988
  {
2989
    item->bring_value();
unknown's avatar
unknown committed
2990
    item->null_value= 0;
2991
    for (uint i=0; i < n; i++)
2992
    {
unknown's avatar
unknown committed
2993
      if (!comparators[i])
unknown's avatar
unknown committed
2994
        if (!(comparators[i]=
2995 2996
              cmp_item::get_comparator(item->element_index(i)->result_type(),
                                       item->element_index(i)->collation.collation)))
unknown's avatar
unknown committed
2997
	  break;					// new failed
2998 2999
      comparators[i]->store_value(item->element_index(i));
      item->null_value|= item->element_index(i)->null_value;
3000
    }
3001
  }
3002
  DBUG_VOID_RETURN;
3003 3004
}

3005

unknown's avatar
unknown committed
3006 3007 3008 3009 3010
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
3011
    my_error(ER_OPERAND_COLUMNS, MYF(0), tmpl->n);
unknown's avatar
unknown committed
3012 3013 3014 3015 3016
    return;
  }
  n= tmpl->n;
  if ((comparators= (cmp_item **) sql_alloc(sizeof(cmp_item *)*n)))
  {
3017
    item->bring_value();
unknown's avatar
unknown committed
3018 3019
    item->null_value= 0;
    for (uint i=0; i < n; i++)
3020 3021 3022 3023
    {
      if (!(comparators[i]= tmpl->comparators[i]->make_same()))
	break;					// new failed
      comparators[i]->store_value_by_template(tmpl->comparators[i],
3024 3025
					      item->element_index(i));
      item->null_value|= item->element_index(i)->null_value;
3026
    }
unknown's avatar
unknown committed
3027 3028 3029
  }
}

3030

3031 3032
int cmp_item_row::cmp(Item *arg)
{
unknown's avatar
unknown committed
3033 3034 3035
  arg->null_value= 0;
  if (arg->cols() != n)
  {
unknown's avatar
unknown committed
3036
    my_error(ER_OPERAND_COLUMNS, MYF(0), n);
unknown's avatar
unknown committed
3037 3038
    return 1;
  }
unknown's avatar
unknown committed
3039
  bool was_null= 0;
3040
  arg->bring_value();
unknown's avatar
unknown committed
3041
  for (uint i=0; i < n; i++)
3042
  {
3043
    if (comparators[i]->cmp(arg->element_index(i)))
unknown's avatar
unknown committed
3044
    {
3045
      if (!arg->element_index(i)->null_value)
unknown's avatar
unknown committed
3046 3047
	return 1;
      was_null= 1;
unknown's avatar
unknown committed
3048
    }
3049
  }
unknown's avatar
unknown committed
3050
  return (arg->null_value= was_null);
unknown's avatar
unknown committed
3051 3052
}

3053

unknown's avatar
unknown committed
3054 3055
int cmp_item_row::compare(cmp_item *c)
{
3056
  cmp_item_row *l_cmp= (cmp_item_row *) c;
unknown's avatar
unknown committed
3057
  for (uint i=0; i < n; i++)
3058 3059
  {
    int res;
3060
    if ((res= comparators[i]->compare(l_cmp->comparators[i])))
unknown's avatar
unknown committed
3061
      return res;
3062
  }
3063 3064
  return 0;
}
unknown's avatar
unknown committed
3065

3066

unknown's avatar
unknown committed
3067 3068 3069
void cmp_item_decimal::store_value(Item *item)
{
  my_decimal *val= item->val_decimal(&value);
unknown's avatar
unknown committed
3070 3071
  /* val may be zero if item is nnull */
  if (val && val != &value)
unknown's avatar
unknown committed
3072 3073 3074 3075 3076 3077 3078 3079 3080 3081 3082 3083 3084
    my_decimal2decimal(val, &value);
}


int cmp_item_decimal::cmp(Item *arg)
{
  my_decimal tmp_buf, *tmp= arg->val_decimal(&tmp_buf);
  if (arg->null_value)
    return 1;
  return my_decimal_cmp(&value, tmp);
}


unknown's avatar
unknown committed
3085
int cmp_item_decimal::compare(cmp_item *arg)
unknown's avatar
unknown committed
3086
{
3087 3088
  cmp_item_decimal *l_cmp= (cmp_item_decimal*) arg;
  return my_decimal_cmp(&value, &l_cmp->value);
unknown's avatar
unknown committed
3089 3090 3091 3092 3093 3094 3095 3096 3097
}


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


3098 3099 3100 3101 3102 3103 3104 3105 3106 3107 3108 3109 3110 3111 3112 3113 3114 3115 3116 3117 3118 3119 3120 3121 3122 3123 3124 3125 3126 3127
void cmp_item_datetime::store_value(Item *item)
{
  bool is_null;
  Item **tmp_item= lval_cache ? &lval_cache : &item;
  value= get_datetime_value(thd, &tmp_item, &lval_cache, warn_item, &is_null);
}


int cmp_item_datetime::cmp(Item *arg)
{
  bool is_null;
  Item **tmp_item= &arg;
  return value !=
    get_datetime_value(thd, &tmp_item, 0, warn_item, &is_null);
}


int cmp_item_datetime::compare(cmp_item *ci)
{
  cmp_item_datetime *l_cmp= (cmp_item_datetime *)ci;
  return (value < l_cmp->value) ? -1 : ((value == l_cmp->value) ? 0 : 1);
}


cmp_item *cmp_item_datetime::make_same()
{
  return new cmp_item_datetime(warn_item);
}


unknown's avatar
unknown committed
3128 3129 3130
bool Item_func_in::nulls_in_row()
{
  Item **arg,**arg_end;
3131
  for (arg= args+1, arg_end= args+arg_count; arg != arg_end ; arg++)
unknown's avatar
unknown committed
3132 3133 3134 3135 3136 3137 3138
  {
    if ((*arg)->null_inside())
      return 1;
  }
  return 0;
}

3139

unknown's avatar
unknown committed
3140 3141 3142 3143 3144 3145 3146 3147 3148 3149 3150 3151 3152 3153 3154 3155 3156 3157 3158 3159 3160 3161 3162 3163 3164 3165 3166 3167 3168 3169
/*
  Perform context analysis of an IN item tree

  SYNOPSIS:
    fix_fields()
    thd     reference to the global context of the query thread
    tables  list of all open tables involved in the query
    ref     pointer to Item* variable where pointer to resulting "fixed"
            item is to be assigned

  DESCRIPTION
    This function performs context analysis (name resolution) and calculates
    various attributes of the item tree with Item_func_in as its root.
    The function saves in ref the pointer to the item or to a newly created
    item that is considered as a replacement for the original one.

  NOTES
    Let T0(e)/T1(e) be the value of not_null_tables(e) when e is used on
    a predicate/function level. Then it's easy to show that:
      T0(e IN(e1,...,en))     = union(T1(e),intersection(T1(ei)))
      T1(e IN(e1,...,en))     = union(T1(e),intersection(T1(ei)))
      T0(e NOT IN(e1,...,en)) = union(T1(e),union(T1(ei)))
      T1(e NOT IN(e1,...,en)) = union(T1(e),intersection(T1(ei)))

  RETURN
    0   ok
    1   got error
*/

bool
3170
Item_func_in::fix_fields(THD *thd, Item **ref)
unknown's avatar
unknown committed
3171 3172 3173
{
  Item **arg, **arg_end;

3174
  if (Item_func_opt_neg::fix_fields(thd, ref))
unknown's avatar
unknown committed
3175 3176 3177 3178 3179 3180 3181 3182 3183 3184 3185 3186 3187 3188 3189
    return 1;

  /* not_null_tables_cache == union(T1(e),union(T1(ei))) */
  if (pred_level && negated)
    return 0;

  /* not_null_tables_cache = union(T1(e),intersection(T1(ei))) */
  not_null_tables_cache= ~(table_map) 0;
  for (arg= args + 1, arg_end= args + arg_count; arg != arg_end; arg++)
    not_null_tables_cache&= (*arg)->not_null_tables();
  not_null_tables_cache|= (*args)->not_null_tables();
  return 0;
}


3190
static int srtcmp_in(CHARSET_INFO *cs, const String *x,const String *y)
3191
{
3192
  return cs->coll->strnncollsp(cs,
unknown's avatar
unknown committed
3193
                               (uchar *) x->ptr(),x->length(),
3194
                               (uchar *) y->ptr(),y->length(), 0);
3195 3196
}

3197

unknown's avatar
unknown committed
3198 3199
void Item_func_in::fix_length_and_dec()
{
3200 3201
  Item **arg, **arg_end;
  uint const_itm= 1;
3202
  THD *thd= current_thd;
3203 3204 3205 3206 3207
  bool datetime_found= FALSE;
  /* TRUE <=> arguments values will be compared as DATETIMEs. */
  bool compare_as_datetime= FALSE;
  Item *date_arg= 0;

3208 3209
  if (agg_cmp_type(thd, &cmp_type, args, arg_count))
    return;
3210

unknown's avatar
unknown committed
3211
  if (cmp_type == STRING_RESULT &&
3212
      agg_arg_charsets(cmp_collation, args, arg_count, MY_COLL_CMP_CONV, 1))
unknown's avatar
unknown committed
3213 3214
    return;

3215
  for (arg=args+1, arg_end=args+arg_count; arg != arg_end ; arg++)
unknown's avatar
unknown committed
3216 3217 3218 3219 3220 3221 3222
  {
    if (!arg[0]->const_item())
    {
      const_itm= 0;
      break;
    }
  }
3223 3224 3225 3226 3227 3228 3229 3230 3231 3232 3233 3234 3235 3236 3237 3238 3239 3240 3241 3242 3243 3244 3245 3246 3247
  /*
    When comparing rows create the row comparator object beforehand to ease
    the DATETIME comparison detection procedure.
  */
  if (cmp_type == ROW_RESULT)
  {
    cmp_item_row *cmp= 0;
    if (const_itm && !nulls_in_row())
    {
      array= new in_row(arg_count-1, 0);
      cmp= &((in_row*)array)->tmp;
    }
    else
    {
      if (!(cmp= new cmp_item_row))
        return;
      in_item= cmp;
    }
    cmp->n= args[0]->cols();
    cmp->alloc_comparators();
  }
  /* All DATE/DATETIME fields/functions has the STRING result type. */
  if (cmp_type == STRING_RESULT || cmp_type == ROW_RESULT)
  {
    uint col, cols= args[0]->cols();
3248

3249 3250 3251 3252 3253 3254 3255 3256 3257 3258 3259 3260 3261 3262 3263 3264 3265 3266 3267 3268 3269 3270 3271 3272 3273 3274 3275 3276 3277 3278 3279 3280 3281 3282 3283 3284 3285 3286 3287 3288 3289 3290 3291 3292 3293 3294 3295 3296 3297 3298 3299 3300 3301 3302 3303
    for (col= 0; col < cols; col++)
    {
      bool skip_column= FALSE;
      /*
        Check that all items to be compared has the STRING result type and at
        least one of them is a DATE/DATETIME item.
      */
      for (arg= args, arg_end= args + arg_count; arg != arg_end ; arg++)
      {
        Item *itm= ((cmp_type == STRING_RESULT) ? arg[0] :
                    arg[0]->element_index(col));
        if (itm->result_type() != STRING_RESULT)
        {
          skip_column= TRUE;
          break;
        }
        else if (itm->is_datetime())
        {
          datetime_found= TRUE;
          /*
            Internally all DATE/DATETIME values are converted to the DATETIME
            type. So try to find a DATETIME item to issue correct warnings.
          */
          if (!date_arg)
            date_arg= itm;
          else if (itm->field_type() == MYSQL_TYPE_DATETIME)
          {
            date_arg= itm;
            /* All arguments are already checked to have the STRING result. */
            if (cmp_type == STRING_RESULT)
              break;
          }
        }
      }
      if (skip_column)
        continue;
      if (datetime_found)
      {
        if (cmp_type == ROW_RESULT)
        {
          cmp_item **cmp= 0;
          if (array)
            cmp= ((in_row*)array)->tmp.comparators + col;
          else
            cmp= ((cmp_item_row*)in_item)->comparators + col;
          *cmp= new cmp_item_datetime(date_arg);
          /* Reset variables for the next column. */
          date_arg= 0;
          datetime_found= FALSE;
        }
        else
          compare_as_datetime= TRUE;
      }
    }
  }
unknown's avatar
unknown committed
3304 3305 3306 3307
  /*
    Row item with NULLs inside can return NULL or FALSE => 
    they can't be processed as static
  */
3308
  if (const_itm && !nulls_in_row())
unknown's avatar
unknown committed
3309
  {
3310 3311 3312
    if (compare_as_datetime)
      array= new in_datetime(date_arg, arg_count - 1);
    else
unknown's avatar
unknown committed
3313
    {
3314 3315 3316 3317 3318 3319 3320 3321 3322 3323 3324
      /*
        IN must compare INT columns and constants as int values (the same
        way as equality does).
        So we must check here if the column on the left and all the constant 
        values on the right can be compared as integers and adjust the 
        comparison type accordingly.
      */  
      if (args[0]->real_item()->type() == FIELD_ITEM &&
          thd->lex->sql_command != SQLCOM_CREATE_VIEW &&
          thd->lex->sql_command != SQLCOM_SHOW_CREATE &&
          cmp_type != INT_RESULT)
unknown's avatar
unknown committed
3325
      {
3326 3327
        Field *field= ((Item_field*) (args[0]->real_item()))->field;
        if (field->can_be_compared_as_longlong())
unknown's avatar
unknown committed
3328
        {
3329 3330 3331 3332 3333 3334 3335 3336
          bool all_converted= TRUE;
          for (arg=args+1, arg_end=args+arg_count; arg != arg_end ; arg++)
          {
            if (!convert_constant_item (thd, field, &arg[0]))
              all_converted= FALSE;
          }
          if (all_converted)
            cmp_type= INT_RESULT;
unknown's avatar
unknown committed
3337 3338
        }
      }
3339 3340 3341 3342 3343 3344 3345 3346 3347 3348 3349 3350 3351 3352 3353 3354 3355 3356 3357 3358 3359 3360 3361 3362 3363 3364
      switch (cmp_type) {
      case STRING_RESULT:
        array=new in_string(arg_count-1,(qsort2_cmp) srtcmp_in, 
                            cmp_collation.collation);
        break;
      case INT_RESULT:
        array= new in_longlong(arg_count-1);
        break;
      case REAL_RESULT:
        array= new in_double(arg_count-1);
        break;
      case ROW_RESULT:
        /*
          The row comparator was created at the beginning but only DATETIME
          items comparators were initialized. Call store_value() to setup
          others.
        */
        ((in_row*)array)->tmp.store_value(args[0]);
        break;
      case DECIMAL_RESULT:
        array= new in_decimal(arg_count - 1);
        break;
      default:
        DBUG_ASSERT(0);
        return;
      }
unknown's avatar
unknown committed
3365
    }
3366
    if (array && !(thd->is_fatal_error))		// If not EOM
unknown's avatar
unknown committed
3367
    {
unknown's avatar
unknown committed
3368
      uint j=0;
unknown's avatar
unknown committed
3369
      for (uint i=1 ; i < arg_count ; i++)
unknown's avatar
unknown committed
3370 3371 3372 3373
      {
	array->set(j,args[i]);
	if (!args[i]->null_value)			// Skip NULL values
	  j++;
unknown's avatar
unknown committed
3374 3375
	else
	  have_null= 1;
unknown's avatar
unknown committed
3376 3377 3378
      }
      if ((array->used_count=j))
	array->sort();
unknown's avatar
unknown committed
3379 3380 3381 3382
    }
  }
  else
  {
3383 3384 3385 3386 3387 3388 3389 3390 3391 3392 3393 3394 3395
    if (in_item)
    {
      /*
        The row comparator was created at the beginning but only DATETIME
        items comparators were initialized. Call store_value() to setup
        others.
      */
      in_item->store_value(args[0]);
    }
    else if (compare_as_datetime)
      in_item= new cmp_item_datetime(date_arg);
    else
      in_item= cmp_item::get_comparator(cmp_type, cmp_collation.collation);
3396
    if (cmp_type  == STRING_RESULT)
3397
      in_item->cmp_charset= cmp_collation.collation;
unknown's avatar
unknown committed
3398
  }
unknown's avatar
unknown committed
3399
  max_length= 1;
unknown's avatar
unknown committed
3400 3401 3402 3403 3404 3405
}


void Item_func_in::print(String *str)
{
  str->append('(');
3406
  args[0]->print(str);
unknown's avatar
unknown committed
3407
  if (negated)
3408 3409
    str->append(STRING_WITH_LEN(" not"));
  str->append(STRING_WITH_LEN(" in ("));
unknown's avatar
unknown committed
3410
  print_args(str, 1);
3411
  str->append(STRING_WITH_LEN("))"));
unknown's avatar
unknown committed
3412 3413 3414 3415 3416
}


longlong Item_func_in::val_int()
{
3417
  DBUG_ASSERT(fixed == 1);
unknown's avatar
unknown committed
3418 3419
  if (array)
  {
3420 3421
    int tmp=array->find(args[0]);
    null_value=args[0]->null_value || (!tmp && have_null);
unknown's avatar
unknown committed
3422
    return (longlong) (!null_value && tmp != negated);
unknown's avatar
unknown committed
3423
  }
3424 3425
  in_item->store_value(args[0]);
  if ((null_value=args[0]->null_value))
unknown's avatar
unknown committed
3426
    return 0;
3427
  have_null= 0;
3428
  for (uint i=1 ; i < arg_count ; i++)
unknown's avatar
unknown committed
3429 3430
  {
    if (!in_item->cmp(args[i]) && !args[i]->null_value)
unknown's avatar
unknown committed
3431
      return (longlong) (!negated);
3432
    have_null|= args[i]->null_value;
unknown's avatar
unknown committed
3433
  }
3434
  null_value= have_null;
unknown's avatar
unknown committed
3435
  return (longlong) (!null_value && negated);
unknown's avatar
unknown committed
3436 3437 3438 3439 3440
}


longlong Item_func_bit_or::val_int()
{
3441
  DBUG_ASSERT(fixed == 1);
unknown's avatar
unknown committed
3442 3443 3444 3445 3446 3447 3448 3449 3450 3451 3452 3453 3454 3455 3456 3457 3458 3459 3460
  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()
{
3461
  DBUG_ASSERT(fixed == 1);
unknown's avatar
unknown committed
3462 3463 3464 3465 3466 3467 3468 3469 3470 3471 3472 3473 3474 3475 3476 3477
  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);
}

3478
Item_cond::Item_cond(THD *thd, Item_cond *item)
3479
  :Item_bool_func(thd, item),
3480 3481
   abort_on_null(item->abort_on_null),
   and_tables_cache(item->and_tables_cache)
3482 3483
{
  /*
unknown's avatar
unknown committed
3484
    item->list will be copied by copy_andor_arguments() call
3485 3486 3487
  */
}

unknown's avatar
unknown committed
3488

3489 3490 3491
void Item_cond::copy_andor_arguments(THD *thd, Item_cond *item)
{
  List_iterator_fast<Item> li(item->list);
unknown's avatar
unknown committed
3492
  while (Item *it= li++)
3493 3494
    list.push_back(it->copy_andor_structure(thd));
}
unknown's avatar
unknown committed
3495

unknown's avatar
unknown committed
3496

unknown's avatar
unknown committed
3497
bool
3498
Item_cond::fix_fields(THD *thd, Item **ref)
unknown's avatar
unknown committed
3499
{
3500
  DBUG_ASSERT(fixed == 0);
unknown's avatar
unknown committed
3501 3502
  List_iterator<Item> li(list);
  Item *item;
3503
#ifndef EMBEDDED_LIBRARY
unknown's avatar
unknown committed
3504
  char buff[sizeof(char*)];			// Max local vars in function
3505
#endif
3506
  not_null_tables_cache= used_tables_cache= 0;
unknown's avatar
unknown committed
3507
  const_item_cache= 1;
3508 3509 3510 3511 3512
  /*
    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
3513

3514
  if (check_stack_overrun(thd, STACK_MIN_SIZE, buff))
unknown's avatar
unknown committed
3515
    return TRUE;				// Fatal error flag is set!
3516 3517 3518 3519 3520 3521 3522 3523 3524 3525 3526 3527 3528 3529 3530
  /*
    The following optimization reduces the depth of an AND-OR tree.
    E.g. a WHERE clause like
      F1 AND (F2 AND (F2 AND F4))
    is parsed into a tree with the same nested structure as defined
    by braces. This optimization will transform such tree into
      AND (F1, F2, F3, F4).
    Trees of OR items are flattened as well:
      ((F1 OR F2) OR (F3 OR F4))   =>   OR (F1, F2, F3, F4)
    Items for removed AND/OR levels will dangle until the death of the
    entire statement.
    The optimization is currently prepared statements and stored procedures
    friendly as it doesn't allocate any memory and its effects are durable
    (i.e. do not depend on PS/SP arguments).
  */
unknown's avatar
unknown committed
3531 3532
  while ((item=li++))
  {
3533
    table_map tmp_table_map;
unknown's avatar
unknown committed
3534
    while (item->type() == Item::COND_ITEM &&
3535 3536
	   ((Item_cond*) item)->functype() == functype() &&
           !((Item_cond*) item)->list.is_empty())
unknown's avatar
unknown committed
3537 3538 3539 3540 3541
    {						// Identical function
      li.replace(((Item_cond*) item)->list);
      ((Item_cond*) item)->list.empty();
      item= *li.ref();				// new current item
    }
3542 3543
    if (abort_on_null)
      item->top_level_item();
3544 3545

    // item can be substituted in fix_fields
3546
    if ((!item->fixed &&
3547
	 item->fix_fields(thd, li.ref())) ||
3548
	(item= *li.ref())->check_cols(1))
unknown's avatar
unknown committed
3549
      return TRUE; /* purecov: inspected */
3550
    used_tables_cache|=     item->used_tables();
unknown's avatar
unknown committed
3551 3552 3553
    if (item->const_item())
      and_tables_cache= (table_map) 0;
    else
unknown's avatar
unknown committed
3554 3555 3556 3557 3558 3559
    {
      tmp_table_map= item->not_null_tables();
      not_null_tables_cache|= tmp_table_map;
      and_tables_cache&= tmp_table_map;
      const_item_cache= FALSE;
    }  
3560
    with_sum_func=	    with_sum_func || item->with_sum_func;
3561
    with_subselect|=        item->with_subselect;
unknown's avatar
unknown committed
3562 3563
    if (item->maybe_null)
      maybe_null=1;
unknown's avatar
unknown committed
3564
  }
3565
  thd->lex->current_select->cond_count+= list.elements;
unknown's avatar
unknown committed
3566
  fix_length_and_dec();
3567
  fixed= 1;
unknown's avatar
unknown committed
3568
  return FALSE;
unknown's avatar
unknown committed
3569 3570
}

unknown's avatar
unknown committed
3571 3572 3573 3574 3575 3576 3577 3578 3579 3580
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);
}

unknown's avatar
unknown committed
3581 3582 3583 3584 3585 3586

/*
  Transform an Item_cond object with a transformer callback function
   
  SYNOPSIS
    transform()
3587 3588 3589
      transformer   the transformer callback function to be applied to the nodes
                    of the tree of the object
      arg           parameter to be passed to the transformer
unknown's avatar
unknown committed
3590 3591
  
  DESCRIPTION
3592 3593
    The function recursively applies the transform method to each
     member item of the condition list.
unknown's avatar
unknown committed
3594 3595
    If the call of the method for a member item returns a new item
    the old item is substituted for a new one.
3596
    After this the transformer is applied to the root node
unknown's avatar
unknown committed
3597 3598 3599 3600 3601 3602 3603
    of the Item_cond object. 
     
  RETURN VALUES
    Item returned as the result of transformation of the root node 
*/

Item *Item_cond::transform(Item_transformer transformer, byte *arg)
3604
{
3605 3606
  DBUG_ASSERT(!current_thd->is_stmt_prepare());

3607 3608 3609 3610
  List_iterator<Item> li(list);
  Item *item;
  while ((item= li++))
  {
unknown's avatar
unknown committed
3611
    Item *new_item= item->transform(transformer, arg);
3612 3613
    if (!new_item)
      return 0;
3614 3615 3616 3617 3618 3619 3620

    /*
      THD::change_item_tree() should be called only if the tree was
      really transformed, i.e. when a new item has been created.
      Otherwise we'll be allocating a lot of unnecessary memory for
      change records at each execution.
    */
3621
    if (new_item != item)
3622
      current_thd->change_item_tree(li.ref(), new_item);
3623
  }
unknown's avatar
unknown committed
3624
  return Item_func::transform(transformer, arg);
3625 3626
}

3627 3628 3629 3630 3631 3632 3633 3634 3635 3636 3637 3638 3639 3640 3641 3642 3643 3644 3645 3646 3647 3648 3649 3650 3651 3652 3653 3654 3655 3656 3657 3658 3659 3660 3661 3662 3663 3664 3665 3666 3667

/*
  Compile Item_cond object with a processor and a transformer callback functions
   
  SYNOPSIS
    compile()
      analyzer      the analyzer callback function to be applied to the nodes
                    of the tree of the object
      arg_p         in/out parameter to be passed to the analyzer
      transformer   the transformer callback function to be applied to the nodes
                    of the tree of the object
      arg_t         parameter to be passed to the transformer
  
  DESCRIPTION
    First the function applies the analyzer to the root node of
    the Item_func object. Then if the analyzer succeeeds (returns TRUE)
    the function recursively applies the compile method to member
    item of the condition list.
    If the call of the method for a member item returns a new item
    the old item is substituted for a new one.
    After this the transformer is applied to the root node
    of the Item_cond object. 
     
  RETURN VALUES
    Item returned as the result of transformation of the root node 
*/

Item *Item_cond::compile(Item_analyzer analyzer, byte **arg_p,
                         Item_transformer transformer, byte *arg_t)
{
  if (!(this->*analyzer)(arg_p))
    return 0;
  
  List_iterator<Item> li(list);
  Item *item;
  while ((item= li++))
  {
    /* 
      The same parameter value of arg_p must be passed
      to analyze any argument of the condition formula.
    */   
3668
    byte *arg_v= *arg_p;
3669 3670 3671 3672 3673 3674 3675
    Item *new_item= item->compile(analyzer, &arg_v, transformer, arg_t);
    if (new_item && new_item != item)
      li.replace(new_item);
  }
  return Item_func::transform(transformer, arg_t);
}

3676 3677
void Item_cond::traverse_cond(Cond_traverser traverser,
                              void *arg, traverse_order order)
3678 3679 3680 3681
{
  List_iterator<Item> li(list);
  Item *item;

3682 3683 3684 3685 3686 3687 3688
  switch(order) {
  case(PREFIX):
    (*traverser)(this, arg);
    while ((item= li++))
    {
      item->traverse_cond(traverser, arg, order);
    }
3689
    (*traverser)(NULL, arg);
3690 3691 3692 3693 3694 3695 3696
    break;
  case(POSTFIX):
    while ((item= li++))
    {
      item->traverse_cond(traverser, arg, order);
    }
    (*traverser)(this, arg);
3697 3698
  }
}
unknown's avatar
unknown committed
3699

3700 3701 3702 3703
/*
  Move SUM items out from item tree and replace with reference

  SYNOPSIS
3704 3705 3706 3707
    split_sum_func()
    thd			Thread handler
    ref_pointer_array	Pointer to array of reference fields
    fields		All fields in select
3708 3709 3710 3711 3712 3713 3714 3715 3716 3717 3718

  NOTES
   This function is run on all expression (SELECT list, WHERE, HAVING etc)
   that have or refer (HAVING) to a SUM expression.

   The split is done to get an unique item for each SUM function
   so that we can easily find and calculate them.
   (Calculation done by update_sum_func() and copy_sum_funcs() in
   sql_select.cc)
*/

3719 3720
void Item_cond::split_sum_func(THD *thd, Item **ref_pointer_array,
                               List<Item> &fields)
unknown's avatar
unknown committed
3721 3722 3723
{
  List_iterator<Item> li(list);
  Item *item;
3724
  while ((item= li++))
unknown's avatar
unknown committed
3725
    item->split_sum_func2(thd, ref_pointer_array, fields, li.ref(), TRUE);
unknown's avatar
unknown committed
3726 3727 3728 3729 3730 3731 3732 3733 3734
}


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

3735

unknown's avatar
unknown committed
3736 3737
void Item_cond::update_used_tables()
{
unknown's avatar
unknown committed
3738
  List_iterator_fast<Item> li(list);
unknown's avatar
unknown committed
3739
  Item *item;
3740 3741 3742

  used_tables_cache=0;
  const_item_cache=1;
unknown's avatar
unknown committed
3743 3744 3745
  while ((item=li++))
  {
    item->update_used_tables();
3746
    used_tables_cache|= item->used_tables();
unknown's avatar
unknown committed
3747
    const_item_cache&= item->const_item();
unknown's avatar
unknown committed
3748 3749 3750 3751 3752 3753 3754
  }
}


void Item_cond::print(String *str)
{
  str->append('(');
unknown's avatar
unknown committed
3755
  List_iterator_fast<Item> li(list);
unknown's avatar
unknown committed
3756 3757 3758 3759 3760 3761 3762 3763 3764 3765 3766 3767 3768
  Item *item;
  if ((item=li++))
    item->print(str);
  while ((item=li++))
  {
    str->append(' ');
    str->append(func_name());
    str->append(' ');
    item->print(str);
  }
  str->append(')');
}

3769

3770
void Item_cond::neg_arguments(THD *thd)
3771 3772 3773 3774 3775
{
  List_iterator<Item> li(list);
  Item *item;
  while ((item= li++))		/* Apply not transformation to the arguments */
  {
3776 3777 3778
    Item *new_item= item->neg_transformer(thd);
    if (!new_item)
    {
unknown's avatar
unknown committed
3779 3780
      if (!(new_item= new Item_func_not(item)))
	return;					// Fatal OEM error
3781 3782
    }
    VOID(li.replace(new_item));
3783 3784 3785 3786
  }
}


3787
/*
unknown's avatar
unknown committed
3788
  Evaluation of AND(expr, expr, expr ...)
3789 3790 3791 3792 3793 3794 3795 3796 3797 3798 3799 3800 3801 3802 3803

  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
3804 3805 3806

longlong Item_cond_and::val_int()
{
3807
  DBUG_ASSERT(fixed == 1);
unknown's avatar
unknown committed
3808
  List_iterator_fast<Item> li(list);
unknown's avatar
unknown committed
3809
  Item *item;
3810
  null_value= 0;
unknown's avatar
unknown committed
3811 3812
  while ((item=li++))
  {
unknown's avatar
unknown committed
3813
    if (!item->val_bool())
unknown's avatar
unknown committed
3814
    {
3815 3816
      if (abort_on_null || !(null_value= item->null_value))
	return 0;				// return FALSE
unknown's avatar
unknown committed
3817 3818
    }
  }
3819
  return null_value ? 0 : 1;
unknown's avatar
unknown committed
3820 3821
}

3822

unknown's avatar
unknown committed
3823 3824
longlong Item_cond_or::val_int()
{
3825
  DBUG_ASSERT(fixed == 1);
unknown's avatar
unknown committed
3826
  List_iterator_fast<Item> li(list);
unknown's avatar
unknown committed
3827 3828 3829 3830
  Item *item;
  null_value=0;
  while ((item=li++))
  {
unknown's avatar
unknown committed
3831
    if (item->val_bool())
unknown's avatar
unknown committed
3832 3833 3834 3835 3836 3837 3838 3839 3840 3841
    {
      null_value=0;
      return 1;
    }
    if (item->null_value)
      null_value=1;
  }
  return 0;
}

3842 3843 3844 3845 3846 3847 3848 3849 3850 3851 3852 3853 3854 3855 3856 3857 3858 3859 3860 3861 3862 3863 3864 3865
/*
  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)
3866
    return (*org_item= (Item*) b);
3867 3868 3869
  if (a == *org_item)
  {
    Item_cond *res;
3870
    if ((res= new Item_cond_and(a, (Item*) b)))
3871
    {
3872
      res->used_tables_cache= a->used_tables() | b->used_tables();
3873 3874
      res->not_null_tables_cache= a->not_null_tables() | b->not_null_tables();
    }
3875 3876
    return res;
  }
3877
  if (((Item_cond_and*) a)->add((Item*) b))
3878 3879
    return 0;
  ((Item_cond_and*) a)->used_tables_cache|= b->used_tables();
3880
  ((Item_cond_and*) a)->not_null_tables_cache|= b->not_null_tables();
3881 3882 3883 3884
  return a;
}


unknown's avatar
unknown committed
3885 3886
longlong Item_func_isnull::val_int()
{
3887
  DBUG_ASSERT(fixed == 1);
3888 3889 3890 3891
  /*
    Handle optimization if the argument can't be null
    This has to be here because of the test in update_used_tables().
  */
unknown's avatar
unknown committed
3892
  if (!used_tables_cache && !with_subselect)
unknown's avatar
unknown committed
3893
    return cached_value;
unknown's avatar
unknown committed
3894
  return args[0]->is_null() ? 1: 0;
unknown's avatar
unknown committed
3895 3896
}

3897 3898
longlong Item_is_not_null_test::val_int()
{
3899
  DBUG_ASSERT(fixed == 1);
3900
  DBUG_ENTER("Item_is_not_null_test::val_int");
unknown's avatar
unknown committed
3901
  if (!used_tables_cache && !with_subselect)
3902 3903
  {
    owner->was_null|= (!cached_value);
unknown's avatar
unknown committed
3904
    DBUG_PRINT("info", ("cached :%ld", (long) cached_value));
3905 3906 3907 3908 3909 3910 3911 3912 3913 3914 3915 3916 3917 3918 3919 3920 3921 3922 3923 3924 3925 3926 3927
    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();
unknown's avatar
unknown committed
3928
    if (!(used_tables_cache=args[0]->used_tables()) && !with_subselect)
3929 3930 3931 3932 3933 3934
    {
      /* Remember if the value is always NULL or never NULL */
      cached_value= (longlong) !args[0]->is_null();
    }
  }
}
3935

3936

unknown's avatar
unknown committed
3937 3938
longlong Item_func_isnotnull::val_int()
{
3939
  DBUG_ASSERT(fixed == 1);
unknown's avatar
unknown committed
3940
  return args[0]->is_null() ? 0 : 1;
unknown's avatar
unknown committed
3941 3942 3943
}


3944 3945 3946 3947
void Item_func_isnotnull::print(String *str)
{
  str->append('(');
  args[0]->print(str);
3948
  str->append(STRING_WITH_LEN(" is not null)"));
3949 3950 3951
}


unknown's avatar
unknown committed
3952 3953
longlong Item_func_like::val_int()
{
3954
  DBUG_ASSERT(fixed == 1);
3955
  String* res = args[0]->val_str(&tmp_value1);
unknown's avatar
unknown committed
3956 3957 3958 3959 3960
  if (args[0]->null_value)
  {
    null_value=1;
    return 0;
  }
3961
  String* res2 = args[1]->val_str(&tmp_value2);
unknown's avatar
unknown committed
3962 3963 3964 3965 3966 3967
  if (args[1]->null_value)
  {
    null_value=1;
    return 0;
  }
  null_value=0;
3968 3969
  if (canDoTurboBM)
    return turboBM_matches(res->ptr(), res->length()) ? 1 : 0;
3970
  return my_wildcmp(cmp.cmp_collation.collation,
3971 3972 3973
		    res->ptr(),res->ptr()+res->length(),
		    res2->ptr(),res2->ptr()+res2->length(),
		    escape,wild_one,wild_many) ? 0 : 1;
unknown's avatar
unknown committed
3974 3975 3976 3977 3978 3979 3980
}


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

Item_func::optimize_type Item_func_like::select_optimize() const
{
3981
  if (args[1]->const_item())
unknown's avatar
unknown committed
3982
  {
3983 3984 3985 3986 3987 3988
    String* res2= args[1]->val_str((String *)&tmp_value2);

    if (!res2)
      return OPTIMIZE_NONE;

    if (*res2->ptr() != wild_many)
unknown's avatar
unknown committed
3989
    {
3990
      if (args[0]->result_type() != STRING_RESULT || *res2->ptr() != wild_one)
unknown's avatar
unknown committed
3991 3992 3993 3994 3995 3996
	return OPTIMIZE_OP;
    }
  }
  return OPTIMIZE_NONE;
}

3997

3998
bool Item_func_like::fix_fields(THD *thd, Item **ref)
3999
{
4000
  DBUG_ASSERT(fixed == 0);
4001 4002
  if (Item_bool_func2::fix_fields(thd, ref) ||
      escape_item->fix_fields(thd, &escape_item))
unknown's avatar
unknown committed
4003
    return TRUE;
4004

4005
  if (!escape_item->const_during_execution())
4006
  {
4007
    my_error(ER_WRONG_ARGUMENTS,MYF(0),"ESCAPE");
unknown's avatar
unknown committed
4008
    return TRUE;
4009 4010 4011 4012 4013 4014
  }
  
  if (escape_item->const_item())
  {
    /* If we are on execution stage */
    String *escape_str= escape_item->val_str(&tmp_value1);
4015 4016
    if (escape_str)
    {
4017 4018 4019 4020 4021 4022 4023 4024 4025
      if (escape_used_in_parsing && (
             (((thd->variables.sql_mode & MODE_NO_BACKSLASH_ESCAPES) &&
                escape_str->numchars() != 1) ||
               escape_str->numchars() > 1)))
      {
        my_error(ER_WRONG_ARGUMENTS,MYF(0),"ESCAPE");
        return TRUE;
      }

unknown's avatar
unknown committed
4026
      if (use_mb(cmp.cmp_collation.collation))
4027
      {
4028
        CHARSET_INFO *cs= escape_str->charset();
4029 4030 4031 4032 4033 4034 4035 4036 4037
        my_wc_t wc;
        int rc= cs->cset->mb_wc(cs, &wc,
                                (const uchar*) escape_str->ptr(),
                                (const uchar*) escape_str->ptr() +
                                               escape_str->length());
        escape= (int) (rc > 0 ? wc : '\\');
      }
      else
      {
unknown's avatar
unknown committed
4038 4039 4040 4041 4042
        /*
          In the case of 8bit character set, we pass native
          code instead of Unicode code as "escape" argument.
          Convert to "cs" if charset of escape differs.
        */
unknown's avatar
unknown committed
4043
        CHARSET_INFO *cs= cmp.cmp_collation.collation;
unknown's avatar
unknown committed
4044 4045 4046 4047 4048 4049 4050 4051 4052 4053 4054 4055 4056
        uint32 unused;
        if (escape_str->needs_conversion(escape_str->length(),
                                         escape_str->charset(), cs, &unused))
        {
          char ch;
          uint errors;
          uint32 cnvlen= copy_and_convert(&ch, 1, cs, escape_str->ptr(),
                                          escape_str->length(),
                                          escape_str->charset(), &errors);
          escape= cnvlen ? ch : '\\';
        }
        else
          escape= *(escape_str->ptr());
4057 4058 4059 4060
      }
    }
    else
      escape= '\\';
unknown's avatar
unknown committed
4061

4062
    /*
4063 4064
      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.
4065
    */
4066 4067
    if (args[1]->const_item() && !use_strnxfrm(collation.collation) &&
       !(specialflag & SPECIAL_NO_NEW_FUNC))
4068
    {
4069 4070
      String* res2 = args[1]->val_str(&tmp_value2);
      if (!res2)
unknown's avatar
unknown committed
4071
        return FALSE;				// Null argument
4072 4073 4074 4075 4076 4077 4078 4079 4080 4081 4082 4083 4084 4085 4086 4087 4088 4089 4090 4091
      
      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;
        for (; *tmp != wild_many && *tmp != wild_one && *tmp != escape; tmp++) ;
        canDoTurboBM = (tmp == last) && !use_mb(args[0]->collation.collation);
      }
      if (canDoTurboBM)
      {
        pattern     = first + 1;
4092
        pattern_len = (int) len - 2;
4093
        DBUG_PRINT("info", ("Initializing pattern: '%s'", first));
4094 4095 4096
        int *suff = (int*) thd->alloc((int) (sizeof(int)*
                                      ((pattern_len + 1)*2+
                                      alphabet_size)));
4097 4098 4099 4100 4101 4102
        bmGs      = suff + pattern_len + 1;
        bmBc      = bmGs + pattern_len + 1;
        turboBM_compute_good_suffix_shifts(suff);
        turboBM_compute_bad_character_shifts();
        DBUG_PRINT("info",("done"));
      }
4103 4104
    }
  }
unknown's avatar
unknown committed
4105
  return FALSE;
4106 4107
}

4108 4109 4110 4111 4112 4113
void Item_func_like::cleanup()
{
  canDoTurboBM= FALSE;
  Item_bool_func2::cleanup();
}

unknown's avatar
unknown committed
4114 4115 4116
#ifdef USE_REGEX

bool
4117
Item_func_regex::fix_fields(THD *thd, Item **ref)
unknown's avatar
unknown committed
4118
{
4119
  DBUG_ASSERT(fixed == 0);
unknown's avatar
unknown committed
4120
  if ((!args[0]->fixed &&
4121
       args[0]->fix_fields(thd, args)) || args[0]->check_cols(1) ||
unknown's avatar
unknown committed
4122
      (!args[1]->fixed &&
4123
       args[1]->fix_fields(thd, args + 1)) || args[1]->check_cols(1))
unknown's avatar
unknown committed
4124
    return TRUE;				/* purecov: inspected */
unknown's avatar
unknown committed
4125
  with_sum_func=args[0]->with_sum_func || args[1]->with_sum_func;
unknown's avatar
unknown committed
4126 4127
  max_length= 1;
  decimals= 0;
4128

4129
  if (agg_arg_charsets(cmp_collation, args, 2, MY_COLL_CMP_CONV, 1))
unknown's avatar
unknown committed
4130
    return TRUE;
4131

unknown's avatar
unknown committed
4132
  used_tables_cache=args[0]->used_tables() | args[1]->used_tables();
4133 4134
  not_null_tables_cache= (args[0]->not_null_tables() |
			  args[1]->not_null_tables());
unknown's avatar
unknown committed
4135 4136 4137 4138
  const_item_cache=args[0]->const_item() && args[1]->const_item();
  if (!regex_compiled && args[1]->const_item())
  {
    char buff[MAX_FIELD_WIDTH];
4139
    String tmp(buff,sizeof(buff),&my_charset_bin);
unknown's avatar
unknown committed
4140 4141 4142 4143
    String *res=args[1]->val_str(&tmp);
    if (args[1]->null_value)
    {						// Will always return NULL
      maybe_null=1;
unknown's avatar
unknown committed
4144
      return FALSE;
unknown's avatar
unknown committed
4145 4146
    }
    int error;
unknown's avatar
unknown committed
4147 4148 4149 4150 4151 4152
    if ((error= my_regcomp(&preg,res->c_ptr(),
                           ((cmp_collation.collation->state &
                             (MY_CS_BINSORT | MY_CS_CSSORT)) ?
                            REG_EXTENDED | REG_NOSUB :
                            REG_EXTENDED | REG_NOSUB | REG_ICASE),
                           cmp_collation.collation)))
unknown's avatar
unknown committed
4153
    {
unknown's avatar
unknown committed
4154
      (void) my_regerror(error,&preg,buff,sizeof(buff));
4155
      my_error(ER_REGEXP_ERROR, MYF(0), buff);
unknown's avatar
unknown committed
4156
      return TRUE;
unknown's avatar
unknown committed
4157 4158 4159 4160 4161 4162
    }
    regex_compiled=regex_is_const=1;
    maybe_null=args[0]->maybe_null;
  }
  else
    maybe_null=1;
4163
  fixed= 1;
unknown's avatar
unknown committed
4164
  return FALSE;
unknown's avatar
unknown committed
4165 4166
}

4167

unknown's avatar
unknown committed
4168 4169
longlong Item_func_regex::val_int()
{
4170
  DBUG_ASSERT(fixed == 1);
unknown's avatar
unknown committed
4171
  char buff[MAX_FIELD_WIDTH];
4172
  String *res, tmp(buff,sizeof(buff),&my_charset_bin);
unknown's avatar
unknown committed
4173 4174 4175 4176 4177 4178 4179 4180 4181 4182

  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];
4183
    String *res2, tmp2(buff2,sizeof(buff2),&my_charset_bin);
unknown's avatar
unknown committed
4184 4185 4186 4187 4188 4189 4190

    res2= args[1]->val_str(&tmp2);
    if (args[1]->null_value)
    {
      null_value=1;
      return 0;
    }
unknown's avatar
unknown committed
4191
    if (!regex_compiled || stringcmp(res2,&prev_regexp))
unknown's avatar
unknown committed
4192 4193 4194 4195
    {
      prev_regexp.copy(*res2);
      if (regex_compiled)
      {
unknown's avatar
unknown committed
4196
	my_regfree(&preg);
unknown's avatar
unknown committed
4197 4198
	regex_compiled=0;
      }
unknown's avatar
Merge  
unknown committed
4199
      if (my_regcomp(&preg,res2->c_ptr_safe(),
unknown's avatar
unknown committed
4200 4201 4202 4203 4204
                     ((cmp_collation.collation->state &
                       (MY_CS_BINSORT | MY_CS_CSSORT)) ?
                      REG_EXTENDED | REG_NOSUB :
                      REG_EXTENDED | REG_NOSUB | REG_ICASE),
                     cmp_collation.collation))
unknown's avatar
unknown committed
4205 4206 4207 4208 4209 4210 4211 4212
      {
	null_value=1;
	return 0;
      }
      regex_compiled=1;
    }
  }
  null_value=0;
4213
  return my_regexec(&preg,res->c_ptr_safe(),0,(my_regmatch_t*) 0,0) ? 0 : 1;
unknown's avatar
unknown committed
4214 4215 4216
}


4217
void Item_func_regex::cleanup()
unknown's avatar
unknown committed
4218
{
4219 4220
  DBUG_ENTER("Item_func_regex::cleanup");
  Item_bool_func::cleanup();
unknown's avatar
unknown committed
4221 4222
  if (regex_compiled)
  {
unknown's avatar
unknown committed
4223
    my_regfree(&preg);
unknown's avatar
unknown committed
4224 4225
    regex_compiled=0;
  }
4226
  DBUG_VOID_RETURN;
unknown's avatar
unknown committed
4227 4228
}

4229

unknown's avatar
unknown committed
4230
#endif /* USE_REGEX */
4231 4232 4233


#ifdef LIKE_CMP_TOUPPER
unknown's avatar
unknown committed
4234
#define likeconv(cs,A) (uchar) (cs)->toupper(A)
4235
#else
unknown's avatar
unknown committed
4236
#define likeconv(cs,A) (uchar) (cs)->sort_order[(uchar) (A)]
4237 4238 4239 4240 4241 4242 4243 4244
#endif


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

4245
void Item_func_like::turboBM_compute_suffixes(int *suff)
4246 4247 4248 4249
{
  const int   plm1 = pattern_len - 1;
  int            f = 0;
  int            g = plm1;
unknown's avatar
unknown committed
4250
  int *const splm1 = suff + plm1;
4251
  CHARSET_INFO	*cs= cmp.cmp_collation.collation;
4252 4253 4254

  *splm1 = pattern_len;

unknown's avatar
unknown committed
4255
  if (!cs->sort_order)
4256 4257 4258 4259 4260 4261 4262 4263 4264 4265 4266 4267 4268 4269 4270 4271 4272 4273 4274 4275 4276 4277 4278 4279 4280 4281 4282 4283 4284 4285 4286
  {
    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;
4287
	while (g >= 0 &&
unknown's avatar
unknown committed
4288
	       likeconv(cs, pattern[g]) == likeconv(cs, pattern[g + plm1 - f]))
4289 4290 4291 4292 4293 4294 4295 4296 4297 4298 4299 4300 4301
	  g--;
	suff[i] = f - g;
      }
    }
  }
}


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

4302
void Item_func_like::turboBM_compute_good_suffix_shifts(int *suff)
4303 4304 4305
{
  turboBM_compute_suffixes(suff);

4306 4307
  int *end = bmGs + pattern_len;
  int *k;
4308 4309 4310 4311 4312 4313 4314 4315 4316 4317 4318 4319 4320
  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++)
      {
4321
	int *tmp2 = bmGs + j;
4322 4323 4324 4325 4326 4327
	if (*tmp2 == pattern_len)
	  *tmp2 = tmp;
      }
    }
  }

4328
  int *tmp2;
4329 4330 4331 4332 4333 4334 4335 4336 4337 4338 4339 4340 4341 4342 4343 4344 4345 4346 4347 4348
  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
4349 4350 4351 4352
  int *i;
  int *end = bmBc + alphabet_size;
  int j;
  const int plm1 = pattern_len - 1;
4353
  CHARSET_INFO	*cs= cmp.cmp_collation.collation;
unknown's avatar
unknown committed
4354

4355 4356 4357
  for (i = bmBc; i < end; i++)
    *i = pattern_len;

unknown's avatar
unknown committed
4358
  if (!cs->sort_order)
unknown's avatar
unknown committed
4359
  {
4360
    for (j = 0; j < plm1; j++)
4361
      bmBc[(uint) (uchar) pattern[j]] = plm1 - j;
unknown's avatar
unknown committed
4362
  }
4363
  else
unknown's avatar
unknown committed
4364
  {
4365
    for (j = 0; j < plm1; j++)
unknown's avatar
unknown committed
4366
      bmBc[(uint) likeconv(cs,pattern[j])] = plm1 - j;
unknown's avatar
unknown committed
4367
  }
4368 4369 4370 4371 4372 4373 4374 4375 4376 4377 4378 4379 4380 4381 4382
}


/**********************************************************************
  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;
4383
  CHARSET_INFO	*cs= cmp.cmp_collation.collation;
4384

4385 4386
  const int plm1=  pattern_len - 1;
  const int tlmpl= text_len - pattern_len;
4387 4388

  /* Searching */
unknown's avatar
unknown committed
4389
  if (!cs->sort_order)
4390 4391 4392
  {
    while (j <= tlmpl)
    {
4393
      register int i= plm1;
4394 4395 4396 4397
      while (i >= 0 && pattern[i] == text[i + j])
      {
	i--;
	if (i == plm1 - shift)
4398
	  i-= u;
4399 4400
      }
      if (i < 0)
unknown's avatar
unknown committed
4401
	return 1;
4402 4403 4404

      register const int v = plm1 - i;
      turboShift = u - v;
4405
      bcShift    = bmBc[(uint) (uchar) text[i + j]] - plm1 + i;
4406 4407 4408 4409 4410 4411 4412 4413 4414 4415
      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;
      }
4416
      j+= shift;
4417
    }
unknown's avatar
unknown committed
4418
    return 0;
4419 4420 4421 4422 4423 4424
  }
  else
  {
    while (j <= tlmpl)
    {
      register int i = plm1;
unknown's avatar
unknown committed
4425
      while (i >= 0 && likeconv(cs,pattern[i]) == likeconv(cs,text[i + j]))
4426 4427 4428
      {
	i--;
	if (i == plm1 - shift)
4429
	  i-= u;
4430 4431
      }
      if (i < 0)
unknown's avatar
unknown committed
4432
	return 1;
4433 4434 4435

      register const int v = plm1 - i;
      turboShift = u - v;
unknown's avatar
unknown committed
4436
      bcShift    = bmBc[(uint) likeconv(cs, text[i + j])] - plm1 + i;
4437 4438 4439 4440 4441 4442 4443 4444 4445 4446
      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;
      }
4447
      j+= shift;
4448
    }
unknown's avatar
unknown committed
4449
    return 0;
4450 4451
  }
}
unknown's avatar
unknown committed
4452

4453 4454 4455 4456 4457 4458 4459 4460 4461 4462 4463 4464 4465 4466 4467 4468 4469 4470 4471 4472 4473

/*
  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
4474 4475
longlong Item_cond_xor::val_int()
{
4476
  DBUG_ASSERT(fixed == 1);
unknown's avatar
unknown committed
4477 4478 4479
  List_iterator<Item> li(list);
  Item *item;
  int result=0;	
4480
  null_value=0;
unknown's avatar
unknown committed
4481 4482
  while ((item=li++))
  {
4483 4484 4485 4486 4487 4488
    result^= (item->val_int() != 0);
    if (item->null_value)
    {
      null_value=1;
      return 0;
    }
unknown's avatar
unknown committed
4489
  }
4490
  return (longlong) result;
unknown's avatar
unknown committed
4491
}
4492 4493 4494 4495

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

unknown's avatar
unknown committed
4496
  SYNOPSIS
4497
    neg_transformer()
4498
    thd		thread handler
4499 4500 4501 4502 4503 4504 4505 4506 4507 4508 4509 4510 4511 4512 4513 4514 4515 4516 4517 4518

  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)

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

4519
Item *Item_func_not::neg_transformer(THD *thd)	/* NOT(x)  ->  x */
4520
{
unknown's avatar
unknown committed
4521
  return args[0];
4522 4523
}

4524 4525

Item *Item_bool_rowready_func2::neg_transformer(THD *thd)
4526
{
4527 4528
  Item *item= negated_item();
  return item;
4529 4530
}

4531 4532 4533

/* a IS NULL  ->  a IS NOT NULL */
Item *Item_func_isnull::neg_transformer(THD *thd)
4534
{
4535 4536
  Item *item= new Item_func_isnotnull(args[0]);
  return item;
4537 4538
}

4539 4540 4541

/* a IS NOT NULL  ->  a IS NULL */
Item *Item_func_isnotnull::neg_transformer(THD *thd)
4542
{
4543 4544
  Item *item= new Item_func_isnull(args[0]);
  return item;
4545 4546
}

4547 4548 4549

Item *Item_cond_and::neg_transformer(THD *thd)	/* NOT(a AND b AND ...)  -> */
					/* NOT a OR NOT b OR ... */
4550
{
4551 4552 4553
  neg_arguments(thd);
  Item *item= new Item_cond_or(list);
  return item;
4554 4555
}

4556 4557 4558

Item *Item_cond_or::neg_transformer(THD *thd)	/* NOT(a OR b OR ...)  -> */
					/* NOT a AND NOT b AND ... */
4559
{
4560 4561 4562
  neg_arguments(thd);
  Item *item= new Item_cond_and(list);
  return item;
4563 4564
}

4565

4566 4567 4568 4569 4570 4571 4572 4573 4574 4575 4576 4577 4578 4579 4580 4581 4582 4583 4584 4585 4586 4587
Item *Item_func_nop_all::neg_transformer(THD *thd)
{
  /* "NOT (e $cmp$ ANY (SELECT ...)) -> e $rev_cmp$" ALL (SELECT ...) */
  Item_func_not_all *new_item= new Item_func_not_all(args[0]);
  Item_allany_subselect *allany= (Item_allany_subselect*)args[0];
  allany->func= allany->func_creator(FALSE);
  allany->all= !allany->all;
  allany->upper_item= new_item;
  return new_item;
}

Item *Item_func_not_all::neg_transformer(THD *thd)
{
  /* "NOT (e $cmp$ ALL (SELECT ...)) -> e $rev_cmp$" ANY (SELECT ...) */
  Item_func_nop_all *new_item= new Item_func_nop_all(args[0]);
  Item_allany_subselect *allany= (Item_allany_subselect*)args[0];
  allany->all= !allany->all;
  allany->func= allany->func_creator(TRUE);
  allany->upper_item= new_item;
  return new_item;
}

4588
Item *Item_func_eq::negated_item()		/* a = b  ->  a != b */
4589
{
4590
  return new Item_func_ne(args[0], args[1]);
4591 4592
}

4593 4594

Item *Item_func_ne::negated_item()		/* a != b  ->  a = b */
4595
{
4596
  return new Item_func_eq(args[0], args[1]);
4597 4598
}

4599 4600

Item *Item_func_lt::negated_item()		/* a < b  ->  a >= b */
4601
{
4602
  return new Item_func_ge(args[0], args[1]);
4603 4604
}

4605 4606

Item *Item_func_ge::negated_item()		/* a >= b  ->  a < b */
4607
{
4608
  return new Item_func_lt(args[0], args[1]);
4609 4610
}

4611 4612

Item *Item_func_gt::negated_item()		/* a > b  ->  a <= b */
4613
{
4614
  return new Item_func_le(args[0], args[1]);
4615 4616
}

4617 4618

Item *Item_func_le::negated_item()		/* a <= b  ->  a > b */
4619
{
4620
  return new Item_func_gt(args[0], args[1]);
4621 4622
}

4623 4624
// just fake method, should never be called
Item *Item_bool_rowready_func2::negated_item()
4625
{
4626 4627
  DBUG_ASSERT(0);
  return 0;
4628
}
4629 4630 4631 4632 4633 4634 4635 4636 4637 4638 4639 4640 4641 4642 4643 4644 4645

Item_equal::Item_equal(Item_field *f1, Item_field *f2)
  : Item_bool_func(), const_item(0), eval_item(0), cond_false(0)
{
  const_item_cache= 0;
  fields.push_back(f1);
  fields.push_back(f2);
}

Item_equal::Item_equal(Item *c, Item_field *f)
  : Item_bool_func(), eval_item(0), cond_false(0)
{
  const_item_cache= 0;
  fields.push_back(f);
  const_item= c;
}

4646

4647 4648 4649 4650 4651 4652 4653 4654 4655 4656 4657 4658 4659 4660 4661 4662 4663 4664 4665 4666 4667 4668 4669 4670 4671
Item_equal::Item_equal(Item_equal *item_equal)
  : Item_bool_func(), eval_item(0), cond_false(0)
{
  const_item_cache= 0;
  List_iterator_fast<Item_field> li(item_equal->fields);
  Item_field *item;
  while ((item= li++))
  {
    fields.push_back(item);
  }
  const_item= item_equal->const_item;
  cond_false= item_equal->cond_false;
}

void Item_equal::add(Item *c)
{
  if (cond_false)
    return;
  if (!const_item)
  {
    const_item= c;
    return;
  }
  Item_func_eq *func= new Item_func_eq(c, const_item);
  func->set_cmp_func();
unknown's avatar
unknown committed
4672
  func->quick_fix_field();
unknown's avatar
unknown committed
4673 4674
  if ((cond_false= !func->val_int()))
    const_item_cache= 1;
4675 4676 4677 4678 4679 4680 4681
}

void Item_equal::add(Item_field *f)
{
  fields.push_back(f);
}

unknown's avatar
unknown committed
4682 4683
uint Item_equal::members()
{
4684
  return fields.elements;
unknown's avatar
unknown committed
4685 4686 4687 4688 4689 4690 4691 4692
}


/*
  Check whether a field is referred in the multiple equality 

  SYNOPSIS
    contains()
unknown's avatar
unknown committed
4693
    field   field whose occurrence is to be checked
unknown's avatar
unknown committed
4694 4695
  
  DESCRIPTION
unknown's avatar
unknown committed
4696
    The function checks whether field is occurred in the Item_equal object 
unknown's avatar
unknown committed
4697 4698 4699 4700 4701 4702
    
  RETURN VALUES
    1       if nultiple equality contains a reference to field
    0       otherwise    
*/

4703 4704 4705 4706 4707 4708 4709 4710 4711 4712 4713 4714
bool Item_equal::contains(Field *field)
{
  List_iterator_fast<Item_field> it(fields);
  Item_field *item;
  while ((item= it++))
  {
    if (field->eq(item->field))
        return 1;
  }
  return 0;
}

unknown's avatar
unknown committed
4715 4716 4717 4718 4719 4720 4721 4722 4723

/*
  Join members of another Item_equal object  

  SYNOPSIS
    merge()
    item    multiple equality whose members are to be joined
  
  DESCRIPTION
unknown's avatar
unknown committed
4724
    The function actually merges two multiple equalities.
unknown's avatar
unknown committed
4725 4726 4727 4728 4729 4730 4731 4732 4733
    After this operation the Item_equal object additionally contains
    the field items of another item of the type Item_equal.
    If the optional constant items are not equal the cond_false flag is
    set to 1.  
       
  RETURN VALUES
    none    
*/

4734 4735 4736 4737 4738 4739 4740 4741 4742 4743 4744
void Item_equal::merge(Item_equal *item)
{
  fields.concat(&item->fields);
  Item *c= item->const_item;
  if (c)
  {
    /* 
      The flag cond_false will be set to 1 after this, if 
      the multiple equality already contains a constant and its 
      value is  not equal to the value of c.
    */
unknown's avatar
unknown committed
4745
    add(c);
4746 4747 4748 4749
  }
  cond_false|= item->cond_false;
} 

unknown's avatar
unknown committed
4750 4751 4752 4753 4754 4755 4756 4757 4758 4759 4760 4761 4762 4763 4764 4765 4766 4767 4768 4769 4770 4771 4772 4773 4774 4775

/*
  Order field items in multiple equality according to a sorting criteria 

  SYNOPSIS
    sort()
    cmp          function to compare field item 
    arg          context extra parameter for the cmp function
  
  DESCRIPTION
    The function perform ordering of the field items in the Item_equal
    object according to the criteria determined by the cmp callback parameter.
    If cmp(item_field1,item_field2,arg)<0 than item_field1 must be
    placed after item_fiel2.

  IMPLEMENTATION
    The function sorts field items by the exchange sort algorithm.
    The list of field items is looked through and whenever two neighboring
    members follow in a wrong order they are swapped. This is performed
    again and again until we get all members in a right order.
         
  RETURN VALUES
    None    
*/

void Item_equal::sort(Item_field_cmpfunc cmp, void *arg)
4776 4777 4778 4779 4780 4781 4782 4783 4784 4785 4786 4787
{
  bool swap;
  List_iterator<Item_field> it(fields);
  do
  {
    Item_field *item1= it++;
    Item_field **ref1= it.ref();
    Item_field *item2;

    swap= FALSE;
    while ((item2= it++))
    {
unknown's avatar
unknown committed
4788 4789
      Item_field **ref2= it.ref();
      if (cmp(item1, item2, arg) < 0)
4790 4791 4792 4793 4794 4795 4796 4797 4798 4799 4800 4801 4802 4803 4804 4805
      {
        Item_field *item= *ref1;
        *ref1= *ref2;
        *ref2= item;
        swap= TRUE;
      }
      else
      {
        item1= item2;
        ref1= ref2;
      }
    }
    it.rewind();
  } while (swap);
}

unknown's avatar
unknown committed
4806 4807 4808 4809 4810

/*
  Check appearance of new constant items in the multiple equality object

  SYNOPSIS
4811
    update_const()
unknown's avatar
unknown committed
4812 4813 4814 4815 4816 4817 4818 4819 4820 4821 4822 4823
  
  DESCRIPTION
    The function checks appearance of new constant items among
    the members of multiple equalities. Each new constant item is
    compared with the designated constant item if there is any in the
    multiple equality. If there is none the first new constant item
    becomes designated.
      
  RETURN VALUES
    none    
*/

4824
void Item_equal::update_const()
unknown's avatar
unknown committed
4825 4826 4827 4828 4829 4830 4831 4832 4833 4834 4835 4836 4837
{
  List_iterator<Item_field> it(fields);
  Item *item;
  while ((item= it++))
  {
    if (item->const_item())
    {
      it.remove();
      add(item);
    }
  }
}

4838
bool Item_equal::fix_fields(THD *thd, Item **ref)
4839 4840 4841 4842 4843
{
  List_iterator_fast<Item_field> li(fields);
  Item *item;
  not_null_tables_cache= used_tables_cache= 0;
  const_item_cache= 0;
unknown's avatar
unknown committed
4844
  while ((item= li++))
4845 4846 4847 4848 4849 4850 4851 4852 4853 4854 4855 4856 4857 4858 4859 4860 4861 4862
  {
    table_map tmp_table_map;
    used_tables_cache|= item->used_tables();
    tmp_table_map= item->not_null_tables();
    not_null_tables_cache|= tmp_table_map;
    if (item->maybe_null)
      maybe_null=1;
  }
  fix_length_and_dec();
  fixed= 1;
  return 0;
}

void Item_equal::update_used_tables()
{
  List_iterator_fast<Item_field> li(fields);
  Item *item;
  not_null_tables_cache= used_tables_cache= 0;
unknown's avatar
unknown committed
4863 4864
  if ((const_item_cache= cond_false))
    return;
4865 4866 4867 4868 4869 4870 4871 4872 4873 4874
  while ((item=li++))
  {
    item->update_used_tables();
    used_tables_cache|= item->used_tables();
    const_item_cache&= item->const_item();
  }
}

longlong Item_equal::val_int()
{
4875
  Item_field *item_field;
4876 4877 4878 4879 4880 4881 4882
  if (cond_false)
    return 0;
  List_iterator_fast<Item_field> it(fields);
  Item *item= const_item ? const_item : it++;
  if ((null_value= item->null_value))
    return 0;
  eval_item->store_value(item);
4883
  while ((item_field= it++))
4884
  {
4885 4886 4887 4888 4889 4890
    /* Skip fields of non-const tables. They haven't been read yet */
    if (item_field->field->table->const_table)
    {
      if ((null_value= item_field->null_value) || eval_item->cmp(item_field))
        return 0;
    }
4891 4892 4893 4894 4895 4896
  }
  return 1;
}

void Item_equal::fix_length_and_dec()
{
unknown's avatar
unknown committed
4897
  Item *item= get_first();
unknown's avatar
unknown committed
4898 4899
  eval_item= cmp_item::get_comparator(item->result_type(),
                                      item->collation.collation);
4900 4901 4902 4903 4904 4905 4906 4907 4908 4909 4910 4911
}

bool Item_equal::walk(Item_processor processor, byte *arg)
{
  List_iterator_fast<Item_field> it(fields);
  Item *item;
  while ((item= it++))
    if (item->walk(processor, arg))
      return 1;
  return Item_func::walk(processor, arg);
}

unknown's avatar
unknown committed
4912
Item *Item_equal::transform(Item_transformer transformer, byte *arg)
4913
{
4914 4915
  DBUG_ASSERT(!current_thd->is_stmt_prepare());

4916 4917 4918 4919
  List_iterator<Item_field> it(fields);
  Item *item;
  while ((item= it++))
  {
unknown's avatar
unknown committed
4920
    Item *new_item= item->transform(transformer, arg);
4921 4922
    if (!new_item)
      return 0;
4923 4924 4925 4926 4927 4928 4929

    /*
      THD::change_item_tree() should be called only if the tree was
      really transformed, i.e. when a new item has been created.
      Otherwise we'll be allocating a lot of unnecessary memory for
      change records at each execution.
    */
4930
    if (new_item != item)
4931
      current_thd->change_item_tree((Item **) it.ref(), new_item);
4932
  }
unknown's avatar
unknown committed
4933
  return Item_func::transform(transformer, arg);
4934 4935 4936 4937 4938 4939 4940 4941
}

void Item_equal::print(String *str)
{
  str->append(func_name());
  str->append('(');
  List_iterator_fast<Item_field> it(fields);
  Item *item;
unknown's avatar
unknown committed
4942 4943 4944 4945 4946
  if (const_item)
    const_item->print(str);
  else
  {
    item= it++;
4947
    item->print(str);
unknown's avatar
unknown committed
4948
  }
4949 4950 4951 4952 4953 4954 4955 4956 4957
  while ((item= it++))
  {
    str->append(',');
    str->append(' ');
    item->print(str);
  }
  str->append(')');
}