Commit message: MDEV-26402: A SEGV in Item_field::used_tables/update_depend_map_for_order...

When doing condition pushdown from HAVING into WHERE,
Item_equal::create_pushable_equalities() calls
item->set_extraction_flag(IMMUTABLE_FL) for constant items.
Then, Item::cleanup_excluding_immutables_processor() checks for this flag
to see if it should call item->cleanup() or leave the item as-is.

The failure happens when a constant item has a non-constant one inside it,
like:

   (tbl.col=0 AND impossible_cond)

item->walk(cleanup_excluding_immutables_processor) works in a bottom-up
way so it
1. will call Item_func_eq(tbl.col=0)->cleanup()
2. will not call Item_cond_and->cleanup (as the AND is constant)

This creates an item tree where a fixed Item has an un-fixed Item inside
it which eventually causes an assertion failure.

Fixed by introducing this rule: instead of just calling

  item->set_extraction_flag(IMMUTABLE_FL);

we call Item::walk() to set the flag for all sub-items of the item.
CVE: CVE-2022-27382
CWE: CWE-617
Vulnerability description: MariaDB Server v10.7 and below was discovered to contain a segmentation fault via the component Item_field::used_tables/update_depend_map_for_order.

Project: server

void Item_equal::sort(Item_field_cmpfunc compare, void *arg)
{
  bubble_sort<Item>(&equal_items, compare, arg);
}

Project: server

  void join_with_sum_func(const Item *item)
  {
    m_with_sum_func|= item->with_sum_func();
  }

Project: server

  Field *create_tmp_field_ex(TABLE *table, Tmp_field_src *src,
                             const Tmp_field_param *param)
  {
    return create_tmp_field_ex_simple(table, src, param);
  }

Project: server

Item_func_nullif::time_op(THD *thd, MYSQL_TIME *ltime)
{
  DBUG_ASSERT(fixed == 1);
  if (!compare())
    return (null_value= true);
  return (null_value= Time(thd, args[2]).copy_to_mysql_time(ltime));

}

Project: server

Item *Item_bool_rowready_func2::negated_item(THD *thd)
{
  DBUG_ASSERT(0);
  return 0;
}

Project: server

  Item_cache_str(THD *thd, const Item *item):
    Item_cache(thd, item->type_handler()), value(0),
    is_varbinary(item->type() == FIELD_ITEM &&
                 Item_cache_str::field_type() == MYSQL_TYPE_VARCHAR &&
                 !((const Item_field *) item)->field->has_charset())
  {
    collation.set(const_cast<DTCollation&>(item->collation));
  }

Project: server

  Item_cache_datetime(THD *thd)
   :Item_cache_temporal(thd, &type_handler_datetime2) { }

Project: server

  Item_fixed_hybrid(THD *thd, Item_fixed_hybrid *item)
   :Item(thd, item), fixed(item->fixed)
  { }

Project: server

Item_func_nullif::real_op()
{
  DBUG_ASSERT(fixed == 1);
  double value;
  if (!compare())
  {
    null_value=1;
    return 0.0;
  }
  value= args[2]->val_real();
  null_value= args[2]->null_value;
  return value;
}

Project: server

void Item_func_nullif::split_sum_func(THD *thd, Ref_ptr_array ref_pointer_array,
                                      List<Item> &fields, uint flags)
{
  if (m_cache)
  {
    flags|= SPLIT_SUM_SKIP_REGISTERED; // See Item_func::split_sum_func
    m_cache->split_sum_func2_example(thd, ref_pointer_array, fields, flags);
    args[1]->split_sum_func2(thd, ref_pointer_array, fields, &args[1], flags);
  }
  else
  {
    Item_func::split_sum_func(thd, ref_pointer_array, fields, flags);
  }
}

Project: server

  virtual const String *const_ptr_string() const { return NULL; }

Project: server

  bool agg_arg_charsets_for_string_result(DTCollation &c,
                                          Item **items, uint nitems,
                                          int item_sep= 1)
  {
    return Type_std_attributes::
      agg_arg_charsets_for_string_result(c, func_name(),
                                         items, nitems, item_sep);
  }

Project: server

bool Item_func::setup_args_and_comparator(THD *thd, Arg_comparator *cmp)
{
  DBUG_ASSERT(arg_count >= 2); // Item_func_nullif has arg_count == 3

  if (args[0]->cmp_type() == STRING_RESULT &&
      args[1]->cmp_type() == STRING_RESULT)
  {
    DTCollation tmp;
    if (agg_arg_charsets_for_comparison(tmp, args, 2))
      return true;
    cmp->m_compare_collation= tmp.collation;
  }
  //  Convert constants when compared to int/year field
  DBUG_ASSERT(functype() != LIKE_FUNC);
  convert_const_compared_to_int_field(thd);

  return cmp->set_cmp_func(this, &args[0], &args[1], true);
}

Project: server

  Item_time_literal(THD *thd, const Time *ltime, uint dec_arg):
    Item_temporal_literal(thd, dec_arg),
    cached_time(*ltime)
  {
    DBUG_ASSERT(cached_time.is_valid_time());
    max_length= MIN_TIME_WIDTH + (decimals ? decimals + 1 : 0);
  }

Project: server

bool Arg_comparator::set_cmp_func_real()
{
  if ((((*a)->result_type() == DECIMAL_RESULT && !(*a)->const_item() &&
        (*b)->result_type() == STRING_RESULT  &&  (*b)->const_item()) ||
      ((*b)->result_type() == DECIMAL_RESULT && !(*b)->const_item() &&
       (*a)->result_type() == STRING_RESULT  &&  (*a)->const_item())))
  {
    /*
     <non-const decimal expression> <cmp> <const string expression>
     or
     <const string expression> <cmp> <non-const decimal expression>

     Do comparison as decimal rather than float, in order not to lose precision.
    */
    m_compare_handler= &type_handler_newdecimal;
    return set_cmp_func_decimal();
  }

  THD *thd= current_thd;
  func= is_owner_equal_func() ? &Arg_comparator::compare_e_real :
                                &Arg_comparator::compare_real;
  if ((*a)->decimals < NOT_FIXED_DEC && (*b)->decimals < NOT_FIXED_DEC)
  {
    precision= 5 / log_10[MY_MAX((*a)->decimals, (*b)->decimals) + 1];
    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;
  }
  a= cache_converted_constant(thd, a, &a_cache, compare_type_handler());
  b= cache_converted_constant(thd, b, &b_cache, compare_type_handler());
  return false;
}

Project: server

  longlong val_time_packed(THD *thd)
  {
    return has_value() ? value : 0;
  }

Project: server

longlong Item_func_between::val_int_cmp_string()
{
  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)
    return (longlong) ((sortcmp(value,a,cmp_collation.collation) >= 0 &&
                        sortcmp(value,b,cmp_collation.collation) <= 0) !=
                       negated);
  if (args[1]->null_value && args[2]->null_value)
    null_value= true;
  else if (args[1]->null_value)
  {
    // Set to not null if false range.
    null_value= sortcmp(value,b,cmp_collation.collation) <= 0;
  }
  else
  {
    // Set to not null if false range.
    null_value= sortcmp(value,a,cmp_collation.collation) >= 0;
  }
  return (longlong) (!null_value && negated);
}

Project: server

  double val_real()
  {
    return m_value.to_datetime(current_thd).to_double();
  }

Project: server

Item_func_nullif::decimal_op(my_decimal * decimal_value)
{
  DBUG_ASSERT(fixed == 1);
  my_decimal *res;
  if (!compare())
  {
    null_value=1;
    return 0;
  }
  res= args[2]->val_decimal(decimal_value);
  null_value= args[2]->null_value;
  return res;
}

Project: server

  const String *const_ptr_string() const
  { return can_return_const_value(STRING_RESULT) ? &value.m_string : NULL; }

Project: server

  With_sum_func_cache(const Item *a, const Item *b)
   :m_with_sum_func(a->with_sum_func() || b->with_sum_func())
  { }

Project: server

  Name_resolution_context_backup(Name_resolution_context &_ctx, TABLE_LIST &_table_list)
    : ctx(_ctx), table_list(_table_list), save_map(_table_list.map)
  {
    ctx_state.save_state(&ctx, &table_list);
    ctx.table_list= &table_list;
    ctx.first_name_resolution_table= &table_list;
  }

Project: server

Item *Item_bool_rowready_func2::neg_transformer(THD *thd)
{
  Item *item= negated_item(thd);
  return item;
}

Project: server

  const Item_const *get_item_const() const { return this; }

Project: server

  Item *get_copy(THD *thd)
  { return get_item_copy<Item_direct_ref>(thd, this); }

Project: server

  double val_real()
  {
    return update_null() ? 0 : cached_time.to_double();
  }

Project: server

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

Project: server

Item_func_nullif::date_op(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzydate)
{
  DBUG_ASSERT(fixed == 1);
  if (!compare())
    return (null_value= true);
  Datetime_truncation_not_needed dt(thd, args[2], fuzzydate);
  return (null_value= dt.copy_to_mysql_time(ltime, mysql_timestamp_type()));
}

Project: server

bool Item_func_regex::fix_fields(THD *thd, Item **ref)
{
  re.set_recursion_limit(thd);
  return Item_bool_func::fix_fields(thd, ref);
}

Project: server

int Arg_comparator::compare_e_str_json()
{
  return compare_e_json_str_basic(*b, *a);
}

Project: server

Item_bool_rowready_func2* Ne_creator::create(THD *thd, Item *a, Item *b) const
{
  return new(thd->mem_root) Item_func_ne(thd, a, b);
}

Project: server

bool Item_func_interval::fix_fields(THD *thd, Item **ref)
{
  if (Item_long_func::fix_fields(thd, ref))
    return true;
  for (uint i= 0 ; i < row->cols(); i++)
  {
    if (row->element_index(i)->check_cols(1))
      return true;
  }
  return false;
}

Project: server

  Field *create_tmp_field_ex(TABLE *table, Tmp_field_src *src,
                             const Tmp_field_param *param)
  {
    DBUG_ASSERT(0);
    return NULL;
  }

Project: server

  Item_literal(THD *thd): Item_basic_constant(thd)
  { }

Project: server

longlong Item_func_dyncol_check::val_int()
{
  char buff[STRING_BUFFER_USUAL_SIZE];
  String tmp(buff, sizeof(buff), &my_charset_bin);
  DYNAMIC_COLUMN col;
  String *str;
  enum enum_dyncol_func_result rc;

  str= args[0]->val_str(&tmp);
  if (args[0]->null_value)
    goto null;
  col.length= str->length();
  /* We do not change the string, so could do this trick */
  col.str= (char *)str->ptr();
  rc= mariadb_dyncol_check(&col);
  if (rc < 0 && rc != ER_DYNCOL_FORMAT)
  {
    dynamic_column_error_message(rc);
    goto null;
  }
  null_value= FALSE;
  return rc == ER_DYNCOL_OK;

null:
  null_value= TRUE;
  return 0;
}

Project: server

  bool agg_arg_charsets_for_comparison(DTCollation &c,
                                       Item **items, uint nitems,
                                       int item_sep= 1)
  {
    return Type_std_attributes::
      agg_arg_charsets_for_comparison(c, func_name(), items, nitems, item_sep);
  }

Project: server

  Longlong_null to_longlong_null()
  {
    longlong nr= val_int();
    /*
      C++ does not guarantee the order of parameter evaluation,
      so to make sure "null_value" is passed to the constructor
      after the val_int() call, val_int() is caled on a separate line.
    */
    return Longlong_null(nr, null_value);
  }

Project: server

bool Regexp_processor_pcre::compile(Item *item, bool send_error)
{
  char buff[MAX_FIELD_WIDTH];
  String tmp(buff, sizeof(buff), &my_charset_bin);
  String *pattern= item->val_str(&tmp);
  if (unlikely(item->null_value) || (unlikely(compile(pattern, send_error))))
    return true;
  return false;
}

Project: server

  bool check_cols(uint c)
  {
    if (cols() != c)
    {
      my_error(ER_OPERAND_COLUMNS, MYF(0), c);
      return true;
    }
    return false;
  }

Project: server

  bool get_date(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzydate)
  { return get_date_from_real(thd, ltime, fuzzydate); }

Project: server

bool Item_equal::merge_with_check(THD *thd, Item_equal *item, bool save_merged)
{
  bool intersected= FALSE;
  Item_equal_fields_iterator_slow fi(*item);
  
  while (fi++)
  {
    if (contains(fi.get_curr_field()))
    {
      intersected= TRUE;
      if (!save_merged)
        fi.remove();
    }
  }
  if (intersected)
  {
    if (!save_merged)
      merge(thd, item);
    else
    {
      Item *c= item->get_const();
      if (c)
        add_const(thd, c);
      if (!cond_false)
      {
        Item *item;
        fi.rewind();
        while ((item= fi++))
	{
          if (!contains(fi.get_curr_field()))
            add(item, thd->mem_root);
        }
      }
    }         
  }
  return intersected;
}

Project: server

  Item_int(THD *thd, const char *str_arg,longlong i,size_t length, bool flag):
    Item_num(thd), value(i)
    {
      max_length=(uint32)length;
      name.str= str_arg; name.length= safe_strlen(name.str);
      unsigned_flag= flag;
    }

Project: server

  bool is_order_clause_position() const { return true; }

Project: server

  my_decimal *val_decimal(my_decimal *decimal_value)
  {
    longlong value= Item_hex_hybrid::val_int();
    int2my_decimal(E_DEC_FATAL_ERROR, value, TRUE, decimal_value);
    return decimal_value;
  }

Project: server

  my_decimal *val_decimal(my_decimal *to)
  {
    return has_value() ? Date(this).to_decimal(to) : NULL;
  }

Project: server

  uint cols() const
  {
    return ref && result_type() == ROW_RESULT ? (*ref)->cols() : 1;
  }

Project: server

bool Item_func_regexp_instr::fix_fields(THD *thd, Item **ref)
{
  re.set_recursion_limit(thd);
  return Item_int_func::fix_fields(thd, ref);
}

Project: server

  Item_cache_int(THD *thd, const Type_handler *handler):
    Item_cache(thd, handler), value(0) {}

Project: server

Item_func_in::fix_fields(THD *thd, Item **ref)
{

  if (Item_func_opt_neg::fix_fields(thd, ref))
    return 1;

  return 0;
}

Project: server

  Item_temporal_literal(THD *thd)
   :Item_literal(thd)
  {
    collation.set(&my_charset_numeric, DERIVATION_NUMERIC, MY_REPERTOIRE_ASCII);
    decimals= 0;
  }

Project: server

Item_func_if::eval_not_null_tables(void *opt_arg)
{
  if (Item_func::eval_not_null_tables(NULL))
    return 1;

  not_null_tables_cache= (args[1]->not_null_tables() &
                          args[2]->not_null_tables());

  return 0;
}

Project: server

  bool const_is_null() const { return true; }

Project: server

  bool val_native_with_conversion_result(THD *thd, Native *to,
                                         const Type_handler *th)
  {
    return th->Item_val_native_with_conversion_result(thd, this, to);
  }

Project: server

  Item_blob(THD *thd, const char *name_arg, uint length):
    Item_partition_func_safe_string(thd, name_arg, (uint) safe_strlen(name_arg),
                                    &my_charset_bin)
  { max_length= length; }

Project: server

  inline void append(const char *str, uint length)
  {
    str_value.append(str, length);
    max_length= str_value.numchars() * collation.collation->mbmaxlen;
  }

Project: server

  longlong val_int()
  {
    return has_value() ? Datetime(this).to_longlong() : 0;
  }

Project: server

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)
    {
      if (set_null)
        owner->null_value= 0;
      if (sval2 < 0)
        return 1;
      if (uval1 < (ulonglong)sval2)
        return -1;
      if (uval1 == (ulonglong)sval2)
        return 0;
      return 1;
    }
  }
  if (set_null)
    owner->null_value= 1;
  return -1;
}

Project: server

  virtual void quick_fix_field()
  {
    DBUG_ASSERT(0);
  }

Project: server

  double val_real() { return decimal_value.to_double(); }

Project: server

longlong Item_func_between::val_int_cmp_decimal()
{
  VDec dec(args[0]);
  if ((null_value= dec.is_null()))
    return 0;					/* purecov: inspected */
  VDec a_dec(args[1]), b_dec(args[2]);
  if (!a_dec.is_null() && !b_dec.is_null())
    return (longlong) ((dec.cmp(a_dec) >= 0 &&
                        dec.cmp(b_dec) <= 0) != negated);
  if (a_dec.is_null() && b_dec.is_null())
    null_value= true;
  else if (a_dec.is_null())
    null_value= (dec.cmp(b_dec) <= 0);
  else
    null_value= (dec.cmp(a_dec) >= 0);
  return (longlong) (!null_value && negated);
}

Project: server

void Item_func_case_simple::print(String *str, enum_query_type query_type)
{
  Item **pos;
  str->append(STRING_WITH_LEN("case "));
  args[0]->print_parenthesised(str, query_type, precedence());
  str->append(' ');
  print_when_then_arguments(str, query_type, &args[1], when_count());
  if ((pos= Item_func_case_simple::else_expr_addr()))
    print_else_argument(str, query_type, pos[0]);
  str->append(STRING_WITH_LEN("end"));
}

Project: server

  Item_args(THD *thd, Item *a, Item *b, Item *c, Item *d)
  {
    arg_count= 0;
    if (likely((args= (Item**) thd_alloc(thd, sizeof(Item*) * 4))))
    {
      arg_count= 4;
      args[0]= a; args[1]= b; args[2]= c; args[3]= d;
    }
  }

Project: server

  void set_geometry_type(uint type)
  { Type_geometry_attributes::set_geometry_type(type); }

Project: server

longlong Item_func_le::val_int()
{
  DBUG_ASSERT(fixed == 1);
  int value= cmp.compare();
  return value <= 0 && !null_value ? 1 : 0;
}

Project: server

  Item_date_literal(THD *thd, const Date *ltime)
    :Item_temporal_literal(thd),
     cached_time(*ltime)
  {
    DBUG_ASSERT(cached_time.is_valid_date());
    max_length= MAX_DATE_WIDTH;
    /*
      If date has zero month or day, it can return NULL in case of
      NO_ZERO_DATE or NO_ZERO_IN_DATE.
      If date is `February 30`, it can return NULL in case if
      no ALLOW_INVALID_DATES is set.
      We can't set null_value using the current sql_mode here in constructor,
      because sql_mode can change in case of prepared statements
      between PREPARE and EXECUTE.
      Here we only set maybe_null to true if the value has such anomalies.
      Later (during execution time), if maybe_null is true, then the value
      will be checked per row, according to the execution time sql_mode.
      The check_date() below call should cover all cases mentioned.
    */
    maybe_null= cached_time.check_date(TIME_NO_ZERO_DATE | TIME_NO_ZERO_IN_DATE);
  }

Project: server

  bool get_date(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzydate)
  {
    bool res= m_value.to_TIME(thd, ltime, fuzzydate);
    DBUG_ASSERT(!res);
    return res;
  }

Project: server

  longlong val_int_from_real()
  {
    DBUG_ASSERT(is_fixed());
    return Converter_double_to_longlong_with_warn(val_real(), false).result();
  }

Project: server

Item *Item_cond::build_clone(THD *thd)
{
  List_iterator_fast<Item> li(list);
  Item *item;
  Item_cond *copy= (Item_cond *) get_copy(thd);
  if (!copy)
    return 0;
  copy->list.empty();
  while ((item= li++))
  {
    Item *arg_clone= item->build_clone(thd);
    if (!arg_clone)
      return 0;
    if (copy->list.push_back(arg_clone, thd->mem_root))
      return 0;
  }
  return copy;
}

Project: server

  const char *field_name_or_null()
  { return real_item()->type() == Item::FIELD_ITEM ? name.str : NULL; }

Project: server

  longlong val_time_packed(THD *thd)
  {
    return Time(thd, this, Time::Options_cmp(thd)).to_packed();
  }

Project: server

void Item_func_like::cleanup()
{
  canDoTurboBM= FALSE;
  Item_bool_func2::cleanup();
}

Project: server

  bool fix_fields(THD *thd, Item **it)
  {
    DBUG_ASSERT(ident->type() == FIELD_ITEM || ident->type() == REF_ITEM);
    if (ident->fix_fields_if_needed_for_scalar(thd, ref))
      return TRUE;
    set_properties();
    return FALSE;
  }

Project: server

bool Item_in_optimizer::is_top_level_item()
{
  if (!invisible_mode())
    return ((Item_in_subselect *)args[1])->is_top_level_item();
  return false;
}

Project: server

bool Item_func_in::fix_for_scalar_comparison_using_cmp_items(THD *thd,
                                                             uint found_types)
{
  if (found_types & (1U << STRING_RESULT) &&
      agg_arg_charsets_for_comparison(cmp_collation, args, arg_count))
    return true;
  if (make_unique_cmp_items(thd, cmp_collation.collation))
    return true;
  return false;
}

Project: server

  String *val_str(String *str)
  {
    return can_return_value() ? value.val_str(str, this) : NULL;
  }

Project: server

  Item_insert_value(THD *thd, Name_resolution_context *context_arg, Item *a)
    :Item_field(thd, context_arg, (const char *)NULL, (const char *)NULL,
                &null_clex_str),
     arg(a) {}

Project: server

Item *Item_func_case_searched::find_item()
{
  uint count= when_count();
  for (uint i= 0 ; i < count ; i++)
  {
    if (args[i]->val_bool())
      return args[i + count];
  }
  Item **pos= Item_func_case_searched::else_expr_addr();
  return pos ? pos[0] : 0;
}

Project: server

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

Project: server

  const String *const_ptr_string() const { return &str_value; }

Project: server

  bool agg_arg_charsets_for_string_result_with_comparison(DTCollation &c,
                                                          Item **items,
                                                          uint nitems,
                                                          int item_sep= 1)
  {
    return Type_std_attributes::
      agg_arg_charsets_for_string_result_with_comparison(c, func_name(),
                                                         items, nitems,
                                                         item_sep);
  }

Project: server

  enum_field_types field_type() const
  {
    return type_handler()->field_type();
  }

Project: server

  longlong val_datetime_packed(THD *thd)
  {
    if (check_null_ref())
      return 0;
    else
      return Item_direct_ref::val_datetime_packed(thd);
  }

Project: server

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;
  val1= (*a)->val_real();
  if (!(*a)->null_value)
  {
    val2= (*b)->val_real();
    if (!(*b)->null_value)
    {
      if (set_null)
        owner->null_value= 0;
      if (val1 == val2 || fabs(val1 - val2) < precision)
        return 0;
      if (val1 < val2)
        return -1;
      return 1;
    }
  }
  if (set_null)
    owner->null_value= 1;
  return -1;
}

Project: server

longlong Item_func_like::val_int()
{
  DBUG_ASSERT(fixed == 1);
  DBUG_ASSERT(escape != ESCAPE_NOT_INITIALIZED);
  String* res= args[0]->val_str(&cmp_value1);
  if (args[0]->null_value)
  {
    null_value=1;
    return 0;
  }
  String* res2= args[1]->val_str(&cmp_value2);
  if (args[1]->null_value)
  {
    null_value=1;
    return 0;
  }
  null_value=0;
  if (canDoTurboBM)
    return turboBM_matches(res->ptr(), res->length()) ? !negated : negated;
  return my_wildcmp(cmp_collation.collation,
		    res->ptr(),res->ptr()+res->length(),
		    res2->ptr(),res2->ptr()+res2->length(),
		    escape,wild_one,wild_many) ? negated : !negated;
}

Project: server

  Item_ignore_specification(THD *thd)
   :Item_contextually_typed_value_specification(thd)
  { }

Project: server

  virtual const MYSQL_TIME *const_ptr_mysql_time() const { return NULL; }

Project: server

  double val_real() { return (double) value; }

Project: server

  Item *get_copy(THD *thd)
  { return get_item_copy<Item_cache_datetime>(thd, this); }

Project: server

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

Project: server

  uint pos() const { return m_pos; }

Project: server

bool Item_func_null_predicate::count_sargable_conds(void *arg)
{
  ((SELECT_LEX*) arg)->cond_count++;
  return 0;
}

Project: server

  const Type_handler *type_handler() const
  { return &type_handler_bool; }

Project: server

  bool pushable_cond_checker_for_derived(uchar *arg)
  {
    return excl_dep_on_table(*((table_map *)arg));
  }

Project: server

