~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to sql/item_cmpfunc.cc

Merging trunk changes from over weekend.

Show diffs side-by-side

added added

removed removed

Lines of Context:
304
304
  bool value= args[0]->val_bool();
305
305
 
306
306
  /*
307
 
    return TRUE if there was records in underlying select in max/min
 
307
    return true if there was records in underlying select in max/min
308
308
    optimization (ALL subquery)
309
309
  */
310
310
  if (empty_underlying_subquery())
335
335
  Item_func_not_all.
336
336
 
337
337
  @return
338
 
    (return TRUE if underlying subquery do not return rows) but if subquery
339
 
    returns some rows it return same value as argument (TRUE/FALSE).
 
338
    (return true if underlying subquery do not return rows) but if subquery
 
339
    returns some rows it return same value as argument (true/false).
340
340
*/
341
341
 
342
342
longlong Item_func_nop_all::val_int()
345
345
  longlong value= args[0]->val_int();
346
346
 
347
347
  /*
348
 
    return FALSE if there was records in underlying select in max/min
 
348
    return false if there was records in underlying select in max/min
349
349
    optimization (SAME/ANY subquery)
350
350
  */
351
351
  if (empty_underlying_subquery())
425
425
    /* Restore the original field value. */
426
426
    if (field_item->depended_from)
427
427
    {
428
 
      result= field->store(orig_field_val, TRUE);
 
428
      result= field->store(orig_field_val, true);
429
429
      /* orig_field_val must be a valid value that can be restored back. */
430
430
      DBUG_ASSERT(!result);
431
431
    }
581
581
        which would be transformed to:
582
582
        WHERE col= 'j'
583
583
      */
584
 
      (*a)->walk(&Item::set_no_const_sub, FALSE, (uchar*) 0);
585
 
      (*b)->walk(&Item::set_no_const_sub, FALSE, (uchar*) 0);
 
584
      (*a)->walk(&Item::set_no_const_sub, false, (uchar*) 0);
 
585
      (*b)->walk(&Item::set_no_const_sub, false, (uchar*) 0);
586
586
    }
587
587
    break;
588
588
  }
668
668
      Do not return yet, we may still want to throw a "trailing garbage"
669
669
      warning.
670
670
    */
671
 
    *error_arg= FALSE;
 
671
    *error_arg= false;
672
672
    value= TIME_to_ulonglong_datetime(&l_time);
673
673
  }
674
674
  else
675
675
  {
676
 
    *error_arg= TRUE;
 
676
    *error_arg= true;
677
677
    error= 1;                                   /* force warning */
678
678
  }
679
679
 
748
748
  if (cmp_type != CMP_DATE_DFLT)