bool Item_in_optimizer::fix_left(THD *thd)
{
  DBUG_ENTER("Item_in_optimizer::fix_left");
  /*
    Here we will store pointer on place of main storage of left expression.
    For usual IN (ALL/ANY) it is subquery left_expr.
    For other cases (MAX/MIN optimization, non-transformed EXISTS (10.0))
    it is args[0].
  */
  Item **ref0= args;
  if (!invisible_mode())
  {
    /*
       left_expr->fix_fields() may cause left_expr to be substituted for
       another item. (e.g. an Item_field may be changed into Item_ref). This
       transformation is undone at the end of statement execution (e.g. the
       Item_ref is deleted). However, Item_in_optimizer::args[0] may keep
       the pointer to the post-transformation item. Because of that, on the
       next execution we need to copy args[1]->left_expr again.
    */
    ref0= &(((Item_in_subselect *)args[1])->left_expr);
    args[0]= ((Item_in_subselect *)args[1])->left_expr;
  }
  if ((*ref0)->fix_fields_if_needed(thd, ref0) ||
      (!cache && !(cache= (*ref0)->get_cache(thd))))
    DBUG_RETURN(1);
  /*
    During fix_field() expression could be substituted.
    So we copy changes before use
  */
  if (args[0] != (*ref0))
    args[0]= (*ref0);
  DBUG_PRINT("info", ("actual fix fields"));

  cache->setup(thd, args[0]);
  if (cache->cols() == 1)
  {
    DBUG_ASSERT(args[0]->type() != ROW_ITEM);
    /* 
      Note: there can be cases when used_tables()==0 && !const_item(). See
      Item_sum::update_used_tables for details.
    */
    if ((used_tables_cache= args[0]->used_tables()) || !args[0]->const_item())
      cache->set_used_tables(OUTER_REF_TABLE_BIT);
    else
      cache->set_used_tables(0);
  }
  else
  {
    uint n= cache->cols();
    for (uint i= 0; i < n; i++)
    {
      /* Check that the expression (part of row) do not contain a subquery */
      if (args[0]->element_index(i)->walk(&Item::is_subquery_processor, 0, 0))
      {
        my_error(ER_NOT_SUPPORTED_YET, MYF(0),
                 "SUBQUERY in ROW in left expression of IN/ALL/ANY");
        DBUG_RETURN(1);
      }
      Item *element=args[0]->element_index(i);
      if (element->used_tables() || !element->const_item())
      {
	((Item_cache *)cache->element_index(i))->
          set_used_tables(OUTER_REF_TABLE_BIT);
        cache->set_used_tables(OUTER_REF_TABLE_BIT);
      }
      else
	((Item_cache *)cache->element_index(i))->set_used_tables(0);
    }
    used_tables_cache= args[0]->used_tables();
  }
  eval_not_null_tables(NULL);
  copy_with_sum_func(args[0]);
  with_param= args[0]->with_param || args[1]->with_param;
  with_field= args[0]->with_field;
  if ((const_item_cache= args[0]->const_item()))
  {
    cache->store(args[0]);
    cache->cache_value();
  }
  if (args[1]->is_fixed())
  {
    /* to avoid overriding is called to update left expression */
    used_tables_and_const_cache_join(args[1]);
    join_with_sum_func(args[1]);
  }
  DBUG_RETURN(0);
}

Project: server

  Item_type_holder(THD *thd,
                   Item *item,
                   const Type_handler *handler,
                   const Type_all_attributes *attr,
                   bool maybe_null_arg)
   :Item(thd),
    Type_handler_hybrid_field_type(handler),
    Type_geometry_attributes(handler, attr),
    enum_set_typelib(attr->get_typelib())
  {
    name= item->name;
    Type_std_attributes::set(*attr);
    maybe_null= maybe_null_arg;
  }

Project: server

  Field *create_tmp_field_ex(TABLE *table, Tmp_field_src *src,
                             const Tmp_field_param *param)
  {

    /*
      create_tmp_field_ex() for this type of Items is called for:
      - CREATE TABLE ... SELECT
      - In ORDER BY: SELECT max(a) FROM t1 GROUP BY a ORDER BY 'const';
      - In CURSORS:
          DECLARE c CURSOR FOR SELECT 'test';
          OPEN c;
    */
    return tmp_table_field_from_field_type_maybe_null(table, src, param,
                                            type() == Item::NULL_ITEM);
  }

Project: server

void Item_func_in::mark_as_condition_AND_part(TABLE_LIST *embedding)
{
  THD *thd= current_thd;

  Query_arena *arena, backup;
  arena= thd->activate_stmt_arena_if_needed(&backup);

  if (!transform_into_subq_checked)
  {
    if ((transform_into_subq= to_be_transformed_into_in_subq(thd)))
      thd->lex->current_select->in_funcs.push_back(this, thd->mem_root);
    transform_into_subq_checked= true;
  }

  if (arena)
    thd->restore_active_arena(arena, &backup);

  emb_on_expr_nest= embedding;
}

Project: server

  virtual longlong val_int_unsigned_typecast()
  {
    return cast_to_int_type_handler()->Item_val_int_unsigned_typecast(this);
  }

Project: server

  bool is_valid_limit_clause_variable_with_error() const
  {
    /*
      In case if the variable has an anchored data type, e.g.:
        DECLARE a TYPE OF t1.a;
      type_handler() is set to &type_handler_null and this
      function detects such variable as not valid in LIMIT.
    */
    if (type_handler()->is_limit_clause_valid_type())
      return true;
    my_error(ER_WRONG_SPVAR_TYPE_IN_LIMIT, MYF(0));
    return false;
  }

Project: server

  Item *in_subq_field_transformer_for_having(THD *thd, uchar *arg)
  { return convert_to_basic_const_item(thd); }

Project: server

void Item_func_nullif::print(String *str, enum_query_type query_type)
{
  /*
    NULLIF(a,b) is implemented according to the SQL standard as a short for
    CASE WHEN a=b THEN NULL ELSE a END

    The constructor of Item_func_nullif sets args[0] and args[2] to the
    same item "a", and sets args[1] to "b".

    If "this" is a part of a WHERE or ON condition, then:
    - the left "a" is a subject to equal field propagation with ANY_SUBST.
    - the right "a" is a subject to equal field propagation with IDENTITY_SUBST.
    Therefore, after equal field propagation args[0] and args[2] can point
    to different items.
  */
  if ((query_type & QT_ITEM_ORIGINAL_FUNC_NULLIF) ||
      (arg_count == 2) ||
      (args[0] == args[2]))
  {
    /*
      If QT_ITEM_ORIGINAL_FUNC_NULLIF is requested,
      that means we want the original NULLIF() representation,
      e.g. when we are in:
        SHOW CREATE {VIEW|FUNCTION|PROCEDURE}

      The original representation is possible only if
      args[0] and args[2] still point to the same Item.

      The caller must never pass call print() with QT_ITEM_ORIGINAL_FUNC_NULLIF
      if an expression has undergone some optimization
      (e.g. equal field propagation done in optimize_cond()) already and
      NULLIF() potentially has two different representations of "a":
      - one "a" for comparison
      - another "a" for the returned value!
    */
    DBUG_ASSERT(arg_count == 2 ||
                args[0] == args[2] || current_thd->lex->context_analysis_only);
    str->append(func_name());
    str->append('(');
    if (arg_count == 2)
      args[0]->print(str, query_type);
    else
      args[2]->print(str, query_type);
    str->append(',');
    args[1]->print(str, query_type);
    str->append(')');
  }
  else
  {
    /*
      args[0] and args[2] are different items.
      This is possible after WHERE optimization (equal fields propagation etc),
      e.g. in EXPLAIN EXTENDED or EXPLAIN FORMAT=JSON.
      As it's not possible to print as a function with 2 arguments any more,
      do it in the CASE style.
    */
    str->append(STRING_WITH_LEN("(case when "));
    args[0]->print(str, query_type);
    str->append(STRING_WITH_LEN(" = "));
    args[1]->print(str, query_type);
    str->append(STRING_WITH_LEN(" then NULL else "));
    args[2]->print(str, query_type);
    str->append(STRING_WITH_LEN(" end)"));
  }
}

Project: server

  bool is_bool_literal() const { return true; }

Project: server

bool Arg_comparator::set_cmp_func_native()
{
  THD *thd= current_thd;
  m_compare_collation= &my_charset_numeric;
  func= is_owner_equal_func() ? &Arg_comparator::compare_e_native :
                                &Arg_comparator::compare_native;
  a= cache_converted_constant(thd, a, &a_cache, compare_type_handler());
  b= cache_converted_constant(thd, b, &b_cache, compare_type_handler());
  return false;
}

Project: server

  Item *get_copy(THD *thd)
  { return get_item_copy<Item_field_row>(thd, this); }

Project: server

Sql_mode_dependency Item_func_like::value_depends_on_sql_mode() const
{
  if (!args[1]->value_depends_on_sql_mode_const_item())
    return Item_func::value_depends_on_sql_mode();
  StringBuffer<64> patternbuf;
  String *pattern= args[1]->val_str_ascii(&patternbuf);
  if (!pattern || !pattern->length())
    return Sql_mode_dependency();                  // Will return NULL or 0
  DBUG_ASSERT(pattern->charset()->mbminlen == 1);
  if (pattern->ptr()[pattern->length() - 1] != '%')
    return Item_func::value_depends_on_sql_mode();
  return ((args[0]->value_depends_on_sql_mode() |
           args[1]->value_depends_on_sql_mode()) &
          Sql_mode_dependency(~0, ~MODE_PAD_CHAR_TO_FULL_LENGTH)).
         soft_to_hard();
}

Project: server

Item *Item_func_ge::negated_item(THD *thd) /* a >= b  ->  a < b */
{
  return new (thd->mem_root) Item_func_lt(thd, args[0], args[1]);
}

Project: server

  const Type_handler *fixed_type_handler() const
  { return &type_handler_bool; }

Project: server

  virtual uint cols() const { return 1; }

Project: server

    PValue(): Type_handler_hybrid_field_type(&type_handler_null) {}

Project: server

  const Type_handler *type_handler() const
  {
    return Type_handler::get_handler_by_field_type(date_time_field_type);
  }

Project: server

void Regexp_processor_pcre::set_recursion_limit(THD *thd)
{
  long stack_used;
  DBUG_ASSERT(thd == current_thd);
  stack_used= available_stack_size(thd->thread_stack, &stack_used);
  m_pcre_extra.match_limit_recursion=
    (ulong)((my_thread_stack_size - STACK_MIN_SIZE - stack_used)/my_pcre_frame_size);
}

Project: server

  Field *create_table_field_from_handler(TABLE *table)
  {
    const Type_handler *h= type_handler();
    return h->make_and_init_table_field(&name, Record_addr(maybe_null),
                                        *this, table);
  }

Project: server

bool Item_func_between::eval_not_null_tables(void *opt_arg)
{
  if (Item_func_opt_neg::eval_not_null_tables(NULL))
    return 1;

  /* 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))) */
  not_null_tables_cache= (args[0]->not_null_tables() |
                          (args[1]->not_null_tables() &
                           args[2]->not_null_tables()));
  return 0;
}

Project: server

void Item_func_like::print(String *str, enum_query_type query_type)
{
  args[0]->print_parenthesised(str, query_type, precedence());
  str->append(' ');
  if (negated)
    str->append(STRING_WITH_LEN(" not "));
  str->append(func_name());
  str->append(' ');
  if (escape_used_in_parsing)
  {
    args[1]->print_parenthesised(str, query_type, precedence());
    str->append(STRING_WITH_LEN(" escape "));
    escape_item->print_parenthesised(str, query_type, higher_precedence());
  }
  else
    args[1]->print_parenthesised(str, query_type, higher_precedence());
}

Project: server

  virtual bool val_native(THD *thd, Native *to)
  {
   /*
     The default implementation for the Items that do not need native format:
     - Item_basic_value (default implementation)
     - Item_copy
     - Item_exists_subselect
     - Item_sum_field
     - Item_sum_or_func (default implementation)
     - Item_proc
     - Item_type_holder (as val_xxx() are never called for it);

     These hybrid Item types override val_native():
     - Item_field
     - Item_param
     - Item_sp_variable
     - Item_ref
     - Item_cache_wrapper
     - Item_direct_ref
     - Item_direct_view_ref
     - Item_ref_null_helper
     - Item_name_const
     - Item_time_literal
     - Item_sum_or_func
         Note, these hybrid type Item_sum_or_func descendants
         override the default implementation:
         * Item_sum_hybrid
         * Item_func_hybrid_field_type
         * Item_func_min_max
         * Item_func_sp
         * Item_func_last_value
         * Item_func_rollup_const
   */
    DBUG_ASSERT(0);
    return null_value= true;
  }

Project: server

longlong Item_cond_or::val_int()
{
  DBUG_ASSERT(fixed == 1);
  List_iterator_fast<Item> li(list);
  Item *item;
  null_value=0;
  while ((item=li++))
  {
    if (item->val_bool())
    {
      null_value=0;
      return 1;
    }
    if (item->null_value)
      null_value=1;
  }
  return 0;
}

Project: server

static inline int cmp_longs (longlong a_val, longlong b_val)
{
  return a_val < b_val ? -1 : a_val == b_val ? 0 : 1;
}

Project: server

  bool check_is_evaluable_expression_or_error()
  {
    if (is_evaluable_expression())
      return false; // Ok
    raise_error_not_evaluable();
    return true;    // Error
  }

Project: server

static int cmp_row(void *cmp_arg, cmp_item_row *a, cmp_item_row *b)
{
  return a->compare(b);
}

Project: server

Item *Item_func_decode_oracle::find_item()
{
  uint idx;
  if (!Predicant_to_list_comparator::cmp_nulls_equal(current_thd, this, &idx))
    return args[idx + when_count()];
  Item **pos= Item_func_decode_oracle::else_expr_addr();
  return pos ? pos[0] : 0;
}

Project: server

  const double *const_ptr_double() const
  { return can_return_const_value(REAL_RESULT) ? &value.real : NULL; }

Project: server

SEL_TREE *Item_func_like::get_mm_tree(RANGE_OPT_PARAM *param, Item **cond_ptr)
{
  MEM_ROOT *tmp_root= param->mem_root;
  param->thd->mem_root= param->old_root;
  bool sargable_pattern= with_sargable_pattern();
  param->thd->mem_root= tmp_root;
  return sargable_pattern ?
    Item_bool_func2::get_mm_tree(param, cond_ptr) :
    Item_func::get_mm_tree(param, cond_ptr);
}

Project: server

  virtual bool const_is_null() const { return false; }

Project: server

  Field *create_tmp_field_ex_simple(TABLE *table,
                                    Tmp_field_src *src,
                                    const Tmp_field_param *param)
  {
    DBUG_ASSERT(!param->make_copy_field());
    DBUG_ASSERT(!is_result_field());
    DBUG_ASSERT(type() != NULL_ITEM);
    return tmp_table_field_from_field_type(table);
  }

Project: server

  longlong val_time_packed(THD *thd)
  {
    DBUG_ASSERT(0);
    return 0;
  }

Project: server

bool Item_in_optimizer::invisible_mode()
{
  /* MAX/MIN transformed or EXISTS->IN prepared => do nothing */
 return (args[1]->type() != Item::SUBSELECT_ITEM ||
         ((Item_subselect *)args[1])->substype() ==
         Item_subselect::EXISTS_SUBS);
}

Project: server

  Item_bool(THD *thd, bool i) :Item_int(thd, (longlong) i, 1) { }

Project: server

  Item *get_copy(THD *thd)
  { return get_item_copy<Item_float>(thd, this); }

Project: server

  Field *tmp_table_field_from_field_type(TABLE *table)
  {
    DBUG_ASSERT(is_fixed());
    const Type_handler *h= type_handler()->type_handler_for_tmp_table(this);
    return h->make_and_init_table_field(&name, Record_addr(maybe_null),
                                        *this, table);
  }

Project: server

bool Item_func_between::fix_length_and_dec()
{
  max_length= 1;

  /*
    As some compare functions are generated after sql_yacc,
    we have to check for out of memory conditions here
  */
  if (!args[0] || !args[1] || !args[2])
    return TRUE;
  if (m_comparator.aggregate_for_comparison(Item_func_between::func_name(),
                                            args, 3, false))
  {
    DBUG_ASSERT(current_thd->is_error());
    return TRUE;
  }

  return m_comparator.type_handler()->
    Item_func_between_fix_length_and_dec(this);
}

Project: server

int cmp_item_decimal::compare(cmp_item *arg)
{
  cmp_item_decimal *l_cmp= (cmp_item_decimal*) arg;
  return my_decimal_cmp(&value, &l_cmp->value);
}

Project: server

  virtual Item *grouping_field_transformer_for_where(THD *thd, uchar *arg)
  { return this; }

Project: server

  double val_real()
  {
    return to_datetime(current_thd).to_double();
  }

Project: server

  Item_int(THD *thd, longlong i,size_t length= MY_INT64_NUM_DECIMAL_DIGITS):
    Item_num(thd), value(i)
    { max_length=(uint32)length; }

Project: server

bool Item_func_not::fix_fields(THD *thd, Item **ref)
{
  args[0]->under_not(this);
  if (args[0]->type() == FIELD_ITEM)
  {
    /* replace  "NOT <field>" with "<field> == 0" */
    Query_arena backup, *arena;
    Item *new_item;
    bool rc= TRUE;
    arena= thd->activate_stmt_arena_if_needed(&backup);
    if ((new_item= new (thd->mem_root) Item_func_eq(thd, args[0], new (thd->mem_root) Item_int(thd, 0, 1))))
    {
      new_item->name= name;
      rc= (*ref= new_item)->fix_fields(thd, ref);
    }
    if (arena)
      thd->restore_active_arena(arena, &backup);
    return rc;
  }
  return Item_func::fix_fields(thd, ref);
}

Project: server

  virtual bool val_native_result(THD *thd, Native *to)
  {
    return val_native(thd, to);
  }

Project: server

  const Type_handler *type_handler_for_comparison() const
  {
    return type_handler()->type_handler_for_comparison();
  }

Project: server

bool Arg_comparator::set_cmp_func_datetime()
{
  THD *thd= current_thd;
  m_compare_collation= &my_charset_numeric;
  func= is_owner_equal_func() ? &Arg_comparator::compare_e_datetime :
                                &Arg_comparator::compare_datetime;
  a= cache_converted_constant(thd, a, &a_cache, compare_type_handler());
  b= cache_converted_constant(thd, b, &b_cache, compare_type_handler());
  return false;
}

Project: server

  Field *default_field() const { return m_default_field; }

Project: server

int cmp_item_decimal::cmp_not_null(const Value *val)
{
  DBUG_ASSERT(!val->is_null());
  DBUG_ASSERT(val->is_decimal());
  return my_decimal_cmp(&value, &val->m_decimal);
}

Project: server

double Item_func_coalesce::real_op()
{
  DBUG_ASSERT(fixed == 1);
  null_value=0;
  for (uint i=0 ; i < arg_count ; i++)
  {
    double res= args[i]->val_real();
    if (!args[i]->null_value)
      return res;
  }
  null_value=1;
  return 0;
}

Project: server

  virtual bool is_bool_literal() const { return false; }

Project: server

  enum Type type() const { return CONTEXTUALLY_TYPED_VALUE_ITEM; }

Project: server

  Item_splocal_with_delayed_data_type(THD *thd,
                                      const Sp_rcontext_handler *rh,
                                      const LEX_CSTRING *sp_var_name,
                                      uint sp_var_idx,
                                      uint pos_in_q, uint len_in_q)
   :Item_splocal(thd, rh, sp_var_name, sp_var_idx, &type_handler_null,
                 pos_in_q, len_in_q)
  { }

Project: server

  const Type_handler *type_handler() const
  { return type_handler_long_or_longlong(); }

Project: server

  bool pushable_equality_checker_for_derived(uchar *arg)
  {
    return (used_tables() == *((table_map *)arg));
  }

Project: server

int cmp_item_row::compare(cmp_item *c)
{
  cmp_item_row *l_cmp= (cmp_item_row *) c;
  for (uint i=0; i < n; i++)
  {
    int res;
    if ((res= comparators[i]->compare(l_cmp->comparators[i])))
      return res;
  }
  return 0;
}

Project: server

  double val_real()
  {
    return has_value() ? Time(this).to_double() : 0;
  }

Project: server

bool Item_func_case_simple::prepare_predicant_and_values(THD *thd,
                                                         uint *found_types,
                                                         bool nulls_equal)
{
  bool have_null= false;
  uint type_cnt;
  Type_handler_hybrid_field_type tmp;
  uint ncases= when_count();
  add_predicant(this, 0);
  for (uint i= 0 ; i < ncases; i++)
  {
    if (nulls_equal ?
        add_value("case..when", this, i + 1) :
        add_value_skip_null("case..when", this, i + 1, &have_null))
      return true;
  }
  all_values_added(&tmp, &type_cnt, &m_found_types);
#ifndef DBUG_OFF
  Predicant_to_list_comparator::debug_print(thd);
#endif
  return false;
}

Project: server

Item *Item_func_isnotnull::neg_transformer(THD *thd)
{
  Item *item= new (thd->mem_root) Item_func_isnull(thd, args[0]);
  return item;
}

Project: server

bool Item_func_nullif::walk(Item_processor processor,
                            bool walk_subquery, void *arg)
{
  /*
    No needs to iterate through args[2] when it's just a copy of args[0].
    See MDEV-9712 Performance degradation of nested NULLIF
  */
  uint tmp_count= arg_count == 2 || args[0] == args[2] ? 2 : 3;
  for (uint i= 0; i < tmp_count; i++)
  {
    if (args[i]->walk(processor, walk_subquery, arg))
      return true;
  }
  return (this->*processor)(arg);
}

Project: server

bool Item_func_in::count_sargable_conds(void *arg)
{
  ((SELECT_LEX*) arg)->cond_count++;
  return 0;
}

Project: server

  int save_in_field(Field *field, bool no_conversions)
  {
    DBUG_ASSERT(sane());
    if (null_value)
      return set_field_to_null(field);
    Timestamp_or_zero_datetime_native native(m_value, decimals);
    return native.save_in_field(field, decimals);
  }

Project: server

Item* Item_func_case_simple::propagate_equal_fields(THD *thd,
                                                    const Context &ctx,
                                                    COND_EQUAL *cond)
{
  const Type_handler *first_expr_cmp_handler;

  first_expr_cmp_handler= args[0]->type_handler_for_comparison();
  /*
    Cannot replace the CASE (the switch) argument if
    there are multiple comparison types were found, or found a single
    comparison type that is not equal to args[0]->cmp_type().

    - Example: multiple comparison types, can't propagate:
        WHERE CASE str_column
              WHEN 'string' THEN TRUE
              WHEN 1 THEN TRUE
              ELSE FALSE END;

    - Example: a single incompatible comparison type, can't propagate:
        WHERE CASE str_column
              WHEN DATE'2001-01-01' THEN TRUE
              ELSE FALSE END;

    - Example: a single incompatible comparison type, can't propagate:
        WHERE CASE str_column
              WHEN 1 THEN TRUE
              ELSE FALSE END;

    - Example: a single compatible comparison type, ok to propagate:
        WHERE CASE str_column
              WHEN 'str1' THEN TRUE
              WHEN 'str2' THEN TRUE
              ELSE FALSE END;
  */
  if (m_found_types == (1UL << first_expr_cmp_handler->cmp_type()))
    propagate_and_change_item_tree(thd, &args[0], cond,
      Context(ANY_SUBST, first_expr_cmp_handler, cmp_collation.collation));

  /*
    These arguments are in comparison.
    Allow invariants of the same value during propagation.
    Note, as we pass ANY_SUBST, none of the WHEN arguments will be
    replaced to zero-filled constants (only IDENTITY_SUBST allows this).
    Such a change for WHEN arguments would require rebuilding cmp_items.
  */
  uint i, count= when_count();
  for (i= 1; i <= count; i++)
  {
    Type_handler_hybrid_field_type tmp(first_expr_cmp_handler);
    if (!tmp.aggregate_for_comparison(args[i]->type_handler_for_comparison()))
      propagate_and_change_item_tree(thd, &args[i], cond,
        Context(ANY_SUBST, tmp.type_handler(), cmp_collation.collation));
  }

  // THEN and ELSE arguments (they are not in comparison)
  for (; i < arg_count; i++)
    propagate_and_change_item_tree(thd, &args[i], cond, Context_identity());

  return this;
}

Project: server

bool Item_func_interval::fix_length_and_dec()
{
  uint rows= row->cols();
  
  use_decimal_comparison= ((row->element_index(0)->result_type() ==
                            DECIMAL_RESULT) ||
                           (row->element_index(0)->result_type() ==
                            INT_RESULT));
  if (rows > 8)
  {
    bool not_null_consts= TRUE;

    for (uint i= 1; not_null_consts && i < rows; i++)
    {
      Item *el= row->element_index(i);
      not_null_consts&= el->const_item() && !el->is_null();
    }

    if (not_null_consts)
    {
      intervals= (interval_range*) current_thd->alloc(sizeof(interval_range) *
                                                         (rows - 1));
      if (!intervals)
        return TRUE;

      if (use_decimal_comparison)
      {
        for (uint i= 1; i < rows; i++)
        {
          Item *el= row->element_index(i);
          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;
            }
          }
          else
          {
            range->type= REAL_RESULT;
            range->dbl= el->val_real();
          }
        }
      }
      else
      {
        for (uint i= 1; i < rows; i++)
        {
          intervals[i-1].dbl= row->element_index(i)->val_real();
        }
      }
    }
  }
  maybe_null= 0;
  max_length= 2;
  used_tables_and_const_cache_join(row);
  not_null_tables_cache= row->not_null_tables();
  join_with_sum_func(row);
  with_param= with_param || row->with_param;
  with_field= with_field || row->with_field;
  return FALSE;
}

Project: server

bool Item_func_decode_oracle::fix_length_and_dec()
{
  THD *thd= current_thd;
  return (aggregate_then_and_else_arguments(thd, when_count() + 1) ||
          aggregate_switch_and_when_arguments(thd, true));
}

Project: server

  void set_modify_item(bool to) { m_modify_item= to; }

Project: server

void Item_func_nullif::update_used_tables()
{
  if (m_cache)
  {
    used_tables_and_const_cache_init();
    used_tables_and_const_cache_update_and_join(m_cache->get_example());
    used_tables_and_const_cache_update_and_join(arg_count, args);
  }
  else
  {
    /*
      MDEV-9712 Performance degradation of nested NULLIF
      No needs to iterate through args[2] when it's just a copy of args[0].
    */
    DBUG_ASSERT(arg_count == 3);
    used_tables_and_const_cache_init();
    used_tables_and_const_cache_update_and_join(args[0] == args[2] ? 2 : 3,
                                                args);
  }
}

Project: server

  Item *get_copy(THD *thd)
  { return get_item_copy<Item_cache_str>(thd, this); }

Project: server

in_timestamp::in_timestamp(THD *thd, uint elements)
  :in_vector(thd, elements, sizeof(Value), (qsort2_cmp) cmp_timestamp, 0)
{}

Project: server

Item *Item_equal::transform(THD *thd, Item_transformer transformer, uchar *arg)
{
  DBUG_ASSERT(!thd->stmt_arena->is_stmt_prepare());

  Item *item;
  Item_equal_fields_iterator it(*this);
  while ((item= it++))
  {
    Item *new_item= item->transform(thd, transformer, arg);
    if (!new_item)
      return 0;

    /*
      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.
    */
    if (new_item != item)
      thd->change_item_tree((Item **) it.ref(), new_item);
  }
  return Item_func::transform(thd, transformer, arg);
}

Project: server

  Item_trigger_field(THD *thd, Name_resolution_context *context_arg,
                     row_version_type row_ver_arg,
                     const LEX_CSTRING *field_name_arg,
                     ulong priv, const bool ro)
    :Item_field(thd, context_arg,
               (const char *)NULL, (const char *)NULL, field_name_arg),
     row_version(row_ver_arg), field_idx((uint)-1), original_privilege(priv),
     want_privilege(priv), table_grants(NULL), read_only (ro)
  {}

Project: server

uchar *in_datetime::get_value(Item *item)
{
  tmp.val= item->val_datetime_packed(current_thd);
  if (item->null_value)
    return 0;
  tmp.unsigned_flag= 1L;
  return (uchar*) &tmp;
}

Project: server

  Item_hex_constant(THD *thd, const char *str, size_t str_length):
    Item_literal(thd)
  {
    hex_string_init(thd, str, str_length);
  }

Project: server

  Item_cache_real(THD *thd, const Type_handler *h)
   :Item_cache(thd, h),
    value(0)
  {}

Project: server

static int cmp_double(void *cmp_arg, double *a,double *b)
{
  return *a < *b ? -1 : *a == *b ? 0 : 1;
}

Project: server

  Item_string(THD *thd, const char *str, uint length, CHARSET_INFO *cs,
              Derivation dv, uint repertoire)
   :Item_literal(thd)
  {
    str_value.set_or_copy_aligned(str, length, cs);
    fix_and_set_name_from_value(thd, dv, Metadata(&str_value, repertoire));
  }

Project: server

Item *Item_in_optimizer::transform(THD *thd, Item_transformer transformer,
                                   uchar *argument)
{
  Item *new_item;

  DBUG_ASSERT(fixed);
  DBUG_ASSERT(!thd->stmt_arena->is_stmt_prepare());
  DBUG_ASSERT(arg_count == 2);

  /* Transform the left IN operand. */
  new_item= (*args)->transform(thd, transformer, argument);
  if (!new_item)
    return 0;
  /*
    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.
  */
  if ((*args) != new_item)
    thd->change_item_tree(args, new_item);

  if (invisible_mode())
  {
    /* MAX/MIN transformed => pass through */
    new_item= args[1]->transform(thd, transformer, argument);
    if (!new_item)
      return 0;
    if (args[1] != new_item)
      thd->change_item_tree(args + 1, new_item);
  }
  else
  {
    /*
      Transform the right IN operand which should be an Item_in_subselect or a
      subclass of it. The left operand of the IN must be the same as the left
      operand of this Item_in_optimizer, so in this case there is no further
      transformation, we only make both operands the same.
      TODO: is it the way it should be?
    */
    DBUG_ASSERT((args[1])->type() == Item::SUBSELECT_ITEM &&
                (((Item_subselect*)(args[1]))->substype() ==
                 Item_subselect::IN_SUBS ||
                 ((Item_subselect*)(args[1]))->substype() ==
                 Item_subselect::ALL_SUBS ||
                 ((Item_subselect*)(args[1]))->substype() ==
                 Item_subselect::ANY_SUBS));

    Item_in_subselect *in_arg= (Item_in_subselect*)args[1];
    thd->change_item_tree(&in_arg->left_expr, args[0]);
  }
  return (this->*transformer)(thd, argument);
}

Project: server

  Load_data_outvar *get_load_data_outvar_or_error()
  {
    Load_data_outvar *dst= get_load_data_outvar();
    if (dst)
      return dst;
    my_error(ER_NONUPDATEABLE_COLUMN, MYF(0), name.str);
    return NULL;
  }

Project: server

  Item *get_copy(THD *thd)
  { return get_item_copy<Item_cache_float>(thd, this); }

Project: server

  virtual void make_send_field(THD *thd, Send_field *field)
  { orig_item->make_send_field(thd, field); }

Project: server

longlong Item_func_between::val_int_cmp_real()
{
  double value= args[0]->val_real(),a,b;
  if ((null_value=args[0]->null_value))
    return 0;					/* purecov: inspected */
  a= args[1]->val_real();
  b= args[2]->val_real();
  if (!args[1]->null_value && !args[2]->null_value)
    return (longlong) ((value >= a && value <= b) != negated);
  if (args[1]->null_value && args[2]->null_value)
    null_value= true;
  else if (args[1]->null_value)
  {
    null_value= value <= b;			// not null if false range.
  }
  else
  {
    null_value= value >= a;
  }
  return (longlong) (!null_value && negated);
}

Project: server

longlong Item_func_in::val_int()
{
  DBUG_ASSERT(fixed == 1);
  if (array)
  {
    bool tmp=array->find(args[0]);
    /*
      NULL on left -> UNKNOWN.
      Found no match, and NULL on right -> UNKNOWN.
      NULL on right can never give a match, as it is not stored in
      array.
      See also the 'bisection_possible' variable in fix_length_and_dec().
    */
    null_value=args[0]->null_value || (!tmp && have_null);
    return (longlong) (!null_value && tmp != negated);
  }

  if ((null_value= args[0]->real_item()->type() == NULL_ITEM))
    return 0;

  null_value= have_null;
  uint idx;
  if (!Predicant_to_list_comparator::cmp(this, &idx, &null_value))
  {
    null_value= false;
    return (longlong) (!negated);
  }
  return (longlong) (!null_value && negated);
}

Project: server

  bool vcol_assignment_allowed_value() const { return vcol_assignment_ok; }

Project: server

  Item *get_copy(THD *thd)
  { return get_item_copy<Item_int>(thd, this); }

Project: server

bool Item_equal::count_sargable_conds(void *arg)
{
  SELECT_LEX *sel= (SELECT_LEX *) arg;
  uint m= equal_items.elements;
  sel->cond_count+= m*(m-1);
  return 0;
}

Project: server