749
749
  {
750
750
    /*
751
 
      Do not cache GET_USER_VAR() function as its const_item() may return TRUE
 
751
      Do not cache GET_USER_VAR() function as its const_item() may return true
752
752
      for the current thread but it still may change during the execution.
753
753
    */
754
754
    if (cmp_type != CMP_DATE_WITH_DATE && str_arg->const_item() &&
785
785
    item_arg   [in/out] item to retrieve TIME value from
786
786
    cache_arg  [in/out] pointer to place to store the cache item to
787
787
    warn_item  [in]     unused
788
 
    is_null    [out]    TRUE <=> the item_arg is null
 
788
    is_null    [out]    true <=> the item_arg is null
789
789
 
790
790
  DESCRIPTION
791
791
    Retrieves the correct TIME value from given item for comparison by the
820
820
    value= !*is_null ? TIME_to_ulonglong_datetime(&ltime) : 0;
821
821
  }
822
822
  /*
823
 
    Do not cache GET_USER_VAR() function as its const_item() may return TRUE
 
823
    Do not cache GET_USER_VAR() function as its const_item() may return true
824
824
    for the current thread but it still may change during the execution.
825
825
  */
826
826
  if (item->const_item() && cache_arg && (item->type() != Item::FUNC_ITEM ||
907
907
  b_type= (*b)->field_type();
908
908
  a_cache= 0;
909
909
  b_cache= 0;
910
 
  is_nulls_eq= FALSE;
 
910
  is_nulls_eq= false;
911
911
  func= &Arg_comparator::compare_datetime;
912
912
  get_value_func= &get_datetime_value;
913
913
}
922
922
    item_arg   [in/out] item to retrieve DATETIME value from
923
923
    cache_arg  [in/out] pointer to place to store the caching item to
924
924
    warn_item  [in]     item for issuing the conversion warning
925
 
    is_null    [out]    TRUE <=> the item_arg is null
 
925
    is_null    [out]    true <=> the item_arg is null
926
926
 
927
927
  DESCRIPTION
928
928
    Retrieves the correct DATETIME value from given item for comparison by the
993
993
    */
994
994
  }
995
995
  /*
996
 
    Do not cache GET_USER_VAR() function as its const_item() may return TRUE
 
996
    Do not cache GET_USER_VAR() function as its const_item() may return true
997
997
    for the current thread but it still may change during the execution.
998
998
  */
999
999
  if (item->const_item() && cache_arg && (item->type() != Item::FUNC_ITEM ||
1021
1021
    with help of the get_datetime_value() function.
1022
1022
 
1023
1023
  RETURN
1024
 
    If is_nulls_eq is TRUE:
 
1024
    If is_nulls_eq is true:
1025
1025
       1    if items are equal or both are null
1026
1026
       0    otherwise
1027
 
    If is_nulls_eq is FALSE:
 
1027
    If is_nulls_eq is false:
1028
1028
      -1   a < b or one of items is null
1029
1029
       0   a == b
1030
1030
       1   a > b
1032
1032
 
1033
1033
int Arg_comparator::compare_datetime()
1034
1034
{
1035
 
  bool is_null= FALSE;
 
1035
  bool is_null= false;
1036
1036
  ulonglong a_value, b_value;
1037
1037
 
1038
1038
  /* Get DATE/DATETIME/TIME value of the 'a' item. */
1439
1439
  if (args[0]->null_value)
1440
1440
  {
1441
1441
    /*
1442
 
      NULL val IS {TRUE, FALSE} --> FALSE
1443
 
      NULL val IS NOT {TRUE, FALSE} --> TRUE
 
1442
      NULL val IS {true, false} --> false
 
1443
      NULL val IS NOT {true, false} --> true
1444
1444
    */
1445
1445
    return (! affirmative);
1446
1446
  }
1447
1447
 
1448
1448
  if (affirmative)
1449
1449
  {
1450
 
    /* {TRUE, FALSE} val IS {TRUE, FALSE} value */
 
1450
    /* {true, false} val IS {true, false} value */
1451
1451
    return (val == value);
1452
1452
  }
1453
1453
 
1454
 
  /* {TRUE, FALSE} val IS NOT {TRUE, FALSE} value */
 
1454
  /* {true, false} val IS NOT {true, false} value */
1455
1455
  return (val != value);
1456
1456
}
1457
1457
 
1500
1500
{
1501
1501
  DBUG_ASSERT(fixed == 0);
1502
1502
  if (fix_left(thd, ref))
1503
 
    return TRUE;
 
1503
    return true;
1504
1504
  if (args[0]->maybe_null)
1505
1505
    maybe_null=1;
1506
1506
 
1507
1507
  if (!args[1]->fixed && args[1]->fix_fields(thd, args+1))
1508
 
    return TRUE;
 
1508
    return true;
1509
1509
  Item_in_subselect * sub= (Item_in_subselect *)args[1];
1510
1510
  if (args[0]->cols() != sub->engine->cols())
1511
1511
  {
1512
1512
    my_error(ER_OPERAND_COLUMNS, MYF(0), args[0]->cols());
1513
 
    return TRUE;
 
1513
    return true;
1514
1514
  }
1515
1515
  if (args[1]->maybe_null)
1516
1516
    maybe_null=1;
1519
1519
  not_null_tables_cache|= args[1]->not_null_tables();
1520
1520
  const_item_cache&= args[1]->const_item();
1521
1521
  fixed= 1;
1522
 
  return FALSE;
 
1522
  return false;
1523
1523
}
1524
1524
 
1525
1525
 
1535
1535
    {
1536
1536
      /*
1537
1537
        We're evaluating "NULL IN (SELECT ...)". The result can be NULL or
1538
 
        FALSE, and we can return one instead of another. Just return NULL.
 
1538
        false, and we can return one instead of another. Just return NULL.
1539
1539
      */
1540
1540
      null_value= 1;
1541
1541
    }
1551
1551
      {
1552
1552
        /*
1553
1553
          We're evaluating "NULL IN (SELECT ...)". The result is:
1554
 
             FALSE if SELECT produces an empty set, or
 
1554
             false if SELECT produces an empty set, or
1555
1555
             NULL  otherwise.
1556
1556
          We disable the predicates we've pushed down into subselect, run the
1557
1557
          subselect and see if it has produced any rows.
1559
1559
        Item_in_subselect *item_subs=(Item_in_subselect*)args[1]; 
1560
1560
        if (cache->cols() == 1)
1561
1561
        {
1562
 
          item_subs->set_cond_guard_var(0, FALSE);
 
1562
          item_subs->set_cond_guard_var(0, false);
1563
1563
          (void) args[1]->val_bool_result();
1564
1564
          result_for_null_param= null_value= !item_subs->engine->no_rows();
1565
 
          item_subs->set_cond_guard_var(0, TRUE);
 
1565
          item_subs->set_cond_guard_var(0, true);
1566
1566
        }
1567
1567
        else
1568
1568
        {
1575
1575
          for (i= 0; i < ncols; i++)
1576
1576
          {
1577
1577
            if (cache->element_index(i)->null_value)
1578
 
              item_subs->set_cond_guard_var(i, FALSE);
 
1578
              item_subs->set_cond_guard_var(i, false);
1579
1579
          }
1580
1580
          
1581
1581
          (void) args[1]->val_bool_result();
1583
1583
          
1584
1584
          /* Turn all predicates back on */
1585
1585
          for (i= 0; i < ncols; i++)
1586
 
            item_subs->set_cond_guard_var(i, TRUE);
 
1586
            item_subs->set_cond_guard_var(i, true);
1587
1587
        }
1588
1588
      }
1589
1589
    }
1790
1790
                            INT_RESULT));