longlong Item_func_not_all::val_int()
{
  DBUG_ASSERT(fixed == 1);
  bool value= args[0]->val_bool();

  /*
    return TRUE if there was records in underlying select in max/min
    optimization (ALL subquery)
  */
  if (empty_underlying_subquery())
    return 1;

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

Project: server

  bool check_vcol_func_processor(void *arg)
  {
    return mark_unsupported_function("value()", arg, VCOL_IMPOSSIBLE);
  }

Project: server

  virtual String *val_raw(String*) { return 0; }

Project: server

void Item_cond::neg_arguments(THD *thd)
{
  List_iterator<Item> li(list);
  Item *item;
  while ((item= li++))		/* Apply not transformation to the arguments */
  {
    Item *new_item= item->neg_transformer(thd);
    if (!new_item)
    {
      if (!(new_item= new (thd->mem_root) Item_func_not(thd, item)))
	return;					// Fatal OEM error
    }
    (void) li.replace(new_item);
  }
}

Project: server

bool Item_cond::excl_dep_on_table(table_map tab_map)
{
  if (used_tables() & OUTER_REF_TABLE_BIT)
    return false;
  if (!(used_tables() & ~tab_map))
    return true;
  List_iterator_fast<Item> li(list);
  Item *item;
  while ((item= li++))
  {
    if (!item->excl_dep_on_table(tab_map))
      return false;
  }
  return true;
}

Project: server

inline bool Virtual_column_info::is_equal(const Virtual_column_info* vcol) const
{
  return type_handler()  == vcol->type_handler()
      && stored_in_db == vcol->is_stored()
      && expr->eq(vcol->expr, true);
}

Project: server

  bool is_expensive() { return true; }

Project: server

void Predicant_to_list_comparator::
       detect_unique_handlers(Type_handler_hybrid_field_type *compatible,
                              uint *unique_count,
                              uint *found_types)
{
  *unique_count= 0;
  *found_types= 0;
  for (uint i= 0; i < m_comparator_count; i++)
  {
    uint idx;
    if (find_handler(&idx, m_comparators[i].m_handler, i))
    {
      m_comparators[i].m_handler_index= i; // New unique handler
      (*unique_count)++;
      (*found_types)|= 1U << m_comparators[i].m_handler->cmp_type();
      compatible->set_handler(m_comparators[i].m_handler);
    }
    else
    {
      m_comparators[i].m_handler_index= idx; // Non-unique handler
    }
  }
}

Project: server

bool Arg_comparator::set_cmp_func_time()
{
  THD *thd= current_thd;
  m_compare_collation= &my_charset_numeric;
  func= is_owner_equal_func() ? &Arg_comparator::compare_e_time :
                                &Arg_comparator::compare_time;
  a= cache_converted_constant(thd, a, &a_cache, compare_type_handler());
  b= cache_converted_constant(thd, b, &b_cache, compare_type_handler());
  return false;
}

Project: server

void Item_cond_and::mark_as_condition_AND_part(TABLE_LIST *embedding)
{
  List_iterator<Item> li(list);
  Item *item;
  while ((item=li++))
  {
    item->mark_as_condition_AND_part(embedding);
  }
}

Project: server

  Item_float(THD *thd, double value_par, uint decimal_par):
    Item_num(thd), presentation(0), value(value_par)
  {
    decimals= (uint8) decimal_par;
  }

Project: server

  bool send(Protocol *protocol, st_value *buffer)
  {
    DBUG_ASSERT(0);
    return true;
  }

Project: server

  Item *get_copy(THD *thd)
  { return get_item_copy<Item_cache_decimal>(thd, this); }

Project: server

longlong Item_func_regexp_instr::val_int()
{
  DBUG_ASSERT(fixed == 1);
  if ((null_value= re.recompile(args[1])))
    return 0;

  if ((null_value= re.exec(args[0], 0, 1)))
    return 0;

  return re.match() ? re.subpattern_start(0) + 1 : 0;
}

Project: server

  Item** addr(uint i) { return this_item()->addr(i); }

Project: server

  double val_real()
  { 
    return double_from_string_with_check(&str_value);
  }

Project: server

bool Item_func_case::native_op(THD *thd, Native *to)
{
  DBUG_ASSERT(fixed == 1);
  Item *item= find_item();
  if (!item)
    return (null_value= true);
  return val_native_with_conversion_from_item(thd, item, to, type_handler());
}

Project: server

inline void Item_func_case::print_else_argument(String *str,
                                                enum_query_type query_type,
                                                Item *item)
{
  str->append(STRING_WITH_LEN("else "));
  item->print(str, query_type);
  str->append(' ');
}

Project: server

  bool is_fixed() const { return fixed; }

Project: server

  Item *get_copy(THD *thd)
  { return get_item_copy<Item_direct_view_ref>(thd, this); }

Project: server

  Item *get_copy(THD *thd)
  { return get_item_copy<Item_string>(thd, this); }

Project: server

  bool get_date(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzydate)
  {
    return get_date_from_string(thd, ltime, fuzzydate);
  }

Project: server

  bool const_item() const { return false; }

Project: server

  Item_result_field *item_result_field() const { return m_item_result_field; }

Project: server

bool Arg_comparator::set_cmp_func_string()
{
  THD *thd= current_thd;
  func= is_owner_equal_func() ? &Arg_comparator::compare_e_string :
                                &Arg_comparator::compare_string;
  if (compare_type() == STRING_RESULT &&
      (*a)->result_type() == STRING_RESULT &&
      (*b)->result_type() == STRING_RESULT)
  {
    /*
      We must set cmp_collation here as we may be called from for an automatic
      generated item, like in natural join
    */
    if (owner->agg_arg_charsets_for_comparison(&m_compare_collation, a, b))
      return true;

    if ((*a)->type() == Item::FUNC_ITEM &&
        ((Item_func *) (*a))->functype() == Item_func::JSON_EXTRACT_FUNC)
    {
      func= is_owner_equal_func() ? &Arg_comparator::compare_e_json_str:
                                    &Arg_comparator::compare_json_str;
      return 0;
    }
    else if ((*b)->type() == Item::FUNC_ITEM &&
             ((Item_func *) (*b))->functype() == Item_func::JSON_EXTRACT_FUNC)
    {
      func= is_owner_equal_func() ? &Arg_comparator::compare_e_json_str:
                                    &Arg_comparator::compare_str_json;
      return 0;
    }
  }

  a= cache_converted_constant(thd, a, &a_cache, compare_type_handler());
  b= cache_converted_constant(thd, b, &b_cache, compare_type_handler());
  return false;
}

Project: server

double Item_func_case::real_op()
{
  DBUG_ASSERT(fixed == 1);
  Item *item= find_item();
  double res;

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

Project: server

  virtual ~Item()
  {
#ifdef EXTRA_DEBUG
    name.str= 0;
    name.length= 0;
#endif
  }		/*lint -e1509 */

Project: server

bool Item_func_between::fix_length_and_dec_temporal(THD *thd)
{
  if (!thd->lex->is_ps_or_view_context_analysis())
  {
    for (uint i= 0; i < 3; i ++)
    {
      if (args[i]->const_item() &&
          args[i]->type_handler_for_comparison() != m_comparator.type_handler())
      {
        Item_cache *cache= m_comparator.type_handler()->Item_get_cache(thd, args[i]);
        if (!cache || cache->setup(thd, args[i]))
          return true;
        thd->change_item_tree(&args[i], cache);
      }
    }
  }
  return false;
}

Project: server

  void reset_buffer()
  {
    m_string.set(buffer, buffer_size, &my_charset_bin);
  }

Project: server

  longlong val_int() { return has_value() ? Date(this).to_longlong() : 0; }

Project: server

void Item_cond::traverse_cond(Cond_traverser traverser,
                              void *arg, traverse_order order)
{
  List_iterator<Item> li(list);
  Item *item;

  switch(order) {
  case(PREFIX):
    (*traverser)(this, arg);
    while ((item= li++))
    {
      item->traverse_cond(traverser, arg, order);
    }
    (*traverser)(NULL, arg);
    break;
  case(POSTFIX):
    while ((item= li++))
    {
      item->traverse_cond(traverser, arg, order);
    }
    (*traverser)(this, arg);
  }
}

Project: server

inline bool Item_sp_variable::send(Protocol *protocol, st_value *buffer)
{
  return this_item()->send(protocol, buffer);
}

Project: server

  bool pushable_cond_checker_for_subquery(uchar *arg)
  {
    return excl_dep_on_in_subq_left_part((Item_in_subselect *)arg);
  }

Project: server

void Item_func_decode_oracle::print(String *str, enum_query_type query_type)
{
  str->append(func_name());
  str->append('(');
  args[0]->print(str, query_type);
  for (uint i= 1, count= when_count() ; i <= count; i++)
  {
    str->append(',');
    args[i]->print(str, query_type);
    str->append(',');
    args[i+count]->print(str, query_type);
  }
  Item **else_expr= Item_func_case_simple::else_expr_addr();
  if (else_expr)
  {
    str->append(',');
    (*else_expr)->print(str, query_type);
  }
  str->append(')');
}

Project: server

longlong Item_func_gt::val_int()
{
  DBUG_ASSERT(fixed == 1);
  int value= cmp.compare();
  return value > 0 ? 1 : 0;
}

Project: server

Item *Item_func_lt::negated_item(THD *thd) /* a < b  ->  a >= b */
{
  return new (thd->mem_root) Item_func_ge(thd, args[0], args[1]);
}

Project: server

  bool get_date(THD *thd, MYSQL_TIME *to, date_mode_t mode)
  {
    return decimal_to_datetime_with_warn(thd, VDec(this).ptr(), to, mode,
                                         NULL, NULL);
  }

Project: server

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

Project: server

  bool is_evaluable_expression() const { return false; }

Project: server

  bool fix_fields(THD *thd, Item **it)
  {
    if ((*ref)->fix_fields_if_needed_for_scalar(thd, ref))
      return TRUE;
    return Item_ref::fix_fields(thd, it);
  }

Project: server

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

Project: server

  bool get_date(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzydate)
  {
    DBUG_ASSERT(sane());
    bool res= m_value.to_TIME(thd, ltime, fuzzydate);
    DBUG_ASSERT(!res);
    return null_value || res;
  }

Project: server

  const Type_handler *type_handler() const { return &type_handler_row; }

Project: server

my_decimal *Item_func_coalesce::decimal_op(my_decimal *decimal_value)
{
  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;
}

Project: server

  Item_copy_timestamp(THD *thd, Item *arg): Item_copy(thd, arg) { }

Project: server

  virtual bool val_bool()
  {
    return type_handler()->Item_val_bool(this);
  }

Project: server

  ValueBuffer()
  {
    reset_buffer();
  }

Project: server

  Item *get_copy(THD *thd)
  { return get_item_copy<Item_ref_null_helper>(thd, this); }

Project: server

bool Item_func_case_searched::fix_length_and_dec()
{
  THD *thd= current_thd;
  return aggregate_then_and_else_arguments(thd, when_count());
}

Project: server

  Item_basic_constant(THD *thd): Item_basic_value(thd) {};

Project: server

Item_bool_rowready_func2* Lt_creator::create(THD *thd, Item *a, Item *b) const
{
  return new(thd->mem_root) Item_func_lt(thd, a, b);
}

Project: server

bool Item_equal::contains(Field *field)
{
  Item_equal_fields_iterator it(*this);
  while (it++)
  {
    if (field->eq(it.get_curr_field()))
        return 1;
  }
  return 0;
}

Project: server

  double val_real()
  {
    return has_value() ? Datetime(this).to_double() : 0;
  }

Project: server

Item *Item_func_not::neg_transformer(THD *thd)	/* NOT(x)  ->  x */
{
  return args[0];
}

Project: server

bool Item_func_like::with_sargable_pattern() const
{
  if (negated)
    return false;

  if (!args[1]->const_item() || args[1]->is_expensive())
    return false;

  String* res2= args[1]->val_str((String *) &cmp_value2);
  if (!res2)
    return false;

  if (!res2->length()) // Can optimize empty wildcard: column LIKE ''
    return true;

  DBUG_ASSERT(res2->ptr());
  char first= res2->ptr()[0];
  return first != wild_many && first != wild_one;
}

Project: server

  virtual bool with_subquery() const { DBUG_ASSERT(is_fixed()); return false; }

Project: server

bool Arg_comparator::set_cmp_func_decimal()
{
  THD *thd= current_thd;
  func= is_owner_equal_func() ? &Arg_comparator::compare_e_decimal :
                                &Arg_comparator::compare_decimal;
  a= cache_converted_constant(thd, a, &a_cache, compare_type_handler());
  b= cache_converted_constant(thd, b, &b_cache, compare_type_handler());
  return false;
}

Project: server

  bool eq(const Item *item, bool binary_cmp) const
  {
    return false;
  }

Project: server

bool Item_func_case_simple::fix_length_and_dec()
{
  THD *thd= current_thd;
  return (aggregate_then_and_else_arguments(thd, when_count() + 1) ||
          aggregate_switch_and_when_arguments(thd, false));
}

Project: server

  my_decimal *val_decimal(my_decimal *dec)
  {
    return can_return_value() ? value.val_decimal(dec, this) : NULL;
  }

Project: server

  Item_datetime_literal_for_invalid_dates(THD *thd,
                                          const Datetime *ltime, uint dec_arg)
   :Item_datetime_literal(thd, ltime, dec_arg)
  {
    maybe_null= false;
  }

Project: server

bool Item_in_optimizer::is_null()
{
  val_int();
  return null_value;
}

Project: server

  virtual bool is_order_clause_position() const { return false; }

Project: server

Item *and_expressions(THD *thd, Item *a, Item *b, Item **org_item)
{
  if (!a)
    return (*org_item= (Item*) b);
  if (a == *org_item)
  {
    Item_cond *res;
    if ((res= new (thd->mem_root) Item_cond_and(thd, a, (Item*) b)))
    {
      res->used_tables_cache= a->used_tables() | b->used_tables();
      res->not_null_tables_cache= a->not_null_tables() | b->not_null_tables();
    }
    return res;
  }
  if (((Item_cond_and*) a)->add((Item*) b, thd->mem_root))
    return 0;
  ((Item_cond_and*) a)->used_tables_cache|= b->used_tables();
  ((Item_cond_and*) a)->not_null_tables_cache|= b->not_null_tables();
  return a;
}

Project: server

  bool const_item() const
  {
    return state != NO_VALUE;
  }

Project: server

  Item** addr(uint i) { return arg_count ? args + i : NULL; }

Project: server

longlong Item_func_bit_and::val_int()
{
  DBUG_ASSERT(fixed == 1);
  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);
}

Project: server

String *Item_func_case::str_op(String *str)
{
  DBUG_ASSERT(fixed == 1);
  String *res;
  Item *item= find_item();

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

Project: server

int Arg_comparator::compare_e_datetime()
{
  THD *thd= current_thd;
  longlong val1= (*a)->val_datetime_packed(thd);
  longlong val2= (*b)->val_datetime_packed(thd);
  if ((*a)->null_value || (*b)->null_value)
    return MY_TEST((*a)->null_value && (*b)->null_value);
  return MY_TEST(val1 == val2);
}

Project: server

  void set_default_field(Field *field) { m_default_field= field; }

Project: server

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

Project: server

  bool alloc_and_extract_row_elements(THD *thd, const Item_args *rows, uint pos)
  {
    DBUG_ASSERT(rows->argument_count() > 0);
    DBUG_ASSERT(rows->arguments()[0]->cols() > pos);
    if (alloc_arguments(thd, rows->argument_count()))
      return true;
    for (uint i= 0; i < rows->argument_count(); i++)
    {
      DBUG_ASSERT(rows->arguments()[0]->cols() == rows->arguments()[i]->cols());
      Item *arg= rows->arguments()[i]->element_index(pos);
      add_argument(arg);
    }
    DBUG_ASSERT(argument_count() == rows->argument_count());
    return false;
  }

Project: server

bool Item_func_like::fix_fields(THD *thd, Item **ref)
{
  DBUG_ASSERT(fixed == 0);
  if (Item_bool_func2::fix_fields(thd, ref) ||
      escape_item->fix_fields_if_needed_for_scalar(thd, &escape_item) ||
      fix_escape_item(thd, escape_item, &cmp_value1, escape_used_in_parsing,
                      cmp_collation.collation, &escape))
    return TRUE;

  if (escape_item->const_item())
  {
    /*
      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.
    */
    if (args[1]->const_item() && !use_strnxfrm(collation.collation) &&
        !args[1]->is_expensive())
    {
      String* res2= args[1]->val_str(&cmp_value2);
      if (!res2)
        return FALSE;				// Null argument
      
      const size_t len= res2->length();

      /*
        len must be > 2 ('%pattern%')
        heuristic: only do TurboBM for pattern_len > 2
      */
      if (len <= 2)
        return FALSE;

      const char*  first= res2->ptr();
      const char*  last=  first + len - 1;
      
      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_len = (int) len - 2;
        pattern     = thd->strmake(first + 1, pattern_len);
        DBUG_PRINT("info", ("Initializing pattern: '%s'", first));
        int *suff = (int*) thd->alloc((int) (sizeof(int)*
                                      ((pattern_len + 1)*2+
                                      alphabet_size)));
        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"));
      }
      use_sampling= (len > 2 && (*first == wild_many || *first == wild_one));
    }
  }
  return FALSE;
}

Project: server

inline bool TABLE::mark_column_with_deps(Field *field)
{
  bool res;
  if (!(res= bitmap_fast_test_and_set(read_set, field->field_index)))
  {
    if (field->vcol_info)
      mark_virtual_column_deps(field);
  }
  return res;
}

Project: server

  Field *create_field_for_schema(THD *thd, TABLE *table)
  { return tmp_table_field_from_field_type(table); }

Project: server

  Item_string(THD *thd, const String *str, CHARSET_INFO *tocs, uint *conv_errors,
              Derivation dv, uint repertoire)
   :Item_literal(thd)
  {
    if (str_value.copy(str, tocs, conv_errors))
      str_value.set("", 0, tocs); // EOM ?
    str_value.mark_as_const();
    fix_and_set_name_from_value(thd, dv, Metadata(&str_value, repertoire));
  }

Project: server

  Item_string(THD *thd, CHARSET_INFO *csi, const char *str_arg, uint length_arg)
   :Item_literal(thd)
  {
    collation.set(csi, DERIVATION_COERCIBLE);
    set_name(thd, NULL, 0, system_charset_info);
    decimals= NOT_FIXED_DEC;
    str_value.copy(str_arg, length_arg, csi);
    max_length= str_value.numchars() * csi->mbmaxlen;
  }

Project: server

  bool val_native(THD *thd, Native *to)
  {
    return has_value() ? Time(thd, this).to_native(to, decimals) : true;
  }

Project: server

  my_decimal *val_decimal_from_item(Item *item, my_decimal *decimal_value)
  {
    DBUG_ASSERT(is_fixed());
    my_decimal *value= item->val_decimal(decimal_value);
    if ((null_value= item->null_value))
      value= NULL;
    return value;
  }

Project: server

  bool walk(Item_processor processor, bool walk_subquery, void *arg)
  {
    if (arg == STOP_PTR)
      return FALSE;
    if (example && example->walk(processor, walk_subquery, arg))
      return TRUE;
    return (this->*processor)(arg);
  }

Project: server

void Item_in_optimizer::restore_first_argument()
{
  if (!invisible_mode())
  {
    args[0]= ((Item_in_subselect *)args[1])->left_expr;
  }
}

Project: server

  Item_cache_date(THD *thd)
   :Item_cache_temporal(thd, &type_handler_newdate) { }

Project: server

Item *Item_cond::propagate_equal_fields(THD *thd,
                                        const Context &ctx,
                                        COND_EQUAL *cond)
{
  DBUG_ASSERT(!thd->stmt_arena->is_stmt_prepare());
  DBUG_ASSERT(arg_count == 0);
  List_iterator<Item> li(list);
  while (li++)
  {
    /*
      The exact value of the last parameter to propagate_and_change_item_tree()
      is not important at this point. Item_func derivants will create and
      pass their own context to the arguments.
    */
    propagate_and_change_item_tree(thd, li.ref(), cond, Context_boolean());
  }
  return this;
}

Project: server

longlong Item_func_interval::val_int()
{
  DBUG_ASSERT(fixed == 1);
  double value;
  my_decimal dec_buf, *dec= NULL;
  uint i;

  if (use_decimal_comparison)
  {
    dec= row->element_index(0)->val_decimal(&dec_buf);
    if (row->element_index(0)->null_value)
      return -1;
    my_decimal2double(E_DEC_FATAL_ERROR, dec, &value);
  }
  else
  {
    value= row->element_index(0)->val_real();
    if (row->element_index(0)->null_value)
      return -1;
  }

  if (intervals)
  {					// Use binary search to find interval
    uint start,end;
    start= 0;
    end=   row->cols()-2;
    while (start != end)
    {
      uint mid= (start + end + 1) / 2;
      interval_range *range= intervals + mid;
      my_bool cmp_result;
      /*
        The values in the range interval may have different types,
        Only do a decimal comparison if the first argument is a decimal
        and we are comparing against a decimal
      */
      if (dec && range->type == DECIMAL_RESULT)
        cmp_result= my_decimal_cmp(&range->dec, dec) <= 0;
      else
        cmp_result= (range->dbl <= value);
      if (cmp_result)
	start= mid;
      else
	end= mid - 1;
    }
    interval_range *range= intervals+start;
    return ((dec && range->type == DECIMAL_RESULT) ?
            my_decimal_cmp(dec, &range->dec) < 0 :
            value < range->dbl) ? 0 : start + 1;
  }

  for (i=1 ; i < row->cols() ; i++)
  {
    Item *el= row->element_index(i);
    if (use_decimal_comparison &&
        ((el->result_type() == DECIMAL_RESULT) ||
         (el->result_type() == INT_RESULT)))
    {
      VDec e_dec(el);
      /* Skip NULL ranges. */
      if (e_dec.is_null())
        continue;
      if (e_dec.cmp(dec) > 0)
        return i - 1;
    }
    else 
    {
      double val= el->val_real();
      /* Skip NULL ranges. */
      if (el->null_value)
        continue;
      if (val > value)
        return i - 1;
    }
  }
  return i-1;
}

Project: server

int Arg_comparator::compare_str_json()
{
  return -compare_json_str_basic(*b, *a);
}

Project: server

  bool eq(const Item_args *other, bool binary_cmp) const
  {
    for (uint i= 0; i < arg_count ; i++)
    {
      if (!args[i]->eq(other->args[i], binary_cmp))
        return false;
    }
    return true;
  }

Project: server

void Item_equal::merge(THD *thd, Item_equal *item)
{
  Item *c= item->get_const();
  if (c)
    item->equal_items.pop();
  equal_items.append(&item->equal_items);
  if (c)
  {
    /* 
      The flag cond_false will be set to TRUE after this if 
      the multiple equality already contains a constant and its 
      value is not equal to the value of c.
    */
    add_const(thd, c);
  }
  cond_false|= item->cond_false;
}

Project: server

  Item *get_copy(THD *thd)
  { return get_item_copy<Item_ignore_specification>(thd, this); }

Project: server

  Tmp_field_src()
   :m_field(0),
    m_default_field(0),
    m_item_result_field(0)
  { }

Project: server

  void set_geometry_type(uint type)
  {
    DBUG_ASSERT(0);
  }

Project: server

  my_decimal *val_decimal(my_decimal *to)
  {
    return has_value() ? Time(this).to_decimal(to) : NULL;
  }

Project: server

bool Item_func_truth::fix_length_and_dec()
{
  maybe_null= 0;
  null_value= 0;
  decimals= 0;
  max_length= 1;
  return FALSE;
}

Project: server

  const longlong *const_ptr_longlong() const { return &value; }

Project: server

bool Regexp_processor_pcre::compile(String *pattern, bool send_error)
{
  const char *pcreErrorStr;
  int pcreErrorOffset;

  if (is_compiled())
  {
    if (!stringcmp(pattern, &m_prev_pattern))
      return false;
    cleanup();
    m_prev_pattern.copy(*pattern);
  }

  if (!(pattern= convert_if_needed(pattern, &pattern_converter)))
    return true;

  m_pcre= pcre_compile(pattern->c_ptr_safe(), m_library_flags,
                       &pcreErrorStr, &pcreErrorOffset, NULL);

  if (unlikely(m_pcre == NULL))
  {
    if (send_error)
    {
      char buff[MAX_FIELD_WIDTH];
      my_snprintf(buff, sizeof(buff), "%s at offset %d", pcreErrorStr, pcreErrorOffset);
      my_error(ER_REGEXP_ERROR, MYF(0), buff);
    }
    return true;
  }
  return false;
}

Project: server

  bool get_date(THD *thd, MYSQL_TIME *to, date_mode_t fuzzydate)
  {
    *to= ltime;
    return false;
  }

Project: server

static uint collect_cmp_types(Item **items, uint nitems, bool skip_nulls= FALSE)
{
  uint i;
  uint found_types;
  Item_result left_cmp_type= items[0]->cmp_type();
  DBUG_ASSERT(nitems > 1);
  found_types= 0;
  for (i= 1; i < nitems ; i++)
  {
    if (skip_nulls && items[i]->type() == Item::NULL_ITEM)
      continue; // Skip NULL constant items
    if ((left_cmp_type == ROW_RESULT ||
         items[i]->cmp_type() == ROW_RESULT) &&
        cmp_row_type(items[0], items[i]))
      return 0;
    found_types|= 1U << (uint) item_cmp_type(left_cmp_type, items[i]);
  }
  /*
   Even if all right-hand items are NULLs and we are skipping them all, we need
   at least one type bit in the found_type bitmask.
  */
  if (skip_nulls && !found_types)
    found_types= 1U << (uint) left_cmp_type;
  return found_types;
}

Project: server

longlong Item_func_between::val_int_cmp_native()
{
  THD *thd= current_thd;
  const Type_handler *h= m_comparator.type_handler();
  NativeBuffer<STRING_BUFFER_USUAL_SIZE> value, a, b;
  if (val_native_with_conversion_from_item(thd, args[0], &value, h))
    return 0;
  bool ra= args[1]->val_native_with_conversion(thd, &a, h);
  bool rb= args[2]->val_native_with_conversion(thd, &b, h);
  if (!ra && !rb)
    return (longlong)
      ((h->cmp_native(value, a) >= 0 &&
        h->cmp_native(value, b) <= 0) != negated);
  if (ra && rb)
    null_value= true;
  else if (ra)
    null_value= h->cmp_native(value, b) <= 0;
  else
    null_value= h->cmp_native(value, a) >= 0;
  return (longlong) (!null_value && negated);
}

Project: server

  Item *get_copy(THD *thd)
  { return get_item_copy<Item_name_const>(thd, this); }

Project: server

  double val_real()
  { 
    return (double) (ulonglong) Item_hex_hybrid::val_int();
  }

Project: server

  bool val_native(THD *thd, Native *to)
  {
    return Time(thd, this).to_native(to, decimals);
  }

Project: server

  Item_date_literal_for_invalid_dates(THD *thd, const Date *ltime)
   :Item_date_literal(thd, ltime)
  {
    maybe_null= false;
  }

Project: server

void Item_cond::fix_after_pullout(st_select_lex *new_parent, Item **ref,
                                  bool merge)
{
  List_iterator<Item> li(list);
  Item *item;

  used_tables_and_const_cache_init();

  and_tables_cache= ~(table_map) 0; // Here and below we do as fix_fields does
  not_null_tables_cache= 0;

  while ((item=li++))
  {
    table_map tmp_table_map;
    item->fix_after_pullout(new_parent, li.ref(), merge);
    item= *li.ref();
    used_tables_and_const_cache_join(item);

    if (item->const_item())
      and_tables_cache= (table_map) 0;
    else
    {
      tmp_table_map= item->not_null_tables();
      not_null_tables_cache|= tmp_table_map;
      and_tables_cache&= tmp_table_map;
      const_item_cache= FALSE;
    }  
  }
}

Project: server

void cmp_item_row::store_value(Item *item)
{
  DBUG_ENTER("cmp_item_row::store_value");
  DBUG_ASSERT(comparators);
  DBUG_ASSERT(n == item->cols());
  item->bring_value();
  item->null_value= 0;
  for (uint i=0; i < n; i++)
  {
    DBUG_ASSERT(comparators[i]);
    comparators[i]->store_value(item->element_index(i));
    item->null_value|= item->element_index(i)->null_value;
  }
  DBUG_VOID_RETURN;
}

Project: server

  uint cols() const
  { return result_type() == ROW_RESULT ? orig_item->cols() : 1; }

Project: server

  TYPELIB *get_typelib() const { return NULL; }

Project: server

  virtual const Item_const *get_item_const() const { return NULL; }

Project: server

    void swap(PValue_simple &other)
    {
      swap_variables(PValue_simple, *this, other);
    }

Project: server

  Item *get_copy(THD *thd)
  { return get_item_copy<Item_cache_wrapper>(thd, this); }

Project: server

void Item_func_case_searched::print(String *str, enum_query_type query_type)
{
  Item **pos;
  str->append(STRING_WITH_LEN("case "));
  print_when_then_arguments(str, query_type, &args[0], when_count());
  if ((pos= Item_func_case_searched::else_expr_addr()))
    print_else_argument(str, query_type, pos[0]);
  str->append(STRING_WITH_LEN("end"));
}

Project: server

  virtual bool with_subquery() const
  {
    return (*ref)->with_subquery();
  }

Project: server

Item_func_nullif::is_null()
{
  return (null_value= (!compare() ? 1 : args[2]->is_null()));
}

Project: server

  Field *create_tmp_field_ex(TABLE *table, Tmp_field_src *src,
                             const Tmp_field_param *param)
  {
    return Item_type_holder::real_type_handler()->
           make_and_init_table_field(&name, Record_addr(maybe_null),
                                     *this, table);
  }

Project: server

my_decimal *Item_func_ifnull::decimal_op(my_decimal *decimal_value)
{
  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;
}

Project: server

  Item *get_copy(THD *thd)
  { return get_item_copy<Item_cache_date>(thd, this); }

Project: server

int cmp_item_row::cmp(Item *arg)
{
  arg->null_value= 0;
  if (arg->cols() != n)
  {
    my_error(ER_OPERAND_COLUMNS, MYF(0), n);
    return 1;
  }
  bool was_null= 0;
  arg->bring_value();
  for (uint i=0; i < n; i++)
  {
    const int rc= comparators[i]->cmp(arg->element_index(i));
    switch (rc)
    {
    case UNKNOWN:
      was_null= true;
      break;
    case TRUE:
      return TRUE;
    case FALSE:
      break;                                    // elements #i are equal
    }
    arg->null_value|= arg->element_index(i)->null_value;
  }
  return was_null ? UNKNOWN : FALSE;
}

Project: server

  bool agg_arg_charsets(DTCollation &c, Item **items, uint nitems,
                        uint flags, int item_sep)
  {
    return Type_std_attributes::agg_arg_charsets(c, func_name(),
                                                 items, nitems,
                                                 flags, item_sep);
  }

Project: server

  virtual Item *in_predicate_to_in_subs_transformer(THD *thd, uchar *arg)
  { return this; }

Project: server

  Item_num(THD *thd): Item_literal(thd) { collation.set_numeric(); }

Project: server

cmp_item* cmp_item_sort_string::make_same()
{
  return new cmp_item_sort_string_in_static(cmp_charset);
}

Project: server

int cmp_item_datetime::cmp_not_null(const Value *val)
{
  DBUG_ASSERT(!val->is_null());
  DBUG_ASSERT(val->is_temporal());
  return value != pack_time(&val->value.m_time);
}

Project: server

Item_bool_rowready_func2* Ge_creator::create(THD *thd, Item *a, Item *b) const
{
  return new(thd->mem_root) Item_func_ge(thd, a, b);
}

Project: server

void in_row::set(uint pos, Item *item)
{
  DBUG_ENTER("in_row::set");
  DBUG_PRINT("enter", ("pos: %u  item: %p", pos,item));
  ((cmp_item_row*) base)[pos].store_value_by_template(current_thd, &tmp, item);
  DBUG_VOID_RETURN;
}

Project: server

int cmp_item_timestamp::cmp_not_null(const Value *val)
{
  /*
    This method will be implemented when we add this syntax:
      SELECT TIMESTAMP WITH LOCAL TIME ZONE '2001-01-01 10:20:30'
    For now TIMESTAMP is compared to non-TIMESTAMP using DATETIME.
  */
  DBUG_ASSERT(0);
  return 0;
}

Project: server

Item_func_nullif::str_op(String *str)
{
  DBUG_ASSERT(fixed == 1);
  String *res;
  if (!compare())
  {
    null_value=1;
    return 0;
  }
  res= args[2]->val_str(str);
  null_value= args[2]->null_value;
  return res;
}

Project: server

  String *val_str(String *to)
  {
    return update_null() ? NULL : cached_time.to_string(to, decimals);
  }

Project: server

  bool val_native(THD *thd, Native *to)
  {
    return m_value.to_native(to, decimals);
  }

Project: server

void Regexp_processor_pcre::fix_owner(Item_func *owner,
                                      Item *subject_arg,
                                      Item *pattern_arg)
{
  if (!is_compiled() && pattern_arg->const_item())
  {
    if (compile(pattern_arg, true))
    {
      owner->maybe_null= 1; // Will always return NULL
      return;
    }
    set_const(true);
    owner->maybe_null= subject_arg->maybe_null;
  }
  else
    owner->maybe_null= 1;
}

Project: server

  Item *in_subq_field_transformer_for_where(THD *thd, uchar *arg)
  { return convert_to_basic_const_item(thd); }

Project: server

  int save_in_field(Field *field_arg, bool no_conversions)
  {
    return field_arg->save_in_field_default_value(false);
  }

Project: server

longlong Item_equal::val_int()
{
  if (cond_false)
    return 0;
  if (cond_true)
    return 1;
  Item *item= get_const();
  Item_equal_fields_iterator it(*this);
  if (!item)
    item= it++;
  eval_item->store_value(item);
  if ((null_value= item->null_value))
    return 0;
  while ((item= it++))
  {
    Field *field= it.get_curr_field();
    /* Skip fields of tables that has not been read yet */
    if (!field->table->status || (field->table->status & STATUS_NULL_ROW))
    {
      const int rc= eval_item->cmp(item);
      if ((rc == TRUE) || (null_value= (rc == UNKNOWN)))
        return 0;
    }
  }
  return 1;
}

Project: server

void in_string::set(uint pos,Item *item)
{
  String *str=((String*) base)+pos;
  String *res=item->val_str(str);
  if (res && res != str)
  {
    if (res->uses_buffer_owned_by(str))
      res->copy();
    if (item->type() == Item::FUNC_ITEM)
      str->copy(*res);
    else
      *str= *res;
  }
  if (!str->charset())
  {
    CHARSET_INFO *cs;
    if (!(cs= item->collation.collation))
      cs= &my_charset_bin;		// Should never happen for STR items
    str->set_charset(cs);
  }
}

Project: server

  Item_string(THD *thd, CHARSET_INFO *cs, Derivation dv= DERIVATION_COERCIBLE):
    Item_literal(thd)
  {
    collation.set(cs, dv);
    max_length= 0;
    set_name(thd, NULL, 0, system_charset_info);
    decimals= NOT_FIXED_DEC;
  }

Project: server

  bool val_native(THD *thd, Native *to)
  {
    DBUG_ASSERT(sane());
    return null_value || m_value.to_native(to, decimals);
  }

Project: server

  Item_cache_decimal(THD *thd): Item_cache(thd, &type_handler_newdecimal) {}

Project: server

  Item *get_copy(THD *thd)
  { return get_item_copy<Item_timestamp_literal>(thd, this); }

Project: server

Item_func_ifnull::real_op()
{
  DBUG_ASSERT(fixed == 1);
  double value= args[0]->val_real();
  if (!args[0]->null_value)
  {
    null_value=0;
    return value;
  }
  value= args[1]->val_real();
  if ((null_value=args[1]->null_value))
    return 0.0;
  return value;
}

Project: server

  virtual void unfix_fields()
  {
    DBUG_ASSERT(0);
  }

Project: server

  bool table_cant_handle_bit_fields() const
  { return m_table_cant_handle_bit_fields; }

Project: server

void in_time::set(uint pos,Item *item)
{
  struct packed_longlong *buff= &((packed_longlong*) base)[pos];

  buff->val= item->val_time_packed(current_thd);
  buff->unsigned_flag= 1L;
}

Project: server

bool Arg_comparator::set_cmp_func_for_row_arguments()
{
  uint n= (*a)->cols();
  if (n != (*b)->cols())
  {
    my_error(ER_OPERAND_COLUMNS, MYF(0), n);
    comparators= 0;
    return true;
  }
  if (!(comparators= new Arg_comparator[n]))
    return true;
  for (uint i=0; i < n; i++)
  {
    if ((*a)->element_index(i)->cols() != (*b)->element_index(i)->cols())
    {
      my_error(ER_OPERAND_COLUMNS, MYF(0), (*a)->element_index(i)->cols());
      return true;
    }
    if (comparators[i].set_cmp_func(owner, (*a)->addr(i),
                                           (*b)->addr(i), set_null))
      return true;
  }
  return false;
}

Project: server

  Item_hex_string(THD *thd, const char *str, size_t str_length):
    Item_hex_constant(thd, str, str_length) {}

Project: server

uchar *in_row::get_value(Item *item)
{
  tmp.store_value(item);
  if (item->is_null())
    return 0;
  return (uchar *)&tmp;
}

Project: server

  uint uint_geometry_type() const
  { return get_geometry_type(); }

Project: server

  enum Type type() const
  {
    // Don't pretend to be a constant unless value for this item is set.
    switch (state) {
    case NO_VALUE:         return PARAM_ITEM;
    case NULL_VALUE:       return NULL_ITEM;
    case SHORT_DATA_VALUE: return CONST_ITEM;
    case LONG_DATA_VALUE:  return CONST_ITEM;
    case DEFAULT_VALUE:    return PARAM_ITEM;
    case IGNORE_VALUE:     return PARAM_ITEM;
    }
    DBUG_ASSERT(0);
    return PARAM_ITEM;
  }

Project: server

void Item_equal::add_const(THD *thd, Item *c)
{
  if (cond_false)
    return;
  if (!with_const)
  {
    with_const= TRUE;
    equal_items.push_front(c, thd->mem_root);
    return;
  }

  /*
    Suppose we have an expression (with a string type field) like this:
      WHERE field=const1 AND field=const2 ...

    For all pairs field=constXXX we know that:

    - Item_func_eq::fix_length_and_dec() performed collation and character
    set aggregation and added character set converters when needed.
    Note, the case like:
      WHERE field=const1 COLLATE latin1_bin AND field=const2
    is not handled here, because the field would be replaced to
    Item_func_set_collation, which cannot get into Item_equal.
    So all constXXX that are handled by Item_equal
    already have compatible character sets with "field".

    - Also, Field_str::test_if_equality_guarantees_uniqueness() guarantees
    that the comparison collation of all equalities handled by Item_equal
    match the the collation of the field.

    Therefore, at Item_equal::add_const() time all constants constXXX
    should be directly comparable to each other without an additional
    character set conversion.
    It's safe to do val_str() for "const_item" and "c" and compare
    them according to the collation of the *field*.

    So in a script like this:
      CREATE TABLE t1 (a VARCHAR(10) COLLATE xxx);
      INSERT INTO t1 VALUES ('a'),('A');
      SELECT * FROM t1 WHERE a='a' AND a='A';
    Item_equal::add_const() effectively rewrites the condition to:
      SELECT * FROM t1 WHERE a='a' AND 'a' COLLATE xxx='A';
    and then to:
      SELECT * FROM t1 WHERE a='a'; // if the two constants were equal
                                    // e.g. in case of latin1_swedish_ci
    or to:
      SELECT * FROM t1 WHERE FALSE; // if the two constants were not equal
                                    // e.g. in case of latin1_bin

    Note, both "const_item" and "c" can return NULL, e.g.:
      SELECT * FROM t1 WHERE a=NULL    AND a='const';
      SELECT * FROM t1 WHERE a='const' AND a=NULL;
      SELECT * FROM t1 WHERE a='const' AND a=(SELECT MAX(a) FROM t2)
  */

  cond_false= !Item_equal::compare_type_handler()->Item_eq_value(thd, this, c,
                                                                 get_const());
  if (with_const && equal_items.elements == 1)
    cond_true= TRUE;
  if (cond_false || cond_true)
    const_item_cache= 1;
}

Project: server

  void add_argument(Item *item)
  {
    args[arg_count++]= item;
  }

Project: server

  DbugStringItemTypeValue(THD *thd, const Item *item)
  {
    append('(');
    append(item->type_handler()->name().ptr());
    append(')');
    const_cast<Item*>(item)->print(this, QT_EXPLAIN);
    /* Append end \0 to allow usage of c_ptr() */
    append('\0');
    str_length--;
  }

Project: server

  const Type_handler *real_type_handler() const
  { return (*ref)->real_type_handler(); }

Project: server

  bool get_time(THD *thd, MYSQL_TIME *ltime)
  { return get_date(thd, ltime, Time::Options(thd)); }

Project: server

  Double_null to_double_null()
  {
    // val_real() must be caleed on a separate line. See to_longlong_null()
    double nr= val_real();
    return Double_null(nr, null_value);
  }

Project: server

  bool sane() const { return !null_value || m_value.is_zero_datetime(); }

Project: server

  void update_table_bitmaps()
  {
    if (field && field->table)
    {
      TABLE *tab= field->table;
      tab->covering_keys.intersect(field->part_of_key);
      if (tab->read_set)
        tab->mark_column_with_deps(field);
    }
  }

Project: server

  longlong val_datetime_packed(THD *thd)
  {
    return has_value() ? value : 0;
  }

Project: server

  Field::geometry_type get_geometry_type() const
  { return Type_geometry_attributes::get_geometry_type(); };

Project: server

  const longlong *const_ptr_longlong() const
  { return can_return_const_value(INT_RESULT) ? &value.integer : NULL; }

Project: server

  Item *get_copy(THD *thd)
  { return get_item_copy<Item_cache_double>(thd, this); }

Project: server

  Field *create_tmp_field_ex(TABLE *table, Tmp_field_src *src,
                             const Tmp_field_param *param)
  {
    /*
      We can get to here when using a CURSOR for a query with NAME_CONST():
        DECLARE c CURSOR FOR SELECT NAME_CONST('x','y') FROM t1;
        OPEN c;
    */
    return tmp_table_field_from_field_type_maybe_null(table, src, param,
                                              type() == Item::NULL_ITEM);
  }

Project: server

  bool const_is_null() const { return state == NULL_VALUE; }

Project: server

  double val_real() { return has_value() ? Date(this).to_double() : 0; }

Project: server

bool Item_cond::walk(Item_processor processor, bool walk_subquery, void *arg)
{
  List_iterator_fast<Item> li(list);
  Item *item;
  while ((item= li++))
    if (item->walk(processor, walk_subquery, arg))
      return 1;
  return Item_func::walk(processor, walk_subquery, arg);
}

Project: server

  Item_cache_double(THD *thd)
   :Item_cache_real(thd, &type_handler_double)
  { }

Project: server

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 (thd->mem_root) Item_func_not_all(thd, args[0]);
  Item_allany_subselect *allany= (Item_allany_subselect*)args[0];
  allany->create_comp_func(FALSE);
  allany->all= !allany->all;
  allany->upper_item= new_item;
  return new_item;
}