1791
1791
  if (rows > 8)
1792
1792
  {
1793
 
    bool not_null_consts= TRUE;
 
1793
    bool not_null_consts= true;
1794
1794
 
1795
1795
    for (uint i= 1; not_null_consts && i < rows; i++)
1796
1796
    {
1990
1990
{
1991
1991
  max_length= 1;
1992
1992
  int i;
1993
 
  bool datetime_found= FALSE;
 
1993
  bool datetime_found= false;
1994
1994
  int time_items_found= 0;
1995
 
  compare_as_dates= TRUE;
 
1995
  compare_as_dates= true;
1996
1996
  THD *thd= current_thd;
1997
1997
 
1998
1998
  /*
2018
2018
    {
2019
2019
      if (args[i]->is_datetime())
2020
2020
      {
2021
 
        datetime_found= TRUE;
 
2021
        datetime_found= true;
2022
2022
        continue;
2023
2023
      }
2024
2024
      if (args[i]->field_type() == MYSQL_TYPE_TIME &&
2027
2027
    }
2028
2028
  }
2029
2029
  if (!datetime_found)
2030
 
    compare_as_dates= FALSE;
 
2030
    compare_as_dates= false;
2031
2031
 
2032
2032
  if (compare_as_dates)
2033
2033
  {
2698
2698
    is not optimized away
2699
2699
  */
2700
2700
  if (check_stack_overrun(thd, STACK_MIN_SIZE, buff))
2701
 
    return TRUE;                                // Fatal error flag is set!
 
2701
    return true;                                // Fatal error flag is set!
2702
2702
  return res;
2703
2703
}
2704
2704
 
2783
2783
  
2784
2784
  max_length=0;
2785
2785
  decimals=0;
2786
 
  unsigned_flag= TRUE;
 
2786
  unsigned_flag= true;
2787
2787
  if (cached_result_type == STRING_RESULT)
2788
2788
  {
2789
2789
    for (uint i= 0; i < ncases; i+= 2)
3544
3544
  Item **arg, **arg_end;
3545
3545
  bool const_itm= 1;
3546
3546
  THD *thd= current_thd;
3547
 
  bool datetime_found= FALSE;
3548
 
  /* TRUE <=> arguments values will be compared as DATETIMEs. */
3549
 
  bool compare_as_datetime= FALSE;
 
3547
  bool datetime_found= false;
 
3548
  /* true <=> arguments values will be compared as DATETIMEs. */
 
3549
  bool compare_as_datetime= false;
3550
3550
  Item *date_arg= 0;
3551
3551
  uint found_types= 0;
3552
3552
  uint type_cnt= 0, i;
3577
3577
    if (cmp_type == STRING_RESULT && 
3578
3578
        agg_arg_charsets(cmp_collation, args, arg_count, MY_COLL_CMP_CONV, 1))
3579
3579
      return;
3580
 
    arg_types_compatible= TRUE;
 
3580
    arg_types_compatible= true;
3581
3581
  }
3582
3582
  if (type_cnt == 1)
3583
3583
  {
3609
3609
 
3610
3610
      for (col= 0; col < cols; col++)
3611
3611
      {
3612
 
        bool skip_column= FALSE;
 
3612
        bool skip_column= false;
3613
3613
        /*
3614
3614
          Check that all items to be compared has the STRING result type and at
3615
3615
          least one of them is a DATE/DATETIME item.
3620
3620
                      arg[0]->element_index(col));
3621
3621
          if (itm->result_type() != STRING_RESULT)
3622
3622
          {
3623
 
            skip_column= TRUE;
 
3623
            skip_column= true;
3624
3624
            break;
3625
3625
          }
3626
3626
          else if (itm->is_datetime())
3627
3627
          {
3628
 
            datetime_found= TRUE;
 
3628
            datetime_found= true;
3629
3629
            /*
3630
3630
              Internally all DATE/DATETIME values are converted to the DATETIME
3631
3631
              type. So try to find a DATETIME item to issue correct warnings.
3655
3655
            *cmp= new cmp_item_datetime(date_arg);
3656
3656
            /* Reset variables for the next column. */
3657
3657
            date_arg= 0;
3658
 
            datetime_found= FALSE;
 
3658
            datetime_found= false;
3659
3659
          }
3660
3660
          else
3661
 
            compare_as_datetime= TRUE;
 
3661
            compare_as_datetime= true;
3662
3662
        }
3663
3663
      }
3664
3664
    }