Project: server

longlong Item_in_optimizer::val_int()
{
  bool tmp;
  DBUG_ASSERT(fixed == 1);
  cache->store(args[0]);
  cache->cache_value();
  DBUG_ENTER(" Item_in_optimizer::val_int");

  if (invisible_mode())
  {
    longlong res= args[1]->val_int();
    null_value= args[1]->null_value;
    DBUG_PRINT("info", ("pass trough"));
    DBUG_RETURN(res);
  }

  if (cache->null_value_inside)
  {
     DBUG_PRINT("info", ("Left NULL..."));
    /*
      We're evaluating 
      "<outer_value_list> [NOT] IN (SELECT <inner_value_list>...)" 
      where one or more of the outer values is NULL. 
    */
    if (((Item_in_subselect*)args[1])->is_top_level_item())
    {
      /*
        We're evaluating a top level item, e.g. 
	"<outer_value_list> IN (SELECT <inner_value_list>...)",
	and in this case a NULL value in the outer_value_list means
        that the result shall be NULL/FALSE (makes no difference for
        top level items). The cached value is NULL, so just return
        NULL.
      */
      null_value= 1;
    }
    else
    {
      /*
	We're evaluating an item where a NULL value in either the
        outer or inner value list does not automatically mean that we
        can return NULL/FALSE. An example of such a query is
        "<outer_value_list> NOT IN (SELECT <inner_value_list>...)" 
        The result when there is at least one NULL value is: NULL if the
        SELECT evaluated over the non-NULL values produces at least
        one row, FALSE otherwise
      */
      Item_in_subselect *item_subs=(Item_in_subselect*)args[1]; 
      bool all_left_cols_null= true;
      const uint ncols= cache->cols();

      /*
        Turn off the predicates that are based on column compares for
        which the left part is currently NULL
      */
      for (uint i= 0; i < ncols; i++)
      {
        if (cache->element_index(i)->null_value)
          item_subs->set_cond_guard_var(i, FALSE);
        else 
          all_left_cols_null= false;
      }

      if (!item_subs->is_correlated && 
          all_left_cols_null && result_for_null_param != UNKNOWN)
      {
        /* 
           This is a non-correlated subquery, all values in the outer
           value list are NULL, and we have already evaluated the
           subquery for all NULL values: Return the same result we
           did last time without evaluating the subquery.
        */
        null_value= result_for_null_param;
      } 
      else 
      {
        /* The subquery has to be evaluated */
        (void) item_subs->val_bool_result();
        if (item_subs->engine->no_rows())
          null_value= item_subs->null_value;
        else
          null_value= TRUE;
        if (all_left_cols_null)
          result_for_null_param= null_value;
      }

      /* Turn all predicates back on */
      for (uint i= 0; i < ncols; i++)
        item_subs->set_cond_guard_var(i, TRUE);
    }
    DBUG_RETURN(0);
  }
  tmp= args[1]->val_bool_result();
  null_value= args[1]->null_value;
  DBUG_RETURN(tmp);
}

Project: server

int cmp_item_time::cmp_not_null(const Value *val)
{
  DBUG_ASSERT(!val->is_null());
  DBUG_ASSERT(val->is_temporal());
  return value != pack_time(&val->value.m_time);
}

Project: server

longlong Item_func_strcmp::val_int()
{
  DBUG_ASSERT(fixed == 1);
  String *a= args[0]->val_str(&value1);
  String *b= args[1]->val_str(&value2);
  if (!a || !b)
  {
    null_value=1;
    return 0;
  }
  int value= cmp_collation.sortcmp(a, b);
  null_value=0;
  return !value ? 0 : (value < 0 ? (longlong) -1 : (longlong) 1);
}

Project: server

  Item *get_copy(THD *thd)
  { return get_item_copy<Item_decimal>(thd, this); }

Project: server

longlong Item_func_isnotnull::val_int()
{
  DBUG_ASSERT(fixed == 1);
  return args[0]->is_null() ? 0 : 1;
}

Project: server

  const Type_handler *type_handler() const
  {
    const Type_handler *handler= field->type_handler();
    return handler->type_handler_for_item_field();
  }

Project: server

  virtual longlong val_datetime_packed(THD *thd)
  {
    return Datetime(thd, this, Datetime::Options_cmp(thd)).to_packed();
  }

Project: server

Item_bool_rowready_func2* Gt_creator::create_swap(THD *thd, Item *a, Item *b) const
{
  return new(thd->mem_root) Item_func_lt(thd, b, a);
}

Project: server

Item *Item_equal::multiple_equality_transformer(THD *thd, uchar *arg)
{
  List<Item> equalities;
  if (create_pushable_equalities(thd, &equalities, 0, 0, false))
    return 0;

  switch (equalities.elements)
  {
  case 0:
    return 0;
  case 1:
    return equalities.head();
    break;
  default:
    return new (thd->mem_root) Item_cond_and(thd, equalities);
    break;
  }
}

Project: server

  String *val_str(String*) { return &str_value; }

Project: server

  void copy_with_sum_func(const Item *item)
  {
    m_with_sum_func= item->with_sum_func();
  }

Project: server

bool Item_func_between::count_sargable_conds(void *arg)
{
  SELECT_LEX *sel= (SELECT_LEX *) arg;
  sel->cond_count++;
  sel->between_count++;
  return 0;
}

Project: server

  void set(size_t pos, size_t length)
  {
    DBUG_ASSERT(pos < UINT_MAX32);
    DBUG_ASSERT(length < UINT_MAX32);
    m_pos= (uint) pos;
    m_length= (uint) length;
  }

Project: server

  void fix_charset_and_length_from_str_value(const String &str, Derivation dv)
  {
    fix_charset_and_length(str.charset(), dv, Metadata(&str));
  }

Project: server

int Arg_comparator::compare_e_row()
{
  (*a)->bring_value();
  (*b)->bring_value();
  uint n= (*a)->cols();
  for (uint i= 0; i<n; i++)
  {
    if (!comparators[i].compare())
      return 0;
  }
  return 1;
}

Project: server

  virtual bool is_evaluable_expression() const { return true; }

Project: server

  longlong val_time_packed(THD *thd)
  {
    return cached_time.valid_time_to_packed();
  }

Project: server

longlong Item_func_not::val_int()
{
  DBUG_ASSERT(fixed == 1);
  bool value= args[0]->val_bool();
  null_value=args[0]->null_value;
  return ((!null_value && value == 0) ? 1 : 0);
}

Project: server

bool Item_func_in::fix_length_and_dec()
{
  THD *thd= current_thd;
  uint found_types;
  m_comparator.set_handler(type_handler_varchar.type_handler_for_comparison());
  max_length= 1;

  if (prepare_predicant_and_values(thd, &found_types))
  {
    DBUG_ASSERT(thd->is_error()); // Must set error
    return TRUE;
  }

  if (arg_types_compatible) // Bisection condition #1
  {
    if (m_comparator.type_handler()->
        Item_func_in_fix_comparator_compatible_types(thd, this))
      return TRUE;
  }
  else
  {
    DBUG_ASSERT(m_comparator.cmp_type() != ROW_RESULT);
    if ( fix_for_scalar_comparison_using_cmp_items(thd, found_types))
      return TRUE;
  }

  DBUG_EXECUTE_IF("Item_func_in",
                  push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE,
                  ER_UNKNOWN_ERROR, "DBUG: types_compatible=%s bisect=%s",
                  arg_types_compatible ? "yes" : "no",
                  array != NULL ? "yes" : "no"););
  return FALSE;
}

Project: server

  virtual longlong val_int_min() const
  {
    return LONGLONG_MIN;
  }

Project: server

  longlong val_int()
  {
    DBUG_ASSERT(0); // never should be called
    null_value= true;
    return 0;
  }

Project: server

  void set_value(const Timestamp_or_zero_datetime &value)
  {
    m_value= value;
  }

Project: server

int Arg_comparator::compare_e_json_str()
{
  return compare_e_json_str_basic(*a, *b);
}

Project: server

  Item_splocal_row_field(THD *thd,
                         const Sp_rcontext_handler *rh,
                         const LEX_CSTRING *sp_var_name,
                         const LEX_CSTRING *sp_field_name,
                         uint sp_var_idx, uint sp_field_idx,
                         const Type_handler *handler,
                         uint pos_in_q= 0, uint len_in_q= 0)
   :Item_splocal(thd, rh, sp_var_name, sp_var_idx, handler, pos_in_q, len_in_q),
    m_field_name(*sp_field_name),
    m_field_idx(sp_field_idx)
  { }

Project: server

  virtual uint32 max_display_length() const
  {
    return type_handler()->max_display_length(this);
  }

Project: server

bool Item_equal::fix_fields(THD *thd, Item **ref)
{ 
  DBUG_ASSERT(fixed == 0);
  Item_equal_fields_iterator it(*this);
  Item *item;
  Field *first_equal_field= NULL;
  Field *last_equal_field= NULL;
  Field *prev_equal_field= NULL;
  not_null_tables_cache= used_tables_cache= 0;
  const_item_cache= 0;
  while ((item= it++))
  {
    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;
    DBUG_ASSERT(!item->with_sum_func() && !item->with_subquery());
    if (item->maybe_null)
      maybe_null= 1;
    if (!item->get_item_equal())
      item->set_item_equal(this);
    if (link_equal_fields && item->real_item()->type() == FIELD_ITEM)
    {
      last_equal_field= ((Item_field *) (item->real_item()))->field;
      if (!prev_equal_field)
        first_equal_field= last_equal_field;
      else
        prev_equal_field->next_equal_field= last_equal_field;
      prev_equal_field= last_equal_field;         
    }
  }
  if (prev_equal_field && last_equal_field != first_equal_field)
    last_equal_field->next_equal_field= first_equal_field;
  if (fix_length_and_dec())
    return TRUE;
  fixed= 1;
  return FALSE;
}

Project: server

  String *val_str(String *to)
  {
    DBUG_ASSERT(sane());
    return null_value ? NULL :
           m_value.to_datetime(current_thd).to_string(to, decimals);
  }

Project: server

  uint length() const { return m_length; }

Project: server

Item_cond::Item_cond(THD *thd, Item_cond *item)
  :Item_bool_func(thd, item),
   abort_on_null(item->abort_on_null),
   and_tables_cache(item->and_tables_cache)
{
  /*
    item->list will be copied by copy_andor_arguments() call
  */
}

Project: server

  bool save_in_param(THD *thd, Item_param *param)
  {
    param->set_default();
    return false;
  }

Project: server

void Item_equal::print(String *str, enum_query_type query_type)
{
  if (cond_false)
  {
    str->append('0');
    return;
  }
  str->append(func_name());
  str->append('(');
  List_iterator_fast<Item> it(equal_items);
  Item *item;
  item= it++;
  item->print(str, query_type);
  while ((item= it++))
  {
    str->append(',');
    str->append(' ');
    item->print(str, query_type);
  }
  str->append(')');
}

Project: server

  Item *get_copy(THD *thd)
  { return get_item_copy<Item_date_literal>(thd, this); }

Project: server

  longlong val_int()
  {
    return longlong_from_string_with_check(&str_value);
  }

Project: server

  const Type_handler *type_handler() const
  {
    if (result_field)
      return result_field->type_handler();
    return &type_handler_null;
  }

Project: server

Item_func_ifnull::int_op()
{
  DBUG_ASSERT(fixed == 1);
  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;
}

Project: server

  virtual Item *in_subq_field_transformer_for_having(THD *thd, uchar *arg)
  { return this; }

Project: server

  With_sum_func_cache(const Item *a)
   :m_with_sum_func(a->with_sum_func())
  { }

Project: server

longlong Item_is_not_null_test::val_int()
{
  DBUG_ASSERT(fixed == 1);
  DBUG_ENTER("Item_is_not_null_test::val_int");
  if (const_item() && !args[0]->maybe_null)
    DBUG_RETURN(1);
  if (args[0]->is_null())
  {
    DBUG_PRINT("info", ("null"));
    owner->was_null|= 1;
    DBUG_RETURN(0);
  }
  else
    DBUG_RETURN(1);
}

Project: server

  longlong val_int()
  {
    DBUG_ASSERT(sane());
    return null_value ? 0 :
           m_value.to_datetime(current_thd).to_longlong();
  }

Project: server

static inline int cmp_ulongs (ulonglong a_val, ulonglong b_val)
{
  return a_val < b_val ? -1 : a_val == b_val ? 0 : 1;
}

Project: server

Item_bool_rowready_func2* Le_creator::create(THD *thd, Item *a, Item *b) const
{
  return new(thd->mem_root) Item_func_le(thd, a, b);
}

Project: server

int Regexp_processor_pcre::default_regex_flags()
{
  return default_regex_flags_pcre(current_thd);
}

Project: server

  bool set_limit_clause_param(longlong nr)
  {
    value.set_handler(&type_handler_longlong);
    set_int(nr, MY_INT64_NUM_DECIMAL_DIGITS);
    return !unsigned_flag && value.integer < 0;
  }

Project: server

  bool is_of_type(Type t, Item_result cmp) const
  {
    return type() == t && cmp_type() == cmp;
  }

Project: server

  bool is_temporal() const { return m_type == DYN_COL_DATETIME; }

Project: server

  Item *grouping_field_transformer_for_where(THD *thd, uchar *arg)
  { return convert_to_basic_const_item(thd); }

Project: server

  int save_in_field(Field *field, bool no_conversions)
  { return save_date_in_field(field, no_conversions); }

Project: server

  void join(const Item *item)
  {
    // Ignore implicit NULLs
    if (m_geometry_type == m_geometry_type_unknown)
      copy(item->type_handler(), item);
    else if (item->type_handler() == &type_handler_geometry)
    {
      m_geometry_type=
        Field_geom::geometry_type_merge((Field_geom::geometry_type)
                                         m_geometry_type,
                                        (Field_geom::geometry_type)
                                         item->uint_geometry_type());
    }
  }

Project: server

  Item_string(THD *thd, const char *name_par, const char *str, size_t length,
              CHARSET_INFO *cs, Derivation dv, uint repertoire)
   :Item_literal(thd)
  {
    str_value.set_or_copy_aligned(str, length, cs);
    fix_from_value(dv, Metadata(&str_value, repertoire));
    set_name(thd, name_par, safe_strlen(name_par), system_charset_info);
  }

Project: server

  bool save_in_value(THD *thd, struct st_value *value)
  {
    return type_handler()->Item_save_in_value(thd, this, value);
  }

Project: server

  void share_name_with(const Item *item)
  {
    name= item->name;
    is_autogenerated_name= item->is_autogenerated_name;
  }

Project: server

bool Item_func_in::fix_for_row_comparison_using_cmp_items(THD *thd)
{
  if (make_unique_cmp_items(thd, cmp_collation.collation))
    return true;
  DBUG_ASSERT(get_comparator_type_handler(0) == &type_handler_row);
  DBUG_ASSERT(get_comparator_cmp_item(0));
  cmp_item_row *cmp_row= (cmp_item_row*) get_comparator_cmp_item(0);
  return cmp_row->prepare_comparators(thd, func_name(), this, 0);
}

Project: server

  Item* get_copy(THD *thd) { return 0; }

Project: server

  enum Type type() const { return CONST_ITEM; }

Project: server

  Item_outer_ref(THD *thd, Name_resolution_context *context_arg, Item **item,
                 const char *table_name_arg, LEX_CSTRING *field_name_arg,
                 bool alias_name_used_arg):
    Item_direct_ref(thd, context_arg, item, table_name_arg, field_name_arg,
                    alias_name_used_arg),
    outer_ref(0), in_sum_func(0), found_in_select_list(1), found_in_group_by(0)
  {}

Project: server

  bool get_date(THD *thd, MYSQL_TIME *to, date_mode_t mode)
  {
    return type_handler_year.Item_get_date_with_warn(thd, this, to, mode);
  }

Project: server

int Arg_comparator::compare_e_decimal()
{
  VDec val1(*a), val2(*b);
  if (val1.is_null() || val2.is_null())
    return MY_TEST(val1.is_null() && val2.is_null());
  val1.round_self_if_needed((*a)->decimals, HALF_UP);
  val2.round_self_if_needed((*b)->decimals, HALF_UP);
  return MY_TEST(val1.cmp(val2) == 0);
}

Project: server

bool Item_bool_rowready_func2::fix_length_and_dec()
{
  max_length= 1;				     // Function returns 0 or 1

  /*
    As some compare functions are generated after sql_yacc,
    we have to check for out of memory conditions here
  */
  if (!args[0] || !args[1])
    return FALSE;
  return setup_args_and_comparator(current_thd, &cmp);
}

Project: server

Item_bool_rowready_func2* Ge_creator::create_swap(THD *thd, Item *a, Item *b) const
{
  return new(thd->mem_root) Item_func_le(thd, b, a);
}

Project: server

  With_sum_func_cache(const Item *a, const Item *b, const Item *c,
                      const Item *d, const Item *e)
   :m_with_sum_func(a->with_sum_func() || b->with_sum_func() ||
                    c->with_sum_func() || d->with_sum_func() ||
                    e->with_sum_func())
  { }

Project: server

bool Item_func_case::fix_fields(THD *thd, Item **ref)
{
  bool res= Item_func::fix_fields(thd, ref);

  Item **pos= else_expr_addr();
  if (!pos || pos[0]->maybe_null)
    maybe_null= 1;
  return res;
}

Project: server

Item *Item_func_ne::negated_item(THD *thd) /* a != b  ->  a = b */
{
  return new (thd->mem_root) Item_func_eq(thd, args[0], args[1]);
}

Project: server

  void set_param_func(uchar **pos, ulong len)
  {
    /*
      To avoid Item_param::set_xxx() asserting on data type mismatch,
      we set the value type handler here:
      - It can not be initialized yet after Item_param::setup_conversion().
      - Also, for LIMIT clause parameters, the value type handler might have
        changed from the real type handler to type_handler_longlong.
        So here we'll restore it.
    */
    const Type_handler *h= Item_param::type_handler();
    value.set_handler(h);
    h->Item_param_set_param_func(this, pos, len);
  }

Project: server

bool Predicant_to_list_comparator::alloc_comparators(THD *thd, uint nargs)
{
  size_t nbytes= sizeof(Predicant_to_value_comparator) * nargs;
  if (!(m_comparators= (Predicant_to_value_comparator *) thd->alloc(nbytes)))
    return true;
  memset(m_comparators, 0, nbytes);
  return false;
}

Project: server

  Item_cache_year(THD *thd, const Type_handler *handler)
   :Item_cache_int(thd, handler) { }

Project: server

Item *Item_func_case_simple::find_item()
{
  /* Compare every WHEN argument with it and return the first match */
  uint idx;
  if (!Predicant_to_list_comparator::cmp(this, &idx, NULL))
    return args[idx + when_count()];
  Item **pos= Item_func_case_simple::else_expr_addr();
  return pos ? pos[0] : 0;
}

Project: server

Item_func_ifnull::str_op(String *str)
{
  DBUG_ASSERT(fixed == 1);
  String *res  =args[0]->val_str(str);
  if (!args[0]->null_value)
  {
    null_value=0;
    res->set_charset(collation.collation);
    return res;
  }
  res=args[1]->val_str(str);
  if ((null_value=args[1]->null_value))
    return 0;
  res->set_charset(collation.collation);
  return res;
}

Project: server

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

Project: server

  Item_args(THD *thd, Item *a, Item *b, Item *c)
  {
    arg_count= 0;
    if (likely((args= (Item**) thd_alloc(thd, sizeof(Item*) * 3))))
    {
      arg_count= 3;
      args[0]= a; args[1]= b; args[2]= c;
    }
  }

Project: server

  Item_fixed_hybrid(THD *thd): Item(thd), fixed(false)
  { }

Project: server

longlong Item_func_case::int_op()
{
  DBUG_ASSERT(fixed == 1);
  Item *item= find_item();
  longlong res;

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

Project: server

bool Regexp_processor_pcre::exec(Item *item, int offset,
                                uint n_result_offsets_to_convert)
{
  char buff[MAX_FIELD_WIDTH];
  String tmp(buff,sizeof(buff),&my_charset_bin);
  String *res= item->val_str(&tmp);
  if (item->null_value)
    return true;
  return exec(res, offset, n_result_offsets_to_convert);
}

Project: server

  Item *get_copy(THD *thd)
  { return get_item_copy<Item_cache_int>(thd, this); }

Project: server

  Item_direct_ref(THD *thd, Name_resolution_context *context_arg, Item **item,
                  const char *table_name_arg,
                  const LEX_CSTRING *field_name_arg,
                  bool alias_name_used_arg= FALSE):
    Item_ref(thd, context_arg, item, table_name_arg,
             field_name_arg, alias_name_used_arg)
  {}

Project: server

  virtual const Type_handler *fixed_type_handler() const
  {
    return NULL;
  }

Project: server

  uint divisor_precision_increment() const
  {
    return type_handler()->Item_divisor_precision_increment(this);
  }

Project: server

  virtual bool with_sum_func() const { return false; }

Project: server

void Item_func_in::print(String *str, enum_query_type query_type)
{
  args[0]->print_parenthesised(str, query_type, precedence());
  if (negated)
    str->append(STRING_WITH_LEN(" not"));
  str->append(STRING_WITH_LEN(" in ("));
  print_args(str, 1, query_type);
  str->append(STRING_WITH_LEN(")"));
}

Project: server

  Field::geometry_type get_geometry_type() const
  {
    return Type_geometry_attributes::get_geometry_type();
  }

Project: server

  virtual bool set_fields_as_dependent_processor(void *arg) { return 0; }

Project: server

uchar *in_longlong::get_value(Item *item)
{
  tmp.val= item->val_int();
  if (item->null_value)
    return 0;
  tmp.unsigned_flag= item->unsigned_flag;
  return (uchar*) &tmp;
}

Project: server

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

Project: server

int Arg_comparator::compare_e_string()
{
  String *res1,*res2;
  res1= (*a)->val_str(&value1);
  res2= (*b)->val_str(&value2);
  if (!res1 || !res2)
    return MY_TEST(res1 == res2);
  return MY_TEST(sortcmp(res1, res2, compare_collation()) == 0);
}

Project: server

int Arg_comparator::compare_native()
{
  THD *thd= current_thd;
  if (!(*a)->val_native_with_conversion(thd, &m_native1,
                                        compare_type_handler()))
  {
    if (!(*b)->val_native_with_conversion(thd, &m_native2,
                                          compare_type_handler()))
    {
      if (set_null)
        owner->null_value= 0;
      return compare_type_handler()->cmp_native(m_native1, m_native2);
    }
  }
  if (set_null)
    owner->null_value= 1;
  return -1;
}

Project: server

  bool modify_item() const { return m_modify_item; }

Project: server

bool in_vector::find(Item *item)
{
  uchar *result=get_value(item);
  if (!result || !used_count)
    return false;				// Null value

  uint start,end;
  start=0; end=used_count-1;
  while (start != end)
  {
    uint mid=(start+end+1)/2;
    int res;
    if ((res=(*compare)(collation, base+mid*size, result)) == 0)
      return true;
    if (res < 0)
      start=mid;
    else
      end=mid-1;
  }
  return ((*compare)(collation, base+start*size, result) == 0);
}

Project: server

void Item_equal::update_used_tables()
{
  not_null_tables_cache= used_tables_cache= 0;
  if ((const_item_cache= cond_false || cond_true))
    return;
  Item_equal_fields_iterator it(*this);
  Item *item;
  const_item_cache= 1;
  while ((item= it++))
  {
    item->update_used_tables();
    used_tables_cache|= item->used_tables();
    /* see commentary at Item_equal::update_const() */
    const_item_cache&= item->const_item() && !item->is_outer_field();
  }
}

Project: server

bool Item_func_equal::fix_length_and_dec()
{
  bool rc= Item_bool_rowready_func2::fix_length_and_dec();
  maybe_null=null_value=0;
  return rc;
}

Project: server

  virtual void print(String *str, enum_query_type query_type)
  {
    decimal_value.to_string(&str_value);
    str->append(str_value);
  }

Project: server

  longlong val_int()
  {
    return has_value() ? Time(this).to_longlong() : 0;
  }

Project: server

Item *Item_in_optimizer::expr_cache_insert_transformer(THD *thd, uchar *unused)
{
  DBUG_ENTER("Item_in_optimizer::expr_cache_insert_transformer");
  DBUG_ASSERT(fixed);

  if (invisible_mode())
    DBUG_RETURN(this);

  if (expr_cache)
    DBUG_RETURN(expr_cache);

  if (args[1]->expr_cache_is_needed(thd) &&
      (expr_cache= set_expr_cache(thd)))
    DBUG_RETURN(expr_cache);

  DBUG_RETURN(this);
}

Project: server

  const Type_handler *type_handler() const
  {
    return Type_handler::get_handler_by_field_type(int_field_type);
  }

Project: server

  bool check_partition_func_processor(void *int_arg) { return false;}

Project: server

  String *val_str(String *str)
  {
    DBUG_ASSERT(0); // never should be called
    null_value= true;
    return 0;
  }

Project: server

  Item_empty_string(THD *thd, const char *header,uint length,
                    CHARSET_INFO *cs= NULL):
    Item_partition_func_safe_string(thd, "", 0,
                                    cs ? cs : &my_charset_utf8_general_ci)
    {
      name.str=    header;
      name.length= strlen(name.str);
      max_length= length * collation.collation->mbmaxlen;
    }

Project: server

  Item* element_index(uint i) { return this_item()->element_index(i); }

Project: server

int Arg_comparator::compare_e_int()
{
  longlong val1= (*a)->val_int();
  longlong val2= (*b)->val_int();
  if ((*a)->null_value || (*b)->null_value)
    return MY_TEST((*a)->null_value && (*b)->null_value);
  return MY_TEST(val1 == val2);
}

Project: server

longlong Item_func_equal::val_int()
{
  DBUG_ASSERT(fixed == 1);
  return cmp.compare();
}

Project: server

    Print(Item *item, enum_query_type type)
    {
      item->print(this, type);
    }

Project: server

bool Item_equal::walk(Item_processor processor, bool walk_subquery, void *arg)
{
  Item *item;
  Item_equal_fields_iterator it(*this);
  while ((item= it++))
  {
    if (item->walk(processor, walk_subquery, arg))
      return 1;
  }
  return Item_func::walk(processor, walk_subquery, arg);
}

Project: server

  my_decimal *val_decimal(my_decimal *to)
  {
    return has_value() ? Datetime(this).to_decimal(to) : NULL;
  }

Project: server

void in_longlong::set(uint pos,Item *item)
{
  struct packed_longlong *buff= &((packed_longlong*) base)[pos];
  
  buff->val= item->val_int();
  buff->unsigned_flag= item->unsigned_flag;
}

Project: server

  bool fix_fields_if_needed_for_order_by(THD *thd, Item **ref)
  {
    return fix_fields_if_needed_for_scalar(thd, ref);
  }

Project: server

bool Item_func_in::prepare_predicant_and_values(THD *thd, uint *found_types)
{
  uint type_cnt;
  have_null= false;

  add_predicant(this, 0);
  for (uint i= 1 ; i < arg_count; i++)
  {
    if (add_value_skip_null(Item_func_in::func_name(), this, i, &have_null))
      return true;
  }
  all_values_added(&m_comparator, &type_cnt, found_types);
  arg_types_compatible= type_cnt < 2;

#ifndef DBUG_OFF
  Predicant_to_list_comparator::debug_print(thd);
#endif
  return false;
}

Project: server

  bool val_native_from_item(THD *thd, Item *item, Native *to)
  {
    DBUG_ASSERT(is_fixed());
    null_value= item->val_native(thd, to);
    DBUG_ASSERT(null_value == item->null_value);
    return null_value;
  }

Project: server

bool fix_escape_item(THD *thd, Item *escape_item, String *tmp_str,
                     bool escape_used_in_parsing, CHARSET_INFO *cmp_cs,
                     int *escape)
{
  /*
    ESCAPE clause accepts only constant arguments and Item_param.

    Subqueries during context_analysis_only might decide they're
    const_during_execution, but not quite const yet, not evaluate-able.
    This is fine, as most of context_analysis_only modes will never
    reach val_int(), so we won't need the value.
    CONTEXT_ANALYSIS_ONLY_DERIVED being a notable exception here.
  */
  if (!escape_item->const_during_execution() ||
     (!escape_item->const_item() &&
      !(thd->lex->context_analysis_only & ~CONTEXT_ANALYSIS_ONLY_DERIVED)))
  {
    my_error(ER_WRONG_ARGUMENTS,MYF(0),"ESCAPE");
    return TRUE;
  }

  IF_DBUG(*escape= ESCAPE_NOT_INITIALIZED,);

  if (escape_item->const_item())
  {
    /* If we are on execution stage */
    /* XXX is it safe to evaluate is_expensive() items here? */
    String *escape_str= escape_item->val_str(tmp_str);
    if (escape_str)
    {
      const char *escape_str_ptr= escape_str->ptr();
      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;
      }

      if (use_mb(cmp_cs))
      {
        CHARSET_INFO *cs= escape_str->charset();
        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
      {
        /*
          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.
        */
        uint32 unused;
        if (escape_str->needs_conversion(escape_str->length(),
                                         escape_str->charset(),cmp_cs,&unused))
        {
          char ch;
          uint errors;
          uint32 cnvlen= copy_and_convert(&ch, 1, cmp_cs, escape_str_ptr,
                                          escape_str->length(),
                                          escape_str->charset(), &errors);
          *escape= cnvlen ? ch : '\\';
        }
        else
          *escape= escape_str_ptr ? *escape_str_ptr : '\\';
      }
    }
    else
      *escape= '\\';
  }

  return FALSE;
}

Project: server

  void make_send_field(THD *thd, Send_field *)
  {
    illegal_method_call((const char*)"make_send_field");
  };

Project: server

  bool vcol_assignment_allowed_value() const
  {
    switch (state) {
    case NULL_VALUE:
    case DEFAULT_VALUE:
    case IGNORE_VALUE:
      return true;
    case NO_VALUE:
    case SHORT_DATA_VALUE:
    case LONG_DATA_VALUE:
      break;
    }
    return false;
  }

Project: server

  virtual Item_func *get_item_func() { return NULL; }

Project: server

int Arg_comparator::compare_time()
{
  THD *thd= current_thd;
  longlong val1= (*a)->val_time_packed(thd);
  if (!(*a)->null_value)
  {
    longlong val2= (*b)->val_time_packed(thd);
    if (!(*b)->null_value)
      return compare_not_null_values(val1, val2);
  }
  if (set_null)
    owner->null_value= true;
  return -1;
}

Project: server

longlong Item_func_isnull::val_int()
{
  DBUG_ASSERT(fixed == 1);
  if (const_item() && !args[0]->maybe_null)
    return 0;
  return args[0]->is_null() ? 1: 0;
}

Project: server

  longlong val_datetime_packed(THD *thd)
  {
    return to_datetime(current_thd).to_packed();
  }

Project: server

bool cmp_item_row::alloc_comparators(THD *thd, uint cols)
{
  if (comparators)
  {
    DBUG_ASSERT(cols == n);
    return false;
  }
  return
    !(comparators= (cmp_item **) thd->calloc(sizeof(cmp_item *) * (n= cols)));
}

Project: server

longlong Item_func_between::val_int_cmp_time()
{
  THD *thd= current_thd;
  longlong value= args[0]->val_time_packed(thd), a, b;
  if ((null_value= args[0]->null_value))
    return 0;
  a= args[1]->val_time_packed(thd);
  b= args[2]->val_time_packed(thd);
  return val_int_cmp_int_finalize(value, a, b);
}

Project: server

int Arg_comparator::compare_e_real()
{
  double val1= (*a)->val_real();
  double val2= (*b)->val_real();
  if ((*a)->null_value || (*b)->null_value)
    return MY_TEST((*a)->null_value && (*b)->null_value);
  return MY_TEST(val1 == val2);
}

Project: server

  void set_with_sum_func() { m_with_sum_func= true; }

Project: server

  bool check_vcol_func_processor(void *arg) { return false; }

Project: server

  void cleanup()
  {
    Item::cleanup();
    fixed= false;
  }

Project: server

int cmp_item_timestamp::cmp(Item *arg)
{
  THD *thd= current_thd;
  Timestamp_or_zero_datetime_native_null tmp(thd, arg, true);
  return m_null_value || tmp.is_null() ? UNKNOWN :
         type_handler_timestamp2.cmp_native(m_native, tmp) != 0;
}

Project: server

  ~Name_resolution_context_backup()
  {
    ctx_state.restore_state(&ctx, &table_list);
    table_list.map= save_map;
  }

Project: server

  virtual uint decimal_precision() const
  {
    return type_handler()->Item_decimal_precision(this);
  }

Project: server

void Item_func::convert_const_compared_to_int_field(THD *thd)
{
  DBUG_ASSERT(arg_count >= 2); // Item_func_nullif has arg_count == 3
  if (!thd->lex->is_ps_or_view_context_analysis())
  {
    int field;
    if (args[field= 0]->real_item()->type() == FIELD_ITEM ||
        args[field= 1]->real_item()->type() == FIELD_ITEM)
    {
      Item_field *field_item= (Item_field*) (args[field]->real_item());
      if (((field_item->field_type() == MYSQL_TYPE_LONGLONG &&
            field_item->type_handler() != &type_handler_vers_trx_id) ||
           field_item->field_type() ==  MYSQL_TYPE_YEAR))
        convert_const_to_int(thd, field_item, &args[!field]);
    }
  }
}

Project: server

  Item *field_transformer_for_having_pushdown(THD *thd, uchar *arg)
  { return this; }

Project: server

bool Item_in_optimizer::is_expensive_processor(void *arg)
{
  DBUG_ASSERT(fixed);
  return args[0]->is_expensive_processor(arg) ||
         args[1]->is_expensive_processor(arg);
}

Project: server

  virtual const char *full_name() const { return name.str ? name.str : "???"; }

Project: server

  Item_splocal_row_field_by_name(THD *thd,
                                 const Sp_rcontext_handler *rh,
                                 const LEX_CSTRING *sp_var_name,
                                 const LEX_CSTRING *sp_field_name,
                                 uint sp_var_idx,
                                 const Type_handler *handler,
                                 uint pos_in_q= 0, uint len_in_q= 0)
   :Item_splocal_row_field(thd, rh, sp_var_name, sp_field_name,
                           sp_var_idx, 0 /* field index will be set later */,
                           handler, pos_in_q, len_in_q)
  { }

Project: server

  double val_real()
  {
    DBUG_ASSERT(0); // never should be called
    null_value= true;
    return 0.0;
  }

Project: server

int Arg_comparator::compare_e_real_fixed()
{
  double val1= (*a)->val_real();
  double val2= (*b)->val_real();
  if ((*a)->null_value || (*b)->null_value)
    return MY_TEST((*a)->null_value && (*b)->null_value);
  return MY_TEST(val1 == val2 || fabs(val1 - val2) < precision);
}

Project: server

bool Predicant_to_list_comparator::add_value(const char *funcname,
                                             Item_args *args,
                                             uint value_index)
{
  DBUG_ASSERT(m_predicant_index < args->argument_count());
  DBUG_ASSERT(value_index < args->argument_count());
  Type_handler_hybrid_field_type tmp;
  Item *tmpargs[2];
  tmpargs[0]= args->arguments()[m_predicant_index];
  tmpargs[1]= args->arguments()[value_index];
  if (tmp.aggregate_for_comparison(funcname, tmpargs, 2, true))
  {
    DBUG_ASSERT(current_thd->is_error());
    return true;
  }
  m_comparators[m_comparator_count].m_handler= tmp.type_handler();
  m_comparators[m_comparator_count].m_arg_index= value_index;
  m_comparator_count++;
  return false;
}

Project: server

  double val_real()
  {
    return can_return_value() ? value.val_real(this) : 0e0;
  }

Project: server

void in_datetime::set(uint pos,Item *item)
{
  struct packed_longlong *buff= &((packed_longlong*) base)[pos];

  buff->val= item->val_datetime_packed(current_thd);
  buff->unsigned_flag= 1L;
}

Project: server

  virtual bool is_outer_field() const { DBUG_ASSERT(is_fixed()); return FALSE; }

Project: server

bool Item_func_case::aggregate_then_and_else_arguments(THD *thd, uint start)
{
  if (aggregate_for_result(func_name(), args + start, arg_count - start, true))
    return true;

  if (fix_attributes(args + start, arg_count - start))
    return true;

  return false;
}

Project: server

  TYPELIB *get_typelib() const { return field->get_typelib(); }

Project: server

  const Type_handler *type_handler() const
  {
    return Type_handler::blob_type_handler(max_length);
  }

Project: server

Item *in_timestamp::create_item(THD *thd)
{
  return new (thd->mem_root) Item_timestamp_literal(thd);
}

Project: server

Item_bool_rowready_func2::value_depends_on_sql_mode() const
{
  if (compare_collation()->state & MY_CS_NOPAD)
    return Item_func::value_depends_on_sql_mode();
  return ((args[0]->value_depends_on_sql_mode() |
           args[1]->value_depends_on_sql_mode()) &
          Sql_mode_dependency(~0, ~MODE_PAD_CHAR_TO_FULL_LENGTH)).
         soft_to_hard();
}

Project: server

longlong Item_func_ne::val_int()
{
  DBUG_ASSERT(fixed == 1);
  int value= cmp.compare();
  return value != 0 && !null_value ? 1 : 0;
}

Project: server

bool Regexp_processor_pcre::exec(String *str, int offset,
                                  uint n_result_offsets_to_convert)
{
  if (!(str= convert_if_needed(str, &subject_converter)))
    return true;
  m_pcre_exec_rc= pcre_exec_with_warn(m_pcre, &m_pcre_extra,
                                      str->c_ptr_safe(), str->length(),
                                      offset, 0,
                                      m_SubStrVec, array_elements(m_SubStrVec));
  if (m_pcre_exec_rc > 0)
  {
    uint i;
    for (i= 0; i < n_result_offsets_to_convert; i++)
    {
      /*
        Convert byte offset into character offset.
      */
      m_SubStrVec[i]= (int) str->charset()->cset->numchars(str->charset(),
                                                           str->ptr(),
                                                           str->ptr() +
                                                           m_SubStrVec[i]);
    }
  }
  return false;
}

Project: server

  virtual Item *multiple_equality_transformer(THD *thd, uchar *arg)
  { return this; }

Project: server

  void fix_from_value(Derivation dv, const Metadata metadata)
  {
    fix_charset_and_length(str_value.charset(), dv, metadata);
  }

Project: server

void Item_func_if::fix_after_pullout(st_select_lex *new_parent,
                                     Item **ref, bool merge)
{
  /* This will re-calculate attributes of the arguments */
  Item_func::fix_after_pullout(new_parent, ref, merge);
  /* Then, re-calculate not_null_tables_cache according to our special rules */
  eval_not_null_tables(NULL);
}

Project: server

  void make_send_field(THD *thd, Send_field *field)
  { item->make_send_field(thd, field); }

Project: server

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

Project: server

  Item_default_value(THD *thd, Name_resolution_context *context_arg, Item *a,
                     bool vcol_assignment_arg)
    :Item_field(thd, context_arg, (const char *)NULL, (const char *)NULL,
                &null_clex_str), vcol_assignment_ok(vcol_assignment_arg),
     arg(a), cached_field(NULL) {}

Project: server

  const Type_handler *type_handler_long_or_longlong() const
  {
    return Type_handler::type_handler_long_or_longlong(max_char_length());
  }

Project: server

  Item_contextually_typed_value_specification(THD *thd) :Item(thd)
  { }

Project: server

  Item_datetime_literal(THD *thd, const Datetime *ltime, uint dec_arg):
    Item_temporal_literal(thd, dec_arg),
    cached_time(*ltime)
  {
    DBUG_ASSERT(cached_time.is_valid_datetime());
    max_length= MAX_DATETIME_WIDTH + (decimals ? decimals + 1 : 0);
    // See the comment on maybe_null in Item_date_literal
    maybe_null= cached_time.check_date(TIME_NO_ZERO_DATE | TIME_NO_ZERO_IN_DATE);
  }

Project: server

  double val_real() { return cached_time.to_double(); }

Project: server

Item_func_nullif::native_op(THD *thd, Native *to)
{
  DBUG_ASSERT(fixed == 1);
  if (!compare())
    return (null_value= true);
  return val_native_with_conversion_from_item(thd, args[2], to, type_handler());
}

Project: server

  Item *get_copy(THD *thd)
  { return get_item_copy<Item_null>(thd, this); }

Project: server

uchar *in_double::get_value(Item *item)
{
  tmp= item->val_real();
  if (item->null_value)
    return 0;					/* purecov: inspected */
  return (uchar*) &tmp;
}

Project: server

static void propagate_and_change_item_tree(THD *thd, Item **place,
                                           COND_EQUAL *cond,
                                           const Item::Context &ctx)
{
  Item *new_value= (*place)->propagate_equal_fields(thd, ctx, cond);
  if (new_value && *place != new_value)
    thd->change_item_tree(place, new_value);
}

Project: server

longlong Item_func_bit_or::val_int()
{
  DBUG_ASSERT(fixed == 1);
  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);
}

Project: server

  Item *build_clone(THD *thd) { return 0; }

Project: server

  uint cols() const { return item_count; }

Project: server

bool Item_func_case::date_op(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzydate)
{
  DBUG_ASSERT(fixed == 1);
  Item *item= find_item();
  if (!item)
    return (null_value= true);
  Datetime_truncation_not_needed dt(thd, item, fuzzydate);
  return (null_value= dt.copy_to_mysql_time(ltime, mysql_timestamp_type()));
}

Project: server

  Item *get_copy(THD *thd)
  { return get_item_copy<Item_hex_hybrid>(thd, this); }

Project: server

  String *val_str_from_item(Item *item, String *str)
  {
    DBUG_ASSERT(is_fixed());
    String *res= item->val_str(str);
    if (res)
      res->set_charset(collation.collation);
    if ((null_value= item->null_value))
      res= NULL;
    return res;
  }

Project: server

in_double::in_double(THD *thd, uint elements)
  :in_vector(thd, elements, sizeof(double), (qsort2_cmp) cmp_double, 0)
{}

Project: server

  virtual bool excl_dep_on_in_subq_left_part(Item_in_subselect *subq_pred)
  { return false; }

Project: server

String *Regexp_processor_pcre::convert_if_needed(String *str, String *converter)
{
  if (m_conversion_is_needed)
  {
    uint dummy_errors;
    if (converter->copy(str->ptr(), str->length(), str->charset(),
                        m_library_charset, &dummy_errors))
      return NULL;
    str= converter;
  }
  return str;
}

Project: server

Item_func_if::fix_fields(THD *thd, Item **ref)
{
  DBUG_ASSERT(fixed == 0);
  args[0]->top_level_item();

  if (Item_func::fix_fields(thd, ref))
    return 1;

  return 0;
}

Project: server

longlong Item_func_eq::val_int()
{
  DBUG_ASSERT(fixed == 1);
  int value= cmp.compare();
  return value == 0 ? 1 : 0;
}

Project: server

void Item_cond::print(String *str, enum_query_type query_type)
{
  List_iterator_fast<Item> li(list);
  Item *item;
  if ((item=li++))
    item->print_parenthesised(str, query_type, precedence());
  while ((item=li++))
  {
    str->append(' ');
    str->append(func_name());
    str->append(' ');
    item->print_parenthesised(str, query_type, precedence());
  }
}

Project: server

void Item_is_not_null_test::update_used_tables()
{
  if (!args[0]->maybe_null)
    used_tables_cache= 0;			/* is always true */
  else
    args[0]->update_used_tables();
}

Project: server

  With_sum_func_cache(const Item *a, const Item *b, const Item *c,
                      const Item *d)
   :m_with_sum_func(a->with_sum_func() || b->with_sum_func() ||
                    c->with_sum_func() || d->with_sum_func())
  { }

Project: server

  Item *remove_item_direct_ref() { return this; }

Project: server

  const Type_handler *type_handler() const { return &type_handler_hex_hybrid; }

Project: server

  bool get_date_from_item(THD *thd, Item *item,
                          MYSQL_TIME *ltime, date_mode_t fuzzydate)
  {
    bool rc= item->get_date(thd, ltime, fuzzydate);
    null_value= MY_TEST(rc || item->null_value);
    return rc;
  }

Project: server

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

Project: server

  int save_in_field(Field *field_arg, bool no_conversions)
  {
    return field_arg->save_in_field_ignore_value(false);
  }

Project: server