3665
3665
  }
3666
3666
  /*
3667
 
    Row item with NULLs inside can return NULL or FALSE =>
 
3667
    Row item with NULLs inside can return NULL or false =>
3668
3668
    they can't be processed as static
3669
3669
  */
3670
3670
  if (type_cnt == 1 && const_itm && !nulls_in_row())
3687
3687
        Item_field *field_item= (Item_field*) (args[0]->real_item());
3688
3688
        if (field_item->field->can_be_compared_as_longlong())
3689
3689
        {
3690
 
          bool all_converted= TRUE;
 
3690
          bool all_converted= true;
3691
3691
          for (arg=args+1, arg_end=args+arg_count; arg != arg_end ; arg++)
3692
3692
          {
3693
3693
            if (!convert_constant_item (thd, field_item, &arg[0]))
3694
 
              all_converted= FALSE;
 
3694
              all_converted= false;
3695
3695
          }
3696
3696
          if (all_converted)
3697
3697
            cmp_type= INT_RESULT;
3915
3915
  and_tables_cache= ~(table_map) 0;
3916
3916
 
3917
3917
  if (check_stack_overrun(thd, STACK_MIN_SIZE, buff))
3918
 
    return TRUE;                                // Fatal error flag is set!
 
3918
    return true;                                // Fatal error flag is set!
3919
3919
  /*
3920
3920
    The following optimization reduces the depth of an AND-OR tree.
3921
3921
    E.g. a WHERE clause like
3949
3949
    if ((!item->fixed &&
3950
3950
         item->fix_fields(thd, li.ref())) ||
3951
3951
        (item= *li.ref())->check_cols(1))
3952
 
      return TRUE; /* purecov: inspected */
 
3952
      return true; /* purecov: inspected */
3953
3953
    used_tables_cache|=     item->used_tables();
3954
3954
    if (item->const_item())
3955
3955
      and_tables_cache= (table_map) 0;
3958
3958
      tmp_table_map= item->not_null_tables();
3959
3959
      not_null_tables_cache|= tmp_table_map;
3960
3960
      and_tables_cache&= tmp_table_map;
3961
 
      const_item_cache= FALSE;
 
3961
      const_item_cache= false;
3962
3962
    }  
3963
3963
    with_sum_func=          with_sum_func || item->with_sum_func;
3964
3964
    with_subselect|=        item->with_subselect;
3969
3969
  thd->thd_marker= orig_thd_marker;
3970
3970
  fix_length_and_dec();
3971
3971
  fixed= 1;
3972
 
  return FALSE;
 
3972
  return false;
3973
3973
}
3974
3974
 
3975
3975
 
3999
3999
      tmp_table_map= item->not_null_tables();
4000
4000
      not_null_tables_cache|= tmp_table_map;
4001
4001
      and_tables_cache&= tmp_table_map;
4002
 
      const_item_cache= FALSE;
 
4002
      const_item_cache= false;
4003
4003
    }  
4004
4004
  }
4005
4005
}
4062
4062
  callback functions.
4063
4063
  