Item_func_nullif::fix_length_and_dec()
{
  /*
    If this is the first invocation of fix_length_and_dec(), create the
    third argument as a copy of the first. This cannot be done before
    fix_fields(), because fix_fields() might replace items,
    for exampe NOT x --> x==0, or (SELECT 1) --> 1.
    See also class Item_func_nullif declaration.
  */
  if (arg_count == 2)
    args[arg_count++]= m_arg0 ? m_arg0 : args[0];

  THD *thd= current_thd;
  /*
    At prepared statement EXECUTE time, args[0] can already
    point to a different Item, created during PREPARE time fix_length_and_dec().
    For example, if character set conversion was needed, arguments can look
    like this:

      args[0]= > Item_func_conv_charset \
                                         l_expr
      args[2]= >------------------------/

    Otherwise (during PREPARE or convensional execution),
    args[0] and args[2] should still point to the same original l_expr.
  */
  DBUG_ASSERT(args[0] == args[2] || thd->stmt_arena->is_stmt_execute());
  if (args[0]->type() == SUM_FUNC_ITEM &&
      !thd->lex->is_ps_or_view_context_analysis())
  {
    /*
      NULLIF(l_expr, r_expr)

        is calculated in the way to return a result equal to:

      CASE WHEN l_expr = r_expr THEN NULL ELSE r_expr END.

      There's nothing special with r_expr, because it's referenced
      only by args[1] and nothing else.

      l_expr needs a special treatment, as it's referenced by both
      args[0] and args[2] initially.

      args[2] is used to return the value. Afrer all transformations
      (e.g. in fix_length_and_dec(), equal field propagation, etc)
      args[2] points to a an Item which preserves the exact data type and
      attributes (e.g. collation) of the original l_expr.
      It can point:
      - to the original l_expr
      - to an Item_cache pointing to l_expr
      - to a constant of the same data type with l_expr.

      args[0] is used for comparison. It can be replaced:

      - to Item_func_conv_charset by character set aggregation routines
      - to a constant Item by equal field propagation routines
        (in case of Item_field)

      The data type and/or the attributes of args[0] can differ from
      the data type and the attributes of the original l_expr, to make
      it comparable to args[1] (which points to r_expr or its replacement).

      For aggregate functions we have to wrap the original args[0]/args[2]
      into Item_cache (see MDEV-9181). In this case the Item_cache
      instance becomes the subject to character set conversion instead of
      the original args[0]/args[2], while the original args[0]/args[2] get
      hidden inside the cache.

      Some examples of what NULLIF can end up with after argument
      substitution (we don't mention args[1] in some cases for simplicity):

      1. l_expr is not an aggregate function:

        a. No conversion happened.
           args[0] and args[2] were not replaced to something else
           (i.e. neither by character set conversion, nor by propagation):

          args[1] > r_expr
          args[0] \
                    l_expr
          args[2] /

        b. Conversion of args[0] happened:

           CREATE OR REPLACE TABLE t1 (
             a CHAR(10) CHARACTER SET latin1,
             b CHAR(10) CHARACTER SET utf8);
           SELECT * FROM t1 WHERE NULLIF(a,b);

           args[1] > r_expr                          (Item_field for t1.b)
           args[0] > Item_func_conv_charset\
                                            l_expr   (Item_field for t1.a)
           args[2] > ----------------------/

        c. Conversion of args[1] happened:

          CREATE OR REPLACE TABLE t1 (
            a CHAR(10) CHARACTER SET utf8,
            b CHAR(10) CHARACTER SET latin1);
          SELECT * FROM t1 WHERE NULLIF(a,b);

          args[1] > Item_func_conv_charset -> r_expr (Item_field for t1.b)
          args[0] \
                   l_expr                            (Item_field for t1.a)
          args[2] /

        d. Conversion of only args[0] happened (by equal field proparation):

           CREATE OR REPLACE TABLE t1 (
             a CHAR(10),
             b CHAR(10));
           SELECT * FROM t1 WHERE NULLIF(a,b) AND a='a';

           args[1] > r_expr            (Item_field for t1.b)
           args[0] > Item_string('a')  (constant replacement for t1.a)
           args[2] > l_expr            (Item_field for t1.a)

        e. Conversion of both args[0] and args[2] happened
           (by equal field propagation):

           CREATE OR REPLACE TABLE t1 (a INT,b INT);
           SELECT * FROM t1 WHERE NULLIF(a,b) AND a=5;

           args[1] > r_expr         (Item_field for "b")
           args[0] \
                    Item_int (5)    (constant replacement for "a")
           args[2] /

      2. In case if l_expr is an aggregate function:

        a. No conversion happened:

          args[0] \
                   Item_cache > l_expr
          args[2] /

        b. Conversion of args[0] happened:

          args[0] > Item_func_conv_charset \
                                            Item_cache > l_expr
          args[2] >------------------------/

        c. Conversion of both args[0] and args[2] happened.
           (e.g. by equal expression propagation)
           TODO: check if it's possible (and add an example query if so).
    */
    m_cache= args[0]->cmp_type() == STRING_RESULT ?
             new (thd->mem_root) Item_cache_str_for_nullif(thd, args[0]) :
             args[0]->get_cache(thd);
    if (!m_cache)
      return TRUE;
    m_cache->setup(thd, args[0]);
    m_cache->store(args[0]);
    m_cache->set_used_tables(args[0]->used_tables());
    thd->change_item_tree(&args[0], m_cache);
    thd->change_item_tree(&args[2], m_cache);
  }
  set_handler(args[2]->type_handler());
  collation.set(args[2]->collation);
  decimals= args[2]->decimals;
  unsigned_flag= args[2]->unsigned_flag;
  fix_char_length(args[2]->max_char_length());
  maybe_null=1;
  m_arg0= args[0];
  if (setup_args_and_comparator(thd, &cmp))
    return TRUE;
  /*
    A special code for EXECUTE..PREPARE.

    If args[0] did not change, then we don't remember it, as it can point
    to a temporary Item object which will be destroyed between PREPARE
    and EXECUTE. EXECUTE time fix_length_and_dec() will correctly set args[2]
    from args[0] again.

    If args[0] changed, then it can be Item_func_conv_charset() for the
    original args[0], which was permanently installed during PREPARE time
    into the item tree as a wrapper for args[0], using change_item_tree(), i.e.

      NULLIF(latin1_field, 'a' COLLATE utf8_bin)

    was "rewritten" to:

      CASE WHEN CONVERT(latin1_field USING utf8) = 'a' COLLATE utf8_bin
        THEN NULL
        ELSE latin1_field

    - m_args0 points to Item_field corresponding to latin1_field
    - args[0] points to Item_func_conv_charset
    - args[0]->args[0] is equal to m_args0
    - args[1] points to Item_func_set_collation
    - args[2] points is eqial to m_args0

    In this case we remember and reuse m_arg0 during EXECUTE time as args[2].

    QQ: How to make sure that m_args0 does not point
    to something temporary which will be destroyed between PREPARE and EXECUTE.
    The condition below should probably be more strict and somehow check that:
    - change_item_tree() was called for the new args[0]
    - m_args0 is referenced from inside args[0], e.g. as a function argument,
      and therefore it is also something that won't be destroyed between
      PREPARE and EXECUTE.
    Any ideas?
  */
  if (args[0] == m_arg0)
    m_arg0= NULL;
  return FALSE;
}

Project: server

  bool set_fields_as_dependent_processor(void *arg)
  {
    if (!(used_tables() & OUTER_REF_TABLE_BIT))
    {
      depended_from= (st_select_lex *) arg;
      item_equal= NULL;
    }
    return 0;
  }

Project: server

  Item_result_field(THD *thd, Item_result_field *item):
    Item_fixed_hybrid(thd, item), result_field(item->result_field)
  {}

Project: server

bool Item_func_case::time_op(THD *thd, MYSQL_TIME *ltime)
{
  DBUG_ASSERT(fixed == 1);
  Item *item= find_item();
  if (!item)
    return (null_value= true);
  return (null_value= Time(thd, item).copy_to_mysql_time(ltime));
}

Project: server

  Item* element_index(uint i) { return arg_count ? args[i] : this; }

Project: server

  Item_direct_view_ref(THD *thd, Name_resolution_context *context_arg,
                       Item **item,
                       const char *table_name_arg,
                       LEX_CSTRING *field_name_arg,
                       TABLE_LIST *view_arg):
    Item_direct_ref(thd, context_arg, item, table_name_arg, field_name_arg),
    item_equal(0), view(view_arg),
    null_ref_table(NULL)
  {
    if (fixed)
      set_null_ref_table();
  }

Project: server

int Arg_comparator::compare_row()
{
  int res= 0;
  bool was_null= 0;
  (*a)->bring_value();
  (*b)->bring_value();

  if ((*a)->null_value || (*b)->null_value)
  {
    owner->null_value= 1;
    return -1;
  }

  uint n= (*a)->cols();
  for (uint i= 0; i<n; i++)
  {
    res= comparators[i].compare();
    /* Aggregate functions don't need special null handling. */
    if (owner->null_value && owner->type() == Item::FUNC_ITEM)
    {
      // NULL was compared
      switch (((Item_func*)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
      case Item_func::EQ_FUNC:
        if (((Item_func_eq*)owner)->abort_on_null)
          return -1; // We do not need correct NULL returning
        break;
      default:
        DBUG_ASSERT(0);
        break;
      }
      was_null= 1;
      owner->null_value= 0;
      res= 0;  // continue comparison (maybe we will meet explicit difference)
    }
    else if (res)
      return res;
  }
  if (was_null)
  {
    /*
      There was NULL(s) in comparison in some parts, but there was no
      explicit difference in other parts, so we have to return NULL.
    */
    owner->null_value= 1;
    return -1;
  }
  return 0;
}

Project: server

bool Item_func_like::find_selective_predicates_list_processor(void *arg)
{
  find_selective_predicates_list_processor_data *data=
    (find_selective_predicates_list_processor_data *) arg;
  if (use_sampling && used_tables() == data->table->map)
  {
    THD *thd= data->table->in_use;
    COND_STATISTIC *stat;
    Item *arg0;
    if (!(stat= (COND_STATISTIC *) thd->alloc(sizeof(COND_STATISTIC))))
      return TRUE;
    stat->cond= this;
    arg0= args[0]->real_item();
    if (args[1]->const_item() && arg0->type() == FIELD_ITEM)
      stat->field_arg= ((Item_field *)arg0)->field;
    else
      stat->field_arg= NULL;
    data->list.push_back(stat, thd->mem_root);
  }
  return FALSE;
}

Project: server

Item_bool_rowready_func2* Lt_creator::create_swap(THD *thd, Item *a, Item *b) const
{
  return new(thd->mem_root) Item_func_gt(thd, b, a);
}

Project: server

  Item_default_specification(THD *thd)
   :Item_contextually_typed_value_specification(thd)
  { }

Project: server

  bool val_native_with_conversion_from_item(THD *thd, Item *item, Native *to,
                                            const Type_handler *handler)
  {
    DBUG_ASSERT(is_fixed());
    return null_value= item->val_native_with_conversion(thd, to, handler);
  }

Project: server

  const MYSQL_TIME *const_ptr_mysql_time() const
  { return can_return_const_value(TIME_RESULT) ? &value.time : NULL; }

Project: server

    void swap(PValue &other)
    {
      Type_handler_hybrid_field_type::swap(other);
      PValue_simple::swap(other);
      m_decimal.swap(other.m_decimal);
      m_string.swap(other.m_string);
      m_string_ptr.swap(other.m_string_ptr);
    }

Project: server

inline void Item_func_case::print_when_then_arguments(String *str,
                                                      enum_query_type
                                                      query_type,
                                                      Item **items, uint count)
{
  for (uint i= 0; i < count; i++)
  {
    str->append(STRING_WITH_LEN("when "));
    items[i]->print(str, query_type);
    str->append(STRING_WITH_LEN(" then "));
    items[i + count]->print(str, query_type);
    str->append(' ');
  }
}

Project: server

  bool set_value(THD *thd, const Type_all_attributes *attr,
                 const st_value *val, const Type_handler *h)
  {
    value.set_handler(h); // See comments in set_param_func()
    return h->Item_param_set_from_value(thd, this, attr, val);
  }

Project: server

  void set_maybe_null(bool maybe_null_arg) { maybe_null= maybe_null_arg; }

Project: server

  void process_error(THD *thd)
  {
    if (context)
      context->process_error(thd);
  }

Project: server

void Item_in_optimizer::get_cache_parameters(List<Item> &parameters)
{
  DBUG_ASSERT(fixed);
  /* Add left expression to the list of the parameters of the subquery */
  if (!invisible_mode())
  {
    if (args[0]->cols() == 1)
      parameters.add_unique(args[0], &cmp_items);
    else
    {
      for (uint i= 0; i < args[0]->cols(); i++)
      {
        parameters.add_unique(args[0]->element_index(i), &cmp_items);
      }
    }
  }
  args[1]->get_cache_parameters(parameters);
}

Project: server

int Arg_comparator::set_cmp_func(Item_func_or_sum *owner_arg,
                                 Item **a1, Item **a2)
{
  owner= owner_arg;
  set_null= set_null && owner_arg;
  a= a1;
  b= a2;
  Item *tmp_args[2]= {*a1, *a2};
  Type_handler_hybrid_field_type tmp;
  if (tmp.aggregate_for_comparison(owner_arg->func_name(), tmp_args, 2, false))
  {
    DBUG_ASSERT(current_thd->is_error());
    return 1;
  }
  m_compare_handler= tmp.type_handler();
  return m_compare_handler->set_comparator_func(this);
}

Project: server

void Item_func_truth::print(String *str, enum_query_type query_type)
{
  args[0]->print_parenthesised(str, query_type, precedence());
  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"));
}

Project: server

longlong Item_func_xor::val_int()
{
  DBUG_ASSERT(fixed == 1);
  int result= 0;
  null_value= false;
  for (uint i= 0; i < arg_count; i++)
  {
    result^= (args[i]->val_int() != 0);
    if (args[i]->null_value)
    {
      null_value= true;
      return 0;
    }
  }
  return result;
}

Project: server

Item_bool_rowready_func2* Ne_creator::create_swap(THD *thd, Item *a, Item *b) const
{
  return new(thd->mem_root) Item_func_ne(thd, b, a);
}

Project: server

  int save_in_field(Field *field, bool no_conversions)
  {
    Timestamp_or_zero_datetime_native native(m_value, decimals);
    return native.save_in_field(field, decimals);
  }

Project: server

  double val_real() { return ulonglong2double((ulonglong)value); }

Project: server

int Arg_comparator::compare_e_native()
{
  THD *thd= current_thd;
  bool res1= (*a)->val_native_with_conversion(thd, &m_native1,
                                              compare_type_handler());
  bool res2= (*b)->val_native_with_conversion(thd, &m_native2,
                                              compare_type_handler());
  if (res1 || res2)
    return MY_TEST(res1 == res2);
  return MY_TEST(compare_type_handler()->cmp_native(m_native1, m_native2) == 0);
}

Project: server

  void print(String *str, enum_query_type query_type)
  {
    str->append(STRING_WITH_LEN("default"));
  }

Project: server

  Tmp_field_param(bool group,
                  bool modify_item,
                  bool table_cant_handle_bit_fields,
                  bool make_copy_field)
   :m_group(group),
    m_modify_item(modify_item),
    m_table_cant_handle_bit_fields(table_cant_handle_bit_fields),
    m_make_copy_field(make_copy_field)
  { }

Project: server

  my_decimal *val_decimal(my_decimal *to)
  {
    return to_datetime(current_thd).to_decimal(to);
  }

Project: server

  Item_cache(THD *thd, const Type_handler *handler):
    Item(thd),
    Type_handler_hybrid_field_type(handler),
    example(0), cached_field(0),
    value_cached(0),
    used_table_map(0)
  {
    maybe_null= 1;
    null_value= 1;
    null_value_inside= true;
  }

Project: server

  Longlong_hybrid_null to_longlong_hybrid_null()
  {
    return Longlong_hybrid_null(to_longlong_null(), unsigned_flag);
  }

Project: server

  const MYSQL_TIME *const_ptr_mysql_time() const
  {
    return cached_time.get_mysql_time();
  }

Project: server

  Item_direct_ref_to_ident(THD *thd, Item_ident *item):
    Item_direct_ref(thd, item->context, (Item**)&item, item->table_name,
                    &item->field_name, FALSE)
  {
    ident= item;
    ref= (Item**)&ident;
  }

Project: server

  bool get_date(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzydate)
  {
    DBUG_ASSERT(0); // never should be called
    return null_value= true;
  }

Project: server

  uint32 max_display_length() const { return field->max_display_length(); }

Project: server

void Item_func_like::turboBM_compute_bad_character_shifts()
{
  int *i;
  int *end = bmBc + alphabet_size;
  int j;
  const int plm1 = pattern_len - 1;
  CHARSET_INFO	*cs= cmp_collation.collation;

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

  if (!cs->sort_order)
  {
    for (j = 0; j < plm1; j++)
      bmBc[(uint) (uchar) pattern[j]] = plm1 - j;
  }
  else
  {
    for (j = 0; j < plm1; j++)
      bmBc[(uint) likeconv(cs,pattern[j])] = plm1 - j;
  }
}

Project: server

  longlong val_int()
  {
    return longlong_from_hex_hybrid(str_value.ptr(), str_value.length());
  }

Project: server

  String *val_str(String *to)
  {
    return update_null() ? 0 : cached_time.to_string(to);
  }

Project: server

  bool val_native(THD *thd, Native *to)
  {
    if (check_null_ref())
      return true;
    return Item_direct_ref::val_native(thd, to);
  }

Project: server

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 (thd->mem_root) Item_func_nop_all(thd, args[0]);
  Item_allany_subselect *allany= (Item_allany_subselect*)args[0];
  allany->all= !allany->all;
  allany->create_comp_func(TRUE);
  allany->upper_item= new_item;
  return new_item;
}

Project: server

  void quick_fix_field() { fixed= true; }

Project: server

  virtual bool is_simplified_cond_processor(void *arg) { return false; }

Project: server

  bool is_null() const { return m_type == DYN_COL_NULL; }

Project: server

  String *val_str(String*)
  {
    return (String*) &str_value;
  }

Project: server

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

  const int plm1=  pattern_len - 1;
  const int tlmpl= text_len - pattern_len;

  /* Searching */
  if (!cs->sort_order)
  {
    while (j <= tlmpl)
    {
      int i= plm1;
      while (i >= 0 && pattern[i] == text[i + j])
      {
	i--;
	if (i == plm1 - shift)
	  i-= u;
      }
      if (i < 0)
	return 1;

      const int v= plm1 - i;
      turboShift = u - v;
      bcShift    = bmBc[(uint) (uchar) text[i + j]] - plm1 + i;
      shift      = MY_MAX(turboShift, bcShift);
      shift      = MY_MAX(shift, bmGs[i]);
      if (shift == bmGs[i])
	u = MY_MIN(pattern_len - shift, v);
      else
      {
	if (turboShift < bcShift)
	  shift = MY_MAX(shift, u + 1);
	u = 0;
      }
      j+= shift;
    }
    return 0;
  }
  else
  {
    while (j <= tlmpl)
    {
      int i= plm1;
      while (i >= 0 && likeconv(cs,pattern[i]) == likeconv(cs,text[i + j]))
      {
	i--;
	if (i == plm1 - shift)
	  i-= u;
      }
      if (i < 0)
	return 1;

      const int v= plm1 - i;
      turboShift = u - v;
      bcShift    = bmBc[(uint) likeconv(cs, text[i + j])] - plm1 + i;
      shift      = MY_MAX(turboShift, bcShift);
      shift      = MY_MAX(shift, bmGs[i]);
      if (shift == bmGs[i])
	u = MY_MIN(pattern_len - shift, v);
      else
      {
	if (turboShift < bcShift)
	  shift = MY_MAX(shift, u + 1);
	u = 0;
      }
      j+= shift;
    }
    return 0;
  }
}

Project: server

void Item_func_in::fix_after_pullout(st_select_lex *new_parent, Item **ref,
                                     bool merge)
{
  /* This will re-calculate attributes of the arguments */
  Item_func_opt_neg::fix_after_pullout(new_parent, ref, merge);
  /* Then, re-calculate not_null_tables_cache according to our special rules */
  eval_not_null_tables(NULL);
}

Project: server

bool Item_func_ifnull::native_op(THD *thd, Native *to)
{
  DBUG_ASSERT(fixed == 1);
  if (!val_native_with_conversion_from_item(thd, args[0], to, type_handler()))
    return false;
  return val_native_with_conversion_from_item(thd, args[1], to, type_handler());
}

Project: server

  longlong val_int()
  {
    if (value <= (double) LONGLONG_MIN)
    {
       return LONGLONG_MIN;
    }
    else if (value >= (double) (ulonglong) LONGLONG_MAX)
    {
      return LONGLONG_MAX;
    }
    return (longlong) rint(value);
  }

Project: server

bool Predicant_to_list_comparator::make_unique_cmp_items(THD *thd,
                                                         CHARSET_INFO *cs)
{
  for (uint i= 0; i < m_comparator_count; i++)
  {
    if (m_comparators[i].m_handler &&                   // Skip implicit NULLs
        m_comparators[i].m_handler_index == i && // Skip non-unuque
        !(m_comparators[i].m_cmp_item=
          m_comparators[i].m_handler->make_cmp_item(thd, cs)))
       return true;
  }
  return false;
}

Project: server

  longlong val_int() { return cached_time.to_longlong(); }

Project: server

  Item *get_copy(THD *thd)
  { return get_item_copy<Item_cache_timestamp>(thd, this); }

Project: server

void Item_func_case::reorder_args(uint start)
{
  /*
    Reorder args, to have at first the optional CASE expression, then all WHEN
    expressions, then all THEN expressions. And the optional ELSE expression
    at the end.

    We reorder an even number of arguments, starting from start.
  */
  uint count = (arg_count - start) / 2;
  const size_t size= sizeof(Item*) * count * 2;
  Item **arg_buffer= (Item **)my_safe_alloca(size);
  memcpy(arg_buffer, &args[start], size);
  for (uint i= 0; i < count; i++)
  {
    args[start + i]= arg_buffer[i*2];
    args[start + i + count]= arg_buffer[i*2 + 1];
  }
  my_safe_afree(arg_buffer, size);
}

Project: server

Item_equal::excl_dep_on_grouping_fields(st_select_lex *sel)
{
  Item_equal_fields_iterator it(*this);
  Item *item;

  while ((item=it++))
  {
    if (item->excl_dep_on_grouping_fields(sel))
    {
      set_extraction_flag(FULL_EXTRACTION_FL);
      return true;
    }
  }
  return false;
}

Project: server

longlong Item_func_coalesce::int_op()
{
  DBUG_ASSERT(fixed == 1);
  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;
}

Project: server

  Item *get_copy(THD *thd)
  { return get_item_copy<Item_default_specification>(thd, this); }

Project: server

  const Item_const *get_item_const() const
  {
    switch (state) {
    case SHORT_DATA_VALUE:
    case LONG_DATA_VALUE:
    case NULL_VALUE:
      return this;
    case IGNORE_VALUE:
    case DEFAULT_VALUE:
    case NO_VALUE:
      break;
    }
    return NULL;
  }

Project: server

in_longlong::in_longlong(THD *thd, uint elements)
  :in_vector(thd, elements, sizeof(packed_longlong),
             (qsort2_cmp) cmp_longlong, 0)
{}

Project: server

  my_decimal *val_decimal(my_decimal *to)
  {
    return update_null() ? NULL : cached_time.to_decimal(to);
  }

Project: server

  void unfix_fields() { fixed= false; }

Project: server

  uint cols() const { return arg_count; }

Project: server

Item *Item_func_isnull::neg_transformer(THD *thd)
{
  Item *item= new (thd->mem_root) Item_func_isnotnull(thd, args[0]);
  return item;
}

Project: server

  Item *get_copy(THD *thd)
  { return get_item_copy<Item_cache_row>(thd, this); }

Project: server

static bool convert_const_to_int(THD *thd, Item_field *field_item,
                                  Item **item)
{
  Field *field= field_item->field;
  int result= 0;

  /*
    We don't need to convert an integer to an integer,
    pretend it's already converted.

    But we still convert it if it is compared with a Field_year,
    as YEAR(2) may change the value of an integer when converting it
    to an integer (say, 0 to 70).
  */
  if ((*item)->cmp_type() == INT_RESULT &&
      field_item->field_type() != MYSQL_TYPE_YEAR)
    return 1;

  if ((*item)->const_item() && !(*item)->is_expensive())
  {
    TABLE *table= field->table;
    Sql_mode_save sql_mode(thd);
    Check_level_instant_set check_level_save(thd, CHECK_FIELD_IGNORE);
    MY_BITMAP *old_maps[2] = { NULL, NULL };
    ulonglong UNINIT_VAR(orig_field_val); /* original field value if valid */

    /* table->read_set may not be set if we come here from a CREATE TABLE */
    if (table && table->read_set)
      dbug_tmp_use_all_columns(table, old_maps,
                               &table->read_set, &table->write_set);
    /* For comparison purposes allow invalid dates like 2000-01-32 */
    thd->variables.sql_mode= (thd->variables.sql_mode & ~MODE_NO_ZERO_DATE) |
                             MODE_INVALID_DATES;

    /*
      Store the value of the field/constant because the call to save_in_field
      below overrides that value. Don't save field value if no data has been
      read yet.
    */
    bool save_field_value= (field_item->const_item() ||
                            !(field->table->status & STATUS_NO_RECORD));
    if (save_field_value)
      orig_field_val= field->val_int();
    if (!(*item)->save_in_field(field, 1) && !field->is_null())
    {
      int field_cmp= 0;
      // If item is a decimal value, we must reject it if it was truncated.
      if (field->type() == MYSQL_TYPE_LONGLONG)
      {
        field_cmp= stored_field_cmp_to_item(thd, field, *item);
        DBUG_PRINT("info", ("convert_const_to_int %d", field_cmp));
      }

      if (0 == field_cmp)
      {
        Item *tmp= new (thd->mem_root) Item_int_with_ref(thd, field->val_int(), *item,
                                         MY_TEST(field->flags & UNSIGNED_FLAG));
        if (tmp)
          thd->change_item_tree(item, tmp);
        result= 1;					// Item was replaced
      }
    }
    /* Restore the original field value. */
    if (save_field_value)
    {
      result= field->store(orig_field_val, TRUE);
      /* orig_field_val must be a valid value that can be restored back. */
      DBUG_ASSERT(!result);
    }
    if (table && table->read_set)
      dbug_tmp_restore_column_maps(&table->read_set, &table->write_set, old_maps);
  }
  return result;
}

Project: server

bool Item_func_coalesce::time_op(THD *thd, MYSQL_TIME *ltime)
{
  DBUG_ASSERT(fixed == 1);
  for (uint i= 0; i < arg_count; i++)
  {
    if (!Time(thd, args[i]).copy_to_mysql_time(ltime))
      return (null_value= false);
  }
  return (null_value= true);
}

Project: server

  longlong val_int_from_item(Item *item)
  {
    DBUG_ASSERT(is_fixed());
    longlong value= item->val_int();
    null_value= item->null_value;
    return value;
  }

Project: server

  longlong val_int() { return decimal_value.to_longlong(unsigned_flag); }

Project: server

  void join(const Item *item) { m_with_subquery|= item->with_subquery(); }

Project: server

  virtual const my_decimal *const_ptr_my_decimal() const { return NULL; }

Project: server

  virtual With_sum_func_cache* get_with_sum_func_cache() { return NULL; }

Project: server

void Item_func_like::turboBM_compute_good_suffix_shifts(int *suff)
{
  turboBM_compute_suffixes(suff);

  int *end = bmGs + pattern_len;
  int *k;
  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++)
      {
	int *tmp2 = bmGs + j;
	if (*tmp2 == pattern_len)
	  *tmp2 = tmp;
      }
    }
  }

  int *tmp2;
  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;
}

Project: server

  bool val_native(THD *thd, Native *to)
  {
    return Item_param::type_handler()->Item_param_val_native(thd, this, to);
  }

Project: server

Item *Item_func_gt::negated_item(THD *thd) /* a > b  ->  a <= b */
{
  return new (thd->mem_root) Item_func_le(thd, args[0], args[1]);
}

Project: server

Item_equal::Item_equal(THD *thd, const Type_handler *handler,
                       Item *f1, Item *f2, bool with_const_item):
  Item_bool_func(thd), eval_item(0), cond_false(0), cond_true(0),
  context_field(NULL), link_equal_fields(FALSE),
  m_compare_handler(handler),
  m_compare_collation(f2->collation.collation)
{
  const_item_cache= 0;
  with_const= with_const_item;
  equal_items.push_back(f1, thd->mem_root);
  equal_items.push_back(f2, thd->mem_root);
  upper_levels= NULL;
}

Project: server

bool Item_equal::create_pushable_equalities(THD *thd,
                                            List<Item> *equalities,
                                            Pushdown_checker checker,
                                            uchar *arg,
                                            bool clone_const)
{
  Item *item;
  Item *left_item= NULL;
  Item *right_item = get_const();
  Item_equal_fields_iterator it(*this);

  while ((item=it++))
  {
    left_item= item;
    if (checker && !((item->*checker) (arg)))
      continue;
    break;
  }

  if (!left_item)
    return false;

  if (right_item)
  {
    Item_func_eq *eq= 0;
    Item *left_item_clone= left_item->build_clone(thd);
    Item *right_item_clone= !clone_const ?
                            right_item : right_item->build_clone(thd);
    if (!left_item_clone || !right_item_clone)
      return true;
    eq= new (thd->mem_root) Item_func_eq(thd,
                                         left_item_clone,
                                         right_item_clone);
    if (!eq ||  equalities->push_back(eq, thd->mem_root))
      return true;
    if (!clone_const)
    {
      /*
        Also set IMMUTABLE_FL for any sub-items of the right_item.
        This is needed to prevent Item::cleanup_excluding_immutables_processor
        from peforming cleanup of the sub-items and so creating an item tree
        where a fixed item has non-fixed items inside it.
      */
      int new_flag= IMMUTABLE_FL;
      right_item->walk(&Item::set_extraction_flag_processor, false,
                       (void*)&new_flag);
    }
  }

  while ((item=it++))
  {
    if (checker && !((item->*checker) (arg)))
      continue;
    Item_func_eq *eq= 0;
    Item *left_item_clone= left_item->build_clone(thd);
    Item *right_item_clone= item->build_clone(thd);
    if (!(left_item_clone && right_item_clone))
      return true;
    left_item_clone->set_item_equal(NULL);
    right_item_clone->set_item_equal(NULL);
    eq= new (thd->mem_root) Item_func_eq(thd,
                                         right_item_clone,
                                         left_item_clone);
    if (!eq || equalities->push_back(eq, thd->mem_root))
      return true;
  }
  return false;
}

Project: server

  virtual table_map used_tables() const
  {
    return state != NO_VALUE ? (table_map)0 : PARAM_TABLE_BIT;
  }

Project: server

  virtual Item *remove_item_direct_ref() { return this; }

Project: server

  bool save_in_param(THD *thd, Item_param *param)
  {
    // It should not be possible to have "EXECUTE .. USING DEFAULT(a)"
    DBUG_ASSERT(0);
    param->set_default();
    return false;
  }

Project: server

bool Item_func_between::val_int_cmp_int_finalize(longlong value,
                                                 longlong a,
                                                 longlong b)
{
  if (!args[1]->null_value && !args[2]->null_value)
    return (longlong) ((value >= a && value <= b) != negated);
  if (args[1]->null_value && args[2]->null_value)
    null_value= true;
  else if (args[1]->null_value)
    null_value= value <= b;			// not null if false range.
  else
    null_value= value >= a;
  return (longlong) (!null_value && negated);
}

Project: server

  virtual Item *in_subq_field_transformer_for_where(THD *thd, uchar *arg)
  { return this; }

Project: server

  const Type_all_attributes *get_type_all_attributes_from_const() const
  { return this; }

Project: server

  longlong val_int()
  {
    return m_value.to_datetime(current_thd).to_longlong();
  }

Project: server

  longlong val_int()
  {
    return update_null() ? 0 : cached_time.to_longlong();
  }

Project: server

  Item_string(THD *thd, const char *str, size_t length,
              CHARSET_INFO *cs, Derivation dv= DERIVATION_COERCIBLE)
   :Item_literal(thd)
  {
    str_value.set_or_copy_aligned(str, length, cs);
    fix_and_set_name_from_value(thd, dv, Metadata(&str_value));
  }

Project: server

  Item *get_copy(THD *thd)
  { return get_item_copy<Item_datetime_literal>(thd, this); }

Project: server

  Item_cache(THD *thd):
    Item(thd),
    Type_handler_hybrid_field_type(&type_handler_string),
    example(0), cached_field(0),
    value_cached(0),
    used_table_map(0)
  {
    maybe_null= 1;
    null_value= 1;
    null_value_inside= true;
  }

Project: server

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->argument_count() ||
      functype() != item_func->functype())
    return 0;
  if (negated != ((Item_func_opt_neg *) item_func)->negated)
    return 0;
  return Item_args::eq(item_func, binary_cmp);
}

Project: server

Item** Arg_comparator::cache_converted_constant(THD *thd_arg, Item **value,
                                                Item **cache_item,
                                                const Type_handler *handler)
{
  /*
    Don't need cache if doing context analysis only.
  */
  if (!thd_arg->lex->is_ps_or_view_context_analysis() &&
      (*value)->const_item() &&
      handler->type_handler_for_comparison() !=
      (*value)->type_handler_for_comparison())
  {
    Item_cache *cache= handler->Item_get_cache(thd_arg, *value);
    cache->setup(thd_arg, *value);
    *cache_item= cache;
    return cache_item;
  }
  return value;
}

Project: server

Item *Item_cond_and::copy_andor_structure(THD *thd)
{
  Item_cond_and *item;
  if ((item= new (thd->mem_root) Item_cond_and(thd, this)))
    item->copy_andor_arguments(thd, this);
  return item;
}

Project: server

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

Project: server

void Item_func_like::turboBM_compute_suffixes(int *suff)
{
  const int   plm1 = pattern_len - 1;
  int            f = 0;
  int            g = plm1;
  int *const splm1 = suff + plm1;
  CHARSET_INFO	*cs= cmp_collation.collation;

  *splm1 = pattern_len;

  if (!cs->sort_order)
  {
    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 = MY_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 = MY_MIN(i, g)
	f = i;
	while (g >= 0 &&
	       likeconv(cs, pattern[g]) == likeconv(cs, pattern[g + plm1 - f]))
	  g--;
	suff[i] = f - g;
      }
    }
  }
}

Project: server

  Item_field_row(THD *thd, Field *field)
   :Item_field(thd, field),
    Item_args()
  { }

Project: server

void Item_equal::merge_into_list(THD *thd, List<Item_equal> *list,
                                 bool save_merged,
                                 bool only_intersected)
{
  Item_equal *item;
  List_iterator<Item_equal> it(*list);
  Item_equal *merge_into= NULL;
  while((item= it++))
  {
    if (!merge_into)
    {
      if (item->merge_with_check(thd, this, save_merged))
        merge_into= item;
    }
    else
    {
      if (merge_into->merge_with_check(thd, item, false))
        it.remove();
    }
  }
  if (!only_intersected && !merge_into)
    list->push_back(this, thd->mem_root);
}

Project: server

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

Project: server

  Item *remove_item_direct_ref()
  {
    *ref= (*ref)->remove_item_direct_ref();
    return this;
  }

Project: server

  bool is_order_clause_position() const
  {
    return state == SHORT_DATA_VALUE &&
           type_handler()->is_order_clause_position_type();
  }

Project: server

  const Type_handler *real_type_handler() const
  {
    // Should not be called, Item_blob is used for SHOW purposes only.
    DBUG_ASSERT(0);
    return &type_handler_varchar;
  }

Project: server

void Item_func_between::fix_after_pullout(st_select_lex *new_parent,
                                          Item **ref, bool merge)
{
  /* This will re-calculate attributes of the arguments */
  Item_func_opt_neg::fix_after_pullout(new_parent, ref, merge);
  /* Then, re-calculate not_null_tables_cache according to our special rules */
  eval_not_null_tables(NULL);
}

Project: server

  void set_typelib(TYPELIB *typelib)
  {
    // Non-field Items (e.g. hybrid functions) never have ENUM/SET types yet.
    DBUG_ASSERT(0);
  }

Project: server

  const Type_handler *type_handler() const { return orig_item->type_handler(); }

Project: server

void Item_cond::split_sum_func(THD *thd, Ref_ptr_array ref_pointer_array,
                               List<Item> &fields, uint flags)
{
  List_iterator<Item> li(list);
  Item *item;
  while ((item= li++))
    item->split_sum_func2(thd, ref_pointer_array, fields, li.ref(),
                          flags | SPLIT_SUM_SKIP_REGISTERED);
}

Project: server

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);
  /* if item->val_decimal() is evaluated to NULL then res == 0 */ 
  if (!item->null_value && res != dec)
    my_decimal2decimal(res, dec);
}

Project: server

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 MY_TEST((*a)->null_value && (*b)->null_value);
  return (val1 >= 0) && MY_TEST(val1 == val2);
}

Project: server

Item *in_string::create_item(THD *thd)
{
  return new (thd->mem_root) Item_string_for_in_vector(thd, collation);
}

Project: server

  Item_cache_float(THD *thd)
   :Item_cache_real(thd, &type_handler_float)
  { }

Project: server

  virtual bool send(Protocol *protocol, st_value *buffer)
  {
    return type_handler()->Item_send(this, protocol, buffer);
  }

Project: server

  bool with_subquery() const { DBUG_ASSERT(fixed); return m_with_subquery; }

Project: server

Item* Item_equal::get_first(JOIN_TAB *context, Item *field_item)
{
  Item_equal_fields_iterator it(*this);
  Item *item;
  if (!field_item)
    return (it++);
  Field *field= ((Item_field *) (field_item->real_item()))->field;

  /*
    Of all equal fields, return the first one we can use. Normally, this is the
    field which belongs to the table that is the first in the join order.

    There is one exception to this: When semi-join materialization strategy is
    used, and the given field belongs to a table within the semi-join nest, we
    must pick the first field in the semi-join nest.

    Example: suppose we have a join order:

       ot1 ot2  SJ-Mat(it1  it2  it3)  ot3

    and equality ot2.col = it1.col = it2.col
    If we're looking for best substitute for 'it2.col', we should pick it1.col
    and not ot2.col.
    
    eliminate_item_equal() also has code that deals with equality substitution
    in presence of SJM nests.
  */

  TABLE_LIST *emb_nest;
  if (context != NO_PARTICULAR_TAB)
    emb_nest= context->emb_sj_nest;
  else
    emb_nest= field->table->pos_in_table_list->embedding;

  if (emb_nest && emb_nest->sj_mat_info && emb_nest->sj_mat_info->is_used)
  {
    /*
      It's a field from an materialized semi-join. We can substitute it for
       - a constant item 
       - a field from the same semi-join
       Find the first of such items:
    */
    while ((item= it++))
    {
      if (item->const_item() || 
          it.get_curr_field()->table->pos_in_table_list->embedding == emb_nest)
      {
        /*
          If we found given field then return NULL to avoid unnecessary
          substitution.
        */
        return (item != field_item) ? item : NULL;
      }
    }
  }
  else
  {
    /*
      The field is not in SJ-Materialization nest. We must return the first
      field in the join order. The field may be inside a semi-join nest, i.e 
      a join order may look like this:

          SJ-Mat(it1  it2)  ot1  ot2

      where we're looking what to substitute ot2.col for. In this case we must 
      still return it1.col, here's a proof why:

      First let's note that either it1.col or it2.col participates in 
      subquery's IN-equality. It can't be otherwise, because materialization is
      only applicable to uncorrelated subqueries, so the only way we could
      infer "it1.col=ot1.col" is from the IN-equality. Ok, so IN-eqality has 
      it1.col or it2.col on its inner side. it1.col is first such item in the
      join order, so it's not possible for SJ-Mat to be
      SJ-Materialization-lookup, it is SJ-Materialization-Scan. The scan part
      of this strategy will unpack value of it1.col=it2.col into it1.col
      (that's the first equal item inside the subquery), and we'll be able to
      get it from there. qed.
    */

    return equal_items.head();
  }
  // Shouldn't get here.
  DBUG_ASSERT(0);
  return NULL;
}

Project: server

longlong Item_func_lt::val_int()
{
  DBUG_ASSERT(fixed == 1);
  int value= cmp.compare();
  return value < 0 && !null_value ? 1 : 0;
}

Project: server

  virtual void update_null_value ()
  {
    return type_handler()->Item_update_null_value(this);
  }

Project: server

bool Item_func_between::fix_length_and_dec_numeric(THD *thd)
{
  /* See the comment about the similar block in Item_bool_func2 */
  if (args[0]->real_item()->type() == FIELD_ITEM &&
      !thd->lex->is_ps_or_view_context_analysis())
  {
    Item_field *field_item= (Item_field*) (args[0]->real_item());
    if (field_item->field_type() ==  MYSQL_TYPE_LONGLONG ||
        field_item->field_type() ==  MYSQL_TYPE_YEAR)
    {
      const bool cvt_arg1= convert_const_to_int(thd, field_item, &args[1]);
      const bool cvt_arg2= convert_const_to_int(thd, field_item, &args[2]);
      if (cvt_arg1 && cvt_arg2)
      {
        // Works for all types
        m_comparator.set_handler(&type_handler_longlong);
      }
    }
  }
  return FALSE;
}

Project: server

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.
    */  
    if ((a->unsigned_flag && ((ulonglong) a->val) > (ulonglong) LONGLONG_MAX)
        ||
        (b->unsigned_flag && ((ulonglong) b->val) > (ulonglong) LONGLONG_MAX))
      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);
  return cmp_longs(a->val, b->val);
}

Project: server

my_decimal *Item_func_case::decimal_op(my_decimal *decimal_value)
{
  DBUG_ASSERT(fixed == 1);
  Item *item= find_item();
  my_decimal *res;

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

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

Project: server

  virtual ~Sp_rcontext_handler() {}

Project: server

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

Project: server

in_row::in_row(THD *thd, uint elements, Item * item)
{
  base= (char*) new (thd->mem_root) cmp_item_row[count= elements];
  size= sizeof(cmp_item_row);
  compare= (qsort2_cmp) cmp_row;
  /*
    We need to reset these as otherwise we will call sort() with
    uninitialized (even if not used) elements
  */
  used_count= elements;
  collation= 0;
}

Project: server

  Item_timestamp_literal(THD *thd)
   :Item_literal(thd)
  { }

Project: server

Item_cond::fix_fields(THD *thd, Item **ref)
{
  DBUG_ASSERT(fixed == 0);
  List_iterator<Item> li(list);
  Item *item;
  uchar buff[sizeof(char*)];			// Max local vars in function
  bool is_and_cond= functype() == Item_func::COND_AND_FUNC;
  not_null_tables_cache= 0;
  used_tables_and_const_cache_init();

  /*
    and_table_cache is the value that Item_cond_or() returns for
    not_null_tables()
  */
  and_tables_cache= ~(table_map) 0;

  if (check_stack_overrun(thd, STACK_MIN_SIZE, buff))
    return TRUE;				// Fatal error flag is set!
  /*
    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).
  */
  while ((item=li++))
  {
    while (item->type() == Item::COND_ITEM &&
	   ((Item_cond*) item)->functype() == functype() &&
           !((Item_cond*) item)->list.is_empty())
    {						// Identical function
      li.replace(((Item_cond*) item)->list);
      ((Item_cond*) item)->list.empty();
      item= *li.ref();				// new current item
    }
    if (abort_on_null)
      item->top_level_item();

    /*
      replace degraded condition:
        was:    <field>
        become: <field> = 1
    */
    Item::Type type= item->type();
    if (type == Item::FIELD_ITEM || type == Item::REF_ITEM)
    {
      Query_arena backup, *arena;
      Item *new_item;
      arena= thd->activate_stmt_arena_if_needed(&backup);
      if ((new_item= new (thd->mem_root) Item_func_ne(thd, item, new (thd->mem_root) Item_int(thd, 0, 1))))
        li.replace(item= new_item);
      if (arena)
        thd->restore_active_arena(arena, &backup);
    }

    if (item->fix_fields_if_needed_for_bool(thd, li.ref()))
      return TRUE; /* purecov: inspected */
    item= *li.ref(); // item can be substituted in fix_fields
    used_tables_cache|=     item->used_tables();
    if (item->const_item() && !item->with_param &&
        !item->is_expensive() && !cond_has_datetime_is_null(item))
    {
      if (item->eval_const_cond() == is_and_cond && top_level())
      {
        /* 
          a. This is "... AND true_cond AND ..."
          In this case, true_cond  has no effect on cond_and->not_null_tables()
          b. This is "... OR false_cond/null cond OR ..." 
          In this case, false_cond has no effect on cond_or->not_null_tables()
        */
      }
      else
      {
        /* 
          a. This is "... AND false_cond/null_cond AND ..."
          The whole condition is FALSE/UNKNOWN.
          b. This is  "... OR const_cond OR ..."
          In this case, cond_or->not_null_tables()=0, because the condition
          const_cond might evaluate to true (regardless of whether some tables
          were NULL-complemented).
        */
        not_null_tables_cache= (table_map) 0;
        and_tables_cache= (table_map) 0;
      }
      if (thd->is_error())
        return TRUE;
    }
    else
    {
      table_map tmp_table_map= item->not_null_tables();
      not_null_tables_cache|= tmp_table_map;
      and_tables_cache&= tmp_table_map;

      const_item_cache= FALSE;
    } 
  
    join_with_sum_func(item);
    with_param|=       item->with_param;
    with_field|=       item->with_field;
    m_with_subquery|=  item->with_subquery();
    with_window_func|= item->with_window_func;
    maybe_null|=       item->maybe_null;
  }
  if (fix_length_and_dec())
    return TRUE;
  fixed= 1;
  return FALSE;
}

Project: server

  longlong val_int_min() const { return value; }

Project: server

Item *Item_cond::compile(THD *thd, Item_analyzer analyzer, uchar **arg_p,
                         Item_transformer transformer, uchar *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.
    */   
    uchar *arg_v= *arg_p;
    Item *new_item= item->compile(thd, analyzer, &arg_v, transformer, arg_t);
    if (new_item && new_item != item)
      thd->change_item_tree(li.ref(), new_item);
  }
  return Item_func::transform(thd, transformer, arg_t);
}

Project: server

  uint datetime_precision(THD *thd)
  {
    return const_item() ? type_handler()->Item_datetime_precision(thd, this) :
                          MY_MIN(decimals, TIME_SECOND_PART_DIGITS);
  }

Project: server

  Item *field_transformer_for_having_pushdown(THD *thd, uchar *arg)
  { return (*ref)->field_transformer_for_having_pushdown(thd, arg); }

Project: server

  bool can_return_const_value(Item_result type) const
  {
    return can_return_value() &&
           value.type_handler()->cmp_type() == type &&
           type_handler()->cmp_type() == type;
  }

Project: server

inline bool TABLE::mark_virtual_column_with_deps(Field *field)
{
  bool res;
  DBUG_ASSERT(field->vcol_info);
  if (!(res= bitmap_fast_test_and_set(read_set, field->field_index)))
    mark_virtual_column_deps(field);
  return res;
}

Project: server

  const double *const_ptr_double() const { return &value; }

Project: server

  virtual bool fix_fields(THD *, Item **)
  {
    /*
      This should not normally be called, because usually before
      fix_fields() we check is_fixed() to be false.
      But historically we allow fix_fields() to be called for Items
      who return basic_const_item()==true.
    */
    DBUG_ASSERT(is_fixed());
    DBUG_ASSERT(basic_const_item());
    return false;
  }

Project: server

int cmp_item_decimal::cmp(Item *arg)
{
  VDec tmp(arg);
  return m_null_value || tmp.is_null() ? UNKNOWN : (tmp.cmp(&value) != 0);
}

Project: server

inline const LEX_CSTRING *Item_splocal::my_name() const
{
  return &m_name;
}

Project: server

  String *val_str(String *to) { return cached_time.to_string(to, decimals); }

Project: server

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

Project: server

  const Type_handler *type_handler() const { return this_item()->type_handler(); }

Project: server

  longlong val_datetime_packed(THD *thd)
  {
    Datetime::Options_cmp opt(thd);
    return has_value() ? Datetime(thd, this, opt).to_packed() : 0;
  }

Project: server

  CHARSET_INFO *charset_for_protocol(void) const
  {
    return type_handler()->charset_for_protocol(this);
  };

Project: server

Item *in_longlong::create_item(THD *thd)
{ 
  /* 
     We're created a signed INT, this may not be correct in 
     general case (see BUG#19342).
  */
  return new (thd->mem_root) Item_int(thd, (longlong)0);
}

Project: server

void Item_in_optimizer::fix_after_pullout(st_select_lex *new_parent,
                                          Item **ref, bool merge)
{
  DBUG_ASSERT(fixed);
  /* This will re-calculate attributes of our Item_in_subselect: */
  Item_bool_func::fix_after_pullout(new_parent, ref, merge);

  /* Then, re-calculate not_null_tables_cache: */
  eval_not_null_tables(NULL);
}

Project: server

  TYPELIB *get_typelib() const { return enum_set_typelib; }

Project: server

bool Item_func_in::list_contains_null()
{
  Item **arg,**arg_end;
  for (arg= args + 1, arg_end= args+arg_count; arg != arg_end ; arg++)
  {
    if ((*arg)->null_inside())
      return 1;
  }
  return 0;
}

Project: server

uchar *in_timestamp::get_value(Item *item)
{
  Timestamp_or_zero_datetime_native_null native(current_thd, item, true);
  if (native.is_null())
    return 0;
  tmp= Timestamp_or_zero_datetime(native);
  return (uchar*) &tmp;
}

Project: server

  uint cols() const { return this_item()->cols(); }

Project: server

  virtual bool get_date_result(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzydate)
  { return get_date(thd, ltime,fuzzydate); }

Project: server

bool Arg_comparator::set_cmp_func_row()
{
  func= is_owner_equal_func() ? &Arg_comparator::compare_e_row :
                                &Arg_comparator::compare_row;
  return set_cmp_func_for_row_arguments();
}

Project: server

  Item_ref_null_helper(THD *thd, Name_resolution_context *context_arg,
                       Item_in_subselect* master, Item **item,
		       const char *table_name_arg,
                       const LEX_CSTRING *field_name_arg):
    Item_ref(thd, context_arg, item, table_name_arg, field_name_arg),
    owner(master) {}

Project: server

  bool fix_fields_if_needed_for_scalar(THD *thd, Item **ref)
  {
    return fix_fields_if_needed(thd, ref) || check_cols(1);
  }

Project: server

void cmp_item_row::store_value_by_template(THD *thd, cmp_item *t, Item *item)
{
  cmp_item_row *tmpl= (cmp_item_row*) t;
  if (tmpl->n != item->cols())
  {
    my_error(ER_OPERAND_COLUMNS, MYF(0), tmpl->n);
    return;
  }
  n= tmpl->n;
  if ((comparators= (cmp_item **) thd->alloc(sizeof(cmp_item *)*n)))
  {
    item->bring_value();
    item->null_value= 0;
    for (uint i=0; i < n; i++)
    {
      if (!(comparators[i]= tmpl->comparators[i]->make_same()))
	break;					// new failed
      comparators[i]->store_value_by_template(thd, tmpl->comparators[i],
					      item->element_index(i));
      item->null_value|= item->element_index(i)->null_value;
    }
  }
}

Project: server

Item *Item_func_le::negated_item(THD *thd) /* a <= b  ->  a > b */
{
  return new (thd->mem_root) Item_func_gt(thd, args[0], args[1]);
}

Project: server

  const Type_handler *real_type_handler() const
  {
    if (field->is_created_from_null_item)
      return &type_handler_null;
    return field->type_handler();
  }

Project: server

  bool excl_dep_on_in_subq_left_part(Item_in_subselect *subq_pred)
  {
    for (uint i= 0; i < arg_count; i++)
    {
      if (args[i]->const_item())
        continue;
      if (!args[i]->excl_dep_on_in_subq_left_part(subq_pred))
        return false;
    }
    return true;
  }

Project: server

  bool fix_fields(THD *thd, Item **ref)
  {
    DBUG_ASSERT(!fixed);
    fixed= true;
    return false;
  }