4064
4064
    First the function applies the analyzer to the root node of
4065
 
    the Item_func object. Then if the analyzer succeeeds (returns TRUE)
 
4065
    the Item_func object. Then if the analyzer succeeeds (returns true)
4066
4066
    the function recursively applies the compile method to member
4067
4067
    item of the condition list.
4068
4068
    If the call of the method for a member item returns a new item
4150
4150
  List_iterator<Item> li(list);
4151
4151
  Item *item;
4152
4152
  while ((item= li++))
4153
 
    item->split_sum_func2(thd, ref_pointer_array, fields, li.ref(), TRUE);
 
4153
    item->split_sum_func2(thd, ref_pointer_array, fields, li.ref(), true);
4154
4154
}
4155
4155
 
4156
4156
 
4243
4243
    if (!item->val_bool())
4244
4244
    {
4245
4245
      if (abort_on_null || !(null_value= item->null_value))
4246
 
        return 0;                               // return FALSE
 
4246
        return 0;                               // return false
4247
4247
    }
4248
4248
  }
4249
4249
  return null_value ? 0 : 1;
4433
4433
  DBUG_ASSERT(fixed == 0);
4434
4434
  if (Item_bool_func2::fix_fields(thd, ref) ||
4435
4435
      escape_item->fix_fields(thd, &escape_item))
4436
 
    return TRUE;
 
4436
    return true;
4437
4437
 
4438
4438
  if (!escape_item->const_during_execution())
4439
4439
  {
4440
4440
    my_error(ER_WRONG_ARGUMENTS,MYF(0),"ESCAPE");
4441
 
    return TRUE;
 
4441
    return true;
4442
4442
  }
4443
4443
  
4444
4444
  if (escape_item->const_item())
4453
4453
               escape_str->numchars() > 1)))
4454
4454
      {
4455
4455
        my_error(ER_WRONG_ARGUMENTS,MYF(0),"ESCAPE");
4456
 
        return TRUE;
 
4456
        return true;
4457
4457
      }
4458
4458
 
4459
4459
      if (use_mb(cmp.cmp_collation.collation))
4501
4501
    {
4502
4502
      String* res2 = args[1]->val_str(&tmp_value2);
4503
4503
      if (!res2)
4504
 
        return FALSE;                           // Null argument
 
4504
        return false;                           // Null argument
4505
4505
      
4506
4506
      const size_t len   = res2->length();
4507
4507
      const char*  first = res2->ptr();
4535
4535
      }
4536
4536
    }
4537
4537
  }
4538
 
  return FALSE;
 
4538
  return false;
4539
4539
}
4540
4540
 
4541
4541
void Item_func_like::cleanup()
4542
4542
{
4543
 
  canDoTurboBM= FALSE;
 
4543
  canDoTurboBM= false;
4544
4544
  Item_bool_func2::cleanup();
4545
4545
}
4546
4546
 
4881
4881
  /* "NOT (e $cmp$ ANY (SELECT ...)) -> e $rev_cmp$" ALL (SELECT ...) */
4882
4882
  Item_func_not_all *new_item= new Item_func_not_all(args[0]);
4883
4883
  Item_allany_subselect *allany= (Item_allany_subselect*)args[0];
4884
 
  allany->func= allany->func_creator(FALSE);
 
4884
  allany->func= allany->func_creator(false);
4885
4885
  allany->all= !allany->all;
4886
4886
  allany->upper_item= new_item;
4887
4887
  return new_item;
4893
4893
  Item_func_nop_all *new_item= new Item_func_nop_all(args[0]);
4894
4894
  Item_allany_subselect *allany= (Item_allany_subselect*)args[0];
4895
4895
  allany->all= !allany->all;
4896
 
  allany->func= allany->func_creator(TRUE);
 
4896
  allany->func= allany->func_creator(true);
4897
4897
  allany->upper_item= new_item;
4898
4898
  return new_item;
4899
4899
}
5081
5081
    Item_field **ref1= it.ref();
5082
5082
    Item_field *item2;
5083
5083
 
5084
 
    swap= FALSE;
 
5084
    swap= false;
5085
5085
    while ((item2= it++))
5086
5086
    {
5087
5087
      Item_field **ref2= it.ref();
5090
5090
        Item_field *item= *ref1;
5091
5091
        *ref1= *ref2;
5092
5092
        *ref2= item;
5093
 
        swap= TRUE;
 
5093
        swap= true;
5094
5094
      }
5095
5095
      else
5096
5096
      {