Commit message: Bug#26361149  MYSQL SERVER CRASHES AT: COL IN(IFNULL(CONST, COL), NAME_CONST('NAME', NULL))

based on:

commit f7316aa0c9a
Author: Ajo Robert <ajo.robert@oracle.com>
Date:   Thu Aug 24 17:03:21 2017 +0530

    Bug#26361149  MYSQL SERVER CRASHES AT: COL IN(IFNULL(CONST,
                           COL), NAME_CONST('NAME', NULL))

    Backport of Bug#19143243 fix.

    NAME_CONST item can return NULL_ITEM type in case of incorrect arguments.
    NULL_ITEM has special processing in Item_func_in function.
    In Item_func_in::fix_length_and_dec an array of possible comparators is
    created. Since NAME_CONST function has NULL_ITEM type, corresponding
    array element is empty. Then NAME_CONST is wrapped to ITEM_CACHE.
    ITEM_CACHE can not return proper type(NULL_ITEM) in Item_func_in::val_int(),
    so the NULL_ITEM is attempted compared with an empty comparator.
    The fix is to disable the caching of Item_name_const item.
CVE: CVE-2017-10378
CWE: NVD-CWE-noinfo
Vulnerability description: Vulnerability in the MySQL Server component of Oracle MySQL (subcomponent: Server: Optimizer). Supported versions that are affected are 5.5.57 and earlier, 5.6.37 and earlier and 5.7.11 and earlier. Easily exploitable vulnerability allows low privileged attacker with network access via multiple protocols to compromise MySQL Server. Successful attacks of this vulnerability can result in unauthorized ability to cause a hang or frequently repeatable crash (complete DOS) of MySQL Server. CVSS 3.0 Base Score 6.5 (Availability impacts). CVSS Vector: (CVSS:3.0/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H).

Project: server

void Item_ref_null_helper::print(String *str, enum_query_type query_type)
{
  str->append(STRING_WITH_LEN("<ref_null_helper>("));
  if (ref)
    (*ref)->print(str, query_type);
  else
    str->append('?');
  str->append(')');
}

Project: server

my_decimal *Item_sp_variable::val_decimal(my_decimal *decimal_value)
{
  DBUG_ASSERT(fixed);
  Item *it= this_item();
  my_decimal *val= it->val_decimal(decimal_value);
  null_value= it->null_value;
  return val;
}

Project: server

void Item_ref::save_val(Field *to)
{
  (*ref)->save_result(to);
  null_value= (*ref)->null_value;
}

Project: server

Item *Item_field::equal_fields_propagator(uchar *arg)
{
  if (no_const_subst)
    return this;
  item_equal= find_item_equal((COND_EQUAL *) arg);
  Item *item= 0;
  if (item_equal)
    item= item_equal->get_const();
  /*
    Disable const propagation for items used in different comparison contexts.
    This must be done because, for example, Item_hex_string->val_int() is not
    the same as (Item_hex_string->val_str() in BINARY column)->val_int().
    We cannot simply disable the replacement in a particular context (
    e.g. <bin_col> = <int_col> AND <bin_col> = <hex_string>) since
    Items don't know the context they are in and there are functions like 
    IF (<hex_string>, 'yes', 'no').
  */
  if (!item || !has_compatible_context(item))
    item= this;
  else if (field && (field->flags & ZEROFILL_FLAG) && IS_NUM(field->type()))
  {
    if (item && (cmp_context == STRING_RESULT || cmp_context == IMPOSSIBLE_RESULT))
      convert_zerofill_number_to_string(&item, (Field_num *)field);
    else
      item= this;
  }
  return item;
}

Project: server

const Hybrid_type_traits_integer *Hybrid_type_traits_integer::instance()
{
  return &integer_traits_instance;
}

Project: server

Item* Item::cache_const_expr_transformer(uchar *arg)
{
  if (*(bool*)arg)
  {
    *((bool*)arg)= FALSE;
    Item_cache *cache= Item_cache::get_cache(this);
    if (!cache)
      return NULL;
    cache->setup(this);
    cache->store(this);
    return cache;
  }
  return this;
}

Project: server

void Item_ref::save_org_in_field(Field *field)
{
  (*ref)->save_org_in_field(field);
}

Project: server

longlong Item_field::val_int_endpoint(bool left_endp, bool *incl_endp)
{
  longlong res= val_int();
  return null_value? LONGLONG_MIN : res;
}

Project: server

String *Item_param::val_str(String* str) 
{ 
  switch (state) {
  case STRING_VALUE:
  case LONG_DATA_VALUE:
    return &str_value_ptr;
  case REAL_VALUE:
    str->set_real(value.real, NOT_FIXED_DEC, &my_charset_bin);
    return str;
  case INT_VALUE:
    str->set(value.integer, &my_charset_bin);
    return str;
  case DECIMAL_VALUE:
    if (my_decimal2string(E_DEC_FATAL_ERROR, &decimal_value,
                          0, 0, 0, str) <= 1)
      return str;
    return NULL;
  case TIME_VALUE:
  {
    if (str->reserve(MAX_DATE_STRING_REP_LENGTH))
      break;
    str->length((uint) my_TIME_to_str(&value.time, (char*) str->ptr(),
                decimals));
    str->set_charset(&my_charset_bin);
    return str;
  }
  case NULL_VALUE:
    return NULL; 
  default:
    DBUG_ASSERT(0);
  }
  return str;
}

Project: server

void Item_insert_value::print(String *str, enum_query_type query_type)
{
  str->append(STRING_WITH_LEN("values("));
  arg->print(str, query_type);
  str->append(')');
}

Project: server

void Item::init_make_field(Send_field *tmp_field,
			   enum enum_field_types field_type_arg)
{
  char *empty_name= (char*) "";
  tmp_field->db_name=		empty_name;
  tmp_field->org_table_name=	empty_name;
  tmp_field->org_col_name=	empty_name;
  tmp_field->table_name=	empty_name;
  tmp_field->col_name=		name;
  tmp_field->charsetnr=         collation.collation->number;
  tmp_field->flags=             (maybe_null ? 0 : NOT_NULL_FLAG) | 
                                (my_binary_compare(charset_for_protocol()) ?
                                 BINARY_FLAG : 0);
  tmp_field->type=              field_type_arg;
  tmp_field->length=max_length;
  tmp_field->decimals=decimals;
  if (unsigned_flag)
    tmp_field->flags |= UNSIGNED_FLAG;
}

Project: server

Item_case_expr::Item_case_expr(uint case_expr_id)
  :Item_sp_variable( C_STRING_WITH_LEN("case_expr")),
   m_case_expr_id(case_expr_id)
{
}

Project: server

double Item_ref::val_result()
{
  if (result_field)
  {
    if ((null_value= result_field->is_null()))
      return 0.0;
    return result_field->val_real();
  }
  return val_real();
}

Project: server

Item_cache_wrapper::~Item_cache_wrapper()
{
  DBUG_ASSERT(expr_cache == 0);
}

Project: server

static Item** find_field_in_group_list(Item *find_item, ORDER *group_list)
{
  const char *db_name;
  const char *table_name;
  const char *field_name;
  ORDER      *found_group= NULL;
  int         found_match_degree= 0;
  char        name_buff[SAFE_NAME_LEN+1];

  if (find_item->type() == Item::FIELD_ITEM ||
      find_item->type() == Item::REF_ITEM)
  {
    db_name=    ((Item_ident*) find_item)->db_name;
    table_name= ((Item_ident*) find_item)->table_name;
    field_name= ((Item_ident*) find_item)->field_name;
  }
  else
    return NULL;

  if (db_name && lower_case_table_names)
  {
    /* Convert database to lower case for comparison */
    strmake_buf(name_buff, db_name);
    my_casedn_str(files_charset_info, name_buff);
    db_name= name_buff;
  }

  DBUG_ASSERT(field_name != 0);

  for (ORDER *cur_group= group_list ; cur_group ; cur_group= cur_group->next)
  {
    int cur_match_degree= 0;

    /* SELECT list element with explicit alias */
    if ((*(cur_group->item))->name && !table_name &&
        !(*(cur_group->item))->is_autogenerated_name &&
        !my_strcasecmp(system_charset_info,
                       (*(cur_group->item))->name, field_name))
    {
      ++cur_match_degree;
    }
    /* Reference on the field or view/derived field. */
    else if ((*(cur_group->item))->type() == Item::FIELD_ITEM ||
             (*(cur_group->item))->type() == Item::REF_ITEM )
    {
      Item_ident *cur_field= (Item_ident*) *cur_group->item;
      const char *l_db_name= cur_field->db_name;
      const char *l_table_name= cur_field->table_name;
      const char *l_field_name= cur_field->field_name;

      DBUG_ASSERT(l_field_name != 0);

      if (!my_strcasecmp(system_charset_info,
                         l_field_name, field_name))
        ++cur_match_degree;
      else
        continue;

      if (l_table_name && table_name)
      {
        /* If field_name is qualified by a table name. */
        if (my_strcasecmp(table_alias_charset, l_table_name, table_name))
          /* Same field names, different tables. */
          return NULL;

        ++cur_match_degree;
        if (l_db_name && db_name)
        {
          /* If field_name is also qualified by a database name. */
          if (strcmp(l_db_name, db_name))
            /* Same field names, different databases. */
            return NULL;
          ++cur_match_degree;
        }
      }
    }
    else
      continue;

    if (cur_match_degree > found_match_degree)
    {
      found_match_degree= cur_match_degree;
      found_group= cur_group;
    }
    else if (found_group && (cur_match_degree == found_match_degree) &&
             !(*(found_group->item))->eq((*(cur_group->item)), 0))
    {
      /*
        If the current resolve candidate matches equally well as the current
        best match, they must reference the same column, otherwise the field
        is ambiguous.
      */
      my_error(ER_NON_UNIQ_ERROR, MYF(0),
               find_item->full_name(), current_thd->where);
      return NULL;
    }
  }

  if (found_group)
    return found_group->item;
  else
    return NULL;
}

Project: server

Item::Item():
  is_expensive_cache(-1), rsize(0), name(0), orig_name(0), name_length(0),
  fixed(0), is_autogenerated_name(TRUE),
  collation(&my_charset_bin, DERIVATION_COERCIBLE)
{
  marker= 0;
  maybe_null=null_value=with_sum_func=with_field=unsigned_flag=0;
  in_rollup= 0;
  decimals= 0; max_length= 0;
  with_subselect= 0;
  cmp_context= IMPOSSIBLE_RESULT;
   /* Initially this item is not attached to any JOIN_TAB. */
  join_tab_idx= MAX_TABLES;

  /* Put item in free list so that we can free all items at end */
  THD *thd= current_thd;
  next= thd->free_list;
  thd->free_list= this;
  /*
    Item constructor can be called during execution other then SQL_COM
    command => we should check thd->lex->current_select on zero (thd->lex
    can be uninitialised)
  */
  if (thd->lex->current_select)
  {
    enum_parsing_place place= 
      thd->lex->current_select->parsing_place;
    if (place == SELECT_LIST ||
	place == IN_HAVING)
      thd->lex->current_select->select_n_having_items++;
  }
}

Project: server

Item_param::set_out_param_info(Send_field *info)
{
  m_out_param_info= info;
  param_type= m_out_param_info->type;
}

Project: server

Item_field::Item_field(THD *thd, Name_resolution_context *context_arg,
                       Field *f)
  :Item_ident(context_arg, f->table->s->db.str, *f->table_name, f->field_name),
   item_equal(0), no_const_subst(0),
   have_privileges(0), any_privileges(0)
{
  /*
    We always need to provide Item_field with a fully qualified field
    name to avoid ambiguity when executing prepared statements like
    SELECT * from d1.t1, d2.t1; (assuming d1.t1 and d2.t1 have columns
    with same names).
    This is because prepared statements never deal with wildcards in
    select list ('*') and always fix fields using fully specified path
    (i.e. db.table.column).
    No check for OOM: if db_name is NULL, we'll just get
    "Field not found" error.
    We need to copy db_name, table_name and field_name because they must
    be allocated in the statement memory, not in table memory (the table
    structure can go away and pop up again between subsequent executions
    of a prepared statement or after the close_tables_for_reopen() call
    in mysql_multi_update_prepare() or due to wildcard expansion in stored
    procedures).
  */
  {
    if (db_name)
      orig_db_name= thd->strdup(db_name);
    if (table_name)
      orig_table_name= thd->strdup(table_name);
    if (field_name)
      orig_field_name= thd->strdup(field_name);
    /*
      We don't restore 'name' in cleanup because it's not changed
      during execution. Still we need it to point to persistent
      memory if this item is to be reused.
    */
    name= (char*) orig_field_name;
  }
  set_field(f);
  with_field= 1;
}

Project: server

void Item_param::set_decimal(const my_decimal *dv)
{
  state= DECIMAL_VALUE;

  my_decimal2decimal(dv, &decimal_value);

  decimals= (uint8) decimal_value.frac;
  unsigned_flag= !decimal_value.sign();
  max_length= my_decimal_precision_to_length(decimal_value.intg + decimals,
                                             decimals, unsigned_flag);
}

Project: server

bool Item_outer_ref::fix_fields(THD *thd, Item **reference)
{
  bool err;
  /* outer_ref->check_cols() will be made in Item_direct_ref::fix_fields */
  if ((*ref) && !(*ref)->fixed && ((*ref)->fix_fields(thd, reference)))
    return TRUE;
  err= Item_direct_ref::fix_fields(thd, reference);
  if (!outer_ref)
    outer_ref= *ref;
  if ((*ref)->type() == Item::FIELD_ITEM)
    table_name= ((Item_field*)outer_ref)->table_name;
  return err;
}

Project: server

void Item_copy_string::copy()
{
  String *res=item->val_str(&str_value);
  if (res && res != &str_value)
    str_value.copy(*res);
  null_value=item->null_value;
}

Project: server

longlong Item_hex_hybrid::val_int()
{
  // following assert is redundant, because fixed=1 assigned in constructor
  DBUG_ASSERT(fixed == 1);
  char *end=(char*) str_value.ptr()+str_value.length(),
       *ptr=end-min(str_value.length(),sizeof(longlong));

  ulonglong value=0;
  for (; ptr != end ; ptr++)
    value=(value << 8)+ (ulonglong) (uchar) *ptr;
  return (longlong) value;
}

Project: server

void Item_field::print(String *str, enum_query_type query_type)
{
  if (field && field->table->const_table &&
      !(query_type & QT_NO_DATA_EXPANSION))
  {
    print_value(str);
    return;
  }
  Item_ident::print(str, query_type);
}

Project: server

bool Item_float::eq(const Item *arg, bool binary_cmp) const
{
  if (arg->basic_const_item() && arg->type() == type())
  {
    /*
      We need to cast off const to call val_int(). This should be OK for
      a basic constant.
    */
    Item *item= (Item*) arg;
    return item->val_real() == value;
  }
  return FALSE;
}

Project: server

bool Item_null::eq(const Item *item, bool binary_cmp) const
{ return item->type() == type(); }

Project: server

String *Item::check_well_formed_result(String *str, bool send_error)
{
  /* Check whether we got a well-formed string */
  CHARSET_INFO *cs= str->charset();
  int well_formed_error;
  uint wlen= cs->cset->well_formed_len(cs,
                                       str->ptr(), str->ptr() + str->length(),
                                       str->length(), &well_formed_error);
  null_value= false;
  if (wlen < str->length())
  {
    THD *thd= current_thd;
    char hexbuf[7];
    uint diff= str->length() - wlen;
    set_if_smaller(diff, 3);
    octet2hex(hexbuf, str->ptr() + wlen, diff);
    if (send_error)
    {
      my_error(ER_INVALID_CHARACTER_STRING, MYF(0),
               cs->csname,  hexbuf);
      return 0;
    }
    if ((thd->variables.sql_mode &
         (MODE_STRICT_TRANS_TABLES | MODE_STRICT_ALL_TABLES)))
    {
      null_value= 1;
      str= 0;
    }
    else
    {
      str->length(wlen);
    }
    push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_INVALID_CHARACTER_STRING,
                        ER(ER_INVALID_CHARACTER_STRING), cs->csname, hexbuf);
  }
  return str;
}

Project: server

void Item_cache_wrapper::cleanup()
{
  DBUG_ENTER("Item_cache_wrapper::cleanup");
  Item_result_field::cleanup();
  delete expr_cache;
  expr_cache= 0;
  /* expr_value is Item so it will be destroyed from list of Items */
  expr_value= 0;
  parameters.empty();
  DBUG_VOID_RETURN;
}

Project: server

void Item_hex_string::print(String *str, enum_query_type query_type)
{
  str->append("X'");
  str->append_hex(str_value.ptr(), str_value.length());
  str->append("'");
}

Project: server

bool Item_direct_view_ref::fix_fields(THD *thd, Item **reference)
{
  /* view fild reference must be defined */
  DBUG_ASSERT(*ref);
  /* (*ref)->check_cols() will be made in Item_direct_ref::fix_fields */
  if ((*ref)->fixed)
  {
    Item *ref_item= (*ref)->real_item();
    if (ref_item->type() == Item::FIELD_ITEM)
    {
      /*
        In some cases we need to update table read set(see bug#47150).
        If ref item is FIELD_ITEM and fixed then field and table
        have proper values. So we can use them for update.
      */
      Field *fld= ((Item_field*) ref_item)->field;
      DBUG_ASSERT(fld && fld->table);
      if (thd->mark_used_columns == MARK_COLUMNS_READ)
        bitmap_set_bit(fld->table->read_set, fld->field_index);
    }
  }
  else if (!(*ref)->fixed &&
           ((*ref)->fix_fields(thd, ref)))
    return TRUE;

  if (Item_direct_ref::fix_fields(thd, reference))
    return TRUE;
  if (view->table && view->table->maybe_null)
    maybe_null= TRUE;
  set_null_ref_table();
  return FALSE;
}

Project: server

bool Item_direct_ref::is_null()
{
  return (*ref)->is_null();
}

Project: server

void Item_case_expr::print(String *str, enum_query_type)
{
  if (str->reserve(MAX_INT_WIDTH + sizeof("case_expr@")))
    return;                                    /* purecov: inspected */
  (void) str->append(STRING_WITH_LEN("case_expr@"));
  str->qs_append(m_case_expr_id);
}

Project: server

bool Item::eq_by_collation(Item *item, bool binary_cmp, CHARSET_INFO *cs)
{
  CHARSET_INFO *save_cs= 0;
  CHARSET_INFO *save_item_cs= 0;
  if (collation.collation != cs)
  {
    save_cs= collation.collation;
    collation.collation= cs;
  }
  if (item->collation.collation != cs)
  {
    save_item_cs= item->collation.collation;
    item->collation.collation= cs;
  }
  bool res= eq(item, binary_cmp);
  if (save_cs)
    collation.collation= save_cs;
  if (save_item_cs)
    item->collation.collation= save_item_cs;
  return res;
}

Project: server

longlong Item_field::val_int()
{
  DBUG_ASSERT(fixed == 1);
  if ((null_value=field->is_null()))
    return 0;
  return field->val_int();
}

Project: server

void Item_ref::make_field(Send_field *field)
{
  (*ref)->make_field(field);
  /* Non-zero in case of a view */
  if (name)
    field->col_name= name;
  if (table_name)
    field->table_name= table_name;
  if (db_name)
    field->db_name= db_name;
  if (orig_field_name)
    field->org_col_name= orig_field_name;
  if (orig_table_name)
    field->org_table_name= orig_table_name;
}

Project: server

bool Item_trigger_field::fix_fields(THD *thd, Item **items)
{
  /*
    Since trigger is object tightly associated with TABLE object most
    of its set up can be performed during trigger loading i.e. trigger
    parsing! So we have little to do in fix_fields. :)
  */

  DBUG_ASSERT(fixed == 0);

  /* Set field. */

  if (field_idx != (uint)-1)
  {
#ifndef NO_EMBEDDED_ACCESS_CHECKS
    /*
      Check access privileges for the subject table. We check privileges only
      in runtime.
    */

    if (table_grants)
    {
      table_grants->want_privilege= want_privilege;

      if (check_grant_column(thd, table_grants, triggers->trigger_table->s->db.str,
                             triggers->trigger_table->s->table_name.str, field_name,
                             strlen(field_name), thd->security_ctx))
        return TRUE;
    }
#endif // NO_EMBEDDED_ACCESS_CHECKS

    field= (row_version == OLD_ROW) ? triggers->old_field[field_idx] :
                                      triggers->new_field[field_idx];
    set_field(field);
    fixed= 1;
    return FALSE;
  }

  my_error(ER_BAD_FIELD_ERROR, MYF(0), field_name,
           (row_version == NEW_ROW) ? "NEW" : "OLD");
  return TRUE;
}

Project: server

bool Item::eq(const Item *item, bool binary_cmp) const
{
  /*
    Note, that this is never TRUE if item is a Item_param:
    for all basic constants we have special checks, and Item_param's
    type() can be only among basic constant types.
  */
  return type() == item->type() && name && item->name &&
    !my_strcasecmp(system_charset_info,name,item->name);
}

Project: server

String *Item_int::val_str(String *str)
{
  // following assert is redundant, because fixed=1 assigned in constructor
  DBUG_ASSERT(fixed == 1);
  str->set_int(value, unsigned_flag, collation.collation);
  return str;
}

Project: server

void Item_string::print(String *str, enum_query_type query_type)
{
  const bool print_introducer=
    !(query_type & QT_WITHOUT_INTRODUCERS) && is_cs_specified();
  if (print_introducer)
  {
    str->append('_');
    str->append(collation.collation->csname);
  }

  str->append('\'');

  if (query_type & QT_TO_SYSTEM_CHARSET)
  {
    if (print_introducer)
    {
      /*
        Because we wrote an introducer, we must print str_value in its
        charset, and the resulting bytes must not be changed until they
        reach the end client.
        But the caller is asking for system_charset_info, and may later
        convert into character_set_results. That means two conversions: we
        must ensure that they don't change our printed bytes.
        So we print str_value in the least common denominator of the three
        charsets involved: ASCII. Non-ASCII characters are printed as \xFF
        sequences (which is ASCII too). This way, our bytes will not be
        changed.
      */
      ErrConvString tmp(str_value.ptr(), str_value.length(), &my_charset_bin);
      str->append(tmp.ptr());
    }
    else
    {
      if (my_charset_same(str_value.charset(), system_charset_info))
        str_value.print(str); // already in system_charset_info
      else // need to convert
      {
        THD *thd= current_thd;
        LEX_STRING utf8_lex_str;

        thd->convert_string(&utf8_lex_str,
                            system_charset_info,
                            str_value.c_ptr_safe(),
                            str_value.length(),
                            str_value.charset());

        String utf8_str(utf8_lex_str.str,
                        utf8_lex_str.length,
                        system_charset_info);

        utf8_str.print(str);
      }
    }
  }
  else
  {
    // Caller wants a result in the charset of str_value.
    str_value.print(str);
  }

  str->append('\'');
}

Project: server

bool Item_cache_row::cache_value()
{
  if (!example)
    return FALSE;
  value_cached= TRUE;
  null_value= 0;
  example->bring_value();
  for (uint i= 0; i < item_count; i++)
  {
    values[i]->cache_value();
    null_value|= values[i]->null_value;
  }
  return TRUE;
}

Project: server

longlong Item_cache_wrapper::val_int()
{
  Item *cached_value;
  DBUG_ENTER("Item_cache_wrapper::val_int");
  if (!expr_cache)
  {
    longlong tmp= orig_item->val_int();
    null_value= orig_item->null_value;
    DBUG_RETURN(tmp);
  }

  if ((cached_value= check_cache()))
  {
    longlong tmp= cached_value->val_int();
    null_value= cached_value->null_value;
    DBUG_RETURN(tmp);
  }
  cache();
  null_value= expr_value->null_value;
  DBUG_RETURN(expr_value->val_int());
}

Project: server

void Item::print_value(String *str)
{
  char buff[MAX_FIELD_WIDTH];
  String *ptr, tmp(buff,sizeof(buff),str->charset());
  ptr= val_str(&tmp);
  if (!ptr)
    str->append("NULL");
  else
  {
    switch (result_type()) {
    case STRING_RESULT:
      append_unescaped(str, ptr->ptr(), ptr->length());
      break;
    case DECIMAL_RESULT:
    case REAL_RESULT:
    case INT_RESULT:
      str->append(*ptr);
      break;
    case ROW_RESULT:
    case TIME_RESULT:
    case IMPOSSIBLE_RESULT:
      DBUG_ASSERT(0);
    }
  }
}

Project: server

bool Item::get_seconds(ulonglong *sec, ulong *sec_part)
{
  if (decimals == 0)
  { // optimize for an important special case
    longlong val= val_int();
    bool neg= val < 0 && !unsigned_flag;
    *sec= neg ? -val : val;
    *sec_part= 0;
    return neg;
  }
  my_decimal tmp, *dec= val_decimal(&tmp);
  if (!dec)
    return 0;
  return my_decimal2seconds(dec, sec, sec_part);
}

Project: server

bool Item_param::set_str(const char *str, ulong length)
{
  DBUG_ENTER("Item_param::set_str");
  /*
    Assign string with no conversion: data is converted only after it's
    been written to the binary log.
  */
  uint dummy_errors;
  if (str_value.copy(str, length, &my_charset_bin, &my_charset_bin,
                     &dummy_errors))
    DBUG_RETURN(TRUE);
  state= STRING_VALUE;
  max_length= length;
  maybe_null= 0;
  /* max_length and decimals are set after charset conversion */
  /* sic: str may be not null-terminated, don't add DBUG_PRINT here */
  DBUG_RETURN(FALSE);
}

Project: server

String *Item_direct_ref::val_str(String* tmp)
{
  tmp=(*ref)->val_str(tmp);
  null_value=(*ref)->null_value;
  return tmp;
}

Project: server

void Item_splocal::print(String *str, enum_query_type)
{
  str->reserve(m_name.length+8);
  str->append(m_name.str, m_name.length);
  str->append('@');
  str->qs_append(m_var_idx);
}

Project: server

my_decimal *Item_null::val_decimal(my_decimal *decimal_value)
{
  return 0;
}

Project: server

const char *dbug_print_item(Item *item)
{
  char *buf= dbug_item_print_buf;
  String str(buf, sizeof(dbug_item_print_buf), &my_charset_bin);
  str.length(0);
  if (!item)
    return "(Item*)NULL";
  item->print(&str ,QT_ORDINARY);
  if (str.c_ptr() == buf)
    return buf;
  else
    return "Couldn't fit into buffer";
}

Project: server

Item_param::Item_param(uint pos_in_query_arg) :
  state(NO_VALUE),
  item_result_type(STRING_RESULT),
  /* Don't pretend to be a literal unless value for this item is set. */
  item_type(PARAM_ITEM),
  param_type(MYSQL_TYPE_VARCHAR),
  pos_in_query(pos_in_query_arg),
  set_param_func(default_set_param_func),
  limit_clause_param(FALSE),
  m_out_param_info(NULL)
{
  name= (char*) "?";
  /* 
    Since we can't say whenever this item can be NULL or cannot be NULL
    before mysql_stmt_execute(), so we assuming that it can be NULL until
    value is set.
  */
  maybe_null= 1;
  cnvitem= new Item_string("", 0, &my_charset_bin, DERIVATION_COERCIBLE);
  cnvstr.set(cnvbuf, sizeof(cnvbuf), &my_charset_bin);
}

Project: server

longlong Item_cache_temporal::val_int()
{
  DBUG_ASSERT(fixed == 1);
  if ((!value_cached && !cache_value()) || null_value)
  {
    null_value= true;
    return 0;
  }
  return val_int_from_date();
}

Project: server

Item* Item_cache_wrapper::get_tmp_table_item(THD *thd_arg)
{
  if (!orig_item->with_sum_func && !orig_item->const_item())
    return new Item_field(result_field);
  return copy_or_same(thd_arg);
}

Project: server

void Item_ref::set_properties()
{
  max_length= (*ref)->max_length;
  maybe_null= (*ref)->maybe_null;
  decimals=   (*ref)->decimals;
  collation.set((*ref)->collation);
  /*
    We have to remember if we refer to a sum function, to ensure that
    split_sum_func() doesn't try to change the reference.
  */
  with_sum_func= (*ref)->with_sum_func;
  with_field= (*ref)->with_field;
  unsigned_flag= (*ref)->unsigned_flag;
  fixed= 1;
  if (alias_name_used)
    return;
  if ((*ref)->type() == FIELD_ITEM)
    alias_name_used= ((Item_ident *) (*ref))->alias_name_used;
  else
    alias_name_used= TRUE; // it is not field, so it is was resolved by alias
}

Project: server

bool agg_item_collations_for_comparison(DTCollation &c, const char *fname,
                                        Item **av, uint count, uint flags)
{
  return (agg_item_collations(c, fname, av, count,
                              flags | MY_COLL_DISALLOW_NONE, 1));
}

Project: server

int Item_float::save_in_field(Field *field, bool no_conversions)
{
  double nr= val_real();
  if (null_value)
    return set_field_to_null(field);
  field->set_notnull();
  return field->store(nr);
}

Project: server

Field *Item_type_holder::make_field_by_type(TABLE *table)
{
  /*
    The field functions defines a field to be not null if null_ptr is not 0
  */
  uchar *null_ptr= maybe_null ? (uchar*) "" : 0;
  Field *field;

  switch (fld_type) {
  case MYSQL_TYPE_ENUM:
    DBUG_ASSERT(enum_set_typelib);
    field= new Field_enum((uchar *) 0, max_length, null_ptr, 0,
                          Field::NONE, name,
                          get_enum_pack_length(enum_set_typelib->count),
                          enum_set_typelib, collation.collation);
    if (field)
      field->init(table);
    return field;
  case MYSQL_TYPE_SET:
    DBUG_ASSERT(enum_set_typelib);
    field= new Field_set((uchar *) 0, max_length, null_ptr, 0,
                         Field::NONE, name,
                         get_set_pack_length(enum_set_typelib->count),
                         enum_set_typelib, collation.collation);
    if (field)
      field->init(table);
    return field;
  case MYSQL_TYPE_NULL:
    return make_string_field(table);
  default:
    break;
  }
  return tmp_table_field_from_field_type(table, 0);
}

Project: server

Item_cache_wrapper::Item_cache_wrapper(Item *item_arg)
:orig_item(item_arg), expr_cache(NULL), expr_value(NULL)
{
  DBUG_ASSERT(orig_item->fixed);
  max_length= orig_item->max_length;
  maybe_null= orig_item->maybe_null;
  decimals=   orig_item->decimals;
  collation.set(orig_item->collation);
  with_sum_func= orig_item->with_sum_func;
  with_field= orig_item->with_field;
  unsigned_flag= orig_item->unsigned_flag;
  name= item_arg->name;
  name_length= item_arg->name_length;
  with_subselect=  orig_item->with_subselect;

  if ((expr_value= Item_cache::get_cache(orig_item)))
    expr_value->setup(orig_item);

  fixed= 1;
}

Project: server

int Item_null::save_safe_in_field(Field *field)
{
  return set_field_to_null(field);
}

Project: server

void Item_field::reset_field(Field *f)
{
  set_field(f);
  /* 'name' is pointing at field->field_name of old field */
  name= (char*) f->field_name;
}

Project: server

my_decimal *Item_ref::val_decimal_result(my_decimal *decimal_value)
{
  if (result_field)
  {
    if ((null_value= result_field->is_null()))
      return 0;
    return result_field->val_decimal(decimal_value);
  }
  return val_decimal(decimal_value);
}

Project: server

bool Item_field::update_table_bitmaps_processor(uchar *arg)
{
  update_table_bitmaps();
  return FALSE;
}

Project: server

adjust_max_effective_column_length(Field *field_par, uint32 max_length)
{
  uint32 new_max_length= field_par->max_display_length();
  uint32 sign_length= (field_par->flags & UNSIGNED_FLAG) ? 0 : 1;

  switch (field_par->type())
  {
  case MYSQL_TYPE_INT24:
    /*
      Compensate for MAX_MEDIUMINT_WIDTH being 1 too long (8)
      compared to the actual number of digits that can fit into
      the column.
    */
    new_max_length+= 1;
    /* fall through */
  case MYSQL_TYPE_LONG:
  case MYSQL_TYPE_TINY:
  case MYSQL_TYPE_SHORT:

    /* Take out the sign and add a conditional sign */
    new_max_length= new_max_length - 1 + sign_length;
    break;

  /* BINGINT is always 20 no matter the sign */
  case MYSQL_TYPE_LONGLONG:
  /* make gcc happy */
  default:
    break;
  }

  /* Adjust only if the actual precision based one is bigger than specified */
  return new_max_length > max_length ? new_max_length : max_length;
}

Project: server

void Item_ident_for_show::make_field(Send_field *tmp_field)
{
  tmp_field->table_name= tmp_field->org_table_name= table_name;
  tmp_field->db_name= db_name;
  tmp_field->col_name= tmp_field->org_col_name= field->field_name;
  tmp_field->charsetnr= field->charset()->number;
  tmp_field->length=field->field_length;
  tmp_field->type=field->type();
  tmp_field->flags= field->table->maybe_null ? 
    (field->flags & ~NOT_NULL_FLAG) : field->flags;
  tmp_field->decimals= field->decimals();
}

Project: server

String *Item_decimal::val_str(String *result)
{
  result->set_charset(&my_charset_numeric);
  my_decimal2string(E_DEC_FATAL_ERROR, &decimal_value, 0, 0, 0, result);
  return result;
}

Project: server

void Item::make_field(Send_field *tmp_field)
{
  init_make_field(tmp_field, field_type());
}

Project: server

Item *Item_int_with_ref::clone_item()
{
  DBUG_ASSERT(ref->const_item());
  /*
    We need to evaluate the constant to make sure it works with
    parameter markers.
  */
  return (ref->unsigned_flag ?
          new Item_uint(ref->name, ref->val_int(), ref->max_length) :
          new Item_int(ref->name, ref->val_int(), ref->max_length));
}

Project: server

bool is_outer_table(TABLE_LIST *table, SELECT_LEX *select)
{
  DBUG_ASSERT(table->select_lex != select);
  TABLE_LIST *tl;

  if (table->belong_to_view &&
      table->belong_to_view->select_lex == select)
    return FALSE;

  for (tl= select->master_unit()->derived;
       tl && tl->is_merged_derived();
       select= tl->select_lex, tl= select->master_unit()->derived)
  {
    if (tl->select_lex == table->select_lex)
      return FALSE;
  }
  return TRUE;
}

Project: server

Item *Item_cache_wrapper::check_cache()
{
  DBUG_ENTER("Item_cache_wrapper::check_cache");
  if (expr_cache)
  {
    Expression_cache_tmptable::result res;
    Item *cached_value;
    init_on_demand();
    res= expr_cache->check_value(&cached_value);
    if (res == Expression_cache_tmptable::HIT)
      DBUG_RETURN(cached_value);
  }
  DBUG_RETURN(NULL);
}

Project: server

bool Item_cache_wrapper::is_null()
{
  Item *cached_value;
  DBUG_ENTER("Item_cache_wrapper::is_null");
  if (!expr_cache)
  {
    bool tmp= orig_item->is_null();
    null_value= orig_item->null_value;
    DBUG_RETURN(tmp);
  }

  if ((cached_value= check_cache()))
  {
    bool tmp= cached_value->is_null();
    null_value= cached_value->null_value;
    DBUG_RETURN(tmp);
  }
  cache();
  DBUG_RETURN((null_value= expr_value->null_value));
}

Project: server

bool Item_null::send(Protocol *protocol, String *packet)
{
  return protocol->store_null();
}

Project: server

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

  return (this->*transformer)(arg);
}

Project: server

longlong_from_string_with_check(CHARSET_INFO *cs, const char *cptr,
                                const char *end)
{
  int err;
  longlong tmp;
  char *end_of_num= (char*) end;

  tmp= (*(cs->cset->strtoll10))(cs, cptr, &end_of_num, &err);
  /*
    TODO: Give error if we wanted a signed integer and we got an unsigned
    one
  */
  if (!current_thd->no_errors &&
      (err > 0 ||
       (end != end_of_num && !check_if_only_end_space(cs, end_of_num, end))))
  {
    ErrConvString err(cptr, end - cptr, cs);
    push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
                        ER_TRUNCATED_WRONG_VALUE,
                        ER(ER_TRUNCATED_WRONG_VALUE), "INTEGER",
                        err.ptr());
  }
  return tmp;
}

Project: server

int Item_field::save_in_field(Field *to, bool no_conversions)
{
  return save_field_in_field(result_field, &null_value, to, no_conversions);
}

Project: server

Item *Item_param::safe_charset_converter(CHARSET_INFO *tocs)
{
  if (const_item())
  {
    uint cnv_errors;
    String *ostr= val_str(&cnvstr);
    if (null_value)
    {
      Item_null *n= new Item_null();
      return n ? n->safe_charset_converter(tocs) : NULL;
    }
    cnvitem->str_value.copy(ostr->ptr(), ostr->length(),
                            ostr->charset(), tocs, &cnv_errors);
    if (cnv_errors)
       return NULL;
    cnvitem->str_value.mark_as_const();
    cnvitem->max_length= cnvitem->str_value.numchars() * tocs->mbmaxlen;
    return cnvitem;
  }
  return Item::safe_charset_converter(tocs);
}

Project: server

double Item_cache_int::val_real()
{
  DBUG_ASSERT(fixed == 1);
  if (!has_value())
    return 0.0;
  return (double) value;
}

Project: server

longlong Item_copy_string::val_int()
{
  int err;
  return null_value ? LL(0) : my_strntoll(str_value.charset(),str_value.ptr(),
                                          str_value.length(),10, (char**) 0,
                                          &err); 
}

Project: server

Item *Item_num::safe_charset_converter(CHARSET_INFO *tocs)
{
  /*
    Item_num returns pure ASCII result,
    so conversion is needed only in case of "tricky" character
    sets like UCS2. If tocs is not "tricky", return the item itself.
  */
  if (!(tocs->state & MY_CS_NONASCII))
    return this;
  
  Item_string *conv;
  uint conv_errors;
  char buf[64], buf2[64];
  String tmp(buf, sizeof(buf), &my_charset_bin);
  String cstr(buf2, sizeof(buf2), &my_charset_bin);
  String *ostr= val_str(&tmp);
  char *ptr;
  cstr.copy(ostr->ptr(), ostr->length(), ostr->charset(), tocs, &conv_errors);
  if (conv_errors || !(conv= new Item_string(cstr.ptr(), cstr.length(),
                                             cstr.charset(),
                                             collation.derivation)))
  {
    /*
      Safe conversion is not possible (or EOM).
      We could not convert a string into the requested character set
      without data loss. The target charset does not cover all the
      characters from the string. Operation cannot be done correctly.
    */
    return NULL;
  }
  if (!(ptr= current_thd->strmake(cstr.ptr(), cstr.length())))
    return NULL;
  conv->str_value.set(ptr, cstr.length(), cstr.charset());
  /* Ensure that no one is going to change the result string */
  conv->str_value.mark_as_const();
  conv->fix_char_length(max_char_length());
  return conv;
}

Project: server

bool Item_ref::is_null()
{
  DBUG_ASSERT(fixed);
  bool tmp=(*ref)->is_null_result();
  null_value=(*ref)->null_value;
  return tmp;
}

Project: server

Item* Item::set_expr_cache(THD *thd)
{
  DBUG_ENTER("Item::set_expr_cache");
  Item_cache_wrapper *wrapper;
  if ((wrapper= new Item_cache_wrapper(this)) &&
      !wrapper->fix_fields(thd, (Item**)&wrapper))
  {
    if (wrapper->set_cache(thd))
      DBUG_RETURN(NULL);
    DBUG_RETURN(wrapper);
  }
  DBUG_RETURN(NULL);
}

Project: server

int Item_null::save_in_field(Field *field, bool no_conversions)
{
  return set_field_to_null_with_conversions(field, no_conversions);
}

Project: server

void dummy_error_processor(THD *thd, void *data)
{}

Project: server

my_decimal *Item_ref_null_helper::val_decimal(my_decimal *decimal_value)
{
  DBUG_ASSERT(fixed == 1);
  my_decimal *val= (*ref)->val_decimal_result(decimal_value);
  owner->was_null|= null_value= (*ref)->null_value;
  return val;
}

Project: server

Item *Item_default_value::transform(Item_transformer transformer, uchar *args)
{
  DBUG_ASSERT(!current_thd->stmt_arena->is_stmt_prepare());

  /*
    If the value of arg is NULL, then this object represents a constant,
    so further transformation is unnecessary (and impossible).
  */
  if (!arg)
    return 0;

  Item *new_item= arg->transform(transformer, args);
  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 (arg != new_item)
    current_thd->change_item_tree(&arg, new_item);
  return (this->*transformer)(args);
}

Project: server

int Item_param::save_in_field(Field *field, bool no_conversions)
{
  field->set_notnull();

  switch (state) {
  case INT_VALUE:
    return field->store(value.integer, unsigned_flag);
  case REAL_VALUE:
    return field->store(value.real);
  case DECIMAL_VALUE:
    return field->store_decimal(&decimal_value);
  case TIME_VALUE:
    field->store_time_dec(&value.time, decimals);
    return 0;
  case STRING_VALUE:
  case LONG_DATA_VALUE:
    return field->store(str_value.ptr(), str_value.length(),
                        str_value.charset());
  case NULL_VALUE:
    return set_field_to_null_with_conversions(field, no_conversions);
  case NO_VALUE:
  default:
    DBUG_ASSERT(0);
  }
  return 1;
}

Project: server

int Item::save_in_field(Field *field, bool no_conversions)
{
  int error;
  if (result_type() == STRING_RESULT)
  {
    String *result;
    CHARSET_INFO *cs= collation.collation;
    char buff[MAX_FIELD_WIDTH];		// Alloc buffer for small columns
    str_value.set_quick(buff, sizeof(buff), cs);
    result=val_str(&str_value);
    if (null_value)
    {
      str_value.set_quick(0, 0, cs);
      return set_field_to_null_with_conversions(field, no_conversions);
    }

    /* NOTE: If null_value == FALSE, "result" must be not NULL.  */

    field->set_notnull();
    error=field->store(result->ptr(),result->length(),cs);
    str_value.set_quick(0, 0, cs);
  }
  else if (result_type() == REAL_RESULT)
  {
    double nr= val_real();
    if (null_value)
      return set_field_to_null_with_conversions(field, no_conversions);
    field->set_notnull();
    error=field->store(nr);
  }
  else if (result_type() == DECIMAL_RESULT)
  {
    my_decimal decimal_value;
    my_decimal *value= val_decimal(&decimal_value);
    if (null_value)
      return set_field_to_null_with_conversions(field, no_conversions);
    field->set_notnull();
    error=field->store_decimal(value);
  }
  else
  {
    longlong nr=val_int();
    if (null_value)
      return set_field_to_null_with_conversions(field, no_conversions);
    field->set_notnull();
    error=field->store(nr, unsigned_flag);
  }
  return error ? error : (field->table->in_use->is_error() ? 1 : 0);
}

Project: server

my_decimal *Item_copy_float::val_decimal(my_decimal *decimal_value)
{
  if (null_value)
    return (my_decimal *) 0;
  else
  {
    double nr= val_real();
    double2my_decimal(E_DEC_FATAL_ERROR, nr, decimal_value);
    return decimal_value;
  }
}

Project: server

void Item_cache_wrapper::print(String *str, enum_query_type query_type)
{
  str->append(func_name());
  if (expr_cache)
  {
    init_on_demand();
    expr_cache->print(str, query_type);
  }
  else
    str->append(STRING_WITH_LEN("<<DISABLED>>"));
  str->append('(');
  orig_item->print(str, query_type);
  str->append(')');
}

Project: server

longlong Item_sp_variable::val_int()
{
  DBUG_ASSERT(fixed);
  Item *it= this_item();
  longlong ret= it->val_int();
  null_value= it->null_value;
  return ret;
}

Project: server

Item_field::fix_outer_field(THD *thd, Field **from_field, Item **reference)
{
  enum_parsing_place place= NO_MATTER;
  bool field_found= (*from_field != not_found_field);
  bool upward_lookup= FALSE;
  TABLE_LIST *table_list;

  /* Calulate the TABLE_LIST for the table */
  table_list= (cached_table ? cached_table :
               field_found && (*from_field) != view_ref_found ?
               (*from_field)->table->pos_in_table_list : 0);
  /*
    If there are outer contexts (outer selects, but current select is
    not derived table or view) try to resolve this reference in the
    outer contexts.

    We treat each subselect as a separate namespace, so that different
    subselects may contain columns with the same names. The subselects
    are searched starting from the innermost.
  */
  Name_resolution_context *last_checked_context= context;
  Item **ref= (Item **) not_found_item;
  SELECT_LEX *current_sel= (SELECT_LEX *) thd->lex->current_select;
  Name_resolution_context *outer_context= 0;
  SELECT_LEX *select= 0;
  /* Currently derived tables cannot be correlated */
  if (current_sel->master_unit()->first_select()->linkage !=
      DERIVED_TABLE_TYPE)
    outer_context= context->outer_context;

  /*
    This assert is to ensure we have an outer contex when *from_field
    is set.
    If this would not be the case, we would assert in mark_as_dependent
    as last_checked_countex == context
  */
  DBUG_ASSERT(outer_context || !*from_field ||
              *from_field == not_found_field);
  for (;
       outer_context;
       outer_context= outer_context->outer_context)
  {
    select= outer_context->select_lex;
    Item_subselect *prev_subselect_item=
      last_checked_context->select_lex->master_unit()->item;
    last_checked_context= outer_context;
    upward_lookup= TRUE;

    place= prev_subselect_item->parsing_place;
    /*
      If outer_field is set, field was already found by first call
      to find_field_in_tables(). Only need to find appropriate context.
    */
    if (field_found && outer_context->select_lex !=
        table_list->select_lex)
      continue;
    /*
      In case of a view, find_field_in_tables() writes the pointer to
      the found view field into '*reference', in other words, it
      substitutes this Item_field with the found expression.
    */
    if (field_found || (*from_field= find_field_in_tables(thd, this,
                                          outer_context->
                                            first_name_resolution_table,
                                          outer_context->
                                            last_name_resolution_table,
                                          reference,
                                          IGNORE_EXCEPT_NON_UNIQUE,
                                          TRUE, TRUE)) !=
        not_found_field)
    {
      if (*from_field)
      {
        if (thd->variables.sql_mode & MODE_ONLY_FULL_GROUP_BY &&
            select->cur_pos_in_select_list != UNDEF_POS)
        {
          /*
            As this is an outer field it should be added to the list of
            non aggregated fields of the outer select.
          */
          if (select->join)
          {
            marker= select->cur_pos_in_select_list;
            select->join->non_agg_fields.push_back(this);
          }
          else
          {
            /*
              join is absent if it is upper SELECT_LEX of non-select
              command
            */
            DBUG_ASSERT(select->master_unit()->outer_select() == NULL &&
                        (thd->lex->sql_command != SQLCOM_SELECT &&
                         thd->lex->sql_command != SQLCOM_UPDATE_MULTI &&
                         thd->lex->sql_command != SQLCOM_DELETE_MULTI &&
                         thd->lex->sql_command != SQLCOM_INSERT_SELECT &&
                         thd->lex->sql_command != SQLCOM_REPLACE_SELECT));
          }
        }
        if (*from_field != view_ref_found)
        {
          prev_subselect_item->used_tables_cache|= (*from_field)->table->map;
          prev_subselect_item->const_item_cache= 0;
          set_field(*from_field);
          if (!last_checked_context->select_lex->having_fix_field &&
              select->group_list.elements &&
              (place == SELECT_LIST || place == IN_HAVING))
          {
            Item_outer_ref *rf;
            /*
              If an outer field is resolved in a grouping select then it
              is replaced for an Item_outer_ref object. Otherwise an
              Item_field object is used.
              The new Item_outer_ref object is saved in the inner_refs_list of
              the outer select. Here it is only created. It can be fixed only
              after the original field has been fixed and this is done in the
              fix_inner_refs() function.
            */
            ;
            if (!(rf= new Item_outer_ref(context, this)))
              return -1;
            thd->change_item_tree(reference, rf);
            select->inner_refs_list.push_back(rf);
            rf->in_sum_func= thd->lex->in_sum_func;
          }
          /*
            A reference is resolved to a nest level that's outer or the same as
            the nest level of the enclosing set function : adjust the value of
            max_arg_level for the function if it's needed.
          */
          if (thd->lex->in_sum_func &&
              thd->lex->in_sum_func->nest_level >= select->nest_level)
          {
            Item::Type ref_type= (*reference)->type();
            set_if_bigger(thd->lex->in_sum_func->max_arg_level,
                          select->nest_level);
            set_field(*from_field);
            fixed= 1;
            mark_as_dependent(thd, last_checked_context->select_lex,
                              context->select_lex, this,
                              ((ref_type == REF_ITEM ||
                                ref_type == FIELD_ITEM) ?
                               (Item_ident*) (*reference) : 0));
            return 0;
          }
        }
        else
        {
          Item::Type ref_type= (*reference)->type();
          prev_subselect_item->used_tables_cache|=
            (*reference)->used_tables();
          prev_subselect_item->const_item_cache&=
            (*reference)->const_item();
          mark_as_dependent(thd, last_checked_context->select_lex,
                            context->select_lex, this,
                            ((ref_type == REF_ITEM || ref_type == FIELD_ITEM) ?
                             (Item_ident*) (*reference) :
                             0));
          if (thd->lex->in_sum_func &&
              thd->lex->in_sum_func->nest_level >= select->nest_level)
          {
            set_if_bigger(thd->lex->in_sum_func->max_arg_level,
                          select->nest_level);
          }
          /*
            A reference to a view field had been found and we
            substituted it instead of this Item (find_field_in_tables
            does it by assigning the new value to *reference), so now
            we can return from this function.
          */
          return 0;
        }
      }
      break;
    }

    /* Search in SELECT and GROUP lists of the outer select. */
    if (place != IN_WHERE && place != IN_ON)
    {
      if (!(ref= resolve_ref_in_select_and_group(thd, this, select)))
        return -1; /* Some error occurred (e.g. ambiguous names). */
      if (ref != not_found_item)
      {
        DBUG_ASSERT(*ref && (*ref)->fixed);
        prev_subselect_item->used_tables_cache|= (*ref)->used_tables();
        prev_subselect_item->const_item_cache&= (*ref)->const_item();
        break;
      }
    }

    /*
      Reference is not found in this select => this subquery depend on
      outer select (or we just trying to find wrong identifier, in this
      case it does not matter which used tables bits we set)
    */
    prev_subselect_item->used_tables_cache|= OUTER_REF_TABLE_BIT;
    prev_subselect_item->const_item_cache= 0;
  }

  DBUG_ASSERT(ref != 0);
  if (!*from_field)
    return -1;
  if (ref == not_found_item && *from_field == not_found_field)
  {
    if (upward_lookup)
    {
      // We can't say exactly what absent table or field
      my_error(ER_BAD_FIELD_ERROR, MYF(0), full_name(), thd->where);
    }
    else
    {
      /* Call find_field_in_tables only to report the error */
      find_field_in_tables(thd, this,
                           context->first_name_resolution_table,
                           context->last_name_resolution_table,
                           reference, REPORT_ALL_ERRORS,
                           !any_privileges, TRUE);
    }
    return -1;
  }
  else if (ref != not_found_item)
  {
    Item *save;
    Item_ref *rf;

    /* Should have been checked in resolve_ref_in_select_and_group(). */
    DBUG_ASSERT(*ref && (*ref)->fixed);
    /*
      Here, a subset of actions performed by Item_ref::set_properties
      is not enough. So we pass ptr to NULL into Item_[direct]_ref
      constructor, so no initialization is performed, and call 
      fix_fields() below.
    */
    save= *ref;
    *ref= NULL;                             // Don't call set_properties()
    rf= (place == IN_HAVING ?
         new Item_ref(context, ref, (char*) table_name,
                      (char*) field_name, alias_name_used) :
         (!select->group_list.elements ?
         new Item_direct_ref(context, ref, (char*) table_name,
                             (char*) field_name, alias_name_used) :
         new Item_outer_ref(context, ref, (char*) table_name,
                            (char*) field_name, alias_name_used)));
    *ref= save;
    if (!rf)
      return -1;

    if (place != IN_HAVING && select->group_list.elements)
    {
      outer_context->select_lex->inner_refs_list.push_back((Item_outer_ref*)rf);
      ((Item_outer_ref*)rf)->in_sum_func= thd->lex->in_sum_func;
    }
    thd->change_item_tree(reference, rf);
    /*
      rf is Item_ref => never substitute other items (in this case)
      during fix_fields() => we can use rf after fix_fields()
    */
    DBUG_ASSERT(!rf->fixed);                // Assured by Item_ref()
    if (rf->fix_fields(thd, reference) || rf->check_cols(1))
      return -1;

    mark_as_dependent(thd, last_checked_context->select_lex,
                      context->select_lex, rf,
                      rf);

    return 0;
  }
  else
  {
    mark_as_dependent(thd, last_checked_context->select_lex,
                      context->select_lex,
                      this, (Item_ident*)*reference);
    if (last_checked_context->select_lex->having_fix_field)
    {
      Item_ref *rf;
      rf= new Item_ref(context, (*from_field)->table->s->db.str,
                       (*from_field)->table->alias.c_ptr(),
                       (char*) field_name);
      if (!rf)
        return -1;
      thd->change_item_tree(reference, rf);
      /*
        rf is Item_ref => never substitute other items (in this case)
        during fix_fields() => we can use rf after fix_fields()
      */
      DBUG_ASSERT(!rf->fixed);                // Assured by Item_ref()
      if (rf->fix_fields(thd, reference) || rf->check_cols(1))
        return -1;
      return 0;
    }
  }
  return 1;
}

Project: server

double Item_string::val_real()
{
  DBUG_ASSERT(fixed == 1);
  return double_from_string_with_check(str_value.charset(),
                                       str_value.ptr(), 
                                       str_value.ptr() +
                                       str_value.length());
}

Project: server

bool Item_cache_wrapper::set_cache(THD *thd)
{
  DBUG_ENTER("Item_cache_wrapper::set_cache");
  DBUG_ASSERT(expr_cache == 0);
  expr_cache= new Expression_cache_tmptable(thd, parameters, expr_value);
  DBUG_RETURN(expr_cache == NULL);
}

Project: server

my_decimal *Item_field::val_decimal_result(my_decimal *decimal_value)
{
  if ((null_value= result_field->is_null()))
    return 0;
  return result_field->val_decimal(decimal_value);
}

Project: server

bool  Item_cache_int::cache_value()
{
  if (!example)
    return FALSE;
  value_cached= TRUE;
  value= example->val_int_result();
  null_value= example->null_value;
  unsigned_flag= example->unsigned_flag;
  return TRUE;
}

Project: server

Item_ident::Item_ident(TABLE_LIST *view_arg, const char *field_name_arg)
  :orig_db_name(NullS), orig_table_name(view_arg->table_name),
   orig_field_name(field_name_arg), context(&view_arg->view->select_lex.context),
   db_name(NullS), table_name(view_arg->alias),
   field_name(field_name_arg),
   alias_name_used(FALSE), cached_field_index(NO_CACHED_FIELD_INDEX),
   cached_table(NULL), depended_from(NULL), can_be_depended(TRUE)
{
  name = (char*) field_name_arg;
  name_length= name ? strlen(name) : 0;
}

Project: server

int Item_cache_int::save_in_field(Field *field, bool no_conversions)
{
  int error;
  if (!has_value())
    return set_field_to_null_with_conversions(field, no_conversions);

  field->set_notnull();
  error= field->store(value, unsigned_flag);

  return error ? error : field->table->in_use->is_error() ? 1 : 0;
}

Project: server

bool Item_param::basic_const_item() const
{
  if (state == NO_VALUE || state == TIME_VALUE)
    return FALSE;
  return TRUE;
}

Project: server

Item *Item_ref::get_tmp_table_item(THD *thd)
{
  if (!result_field)
    return (*ref)->get_tmp_table_item(thd);

  Item_field *item= new Item_field(result_field);
  if (item)
  {
    item->table_name= table_name;
    item->db_name= db_name;
  }
  return item;
}

Project: server

Item *Item_field::replace_equal_field(uchar *arg)
{
  REPLACE_EQUAL_FIELD_ARG* param= (REPLACE_EQUAL_FIELD_ARG*)arg;
  if (item_equal && item_equal == param->item_equal)
  {
    Item *const_item= item_equal->get_const();
    if (const_item)
    {
      if (!has_compatible_context(const_item))
        return this;
      return const_item;
    }
    Item_field *subst= 
      (Item_field *)(item_equal->get_first(param->context_tab, this));
    if (subst)
      subst= (Item_field *) (subst->real_item());
    if (subst && !field->eq(subst->field))
      return subst;
  }
  return this;
}

Project: server

Item_case_expr::this_item()
{
  DBUG_ASSERT(m_sp == m_thd->spcont->sp);

  return m_thd->spcont->get_case_expr(m_case_expr_id);
}

Project: server

void Item_cache_row::set_null()
{
  Item_cache::set_null();
  if (!values)
    return;
  for (uint i= 0; i < item_count; i++)
    values[i]->set_null();
};

Project: server

Item_case_expr::this_item() const
{
  DBUG_ASSERT(m_sp == m_thd->spcont->sp);

  return m_thd->spcont->get_case_expr(m_case_expr_id);
}

Project: server

Item_decimal::Item_decimal(const uchar *bin, int precision, int scale)
{
  binary2my_decimal(E_DEC_FATAL_ERROR, bin,
                    &decimal_value, precision, scale);
  decimals= (uint8) decimal_value.frac;
  fixed= 1;
  max_length= my_decimal_precision_to_length_no_truncation(precision, decimals,
                                                           unsigned_flag);
}

Project: server

void Item_ident::cleanup()
{
  DBUG_ENTER("Item_ident::cleanup");
  bool was_fixed= fixed;
  Item::cleanup();
  db_name= orig_db_name; 
  table_name= orig_table_name;
  field_name= orig_field_name;
  /* Store if this Item was depended */
  if (was_fixed)
  {
    /*
      We can trust that depended_from set correctly only if this item
      was fixed
    */
    can_be_depended= test(depended_from);
  }
  DBUG_VOID_RETURN;
}

Project: server

Item_uint::Item_uint(const char *str_arg, longlong i, uint length):
  Item_int(str_arg, i, length)
{
  unsigned_flag= 1;
}

Project: server

bool Item_sp_variable::fix_fields(THD *thd, Item **)
{
  Item *it;

  m_thd= thd; /* NOTE: this must be set before any this_xxx() */
  it= this_item();

  DBUG_ASSERT(it->fixed);

  max_length= it->max_length;
  decimals= it->decimals;
  unsigned_flag= it->unsigned_flag;
  fixed= 1;
  collation.set(it->collation.collation, it->collation.derivation);

  return FALSE;
}

Project: server

left_is_superset(DTCollation *left, DTCollation *right)
{
  /* Allow convert to Unicode */
  if (left->collation->state & MY_CS_UNICODE &&
      (left->derivation < right->derivation ||
       (left->derivation == right->derivation &&
        (!(right->collation->state & MY_CS_UNICODE) ||
         /* The code below makes 4-byte utf8 a superset over 3-byte utf8 */
         (left->collation->state & MY_CS_UNICODE_SUPPLEMENT &&
          !(right->collation->state & MY_CS_UNICODE_SUPPLEMENT) &&
          left->collation->mbmaxlen > right->collation->mbmaxlen &&
          left->collation->mbminlen == right->collation->mbminlen)))))
    return TRUE;
  /* Allow convert from ASCII */
  if (right->repertoire == MY_REPERTOIRE_ASCII &&
      (left->derivation < right->derivation ||
       (left->derivation == right->derivation &&
        !(left->repertoire == MY_REPERTOIRE_ASCII))))
    return TRUE;
  /* Disallow conversion otherwise */
  return FALSE;
}

Project: server

void Item_hex_hybrid::print(String *str, enum_query_type query_type)
{
  uint32 len= min(str_value.length(), sizeof(longlong));
  const char *ptr= str_value.ptr() + str_value.length() - len;
  str->append("0x");
  str->append_hex(ptr, len);
}

Project: server

bool Item_param::set_from_user_var(THD *thd, const user_var_entry *entry)
{
  DBUG_ENTER("Item_param::set_from_user_var");
  if (entry && entry->value)
  {
    item_result_type= entry->type;
    unsigned_flag= entry->unsigned_flag;
    if (limit_clause_param)
    {
      bool unused;
      set_int(entry->val_int(&unused), MY_INT64_NUM_DECIMAL_DIGITS);
      item_type= Item::INT_ITEM;
      DBUG_RETURN(!unsigned_flag && value.integer < 0 ? 1 : 0);
    }
    switch (item_result_type) {
    case REAL_RESULT:
      set_double(*(double*)entry->value);
      item_type= Item::REAL_ITEM;
      param_type= MYSQL_TYPE_DOUBLE;
      break;
    case INT_RESULT:
      set_int(*(longlong*)entry->value, MY_INT64_NUM_DECIMAL_DIGITS);
      item_type= Item::INT_ITEM;
      param_type= MYSQL_TYPE_LONGLONG;
      break;
    case STRING_RESULT:
    {
      CHARSET_INFO *fromcs= entry->collation.collation;
      CHARSET_INFO *tocs= thd->variables.collation_connection;
      uint32 dummy_offset;

      value.cs_info.character_set_of_placeholder= fromcs;
      value.cs_info.character_set_client= thd->variables.character_set_client;
      /*
        Setup source and destination character sets so that they
        are different only if conversion is necessary: this will
        make later checks easier.
      */
      value.cs_info.final_character_set_of_str_value=
        String::needs_conversion(0, fromcs, tocs, &dummy_offset) ?
        tocs : fromcs;
      /*
        Exact value of max_length is not known unless data is converted to
        charset of connection, so we have to set it later.
      */
      item_type= Item::STRING_ITEM;
      param_type= MYSQL_TYPE_VARCHAR;

      if (set_str((const char *)entry->value, entry->length))
        DBUG_RETURN(1);
      break;
    }
    case DECIMAL_RESULT:
    {
      const my_decimal *ent_value= (const my_decimal *)entry->value;
      my_decimal2decimal(ent_value, &decimal_value);
      state= DECIMAL_VALUE;
      decimals= ent_value->frac;
      max_length=
        my_decimal_precision_to_length_no_truncation(ent_value->precision(),
                                                     decimals, unsigned_flag);
      item_type= Item::DECIMAL_ITEM;
      param_type= MYSQL_TYPE_NEWDECIMAL;
      break;
    }
    case ROW_RESULT:
    case TIME_RESULT:
    case IMPOSSIBLE_RESULT:
      DBUG_ASSERT(0);
      set_null();
    }
  }
  else
    set_null();

  DBUG_RETURN(0);
}

Project: server

String* Item_cache_decimal::val_str(String *str)
{
  DBUG_ASSERT(fixed);
  if (!has_value())
    return NULL;
  my_decimal_round(E_DEC_FATAL_ERROR, &decimal_value, decimals, FALSE,
                   &decimal_value);
  my_decimal2string(E_DEC_FATAL_ERROR, &decimal_value, 0, 0, 0, str);
  return str;
}

Project: server

int Item_copy_int::save_in_field(Field *field, bool no_conversions)
{
  return save_int_value_in_field(field, cached_value, 
                                 null_value, unsigned_flag);
}

Project: server

longlong Item_field::val_int_result()
{
  if ((null_value=result_field->is_null()))
    return 0;
  return result_field->val_int();
}

Project: server

st_select_lex *Item_ident::get_depended_from() const
{
  st_select_lex *dep;
  if ((dep= depended_from))
    for ( ; dep->merged_into; dep= dep->merged_into) ;
  return dep;
}

Project: server

Item_name_const::Item_name_const(Item *name_arg, Item *val):
    value_item(val), name_item(name_arg)
{
  Item::maybe_null= TRUE;
  valid_args= true;
  if (!name_item->basic_const_item())
    goto err;

  if (value_item->basic_const_item())
    return; // ok

  if (value_item->type() == FUNC_ITEM)
  {
    Item_func *value_func= (Item_func *) value_item;
    if (value_func->functype() != Item_func::COLLATE_FUNC &&
        value_func->functype() != Item_func::NEG_FUNC)
      goto err;

    if (value_func->key_item()->basic_const_item())
      return; // ok
  }

err:
  valid_args= false;
  my_error(ER_WRONG_ARGUMENTS, MYF(0), "NAME_CONST");
}

Project: server

double Item_param::val_real()
{
  switch (state) {
  case REAL_VALUE:
    return value.real;
  case INT_VALUE:
    return (double) value.integer;
  case DECIMAL_VALUE:
  {
    double result;
    my_decimal2double(E_DEC_FATAL_ERROR, &decimal_value, &result);
    return result;
  }
  case STRING_VALUE:
  case LONG_DATA_VALUE:
  {
    int dummy_err;
    char *end_not_used;
    return my_strntod(str_value.charset(), (char*) str_value.ptr(),
                      str_value.length(), &end_not_used, &dummy_err);
  }
  case TIME_VALUE:
    /*
      This works for example when user says SELECT ?+0.0 and supplies
      time value for the placeholder.
    */
    return ulonglong2double(TIME_to_ulonglong(&value.time));
  case NULL_VALUE:
    return 0.0;
  default:
    DBUG_ASSERT(0);
  }
  return 0.0;
}

Project: server

double Item_copy_decimal::val_real()
{
  if (null_value)
    return 0.0;
  else
  {
    double result;
    my_decimal2double(E_DEC_FATAL_ERROR, &cached_value, &result);
    return result;
  }
}

Project: server

bool Item_field::register_field_in_bitmap(uchar *arg)
{
  MY_BITMAP *bitmap= (MY_BITMAP *) arg;
  DBUG_ASSERT(bitmap);
  bitmap_set_bit(bitmap, field->field_index);
  return 0;
}

Project: server

int Item_copy_string::save_in_field(Field *field, bool no_conversions)
{
  return save_str_value_in_field(field, &str_value);
}

Project: server

void my_coll_agg_error(Item** args, uint count, const char *fname,
                       int item_sep)
{
  if (count == 2)
    my_coll_agg_error(args[0]->collation, args[item_sep]->collation, fname);
  else if (count == 3)
    my_coll_agg_error(args[0]->collation, args[item_sep]->collation,
                      args[2*item_sep]->collation, fname);
  else
    my_error(ER_CANT_AGGREGATE_NCOLLATIONS,MYF(0),fname);
}

Project: server

my_decimal *Item_cache_wrapper::val_decimal(my_decimal* decimal_value)
{
  Item *cached_value;
  DBUG_ENTER("Item_cache_wrapper::val_decimal");
  if (!expr_cache)
  {
    my_decimal *tmp= orig_item->val_decimal(decimal_value);
    null_value= orig_item->null_value;
    DBUG_RETURN(tmp);
  }

  if ((cached_value= check_cache()))
  {
    my_decimal *tmp= cached_value->val_decimal(decimal_value);
    null_value= cached_value->null_value;
    DBUG_RETURN(tmp);
  }
  cache();
  if ((null_value= expr_value->null_value))
    DBUG_RETURN(NULL);
  DBUG_RETURN(expr_value->val_decimal(decimal_value));
}

Project: server

String *Item_float::val_str(String *str)
{
  // following assert is redundant, because fixed=1 assigned in constructor
  DBUG_ASSERT(fixed == 1);
  str->set_real(value,decimals,&my_charset_bin);
  return str;
}

Project: server

void Hybrid_type_traits_decimal::div(Hybrid_type *val, ulonglong u) const
{
  int2my_decimal(E_DEC_FATAL_ERROR, u, TRUE, &val->dec_buf[2]);
  /* XXX: what is '4' for scale? */
  my_decimal_div(E_DEC_FATAL_ERROR,
                 &val->dec_buf[val->used_dec_buf_no ^ 1],
                 &val->dec_buf[val->used_dec_buf_no],
                 &val->dec_buf[2], 4);
  val->used_dec_buf_no^= 1;
}

Project: server

Item *Item_direct_view_ref::replace_equal_field(uchar *arg)
{
  Item *field_item= real_item();
  if (field_item->type() != FIELD_ITEM)
    return this;
  field_item->set_item_equal(item_equal);
  Item *item= field_item->replace_equal_field(arg);
  field_item->set_item_equal(0);
  return item != field_item ? item : this;
}

Project: server

Item *Item_static_float_func::safe_charset_converter(CHARSET_INFO *tocs)
{
  Item_string *conv;
  char buf[64];
  String *s, tmp(buf, sizeof(buf), &my_charset_bin);
  s= val_str(&tmp);
  if ((conv= new Item_static_string_func(func_name, s->ptr(), s->length(),
                                         s->charset())))
  {
    conv->str_value.copy();
    conv->str_value.mark_as_const();
  }
  return conv;
}

Project: server

Item::Item(THD *thd, Item *item):
  join_tab_idx(item->join_tab_idx),
  is_expensive_cache(-1),
  rsize(0),
  str_value(item->str_value),
  name(item->name),
  orig_name(item->orig_name),
  max_length(item->max_length),
  name_length(item->name_length),
  decimals(item->decimals),
  marker(item->marker),
  maybe_null(item->maybe_null),
  in_rollup(item->in_rollup),
  null_value(item->null_value),
  unsigned_flag(item->unsigned_flag),
  with_sum_func(item->with_sum_func),
  with_field(item->with_field),
  fixed(item->fixed),
  is_autogenerated_name(item->is_autogenerated_name),
  with_subselect(item->has_subquery()),
  collation(item->collation),
  cmp_context(item->cmp_context)
{
  next= thd->free_list;				// Put in free list
  thd->free_list= this;
}

Project: server

void Item::split_sum_func2(THD *thd, Item **ref_pointer_array,
                           List<Item> &fields, Item **ref, 
                           bool skip_registered)
{
  /* An item of type Item_sum  is registered <=> ref_by != 0 */ 
  if (type() == SUM_FUNC_ITEM && skip_registered && 
      ((Item_sum *) this)->ref_by)
    return;
  if ((type() != SUM_FUNC_ITEM && with_sum_func) ||
      (type() == FUNC_ITEM &&
       (((Item_func *) this)->functype() == Item_func::ISNOTNULLTEST_FUNC ||
        ((Item_func *) this)->functype() == Item_func::TRIG_COND_FUNC)))
  {
    /* Will split complicated items and ignore simple ones */
    split_sum_func(thd, ref_pointer_array, fields);
  }
  else if ((type() == SUM_FUNC_ITEM || (used_tables() & ~PARAM_TABLE_BIT)) &&
           type() != SUBSELECT_ITEM &&
           (type() != REF_ITEM ||
           ((Item_ref*)this)->ref_type() == Item_ref::VIEW_REF))
  {
    /*
      Replace item with a reference so that we can easily calculate
      it (in case of sum functions) or copy it (in case of fields)

      The test above is to ensure we don't do a reference for things
      that are constants (PARAM_TABLE_BIT is in effect a constant)
      or already referenced (for example an item in HAVING)
      Exception is Item_direct_view_ref which we need to convert to
      Item_ref to allow fields from view being stored in tmp table.
    */
    Item_aggregate_ref *item_ref;
    uint el= fields.elements;
    DBUG_ASSERT(fields.elements <=
                thd->lex->current_select->ref_pointer_array_size);
    /*
      If this is an item_ref, get the original item
      This is a safety measure if this is called for things that is
      already a reference.
    */
    Item *real_itm= real_item();

    ref_pointer_array[el]= real_itm;
    if (!(item_ref= new Item_aggregate_ref(&thd->lex->current_select->context,
                                           ref_pointer_array + el, 0, name)))
      return;                                   // fatal_error is set
    if (type() == SUM_FUNC_ITEM)
      item_ref->depended_from= ((Item_sum *) this)->depended_from(); 
    fields.push_front(real_itm);
    thd->change_item_tree(ref, item_ref);
  }
}

Project: server

bool Item_field::get_date_result(MYSQL_TIME *ltime, ulonglong fuzzydate)
{
  if (result_field->is_null() || result_field->get_date(ltime,fuzzydate))
  {
    bzero((char*) ltime,sizeof(*ltime));
    return (null_value= 1);
  }
  return (null_value= 0);
}

Project: server

void Item_cache_wrapper::save_val(Field *to)
{
  Item *cached_value;
  DBUG_ENTER("Item_cache_wrapper::val_int");
  if (!expr_cache)
  {
    orig_item->save_val(to);
    null_value= orig_item->null_value;
    DBUG_VOID_RETURN;
  }

  if ((cached_value= check_cache()))
  {
    cached_value->save_val(to);
    null_value= cached_value->null_value;
    DBUG_VOID_RETURN;
  }
  cache();
  null_value= expr_value->null_value;
  expr_value->save_val(to);
  DBUG_VOID_RETURN;
}

Project: server

my_decimal *Item_string::val_decimal(my_decimal *decimal_value)
{
  return val_decimal_from_string(decimal_value);
}

Project: server

double Item_copy_string::val_real()
{
  int err_not_used;
  char *end_not_used;
  return (null_value ? 0.0 :
          my_strntod(str_value.charset(), (char*) str_value.ptr(),
                     str_value.length(), &end_not_used, &err_not_used));
}

Project: server

bool Item_field::set_no_const_sub(uchar *arg)
{
  if (field->charset() != &my_charset_bin)
    no_const_subst=1;
  return FALSE;
}

Project: server

double_from_string_with_check(CHARSET_INFO *cs, const char *cptr,
                              const char *end)
{
  int error;
  char *end_of_num= (char*) end;
  double tmp;

  tmp= my_strntod(cs, (char*) cptr, end - cptr, &end_of_num, &error);
  if (error || (end != end_of_num &&
                !check_if_only_end_space(cs, end_of_num, end)))
  {
    ErrConvString err(cptr, end - cptr, cs);
    /*
      We can use err.ptr() here as ErrConvString is guranteed to put an
      end \0 here.
    */
    push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
                        ER_TRUNCATED_WRONG_VALUE,
                        ER(ER_TRUNCATED_WRONG_VALUE), "DOUBLE",
                        err.ptr());
  }
  return tmp;
}

Project: server

Item_float::Item_float(const char *str_arg, uint length)
{
  int error;
  char *end_not_used;
  value= my_strntod(&my_charset_bin, (char*) str_arg, length, &end_not_used,
                    &error);
  if (error)
  {
    char tmp[NAME_LEN + 1];
    my_snprintf(tmp, sizeof(tmp), "%.*s", length, str_arg);
    my_error(ER_ILLEGAL_VALUE_FOR_TYPE, MYF(0), "double", tmp);
  }
  presentation= name=(char*) str_arg;
  decimals=(uint8) nr_of_decimals(str_arg, str_arg+length);
  max_length=length;
  fixed= 1;
}

Project: server

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

  // We do not check fields which are fixed during construction
  DBUG_ASSERT(fixed == 0 || basic_const_item());
  fixed= 1;
  return FALSE;
}

Project: server

Hybrid_type_traits::val_str(Hybrid_type *val, String *to, uint8 decimals) const
{
  to->set_real(val->real, decimals, &my_charset_bin);
  return to;
}

Project: server

Item_copy *Item_copy::create (Item *item)
{
  switch (item->result_type())
  {
    case STRING_RESULT:
      return new Item_copy_string (item);
    case REAL_RESULT: 
      return new Item_copy_float (item);
    case INT_RESULT:
      return item->unsigned_flag ? 
        new Item_copy_uint (item) : new Item_copy_int (item);
    case DECIMAL_RESULT:
      return new Item_copy_decimal (item);
    case TIME_RESULT:
    case ROW_RESULT:
  case IMPOSSIBLE_RESULT:
      DBUG_ASSERT (0);
  }
  /* should not happen */
  return NULL;
}

Project: server

bool Item_direct_ref::val_bool()
{
  bool tmp= (*ref)->val_bool();
  null_value=(*ref)->null_value;
  return tmp;
}

Project: server

my_decimal *Item_copy_int::val_decimal(my_decimal *decimal_value)
{
  if (null_value)
    return (my_decimal *) 0;

  int2my_decimal(E_DEC_FATAL_ERROR, cached_value, unsigned_flag, decimal_value);
  return decimal_value;
}

Project: server

bool Item_ident::remove_dependence_processor(uchar * arg)
{
  DBUG_ENTER("Item_ident::remove_dependence_processor");
  if (get_depended_from() == (st_select_lex *) arg)
    depended_from= 0;
  context= &((st_select_lex *) arg)->context;
  DBUG_RETURN(0);
}

Project: server

bool Item_type_holder::join_types(THD *thd, Item *item)
{
  uint max_length_orig= max_length;
  uint decimals_orig= decimals;
  DBUG_ENTER("Item_type_holder::join_types");
  DBUG_PRINT("info:", ("was type %d len %d, dec %d name %s",
                       fld_type, max_length, decimals,
                       (name ? name : "<NULL>")));
  DBUG_PRINT("info:", ("in type %d len %d, dec %d",
                       get_real_type(item),
                       item->max_length, item->decimals));
  fld_type= Field::field_type_merge(fld_type, get_real_type(item));
  {
    uint item_decimals= item->decimals;
    /* fix variable decimals which always is NOT_FIXED_DEC */
    if (Field::result_merge_type(fld_type) == INT_RESULT)
      item_decimals= 0;
    decimals= max(decimals, item_decimals);
  }

  if (fld_type == FIELD_TYPE_GEOMETRY)
    geometry_type=
      Field_geom::geometry_type_merge(geometry_type, item->get_geometry_type());

  if (Field::result_merge_type(fld_type) == DECIMAL_RESULT)
  {
    decimals= min(max(decimals, item->decimals), DECIMAL_MAX_SCALE);
    int item_int_part= item->decimal_int_part();
    int item_prec = max(prev_decimal_int_part, item_int_part) + decimals;
    int precision= min(item_prec, DECIMAL_MAX_PRECISION);
    unsigned_flag&= item->unsigned_flag;
    max_length= my_decimal_precision_to_length_no_truncation(precision,
                                                             decimals,
                                                             unsigned_flag);
  }

  switch (Field::result_merge_type(fld_type))
  {
  case STRING_RESULT:
  {
    const char *old_cs, *old_derivation;
    uint32 old_max_chars= max_length / collation.collation->mbmaxlen;
    old_cs= collation.collation->name;
    old_derivation= collation.derivation_name();
    if (collation.aggregate(item->collation, MY_COLL_ALLOW_CONV))
    {
      my_error(ER_CANT_AGGREGATE_2COLLATIONS, MYF(0),
	       old_cs, old_derivation,
	       item->collation.collation->name,
	       item->collation.derivation_name(),
	       "UNION");
      DBUG_RETURN(TRUE);
    }
    /*
      To figure out max_length, we have to take into account possible
      expansion of the size of the values because of character set
      conversions.
     */
    if (collation.collation != &my_charset_bin)
    {
      max_length= max(old_max_chars * collation.collation->mbmaxlen,
                      display_length(item) /
                      item->collation.collation->mbmaxlen *
                      collation.collation->mbmaxlen);
    }
    else
      set_if_bigger(max_length, display_length(item));
    break;
  }
  case REAL_RESULT:
  {
    if (decimals != NOT_FIXED_DEC)
    {
      /*
        For FLOAT(M,D)/DOUBLE(M,D) do not change precision
         if both fields have the same M and D
      */
      if (item->max_length != max_length_orig ||
          item->decimals != decimals_orig)
      {
        int delta1= max_length_orig - decimals_orig;
        int delta2= item->max_length - item->decimals;
        max_length= max(delta1, delta2) + decimals;
        if (fld_type == MYSQL_TYPE_FLOAT && max_length > FLT_DIG + 2)
        {
          max_length= MAX_FLOAT_STR_LENGTH;
          decimals= NOT_FIXED_DEC;
        } 
        else if (fld_type == MYSQL_TYPE_DOUBLE && max_length > DBL_DIG + 2)
        {
          max_length= MAX_DOUBLE_STR_LENGTH;
          decimals= NOT_FIXED_DEC;
        }
      }
    }
    else
      max_length= (fld_type == MYSQL_TYPE_FLOAT) ? FLT_DIG+6 : DBL_DIG+7;
    break;
  }
  default:
    max_length= max(max_length, display_length(item));
  };
  maybe_null|= item->maybe_null;
  get_full_info(item);

  /* Remember decimal integer part to be used in DECIMAL_RESULT handleng */
  prev_decimal_int_part= decimal_int_part();
  DBUG_PRINT("info", ("become type: %d  len: %u  dec: %u",
                      (int) fld_type, max_length, (uint) decimals));
  DBUG_RETURN(FALSE);
}

Project: server

void Hybrid_type_traits::fix_length_and_dec(Item *item, Item *arg) const
{
  item->decimals= NOT_FIXED_DEC;
  item->max_length= item->float_length(arg->decimals);
}

Project: server

Item_type_holder::Item_type_holder(THD *thd, Item *item)
  :Item(thd, item), enum_set_typelib(0), fld_type(get_real_type(item))
{
  DBUG_ASSERT(item->fixed);
  maybe_null= item->maybe_null;
  collation.set(item->collation);
  get_full_info(item);
  /* fix variable decimals which always is NOT_FIXED_DEC */
  if (Field::result_merge_type(fld_type) == INT_RESULT)
    decimals= 0;
  prev_decimal_int_part= item->decimal_int_part();
#ifdef HAVE_SPATIAL
  if (item->field_type() == MYSQL_TYPE_GEOMETRY)
    geometry_type= item->get_geometry_type();
#endif /* HAVE_SPATIAL */
}

Project: server

Item *Item_cache::safe_charset_converter(CHARSET_INFO *tocs)
{
  if (!example)
    return Item::safe_charset_converter(tocs);
  Item *conv= example->safe_charset_converter(tocs);
  if (conv == example)
    return this;
  Item_cache *cache;
  if (!conv || conv->fix_fields(current_thd, (Item **) NULL) ||
      !(cache= new Item_cache_str(conv)))
    return NULL; // Safe conversion is not possible, or OEM
  cache->setup(conv);
  cache->fixed= false; // Make Item::fix_fields() happy
  return cache;
}

Project: server

Item_sp_variable::Item_sp_variable(char *sp_var_name_str,
                                   uint sp_var_name_length)
  :m_thd(0)
#ifndef DBUG_OFF
   , m_sp(0)
#endif
{
  m_name.str= sp_var_name_str;
  m_name.length= sp_var_name_length;
}

Project: server

bool Item_param::set_longdata(const char *str, ulong length)
{
  DBUG_ENTER("Item_param::set_longdata");

  /*
    If client character set is multibyte, end of long data packet
    may hit at the middle of a multibyte character.  Additionally,
    if binary log is open we must write long data value to the
    binary log in character set of client. This is why we can't
    convert long data to connection character set as it comes
    (here), and first have to concatenate all pieces together,
    write query to the binary log and only then perform conversion.
  */
  if (str_value.length() + length > max_long_data_size)
  {
    my_message(ER_UNKNOWN_ERROR,
               "Parameter of prepared statement which is set through "
               "mysql_send_long_data() is longer than "
               "'max_long_data_size' bytes",
               MYF(0));
    DBUG_RETURN(true);
  }

  if (str_value.append(str, length, &my_charset_bin))
    DBUG_RETURN(TRUE);
  state= LONG_DATA_VALUE;
  maybe_null= 0;

  DBUG_RETURN(FALSE);
}

Project: server

int Item::save_str_value_in_field(Field *field, String *result)
{
  if (null_value)
    return set_field_to_null(field);
  field->set_notnull();
  return field->store(result->ptr(), result->length(),
		      collation.collation);
}

Project: server

bool Item_default_value::fix_fields(THD *thd, Item **items)
{
  Item *real_arg;
  Item_field *field_arg;
  Field *def_field;
  DBUG_ASSERT(fixed == 0);

  if (!arg)
  {
    fixed= 1;
    return FALSE;
  }
  if (!arg->fixed && arg->fix_fields(thd, &arg))
    goto error;


  real_arg= arg->real_item();
  if (real_arg->type() != FIELD_ITEM)
  {
    my_error(ER_NO_DEFAULT_FOR_FIELD, MYF(0), arg->name);
    goto error;
  }

  field_arg= (Item_field *)real_arg;
  if (field_arg->field->flags & NO_DEFAULT_VALUE_FLAG)
  {
    my_error(ER_NO_DEFAULT_FOR_FIELD, MYF(0), field_arg->field->field_name);
    goto error;
  }
  if (!(def_field= (Field*) sql_alloc(field_arg->field->size_of())))
    goto error;
  memcpy((void *)def_field, (void *)field_arg->field, field_arg->field->size_of());
  def_field->move_field_offset((my_ptrdiff_t)
                               (def_field->table->s->default_values -
                                def_field->table->record[0]));
  set_field(def_field);
  return FALSE;

error:
  context->process_error(thd);
  return TRUE;
}

Project: server

bool Item_param::convert_str_value(THD *thd)
{
  bool rc= FALSE;
  if (state == STRING_VALUE || state == LONG_DATA_VALUE)
  {
    /*
      Check is so simple because all charsets were set up properly
      in setup_one_conversion_function, where typecode of
      placeholder was also taken into account: the variables are different
      here only if conversion is really necessary.
    */
    if (value.cs_info.final_character_set_of_str_value !=
        value.cs_info.character_set_of_placeholder)
    {
      rc= thd->convert_string(&str_value,
                              value.cs_info.character_set_of_placeholder,
                              value.cs_info.final_character_set_of_str_value);
    }
    else
      str_value.set_charset(value.cs_info.final_character_set_of_str_value);
    /* Here str_value is guaranteed to be in final_character_set_of_str_value */

    max_length= str_value.numchars() * str_value.charset()->mbmaxlen;

    /* For the strings converted to numeric form within some functions */
    decimals= NOT_FIXED_DEC;
    /*
      str_value_ptr is returned from val_str(). It must be not alloced
      to prevent it's modification by val_str() invoker.
    */
    str_value_ptr.set(str_value.ptr(), str_value.length(),
                      str_value.charset());
    /* Synchronize item charset with value charset */
    collation.set(str_value.charset(), DERIVATION_COERCIBLE);
  }
  return rc;
}

Project: server

static int save_int_value_in_field (Field *field, longlong nr, 
                                    bool null_value, bool unsigned_flag)
{
  if (null_value)
    return set_field_to_null(field);
  field->set_notnull();
  return field->store(nr, unsigned_flag);
}

Project: server

bool Item_cache_row::allocate(uint num)
{
  item_count= num;
  THD *thd= current_thd;
  return (!(values= 
	    (Item_cache **) thd->calloc(sizeof(Item_cache *)*item_count)));
}

Project: server

double Item::val_real_from_date()
{
  DBUG_ASSERT(fixed == 1);
  MYSQL_TIME ltime;
  if (get_date(&ltime, 0))
    return 0;
  return TIME_to_double(&ltime);
}

Project: server

my_decimal *Item_type_holder::val_decimal(my_decimal *)
{
  DBUG_ASSERT(0); // should never be called
  return 0;
}

Project: server

uint Item::decimal_precision() const
{
  Item_result restype= result_type();

  if ((restype == DECIMAL_RESULT) || (restype == INT_RESULT))
  {
    uint prec= 
      my_decimal_length_to_precision(max_char_length(), decimals,
                                     unsigned_flag);
    return min(prec, DECIMAL_MAX_PRECISION);
  }
  return min(max_char_length(), DECIMAL_MAX_PRECISION);
}

Project: server

int Item_cache_temporal::save_in_field(Field *field, bool no_conversions)
{
  MYSQL_TIME ltime;
  if (get_date(&ltime, 0))
    return set_field_to_null_with_conversions(field, no_conversions);
  field->set_notnull();
  int error= field->store_time_dec(&ltime, decimals);
  return error ? error : field->table->in_use->is_error() ? 1 : 0;
}

Project: server

double Item_sp_variable::val_real()
{
  DBUG_ASSERT(fixed);
  Item *it= this_item();
  double ret= it->val_real();
  null_value= it->null_value;
  return ret;
}

Project: server

Item_num *Item_uint::neg()
{
  Item_decimal *item= new Item_decimal(value, 1);
  return item->neg();
}

Project: server

my_decimal *Item_ref::val_decimal(my_decimal *decimal_value)
{
  my_decimal *val= (*ref)->val_decimal_result(decimal_value);
  null_value= (*ref)->null_value;
  return val;
}

Project: server

double Item_cache_real::val_real()
{
  DBUG_ASSERT(fixed == 1);
  if (!has_value())
    return 0.0;
  return value;
}

Project: server

double Item_name_const::val_real()
{
  DBUG_ASSERT(fixed);
  double ret= value_item->val_real();
  null_value= value_item->null_value;
  return ret;
}

Project: server

bool Item_field::add_field_to_set_processor(uchar *arg)
{
  DBUG_ENTER("Item_field::add_field_to_set_processor");
  DBUG_PRINT("info", ("%s", field->field_name ? field->field_name : "noname"));
  TABLE *table= (TABLE *) arg;
  if (field->table == table)
    bitmap_set_bit(&table->tmp_set, field->field_index);
  DBUG_RETURN(FALSE);
}

Project: server

table_map Item_field::used_tables() const
{
  if (field->table->const_table)
    return 0;					// const item
  return (get_depended_from() ? OUTER_REF_TABLE_BIT : field->table->map);
}

Project: server

void Item_trigger_field::setup_field(THD *thd, TABLE *table,
                                     GRANT_INFO *table_grant_info)
{
  /*
    It is too early to mark fields used here, because before execution
    of statement that will invoke trigger other statements may use same
    TABLE object, so all such mark-up will be wiped out.
    So instead we do it in Table_triggers_list::mark_fields_used()
    method which is called during execution of these statements.
  */
  enum_mark_columns save_mark_used_columns= thd->mark_used_columns;
  thd->mark_used_columns= MARK_COLUMNS_NONE;
  /*
    Try to find field by its name and if it will be found
    set field_idx properly.
  */
  (void)find_field_in_table(thd, table, field_name, (uint) strlen(field_name),
                            0, &field_idx);
  thd->mark_used_columns= save_mark_used_columns;
  triggers= table->triggers;
  table_grants= table_grant_info;
}

Project: server

my_decimal *Item_int::val_decimal(my_decimal *decimal_value)
{
  int2my_decimal(E_DEC_FATAL_ERROR, value, unsigned_flag, decimal_value);
  return decimal_value;
}

Project: server

void Item_type_holder::get_full_info(Item *item)
{
  if (fld_type == MYSQL_TYPE_ENUM ||
      fld_type == MYSQL_TYPE_SET)
  {
    if (item->type() == Item::SUM_FUNC_ITEM &&
        (((Item_sum*)item)->sum_func() == Item_sum::MAX_FUNC ||
         ((Item_sum*)item)->sum_func() == Item_sum::MIN_FUNC))
      item = ((Item_sum*)item)->get_arg(0);
    /*
      We can have enum/set type after merging only if we have one enum|set
      field (or MIN|MAX(enum|set field)) and number of NULL fields
    */
    DBUG_ASSERT((enum_set_typelib &&
                 get_real_type(item) == MYSQL_TYPE_NULL) ||
                (!enum_set_typelib &&
                 item->real_item()->type() == Item::FIELD_ITEM &&
                 (get_real_type(item->real_item()) == MYSQL_TYPE_ENUM ||
                  get_real_type(item->real_item()) == MYSQL_TYPE_SET) &&
                 ((Field_enum*)((Item_field *) item->real_item())->field)->typelib));
    if (!enum_set_typelib)
    {
      enum_set_typelib= ((Field_enum*)((Item_field *) item->real_item())->field)->typelib;
    }
  }
}

Project: server

String *Item::val_string_from_date(String *str)
{
  MYSQL_TIME ltime;
  if (get_date(&ltime,
               field_type() == MYSQL_TYPE_TIME ? TIME_TIME_ONLY : 0) ||
      str->alloc(MAX_DATE_STRING_REP_LENGTH))
  {
    null_value= 1;
    return (String *) 0;
  }
  str->length(my_TIME_to_str(&ltime, const_cast<char*>(str->ptr()), decimals));
  str->set_charset(&my_charset_numeric);
  return str;
}

Project: server

my_decimal *Item_direct_ref::val_decimal(my_decimal *decimal_value)
{
  my_decimal *tmp= (*ref)->val_decimal(decimal_value);
  null_value=(*ref)->null_value;
  return tmp;
}

Project: server

Item::Type Item_name_const::type() const
{
  /*
    As 
    1. one can try to create the Item_name_const passing non-constant 
    arguments, although it's incorrect and 
    2. the type() method can be called before the fix_fields() to get
    type information for a further type cast, e.g. 
    if (item->type() == FIELD_ITEM) 
      ((Item_field *) item)->... 
    we return NULL_ITEM in the case to avoid wrong casting.

    valid_args guarantees value_item->basic_const_item(); if type is
    FUNC_ITEM, then we have a fudged item_func_neg() on our hands
    and return the underlying type.
    For Item_func_set_collation()
    e.g. NAME_CONST('name', 'value' COLLATE collation) we return its
    'value' argument type. 
  */
  if (!valid_args)
    return NULL_ITEM;
  Item::Type value_type= value_item->type();
  if (value_type == FUNC_ITEM)
  {
    /* 
      The second argument of NAME_CONST('name', 'value') must be 
      a simple constant item or a NEG_FUNC/COLLATE_FUNC.
    */
    DBUG_ASSERT(((Item_func *) value_item)->functype() == 
                Item_func::NEG_FUNC ||
                ((Item_func *) value_item)->functype() == 
                Item_func::COLLATE_FUNC);
    return ((Item_func *) value_item)->key_item()->type();            
  }
  return value_type;
}

Project: server

table_map Item_direct_view_ref::used_tables() const
{
  DBUG_ASSERT(fixed);

  if (get_depended_from())
    return OUTER_REF_TABLE_BIT;

  if (view->is_merged_derived() || view->merged || !view->table)
  {
    table_map used= (*ref)->used_tables();
    return (used ?
            used :
            ((null_ref_table != NO_NULL_TABLE) ?
             null_ref_table->map :
             (table_map)0 ));
  }
  return view->table->map;
}

Project: server

bool Item_ref::fix_fields(THD *thd, Item **reference)
{
  enum_parsing_place place= NO_MATTER;
  DBUG_ASSERT(fixed == 0);
  SELECT_LEX *current_sel= thd->lex->current_select;

  if (set_properties_only)
  {
    /* do nothing */
  }
  else if (!ref || ref == not_found_item)
  {
    DBUG_ASSERT(reference_trough_name != 0);
    if (!(ref= resolve_ref_in_select_and_group(thd, this,
                                               context->select_lex)))
      goto error;             /* Some error occurred (e.g. ambiguous names). */

    if (ref == not_found_item) /* This reference was not resolved. */
    {
      Name_resolution_context *last_checked_context= context;
      Name_resolution_context *outer_context= context->outer_context;
      Field *from_field;
      ref= 0;

      if (!outer_context)
      {
        /* The current reference cannot be resolved in this query. */
        my_error(ER_BAD_FIELD_ERROR,MYF(0),
                 this->full_name(), thd->where);
        goto error;
      }

      /*
        If there is an outer context (select), and it is not a derived table
        (which do not support the use of outer fields for now), try to
        resolve this reference in the outer select(s).

        We treat each subselect as a separate namespace, so that different
        subselects may contain columns with the same names. The subselects are
        searched starting from the innermost.
      */
      from_field= (Field*) not_found_field;

      do
      {
        SELECT_LEX *select= outer_context->select_lex;
        Item_subselect *prev_subselect_item=
          last_checked_context->select_lex->master_unit()->item;
        last_checked_context= outer_context;

        /* Search in the SELECT and GROUP lists of the outer select. */
        if (outer_context->resolve_in_select_list)
        {
          if (!(ref= resolve_ref_in_select_and_group(thd, this, select)))
            goto error; /* Some error occurred (e.g. ambiguous names). */
          if (ref != not_found_item)
          {
            DBUG_ASSERT(*ref && (*ref)->fixed);
            prev_subselect_item->used_tables_cache|= (*ref)->used_tables();
            prev_subselect_item->const_item_cache&= (*ref)->const_item();
            break;
          }
          /*
            Set ref to 0 to ensure that we get an error in case we replaced
            this item with another item and still use this item in some
            other place of the parse tree.
          */
          ref= 0;
        }

        place= prev_subselect_item->parsing_place;
        /*
          Check table fields only if the subquery is used somewhere out of
          HAVING or the outer SELECT does not use grouping (i.e. tables are
          accessible).
          TODO:
          Here we could first find the field anyway, and then test this
          condition, so that we can give a better error message -
          ER_WRONG_FIELD_WITH_GROUP, instead of the less informative
          ER_BAD_FIELD_ERROR which we produce now.
        */
        if ((place != IN_HAVING ||
             (!select->with_sum_func &&
              select->group_list.elements == 0)))
        {
          /*
            In case of view, find_field_in_tables() write pointer to view
            field expression to 'reference', i.e. it substitute that
            expression instead of this Item_ref
          */
          from_field= find_field_in_tables(thd, this,
                                           outer_context->
                                             first_name_resolution_table,
                                           outer_context->
                                             last_name_resolution_table,
                                           reference,
                                           IGNORE_EXCEPT_NON_UNIQUE,
                                           TRUE, TRUE);
          if (! from_field)
            goto error;
          if (from_field == view_ref_found)
          {
            Item::Type refer_type= (*reference)->type();
            prev_subselect_item->used_tables_cache|=
              (*reference)->used_tables();
            prev_subselect_item->const_item_cache&=
              (*reference)->const_item();
            DBUG_ASSERT((*reference)->type() == REF_ITEM);
            mark_as_dependent(thd, last_checked_context->select_lex,
                              context->select_lex, this,
                              ((refer_type == REF_ITEM ||
                                refer_type == FIELD_ITEM) ?
                               (Item_ident*) (*reference) :
                               0));
            /*
              view reference found, we substituted it instead of this
              Item, so can quit
            */
            return FALSE;
          }
          if (from_field != not_found_field)
          {
            if (cached_table && cached_table->select_lex &&
                outer_context->select_lex &&
                cached_table->select_lex != outer_context->select_lex)
            {
              /*
                Due to cache, find_field_in_tables() can return field which
                doesn't belong to provided outer_context. In this case we have
                to find proper field context in order to fix field correcly.
              */
              do
              {
                outer_context= outer_context->outer_context;
                select= outer_context->select_lex;
                prev_subselect_item=
                  last_checked_context->select_lex->master_unit()->item;
                last_checked_context= outer_context;
              } while (outer_context && outer_context->select_lex &&
                       cached_table->select_lex != outer_context->select_lex);
            }
            prev_subselect_item->used_tables_cache|= from_field->table->map;
            prev_subselect_item->const_item_cache= 0;
            break;
          }
        }
        DBUG_ASSERT(from_field == not_found_field);

        /* Reference is not found => depend on outer (or just error). */
        prev_subselect_item->used_tables_cache|= OUTER_REF_TABLE_BIT;
        prev_subselect_item->const_item_cache= 0;

        outer_context= outer_context->outer_context;
      } while (outer_context);

      DBUG_ASSERT(from_field != 0 && from_field != view_ref_found);
      if (from_field != not_found_field)
      {
        Item_field* fld;
        if (!(fld= new Item_field(from_field)))
          goto error;
        thd->change_item_tree(reference, fld);
        mark_as_dependent(thd, last_checked_context->select_lex,
                          current_sel, fld, fld);
        /*
          A reference is resolved to a nest level that's outer or the same as
          the nest level of the enclosing set function : adjust the value of
          max_arg_level for the function if it's needed.
        */
        if (thd->lex->in_sum_func &&
            thd->lex->in_sum_func->nest_level >= 
            last_checked_context->select_lex->nest_level)
          set_if_bigger(thd->lex->in_sum_func->max_arg_level,
                        last_checked_context->select_lex->nest_level);
        return FALSE;
      }
      if (ref == 0)
      {
        /* The item was not a table field and not a reference */
        my_error(ER_BAD_FIELD_ERROR, MYF(0),
                 this->full_name(), thd->where);
        goto error;
      }
      /* Should be checked in resolve_ref_in_select_and_group(). */
      DBUG_ASSERT(*ref && (*ref)->fixed);
      mark_as_dependent(thd, last_checked_context->select_lex,
                        context->select_lex, this, this);
      /*
        A reference is resolved to a nest level that's outer or the same as
        the nest level of the enclosing set function : adjust the value of
        max_arg_level for the function if it's needed.
      */
      if (thd->lex->in_sum_func &&
          thd->lex->in_sum_func->nest_level >= 
          last_checked_context->select_lex->nest_level)
        set_if_bigger(thd->lex->in_sum_func->max_arg_level,
                      last_checked_context->select_lex->nest_level);
    }
  }
  else if (ref_type() != VIEW_REF)
  {
    /*
      It could be that we're referring to something that's in ancestor selects.
      We must make an appropriate mark_as_dependent() call for each such
      outside reference.
    */
    Dependency_marker dep_marker;
    dep_marker.current_select= current_sel;
    dep_marker.thd= thd;
    (*ref)->walk(&Item::enumerate_field_refs_processor, FALSE,
                 (uchar*)&dep_marker);
  }

  DBUG_ASSERT(*ref);
  /*
    Check if this is an incorrect reference in a group function or forward
    reference. Do not issue an error if this is:
      1. outer reference (will be fixed later by the fix_inner_refs function);
      2. an unnamed reference inside an aggregate function.
  */
  if (!((*ref)->type() == REF_ITEM &&
       ((Item_ref *)(*ref))->ref_type() == OUTER_REF) &&
      (((*ref)->with_sum_func && name &&
        !(current_sel->linkage != GLOBAL_OPTIONS_TYPE &&
          current_sel->having_fix_field)) ||
       !(*ref)->fixed))
  {
    my_error(ER_ILLEGAL_REFERENCE, MYF(0),
             name, ((*ref)->with_sum_func?
                    "reference to group function":
                    "forward reference in item list"));
    goto error;
  }

  set_properties();

  if ((*ref)->check_cols(1))
    goto error;
  return FALSE;

error:
  context->process_error(thd);
  return TRUE;
}

Project: server

String *Item_name_const::val_str(String *sp)
{
  DBUG_ASSERT(fixed);
  String *ret= value_item->val_str(sp);
  null_value= value_item->null_value;
  return ret;
}

Project: server

Item_cache* Item_cache::get_cache(const Item *item)
{
  return get_cache(item, item->cmp_type());
}

Project: server

double Item_type_holder::val_real()
{
  DBUG_ASSERT(0); // should never be called
  return 0.0;
}

Project: server

my_decimal *Item::val_decimal_from_date(my_decimal *decimal_value)
{
  DBUG_ASSERT(fixed == 1);
  MYSQL_TIME ltime;
  if (get_date(&ltime, 0))
  {
    my_decimal_set_zero(decimal_value);
    null_value= 1;                               // set NULL, stop processing
    return 0;
  }
  return date2my_decimal(&ltime, decimal_value);
}

Project: server

const Hybrid_type_traits *Hybrid_type_traits::instance()
{
  return &real_traits_instance;
}

Project: server

bool Item_field::subst_argument_checker(uchar **arg)
{
  return *arg &&
         (*arg == (uchar *) Item::ANY_SUBST ||
          result_type() != STRING_RESULT || 
          (field->flags & BINARY_FLAG));
}

Project: server

bool Item::cache_const_expr_analyzer(uchar **arg)
{
  bool *cache_flag= (bool*)*arg;
  if (!*cache_flag)
  {
    Item *item= real_item();
    /*
      Cache constant items unless it's a basic constant, constant field or
      a subselect (they use their own cache).
    */
    if (const_item() &&
        !(basic_const_item() || item->basic_const_item() ||
          item->type() == Item::NULL_ITEM || /* Item_name_const hack */
          item->type() == Item::FIELD_ITEM ||
          item->type() == SUBSELECT_ITEM ||
           /*
             Do not cache GET_USER_VAR() function as its const_item() may
             return TRUE for the current thread but it still may change
             during the execution.
           */
          (item->type() == Item::FUNC_ITEM &&
           ((Item_func*)item)->functype() == Item_func::GUSERVAR_FUNC)))
      *cache_flag= TRUE;
    return TRUE;
  }
  return FALSE;
}

Project: server

Item_decimal::Item_decimal(my_decimal *value_par)
{
  my_decimal2decimal(value_par, &decimal_value);
  decimals= (uint8) decimal_value.frac;
  fixed= 1;
  max_length= my_decimal_precision_to_length_no_truncation(decimal_value.intg +
                                                           decimals,
                                                           decimals,
                                                           unsigned_flag);
}

Project: server

void Item::cleanup()
{
  DBUG_ENTER("Item::cleanup");
  DBUG_PRINT("enter", ("this: %p", this));
  fixed=0;
  marker= 0;
  join_tab_idx= MAX_TABLES;
  if (orig_name)
    name= orig_name;
  DBUG_VOID_RETURN;
}

Project: server

void Item_cache_row::illegal_method_call(const char *method)
{
  DBUG_ENTER("Item_cache_row::illegal_method_call");
  DBUG_PRINT("error", ("!!! %s method was called for row item", method));
  DBUG_ASSERT(0);
  my_error(ER_OPERAND_COLUMNS, MYF(0), 1);
  DBUG_VOID_RETURN;
}

Project: server

Item_decimal::Item_decimal(longlong val, bool unsig)
{
  int2my_decimal(E_DEC_FATAL_ERROR, val, unsig, &decimal_value);
  decimals= (uint8) decimal_value.frac;
  fixed= 1;
  max_length= my_decimal_precision_to_length_no_truncation(decimal_value.intg +
                                                           decimals,
                                                           decimals,
                                                           unsigned_flag);
}

Project: server

String *Item_ref::str_result(String* str)
{
  if (result_field)
  {
    if ((null_value= result_field->is_null()))
      return 0;
    str->set_charset(str_value.charset());
    return result_field->val_str(str, &str_value);
  }
  return val_str(str);
}

Project: server

void Item_trigger_field::print(String *str, enum_query_type query_type)
{
  str->append((row_version == NEW_ROW) ? "NEW" : "OLD", 3);
  str->append('.');
  str->append(field_name);
}

Project: server

Item_result Item_type_holder::result_type() const
{
  return Field::result_merge_type(fld_type);
}

Project: server

double Item_field::val_real()
{
  DBUG_ASSERT(fixed == 1);
  if ((null_value=field->is_null()))
    return 0.0;
  return field->val_real();
}

Project: server

resolve_ref_in_select_and_group(THD *thd, Item_ident *ref, SELECT_LEX *select)
{
  Item **group_by_ref= NULL;
  Item **select_ref= NULL;
  ORDER *group_list= select->group_list.first;
  bool ambiguous_fields= FALSE;
  uint counter;
  enum_resolution_type resolution;

  /*
    Search for a column or derived column named as 'ref' in the SELECT
    clause of the current select.
  */
  if (!(select_ref= find_item_in_list(ref, *(select->get_item_list()),
                                      &counter, REPORT_EXCEPT_NOT_FOUND,
                                      &resolution)))
    return NULL; /* Some error occurred. */
  if (resolution == RESOLVED_AGAINST_ALIAS)
    ref->alias_name_used= TRUE;

  /* If this is a non-aggregated field inside HAVING, search in GROUP BY. */
  if (select->having_fix_field && !ref->with_sum_func && group_list)
  {
    group_by_ref= find_field_in_group_list(ref, group_list);
    
    /* Check if the fields found in SELECT and GROUP BY are the same field. */
    if (group_by_ref && (select_ref != not_found_item) &&
        !((*group_by_ref)->eq(*select_ref, 0)))
    {
      ambiguous_fields= TRUE;
      push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_NON_UNIQ_ERROR,
                          ER(ER_NON_UNIQ_ERROR), ref->full_name(),
                          current_thd->where);

    }
  }

  if (thd->variables.sql_mode & MODE_ONLY_FULL_GROUP_BY &&
      select->having_fix_field  &&
      select_ref != not_found_item && !group_by_ref)
  {
    /*
      Report the error if fields was found only in the SELECT item list and
      the strict mode is enabled.
    */
    my_error(ER_NON_GROUPING_FIELD_USED, MYF(0),
             ref->name, "HAVING");
    return NULL;
  }
  if (select_ref != not_found_item || group_by_ref)
  {
    if (select_ref != not_found_item && !ambiguous_fields)
    {
      DBUG_ASSERT(*select_ref != 0);
      if (!select->ref_pointer_array[counter])
      {
        my_error(ER_ILLEGAL_REFERENCE, MYF(0),
                 ref->name, "forward reference in item list");
        return NULL;
      }
      DBUG_ASSERT((*select_ref)->fixed);
      return (select->ref_pointer_array + counter);
    }
    if (group_by_ref)
      return group_by_ref;
    DBUG_ASSERT(FALSE);
    return NULL; /* So there is no compiler warning. */
  }

  return (Item**) not_found_item;
}

Project: server

Item_result item_cmp_type(Item_result a,Item_result b)
{
  if (a == STRING_RESULT && b == STRING_RESULT)
    return STRING_RESULT;
  if (a == INT_RESULT && b == INT_RESULT)
    return INT_RESULT;
  else if (a == ROW_RESULT || b == ROW_RESULT)
    return ROW_RESULT;
  else if (a == TIME_RESULT || b == TIME_RESULT)
    return TIME_RESULT;
  if ((a == INT_RESULT || a == DECIMAL_RESULT) &&
      (b == INT_RESULT || b == DECIMAL_RESULT))
    return DECIMAL_RESULT;
  return REAL_RESULT;
}

Project: server

bool Item_field::collect_item_field_processor(uchar *arg)
{
  DBUG_ENTER("Item_field::collect_item_field_processor");
  DBUG_PRINT("info", ("%s", field->field_name ? field->field_name : "noname"));
  List<Item_field> *item_list= (List<Item_field>*) arg;
  List_iterator<Item_field> item_list_it(*item_list);
  Item_field *curr_item;
  while ((curr_item= item_list_it++))
  {
    if (curr_item->eq(this, 1))
      DBUG_RETURN(FALSE); /* Already in the set. */
  }
  item_list->push_back(this);
  DBUG_RETURN(FALSE);
}

Project: server

static int save_field_in_field(Field *from, bool *null_value,
                               Field *to, bool no_conversions)
{
  int res;
  DBUG_ENTER("save_field_in_field");
  if (from->is_null())
  {
    (*null_value)= 1;
    DBUG_RETURN(set_field_to_null_with_conversions(to, no_conversions));
  }
  to->set_notnull();

  /*
    If we're setting the same field as the one we're reading from there's 
    nothing to do. This can happen in 'SET x = x' type of scenarios.
  */
  if (to == from)
  {
    (*null_value)= 0;
    DBUG_RETURN(0);
  }

  res= field_conv(to, from);
  (*null_value)= 0;
  DBUG_RETURN(res);
}

Project: server

Item_field::Item_field(Field *f)
  :Item_ident(0, NullS, *f->table_name, f->field_name),
   item_equal(0), no_const_subst(0),
   have_privileges(0), any_privileges(0)
{
  set_field(f);
  /*
    field_name and table_name should not point to garbage
    if this item is to be reused
  */
  orig_table_name= orig_field_name= "";
  with_field= 1;
}

Project: server

enum_field_types Item::field_type() const
{
  switch (result_type()) {
  case STRING_RESULT:  return string_field_type();
  case INT_RESULT:     return MYSQL_TYPE_LONGLONG;
  case DECIMAL_RESULT: return MYSQL_TYPE_NEWDECIMAL;
  case REAL_RESULT:    return MYSQL_TYPE_DOUBLE;
  case ROW_RESULT:
  case TIME_RESULT:
  case IMPOSSIBLE_RESULT:
    DBUG_ASSERT(0);
    return MYSQL_TYPE_VARCHAR;
  }
  return MYSQL_TYPE_VARCHAR;
}

Project: server

double Item_direct_ref::val_real()
{
  double tmp=(*ref)->val_real();
  null_value=(*ref)->null_value;
  return tmp;
}

Project: server

String *Item::val_string_from_decimal(String *str)
{
  my_decimal dec_buf, *dec= val_decimal(&dec_buf);
  if (null_value)
    return 0;
  my_decimal_round(E_DEC_FATAL_ERROR, dec, decimals, FALSE, &dec_buf);
  my_decimal2string(E_DEC_FATAL_ERROR, &dec_buf, 0, 0, 0, str);
  return str;
}

Project: server

longlong Item_cache_real::val_int()
{
  DBUG_ASSERT(fixed == 1);
  if (!has_value())
    return 0;
  return (longlong) rint(value);
}

Project: server

void Item_empty_string::make_field(Send_field *tmp_field)
{
  init_make_field(tmp_field, string_field_type());
}

Project: server

void Item_param::set_double(double d)
{
  DBUG_ENTER("Item_param::set_double");
  value.real= d;
  state= REAL_VALUE;
  max_length= DBL_DIG + 8;
  decimals= NOT_FIXED_DEC;
  maybe_null= 0;
  DBUG_VOID_RETURN;
}

Project: server

Item_field::Item_field(THD *thd, Item_field *item)
  :Item_ident(thd, item),
   field(item->field),
   result_field(item->result_field),
   item_equal(item->item_equal),
   no_const_subst(item->no_const_subst),
   have_privileges(item->have_privileges),
   any_privileges(item->any_privileges)
{
  collation.set(DERIVATION_IMPLICIT);
  with_field= 1;
}

Project: server

int stored_field_cmp_to_item(THD *thd, Field *field, Item *item)
{
  Item_result res_type=item_cmp_type(field->result_type(),
				     item->result_type());
  if (res_type == STRING_RESULT)
  {
    char item_buff[MAX_FIELD_WIDTH];
    char field_buff[MAX_FIELD_WIDTH];
    
    String item_tmp(item_buff,sizeof(item_buff),&my_charset_bin);
    String field_tmp(field_buff,sizeof(field_buff),&my_charset_bin);
    String *item_result= item->val_str(&item_tmp);
    /*
      Some implementations of Item::val_str(String*) actually modify
      the field Item::null_value, hence we can't check it earlier.
    */
    if (item->null_value)
      return 0;
    String *field_result= field->val_str(&field_tmp);

    enum_field_types field_type= field->type();

    if (field_type == MYSQL_TYPE_DATE || field_type == MYSQL_TYPE_DATETIME ||
        field_type == MYSQL_TYPE_TIMESTAMP)
    {
      enum_mysql_timestamp_type type= MYSQL_TIMESTAMP_ERROR;

      if (field_type == MYSQL_TYPE_DATE)
        type= MYSQL_TIMESTAMP_DATE;
      else
        type= MYSQL_TIMESTAMP_DATETIME;
        
      const char *field_name= field->field_name;
      MYSQL_TIME field_time, item_time;
      get_mysql_time_from_str(thd, field_result, type, field_name, &field_time);
      get_mysql_time_from_str(thd, item_result, type, field_name,  &item_time);

      return my_time_compare(&field_time, &item_time);
    }
    return sortcmp(field_result, item_result, field->charset());
  }
  if (res_type == INT_RESULT)
    return 0;					// Both are of type int
  if (res_type == DECIMAL_RESULT)
  {
    my_decimal item_buf, *item_val,
               field_buf, *field_val;
    item_val= item->val_decimal(&item_buf);
    if (item->null_value)
      return 0;
    field_val= field->val_decimal(&field_buf);
    return my_decimal_cmp(field_val, item_val);
  }
  /*
    We have to check field->cmp_type() instead of res_type,
    as result_type() - and thus res_type - can never be TIME_RESULT (yet).
  */
  if (field->cmp_type() == TIME_RESULT)
  {
    MYSQL_TIME field_time, item_time;
    if (field->type() == MYSQL_TYPE_TIME)
    {
      field->get_time(&field_time);
      item->get_time(&item_time);
    }
    else
    {
      field->get_date(&field_time, TIME_INVALID_DATES);
      item->get_date(&item_time, TIME_INVALID_DATES);
    }
    return my_time_compare(&field_time, &item_time);
  }
  /*
    The patch for Bug#13463415 started using this function for comparing
    BIGINTs. That uncovered a bug in Visual Studio 32bit optimized mode.
    Prefixing the auto variables with volatile fixes the problem....
  */
  volatile double result= item->val_real();
  if (item->null_value)
    return 0;
  volatile double field_result= field->val_real();
  if (field_result < result)
    return -1;
  else if (field_result > result)
    return 1;
  return 0;
}

Project: server

String *Item_copy_string::val_str(String *str)
{
  // Item_copy_string is used without fix_fields call
  if (null_value)
    return (String*) 0;
  return &str_value;
}

Project: server

bool Item_field::find_item_in_field_list_processor(uchar *arg)
{
  KEY_PART_INFO *first_non_group_part= *((KEY_PART_INFO **) arg);
  KEY_PART_INFO *last_part= *(((KEY_PART_INFO **) arg) + 1);
  KEY_PART_INFO *cur_part;

  for (cur_part= first_non_group_part; cur_part != last_part; cur_part++)
  {
    if (field->eq(cur_part->field))
      return TRUE;
  }
  return FALSE;
}

Project: server

String *Item_cache_wrapper::val_str(String* str)
{
  Item *cached_value;
  DBUG_ENTER("Item_cache_wrapper::val_str");
  if (!expr_cache)
  {
    String *tmp= orig_item->val_str(str);
    null_value= orig_item->null_value;
    DBUG_RETURN(tmp);
  }

  if ((cached_value= check_cache()))
  {
    String *tmp= cached_value->val_str(str);
    null_value= cached_value->null_value;
    DBUG_RETURN(tmp);
  }
  cache();
  if ((null_value= expr_value->null_value))
    DBUG_RETURN(NULL);
  DBUG_RETURN(expr_value->val_str(str));
}

Project: server

void Item_cache_row::store(Item * item)
{
  example= item;
  if (!item)
  {
    null_value= TRUE;
    return;
  }
  for (uint i= 0; i < item_count; i++)
    values[i]->store(item->element_index(i));
}

Project: server

bool Item::val_bool()
{
  switch(result_type()) {
  case INT_RESULT:
    return val_int() != 0;
  case DECIMAL_RESULT:
  {
    my_decimal decimal_value;
    my_decimal *val= val_decimal(&decimal_value);
    if (val)
      return !my_decimal_is_zero(val);
    return 0;
  }
  case REAL_RESULT:
  case STRING_RESULT:
    return val_real() != 0.0;
  case ROW_RESULT:
  case TIME_RESULT:
  case IMPOSSIBLE_RESULT:
    DBUG_ASSERT(0);
    return 0;                                   // Wrong (but safe)
  }
  return 0;                                   // Wrong (but safe)
}

Project: server

Item *Item_field::update_value_transformer(uchar *select_arg)
{
  SELECT_LEX *select= (SELECT_LEX*)select_arg;
  DBUG_ASSERT(fixed);

  if (field->table != select->context.table_list->table &&
      type() != Item::TRIGGER_FIELD_ITEM)
  {
    List<Item> *all_fields= &select->join->all_fields;
    Item **ref_pointer_array= select->ref_pointer_array;
    DBUG_ASSERT(all_fields->elements <= select->ref_pointer_array_size);
    int el= all_fields->elements;
    Item_ref *ref;

    ref_pointer_array[el]= (Item*)this;
    all_fields->push_front((Item*)this);
    ref= new Item_ref(&select->context, ref_pointer_array + el,
                      table_name, field_name);
    return ref;
  }
  return this;
}

Project: server

int Item::save_time_in_field(Field *field)
{
  MYSQL_TIME ltime;
  if (get_time(&ltime))
    return set_field_to_null_with_conversions(field, 0);
  field->set_notnull();
  return field->store_time_dec(&ltime, decimals);
}

Project: server

void Item_field::set_field(Field *field_par)
{
  field=result_field=field_par;			// for easy coding with fields
  maybe_null=field->maybe_null();
  decimals= field->decimals();
  table_name= *field_par->table_name;
  field_name= field_par->field_name;
  db_name= field_par->table->s->db.str;
  alias_name_used= field_par->table->alias_name_used;
  unsigned_flag=test(field_par->flags & UNSIGNED_FLAG);
  collation.set(field_par->charset(), field_par->derivation(),
                field_par->repertoire());
  fix_char_length(field_par->char_length());

  max_length= adjust_max_effective_column_length(field_par, max_length);

  fixed= 1;
  if (field->table->s->tmp_table == SYSTEM_TMP_TABLE)
    any_privileges= 0;
}

Project: server

void Item_float::print(String *str, enum_query_type query_type)
{
  if (presentation)
  {
    str->append(presentation);
    return;
  }
  char buffer[20];
  String num(buffer, sizeof(buffer), &my_charset_bin);
  num.set_real(value, decimals, &my_charset_bin);
  str->append(num);
}

Project: server

void Item_result_field::cleanup()
{
  DBUG_ENTER("Item_result_field::cleanup()");
  Item::cleanup();
  result_field= 0;
  DBUG_VOID_RETURN;
}

Project: server

Item_param::set_value(THD *thd, sp_rcontext *ctx, Item **it)
{
  Item *arg= *it;

  if (arg->is_null())
  {
    set_null();
    return FALSE;
  }

  null_value= FALSE;

  switch (arg->result_type()) {
  case STRING_RESULT:
  {
    char str_buffer[STRING_BUFFER_USUAL_SIZE];
    String sv_buffer(str_buffer, sizeof(str_buffer), &my_charset_bin);
    String *sv= arg->val_str(&sv_buffer);

    if (!sv)
      return TRUE;

    set_str(sv->c_ptr_safe(), sv->length());
    str_value_ptr.set(str_value.ptr(),
                      str_value.length(),
                      str_value.charset());
    collation.set(str_value.charset(), DERIVATION_COERCIBLE);
    decimals= 0;

    break;
  }

  case REAL_RESULT:
    set_double(arg->val_real());
    break;

  case INT_RESULT:
    set_int(arg->val_int(), arg->max_length);
    break;

  case DECIMAL_RESULT:
  {
    my_decimal dv_buf;
    my_decimal *dv= arg->val_decimal(&dv_buf);

    if (!dv)
      return TRUE;

    set_decimal(dv);
    break;
  }

  default:
    /* That can not happen. */

    DBUG_ASSERT(TRUE);  // Abort in debug mode.

    set_null();         // Set to NULL in release mode.
    return FALSE;
  }

  item_result_type= arg->result_type();
  item_type= arg->type();
  return FALSE;
}

Project: server

my_decimal *Item_cache_decimal::val_decimal(my_decimal *val)
{
  DBUG_ASSERT(fixed);
  if (!has_value())
    return NULL;
  return &decimal_value;
}

Project: server

Item_param::get_out_param_info() const
{
  return m_out_param_info;
}

Project: server

void Item_ident::print(String *str, enum_query_type query_type)
{
  THD *thd= current_thd;
  char d_name_buff[MAX_ALIAS_NAME], t_name_buff[MAX_ALIAS_NAME];
  const char *d_name= db_name, *t_name= table_name;
  if (lower_case_table_names== 1 ||
      (lower_case_table_names == 2 && !alias_name_used))
  {
    if (table_name && table_name[0])
    {
      strmov(t_name_buff, table_name);
      my_casedn_str(files_charset_info, t_name_buff);
      t_name= t_name_buff;
    }
    if (db_name && db_name[0])
    {
      strmov(d_name_buff, db_name);
      my_casedn_str(files_charset_info, d_name_buff);
      d_name= d_name_buff;
    }
  }

  if (!table_name || !field_name || !field_name[0])
  {
    const char *nm= (field_name && field_name[0]) ?
                      field_name : name ? name : "tmp_field";
    append_identifier(thd, str, nm, (uint) strlen(nm));
    return;
  }
  if (db_name && db_name[0] && !alias_name_used)
  {
    if (!(cached_table && cached_table->belong_to_view &&
          cached_table->belong_to_view->compact_view_format))
    {
      append_identifier(thd, str, d_name, (uint)strlen(d_name));
      str->append('.');
    }
    append_identifier(thd, str, t_name, (uint)strlen(t_name));
    str->append('.');
    append_identifier(thd, str, field_name, (uint)strlen(field_name));
  }
  else
  {
    if (table_name[0])
    {
      append_identifier(thd, str, t_name, (uint) strlen(t_name));
      str->append('.');
      append_identifier(thd, str, field_name, (uint) strlen(field_name));
    }
    else
      append_identifier(thd, str, field_name, (uint) strlen(field_name));
  }
}

Project: server

void Item_name_const::print(String *str, enum_query_type query_type)
{
  str->append(STRING_WITH_LEN("NAME_CONST("));
  name_item->print(str, query_type);
  str->append(',');
  value_item->print(str, query_type);
  str->append(')');
}

Project: server

bool Item_field::register_field_in_write_map(uchar *arg)
{
  TABLE *table= (TABLE *) arg;
  if (field->table == table || !table)
    bitmap_set_bit(field->table->write_set, field->field_index);
  return 0;
}

Project: server

bool agg_item_set_converter(DTCollation &coll, const char *fname,
                            Item **args, uint nargs, uint flags, int item_sep)
{
  Item **arg, *safe_args[2]= {NULL, NULL};

  /*
    For better error reporting: save the first and the second argument.
    We need this only if the the number of args is 3 or 2:
    - for a longer argument list, "Illegal mix of collations"
      doesn't display each argument's characteristics.
    - if nargs is 1, then this error cannot happen.
  */
  if (nargs >=2 && nargs <= 3)
  {
    safe_args[0]= args[0];
    safe_args[1]= args[item_sep];
  }

  THD *thd= current_thd;
  bool res= FALSE;
  uint i;

  /*
    In case we're in statement prepare, create conversion item
    in its memory: it will be reused on each execute.
  */
  Query_arena backup;
  Query_arena *arena= thd->stmt_arena->is_stmt_prepare() ?
                      thd->activate_stmt_arena_if_needed(&backup) :
                      NULL;

  for (i= 0, arg= args; i < nargs; i++, arg+= item_sep)
  {
    Item* conv;
    uint32 dummy_offset;
    if (!String::needs_conversion(1, (*arg)->collation.collation,
                                  coll.collation,
                                  &dummy_offset))
      continue;

    /*
      No needs to add converter if an "arg" is NUMERIC or DATETIME
      value (which is pure ASCII) and at the same time target DTCollation
      is ASCII-compatible. For example, no needs to rewrite:
        SELECT * FROM t1 WHERE datetime_field = '2010-01-01';
      to
        SELECT * FROM t1 WHERE CONVERT(datetime_field USING cs) = '2010-01-01';
      
      TODO: avoid conversion of any values with
      repertoire ASCII and 7bit-ASCII-compatible,
      not only numeric/datetime origin.
    */
    if ((*arg)->collation.derivation == DERIVATION_NUMERIC &&
        (*arg)->collation.repertoire == MY_REPERTOIRE_ASCII &&
        !((*arg)->collation.collation->state & MY_CS_NONASCII) &&
        !(coll.collation->state & MY_CS_NONASCII))
      continue;

    if (!(conv= (*arg)->safe_charset_converter(coll.collation)) &&
        ((*arg)->collation.repertoire == MY_REPERTOIRE_ASCII))
      conv= new Item_func_conv_charset(*arg, coll.collation, 1);

    if (!conv)
    {
      if (nargs >=2 && nargs <= 3)
      {
        /* restore the original arguments for better error message */
        args[0]= safe_args[0];
        args[item_sep]= safe_args[1];
      }
      my_coll_agg_error(args, nargs, fname, item_sep);
      res= TRUE;
      break; // we cannot return here, we need to restore "arena".
    }
    if ((*arg)->type() == Item::FIELD_ITEM)
      ((Item_field *)(*arg))->no_const_subst= 1;
    /*
      If in statement prepare, then we create a converter for two
      constant items, do it once and then reuse it.
      If we're in execution of a prepared statement, arena is NULL,
      and the conv was created in runtime memory. This can be
      the case only if the argument is a parameter marker ('?'),
      because for all true constants the charset converter has already
      been created in prepare. In this case register the change for
      rollback.
    */
    if (thd->stmt_arena->is_stmt_prepare())
      *arg= conv;
    else
      thd->change_item_tree(arg, conv);

    if (conv->fix_fields(thd, arg))
    {
      res= TRUE;
      break; // we cannot return here, we need to restore "arena".
    }
  }
  if (arena)
    thd->restore_active_arena(arena, &backup);
  return res;
}

Project: server

double Item::val_real_from_decimal()
{
  /* Note that fix_fields may not be called for Item_avg_field items */
  double result;
  my_decimal value_buff, *dec_val= val_decimal(&value_buff);
  if (null_value)
    return 0.0;
  my_decimal2double(E_DEC_FATAL_ERROR, dec_val, &result);
  return result;
}

Project: server

Item_param::eq(const Item *arg, bool binary_cmp) const
{
  Item *item;
  if (!basic_const_item() || !arg->basic_const_item() || arg->type() != type())
    return FALSE;
  /*
    We need to cast off const to call val_int(). This should be OK for
    a basic constant.
  */
  item= (Item*) arg;

  switch (state) {
  case NULL_VALUE:
    return TRUE;
  case INT_VALUE:
    return value.integer == item->val_int() &&
           unsigned_flag == item->unsigned_flag;
  case REAL_VALUE:
    return value.real == item->val_real();
  case STRING_VALUE:
  case LONG_DATA_VALUE:
    if (binary_cmp)
      return !stringcmp(&str_value, &item->str_value);
    return !sortcmp(&str_value, &item->str_value, collation.collation);
  default:
    break;
  }
  return FALSE;
}

Project: server

my_decimal *Item::val_decimal_from_int(my_decimal *decimal_value)
{
  longlong nr= val_int();
  if (null_value)
    return 0;
  int2my_decimal(E_DEC_FATAL_ERROR, nr, unsigned_flag, decimal_value);
  return decimal_value;
}

Project: server

longlong Item_type_holder::val_int()
{
  DBUG_ASSERT(0); // should never be called
  return 0;
}

Project: server

longlong Item_cache_temporal::val_temporal_packed()
{
  DBUG_ASSERT(fixed == 1);
  if ((!value_cached && !cache_value()) || null_value)
  {
    null_value= TRUE;
    return 0;
  }
  return value;
}

Project: server

bool Item_name_const::fix_fields(THD *thd, Item **ref)
{
  char buf[128];
  String *item_name;
  String s(buf, sizeof(buf), &my_charset_bin);
  s.length(0);

  if (value_item->fix_fields(thd, &value_item) ||
      name_item->fix_fields(thd, &name_item) ||
      !value_item->const_item() ||
      !name_item->const_item() ||
      !(item_name= name_item->val_str(&s))) // Can't have a NULL name 
  {
    my_error(ER_RESERVED_SYNTAX, MYF(0), "NAME_CONST");
    return TRUE;
  }
  if (is_autogenerated_name)
  {
    set_name(item_name->ptr(), (uint) item_name->length(), system_charset_info);
  }
  collation.set(value_item->collation.collation, DERIVATION_IMPLICIT);
  max_length= value_item->max_length;
  decimals= value_item->decimals;
  fixed= 1;
  return FALSE;
}

Project: server

Hybrid_type_traits_integer::fix_length_and_dec(Item *item, Item *arg) const
{
  item->decimals= 0;
  item->max_length= MY_INT64_NUM_DECIMAL_DIGITS;
  item->unsigned_flag= 0;
}

Project: server

void Item_direct_view_ref::update_used_tables()
{
  set_null_ref_table();
  Item_direct_ref::update_used_tables();
}

Project: server

static void convert_zerofill_number_to_string(Item **item, Field_num *field)
{
  char buff[MAX_FIELD_WIDTH],*pos;
  String tmp(buff,sizeof(buff), field->charset()), *res;

  res= (*item)->val_str(&tmp);
  if ((*item)->is_null())
    *item= new Item_null();
  else
  {
    field->prepend_zeros(res);
    pos= (char *) sql_strmake (res->ptr(), res->length());
    *item= new Item_string(pos, res->length(), field->charset());
  }
}

Project: server

String *Item::val_str(String *str, String *converter, CHARSET_INFO *cs)
{
  String *res= val_str(str);
  if (null_value)
    return (String *) 0;

  if (!cs)
    return res;

  uint errors;
  if ((null_value= converter->copy(res->ptr(), res->length(),
                                   collation.collation, cs,  &errors)))
    return (String *) 0;

  return converter;
}

Project: server

longlong Item_direct_ref::val_int()
{
  longlong tmp=(*ref)->val_int();
  null_value=(*ref)->null_value;
  return tmp;
}

Project: server

void Item_trigger_field::set_required_privilege(bool rw)
{
  /*
    Require SELECT and UPDATE privilege if this field will be read and
    set, and only UPDATE privilege for setting the field.
  */
  want_privilege= (rw ? SELECT_ACL | UPDATE_ACL : UPDATE_ACL);
}

Project: server

bool Item_field::is_null_result()
{
  return (null_value=result_field->is_null());
}

Project: server

longlong Item_cache_decimal::val_int()
{
  DBUG_ASSERT(fixed);
  longlong res;
  if (!has_value())
    return 0;
  my_decimal2int(E_DEC_FATAL_ERROR, &decimal_value, unsigned_flag, &res);
  return res;
}

Project: server

double Item_cache_decimal::val_real()
{
  DBUG_ASSERT(fixed);
  double res;
  if (!has_value())
    return 0.0;
  my_decimal2double(E_DEC_FATAL_ERROR, &decimal_value, &res);
  return res;
}

Project: server

Item_splocal::this_item_addr(THD *thd, Item **)
{
  DBUG_ASSERT(m_sp == thd->spcont->sp);

  return thd->spcont->get_item_addr(m_var_idx);
}

Project: server

int Item::save_in_field_no_warnings(Field *field, bool no_conversions)
{
  int res;
  TABLE *table= field->table;
  THD *thd= table->in_use;
  enum_check_fields tmp= thd->count_cuted_fields;
  my_bitmap_map *old_map= dbug_tmp_use_all_columns(table, table->write_set);
  ulonglong sql_mode= thd->variables.sql_mode;
  thd->variables.sql_mode&= ~(MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE);
  thd->variables.sql_mode|= MODE_INVALID_DATES;
  thd->count_cuted_fields= CHECK_FIELD_IGNORE;

  res= save_in_field(field, no_conversions);

  thd->count_cuted_fields= tmp;
  dbug_tmp_restore_column_map(table->write_set, old_map);
  thd->variables.sql_mode= sql_mode;
  return res;
}

Project: server

void Item::set_name_for_rollback(THD *thd, const char *str, uint length,
                                 CHARSET_INFO *cs)
{
  char *old_name, *new_name; 
  old_name= name;
  set_name(str, length, cs);
  new_name= name;
  if (old_name != new_name)
  {
    name= old_name;
    thd->change_item_tree((Item **) &name, (Item *) new_name);
  }
}

Project: server

bool Item_param::get_date(MYSQL_TIME *res, ulonglong fuzzydate)
{
  if (state == TIME_VALUE)
  {
    *res= value.time;
    return 0;
  }
  return Item::get_date(res, fuzzydate);
}

Project: server

String *Item_copy_uint::val_str(String *str)
{
  if (null_value)
    return (String *) 0;

  str->set((ulonglong) cached_value, &my_charset_bin);
  return str;
}

Project: server

void Item::set_name(const char *str, uint length, CHARSET_INFO *cs)
{
  if (!length)
  {
    /* Empty string, used by AS or internal function like last_insert_id() */
    name= (char*) str;
    name_length= 0;
    return;
  }
  if (cs->ctype)
  {
    const char *str_start= str;

    /*
      This will probably need a better implementation in the future:
      a function in CHARSET_INFO structure.
    */
    while (length && !my_isgraph(cs,*str))
    {						// Fix problem with yacc
      length--;
      str++;
    }
    if (str != str_start && !is_autogenerated_name)
    {
      char buff[SAFE_NAME_LEN];
      strmake(buff, str_start,
              min(sizeof(buff)-1, length + (int) (str-str_start)));

      if (length == 0)
        push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
                            ER_NAME_BECOMES_EMPTY, ER(ER_NAME_BECOMES_EMPTY),
                            buff);
      else
        push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
                            ER_REMOVED_SPACES, ER(ER_REMOVED_SPACES),
                            buff);
    }
  }
  if (!my_charset_same(cs, system_charset_info))
  {
    size_t res_length;
    name= sql_strmake_with_convert(str, length, cs,
				   MAX_ALIAS_NAME, system_charset_info,
				   &res_length);
    name_length= res_length;
  }
  else
    name= sql_strmake(str, (name_length= min(length,MAX_ALIAS_NAME)));
}

Project: server

Item_param::clone_item()
{
  /* see comments in the header file */
  switch (state) {
  case NULL_VALUE:
    return new Item_null(name);
  case INT_VALUE:
    return (unsigned_flag ?
            new Item_uint(name, value.integer, max_length) :
            new Item_int(name, value.integer, max_length));
  case REAL_VALUE:
    return new Item_float(name, value.real, decimals, max_length);
  case STRING_VALUE:
  case LONG_DATA_VALUE:
    return new Item_string(name, str_value.c_ptr_quick(), str_value.length(),
                           str_value.charset());
  case TIME_VALUE:
    break;
  case NO_VALUE:
  default:
    DBUG_ASSERT(0);
  };
  return 0;
}

Project: server

void Item_param::set_time(MYSQL_TIME *tm, timestamp_type time_type,
                          uint32 max_length_arg)
{ 
  DBUG_ENTER("Item_param::set_time");

  value.time= *tm;
  value.time.time_type= time_type;

  if (value.time.year > 9999 || value.time.month > 12 ||
      value.time.day > 31 ||
      (time_type != MYSQL_TIMESTAMP_TIME && value.time.hour > 23) ||
      value.time.minute > 59 || value.time.second > 59 ||
      value.time.second_part > TIME_MAX_SECOND_PART)
  {
    ErrConvTime str(&value.time);
    make_truncated_value_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
                                 &str, time_type, 0);
    set_zero_time(&value.time, MYSQL_TIMESTAMP_ERROR);
  }

  state= TIME_VALUE;
  maybe_null= 0;
  max_length= max_length_arg;
  decimals= tm->second_part > 0 ? TIME_SECOND_PART_DIGITS : 0;
  DBUG_VOID_RETURN;
}

Project: server

int Item_hex_hybrid::save_in_field(Field *field, bool no_conversions)
{
  field->set_notnull();
  if (field->result_type() == STRING_RESULT)
    return field->store(str_value.ptr(), str_value.length(), 
                        collation.collation);

  ulonglong nr;
  uint32 length= str_value.length();
  if (!length)
    return 1;

  if (length > 8)
  {
    nr= field->flags & UNSIGNED_FLAG ? ULONGLONG_MAX : LONGLONG_MAX;
    goto warn;
  }
  nr= (ulonglong) val_int();
  if ((length == 8) && !(field->flags & UNSIGNED_FLAG) && (nr > LONGLONG_MAX))
  {
    nr= LONGLONG_MAX;
    goto warn;
  }
  return field->store((longlong) nr, TRUE);  // Assume hex numbers are unsigned

warn:
  if (!field->store((longlong) nr, TRUE))
    field->set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE,
                       1);
  return 1;
}

Project: server

String *Item::val_string_from_real(String *str)
{
  double nr= val_real();
  if (null_value)
    return 0;					/* purecov: inspected */
  str->set_real(nr,decimals, &my_charset_numeric);
  return str;
}

Project: server

void view_error_processor(THD *thd, void *data)
{
  ((TABLE_LIST *)data)->hide_view_error(thd);
}

Project: server

bool Item_ref::send(Protocol *prot, String *tmp)
{
  if (result_field)
    return prot->store(result_field);
  return (*ref)->send(prot, tmp);
}

Project: server

longlong Item_copy_decimal::val_int()
{
  if (null_value)
    return LL(0);
  else
  {
    longlong result;
    my_decimal2int(E_DEC_FATAL_ERROR, &cached_value, unsigned_flag, &result);
    return result;
  }
}

Project: server

bool Item_decimal::eq(const Item *item, bool binary_cmp) const
{
  if (type() == item->type() && item->basic_const_item())
  {
    /*
      We need to cast off const to call val_decimal(). This should
      be OK for a basic constant. Additionally, we can pass 0 as
      a true decimal constant will return its internal decimal
      storage and ignore the argument.
    */
    Item *arg= (Item*) item;
    my_decimal *value= arg->val_decimal(0);
    return !my_decimal_cmp(&decimal_value, value);
  }
  return 0;
}

Project: server

void Item_field::fix_after_pullout(st_select_lex *new_parent, Item **ref)
{
  if (new_parent == get_depended_from())
    depended_from= NULL;
  if (context)
  {
    bool need_change= false;
    /*
      Suppose there are nested selects:

       select_id=1
         select_id=2
           select_id=3  <----+
             select_id=4    -+
               select_id=5 --+

      Suppose, pullout operation has moved anything that had select_id=4 or 5
      in to select_id=3.

      If this Item_field had a name resolution context pointing into select_lex
      with id=4 or id=5, it needs a new name resolution context.

      However, it could also be that this object is a part of outer reference:
      Item_ref(Item_field(field in select with select_id=1))).
      - The Item_ref object has a context with select_id=5, and so needs a new
        name resolution context.
      - The Item_field object has a context with select_id=1, and doesn't need
        a new name resolution context.

      So, the following loop walks from Item_field's current context upwards.
      If we find that the select we've been pulled out to is up there, we
      create the new name resolution context. Otherwise, we don't.
    */
    for (Name_resolution_context *ct= context; ct; ct= ct->outer_context)
    {
      if (new_parent == ct->select_lex)
      {
        need_change= true;
        break;
      }
    }
    if (!need_change)
      return;

    Name_resolution_context *ctx= new Name_resolution_context();
    if (context->select_lex == new_parent)
    {
      /*
        This field was pushed in then pulled out
        (for example left part of IN)
      */
      ctx->outer_context= context->outer_context;
    }
    else if (context->outer_context)
    {
      /* just pull to the upper context */
      ctx->outer_context= context->outer_context->outer_context;
    }
    else
    {
      /* No upper context (merging Derived/VIEW where context chain ends) */
      ctx->outer_context= NULL;
    }
    ctx->table_list= context->first_name_resolution_table;
    ctx->select_lex= new_parent;
    if (context->select_lex == NULL)
      ctx->select_lex= NULL;
    ctx->first_name_resolution_table= context->first_name_resolution_table;
    ctx->last_name_resolution_table=  context->last_name_resolution_table;
    ctx->error_processor=             context->error_processor;
    ctx->error_processor_data=        context->error_processor_data;
    ctx->resolve_in_select_list=      context->resolve_in_select_list;
    ctx->security_ctx=                context->security_ctx;
    this->context=ctx;
  }
}

Project: server

Item_ref::Item_ref(Name_resolution_context *context_arg,
                   Item **item, const char *table_name_arg,
                   const char *field_name_arg,
                   bool alias_name_used_arg)
  :Item_ident(context_arg, NullS, table_name_arg, field_name_arg),
   result_field(0), ref(item), reference_trough_name(0)
{
  alias_name_used= alias_name_used_arg;
  /*
    This constructor used to create some internals references over fixed items
  */
  if ((set_properties_only= (ref && *ref && (*ref)->fixed)))
    set_properties();
}

Project: server

static bool mark_as_dependent(THD *thd, SELECT_LEX *last, SELECT_LEX *current,
                              Item_ident *resolved_item,
                              Item_ident *mark_item)
{
  DBUG_ENTER("mark_as_dependent");

  /* store pointer on SELECT_LEX from which item is dependent */
  if (mark_item && mark_item->can_be_depended)
  {
    DBUG_PRINT("info", ("mark_item: %p  lex: %p", mark_item, last));
    mark_item->depended_from= last;
  }
  if (current->mark_as_dependent(thd, last,
                                 /** resolved_item psergey-thu **/ mark_item))
    DBUG_RETURN(TRUE);
  if (thd->lex->describe & DESCRIBE_EXTENDED)
  {
    const char *db_name= (resolved_item->db_name ?
                          resolved_item->db_name : "");
    const char *table_name= (resolved_item->table_name ?
                             resolved_item->table_name : "");
    push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
		 ER_WARN_FIELD_RESOLVED, ER(ER_WARN_FIELD_RESOLVED),
                 db_name, (db_name[0] ? "." : ""),
                 table_name, (table_name [0] ? "." : ""),
                 resolved_item->field_name,
                 current->select_number, last->select_number);
  }
  DBUG_RETURN(FALSE);
}

Project: server

void Item_decimal::print(String *str, enum_query_type query_type)
{
  my_decimal2string(E_DEC_FATAL_ERROR, &decimal_value, 0, 0, 0, &str_value);
  str->append(str_value);
}

Project: server

int Item_cache_str::save_in_field(Field *field, bool no_conversions)
{
  if (!has_value())
    return set_field_to_null_with_conversions(field, no_conversions);
  int res= Item_cache::save_in_field(field, no_conversions);
  return (is_varbinary && field->type() == MYSQL_TYPE_STRING &&
          value->length() < field->field_length) ? 1 : res;
}

Project: server

bool Item_cache_wrapper::get_date(MYSQL_TIME *ltime, ulonglong fuzzydate)
{
  Item *cached_value;
  DBUG_ENTER("Item_cache_wrapper::get_date");
  if (!expr_cache)
    DBUG_RETURN((null_value= orig_item->get_date(ltime, fuzzydate)));

  if ((cached_value= check_cache()))
    DBUG_RETURN((null_value= cached_value->get_date(ltime, fuzzydate)));

  cache();
  DBUG_RETURN((null_value= expr_value->get_date(ltime, fuzzydate)));
}

Project: server

void Item_copy_decimal::copy()
{
  my_decimal *nr= item->val_decimal(&cached_value);
  if (nr && nr != &cached_value)
    my_decimal2decimal (nr, &cached_value);
  null_value= item->null_value;
}

Project: server

bool DTCollation::aggregate(DTCollation &dt, uint flags)
{
  if (!my_charset_same(collation, dt.collation))
  {
    /* 
       We do allow to use binary strings (like BLOBS)
       together with character strings.
       Binaries have more precedence than a character
       string of the same derivation.
    */
    if (collation == &my_charset_bin)
    {
      if (derivation <= dt.derivation)
      {
	/* Do nothing */
      }
      else
      {
	set(dt); 
      }
    }
    else if (dt.collation == &my_charset_bin)
    {
      if (dt.derivation <= derivation)
      {
        set(dt);
      }
    }
    else if ((flags & MY_COLL_ALLOW_SUPERSET_CONV) &&
             left_is_superset(this, &dt))
    {
      /* Do nothing */
    }
    else if ((flags & MY_COLL_ALLOW_SUPERSET_CONV) &&
             left_is_superset(&dt, this))
    {
      set(dt);
    }
    else if ((flags & MY_COLL_ALLOW_COERCIBLE_CONV) &&
             derivation < dt.derivation &&
             dt.derivation >= DERIVATION_SYSCONST)
    {
      /* Do nothing */
    }
    else if ((flags & MY_COLL_ALLOW_COERCIBLE_CONV) &&
             dt.derivation < derivation &&
             derivation >= DERIVATION_SYSCONST)
    {
      set(dt);
    }
    else
    {
      // Cannot apply conversion
      set(&my_charset_bin, DERIVATION_NONE,
          (dt.repertoire|repertoire));
      return 1;
    }
  }
  else if (derivation < dt.derivation)
  {
    /* Do nothing */
  }
  else if (dt.derivation < derivation)
  {
    set(dt);
  }
  else
  { 
    if (collation == dt.collation)
    {
      /* Do nothing */
    }
    else 
    {
      if (derivation == DERIVATION_EXPLICIT)
      {
        set(0, DERIVATION_NONE, 0);
        return 1;
      }
      if (collation->state & MY_CS_BINSORT)
        return 0;
      if (dt.collation->state & MY_CS_BINSORT)
      {
        set(dt);
        return 0;
      }
      CHARSET_INFO *bin= get_charset_by_csname(collation->csname, 
                                               MY_CS_BINSORT,MYF(0));
      set(bin, DERIVATION_NONE);
    }
  }
  repertoire|= dt.repertoire;
  return 0;
}

Project: server

  virtual Ref_Type ref_type() { return AGGREGATE_REF; }

Project: server

longlong Item::val_int_from_decimal()
{
  /* Note that fix_fields may not be called for Item_avg_field items */
  longlong result;
  my_decimal value, *dec_val= val_decimal(&value);
  if (null_value)
    return 0;
  my_decimal2int(E_DEC_FATAL_ERROR, dec_val, unsigned_flag, &result);
  return result;
}

Project: server

void Item_field::make_field(Send_field *tmp_field)
{
  field->make_field(tmp_field);
  DBUG_ASSERT(tmp_field->table_name != 0);
  if (name)
    tmp_field->col_name=name;			// Use user supplied name
  if (table_name)
    tmp_field->table_name= table_name;
  if (db_name)
    tmp_field->db_name= db_name;
}

Project: server

void resolve_const_item(THD *thd, Item **ref, Item *comp_item)
{
  Item *item= *ref;
  Item *new_item= NULL;
  if (item->basic_const_item())
    return;                                     // Can't be better
  Item_result res_type=item_cmp_type(comp_item->cmp_type(), item->cmp_type());
  char *name=item->name;			// Alloced by sql_alloc

  switch (res_type) {
  case TIME_RESULT:
  {
    bool is_null;
    Item **ref_copy= ref;
    /* the following call creates a constant and puts it in new_item */
    get_datetime_value(thd, &ref_copy, &new_item, comp_item, &is_null);
    if (is_null)
      new_item= new Item_null(name);
    break;
  }
  case STRING_RESULT:
  {
    char buff[MAX_FIELD_WIDTH];
    String tmp(buff,sizeof(buff),&my_charset_bin),*result;
    result=item->val_str(&tmp);
    if (item->null_value)
      new_item= new Item_null(name);
    else
    {
      uint length= result->length();
      char *tmp_str= sql_strmake(result->ptr(), length);
      new_item= new Item_string(name, tmp_str, length, result->charset());
    }
    break;
  }
  case INT_RESULT:
  {
    longlong result=item->val_int();
    uint length=item->max_length;
    bool null_value=item->null_value;
    new_item= (null_value ? (Item*) new Item_null(name) :
               (Item*) new Item_int(name, result, length));
    break;
  }
  case ROW_RESULT:
  if (item->type() == Item::ROW_ITEM && comp_item->type() == Item::ROW_ITEM)
  {
    /*
      Substitute constants only in Item_rows. Don't affect other Items
      with ROW_RESULT (eg Item_singlerow_subselect).

      For such Items more optimal is to detect if it is constant and replace
      it with Item_row. This would optimize queries like this:
      SELECT * FROM t1 WHERE (a,b) = (SELECT a,b FROM t2 LIMIT 1);
    */
    Item_row *item_row= (Item_row*) item;
    Item_row *comp_item_row= (Item_row*) comp_item;
    uint col;
    new_item= 0;
    /*
      If item and comp_item are both Item_rows and have same number of cols
      then process items in Item_row one by one.
      We can't ignore NULL values here as this item may be used with <=>, in
      which case NULL's are significant.
    */
    DBUG_ASSERT(item->result_type() == comp_item->result_type());
    DBUG_ASSERT(item_row->cols() == comp_item_row->cols());
    col= item_row->cols();
    while (col-- > 0)
      resolve_const_item(thd, item_row->addr(col),
                         comp_item_row->element_index(col));
    break;
  }
  /* Fallthrough */
  case REAL_RESULT:
  {						// It must REAL_RESULT
    double result= item->val_real();
    uint length=item->max_length,decimals=item->decimals;
    bool null_value=item->null_value;
    new_item= (null_value ? (Item*) new Item_null(name) : (Item*)
               new Item_float(name, result, decimals, length));
    break;
  }
  case DECIMAL_RESULT:
  {
    my_decimal decimal_value;
    my_decimal *result= item->val_decimal(&decimal_value);
    uint length= item->max_length, decimals= item->decimals;
    bool null_value= item->null_value;
    new_item= (null_value ?
               (Item*) new Item_null(name) :
               (Item*) new Item_decimal(name, result, length, decimals));
    break;
  }
  case IMPOSSIBLE_RESULT:
    DBUG_ASSERT(0);
    break;
  }
  if (new_item)
    thd->change_item_tree(ref, new_item);
}

Project: server

Item_equal *Item_direct_view_ref::find_item_equal(COND_EQUAL *cond_equal)
{
  Item* field_item= real_item();
  if (field_item->type() != FIELD_ITEM)
    return NULL;
  return ((Item_field *) field_item)->find_item_equal(cond_equal);  
}

Project: server

Item *Item::safe_charset_converter(CHARSET_INFO *tocs)
{
  Item_func_conv_charset *conv= new Item_func_conv_charset(this, tocs, 1);
  return conv->safe ? conv : NULL;
}

Project: server

bool Item_field::register_field_in_read_map(uchar *arg)
{
  TABLE *table= (TABLE *) arg;
  if (field->table == table || !table)
    bitmap_set_bit(field->table->read_set, field->field_index);
  if (field->vcol_info && field->vcol_info->expr_item)
    return field->vcol_info->expr_item->walk(&Item::register_field_in_read_map, 
                                             1, arg);
  return 0;
}

Project: server

void Item_datetime::set(longlong packed)
{
  unpack_time(packed, &ltime);
}

Project: server

String* Item_cache_str::val_str(String *str)
{
  DBUG_ASSERT(fixed == 1);
  if (!has_value())
    return 0;
  return value;
}

Project: server

my_decimal *Item_cache_temporal::val_decimal(my_decimal *decimal_value)
{
  DBUG_ASSERT(fixed == 1);
  if ((!value_cached && !cache_value()) || null_value)
  {
    null_value= true;
    return NULL;
  }
  return val_decimal_from_date(decimal_value);
}

Project: server

String *Item::val_str_ascii(String *str)
{
  DBUG_ASSERT(str != &str_value);
  
  uint errors;
  String *res= val_str(&str_value);
  if (!res)
    return 0;
  
  if (!(res->charset()->state & MY_CS_NONASCII))
    str= res;
  else
  {
    if ((null_value= str->copy(res->ptr(), res->length(), collation.collation,
                               &my_charset_latin1, &errors)))
      return 0;
  }

  return str;
}

Project: server

int Item_copy_float::save_in_field(Field *field, bool no_conversions)
{
  if (null_value)
    return set_field_to_null(field);
  field->set_notnull();
  return field->store(cached_value);
}

Project: server

void Item_param::make_field(Send_field *field)
{
  Item::make_field(field);

  if (!m_out_param_info)
    return;

  /*
    This is an OUT-parameter of stored procedure. We should use
    OUT-parameter info to fill out the names.
  */

  field->db_name= m_out_param_info->db_name;
  field->table_name= m_out_param_info->table_name;
  field->org_table_name= m_out_param_info->org_table_name;
  field->col_name= m_out_param_info->col_name;
  field->org_col_name= m_out_param_info->org_col_name;

  field->length= m_out_param_info->length;
  field->charsetnr= m_out_param_info->charsetnr;
  field->flags= m_out_param_info->flags;
  field->decimals= m_out_param_info->decimals;
  field->type= m_out_param_info->type;
}

Project: server

longlong Item_ref_null_helper::val_int()
{
  DBUG_ASSERT(fixed == 1);
  longlong tmp= (*ref)->val_int_result();
  owner->was_null|= null_value= (*ref)->null_value;
  return tmp;
}

Project: server

bool Item_outer_ref::check_inner_refs_processor(uchar *arg)
{
  List_iterator_fast<Item_outer_ref> *it=
    ((List_iterator_fast<Item_outer_ref> *) arg);
  Item_outer_ref *ref;
  while ((ref= (*it)++))
  {
    if (ref == this)
    {
      ref->found_in_group_by= 1;
      break;
    }
  }
  (*it).rewind();
  return FALSE;
}

Project: server

Item *Item_field::safe_charset_converter(CHARSET_INFO *tocs)
{
  no_const_subst= 1;
  return Item::safe_charset_converter(tocs);
}

Project: server

double Item_cache_wrapper::val_real()
{
  Item *cached_value;
  DBUG_ENTER("Item_cache_wrapper::val_real");
  if (!expr_cache)
  {
    double tmp= orig_item->val_real();
    null_value= orig_item->null_value;
    DBUG_RETURN(tmp);
  }

  if ((cached_value= check_cache()))
  {
    double tmp= cached_value->val_real();
    null_value= cached_value->null_value;
    DBUG_RETURN(tmp);
  }
  cache();
  null_value= expr_value->null_value;
  DBUG_RETURN(expr_value->val_real());
}

Project: server

double Item_ref_null_helper::val_real()
{
  DBUG_ASSERT(fixed == 1);
  double tmp= (*ref)->val_result();
  owner->was_null|= null_value= (*ref)->null_value;
  return tmp;
}

Project: server

Field *Item::tmp_table_field_from_field_type(TABLE *table, bool fixed_length)
{
  /*
    The field functions defines a field to be not null if null_ptr is not 0
  */
  uchar *null_ptr= maybe_null ? (uchar*) "" : 0;
  Field *field;

  switch (field_type()) {
  case MYSQL_TYPE_DECIMAL:
  case MYSQL_TYPE_NEWDECIMAL:
    field= Field_new_decimal::create_from_item(this);
    break;
  case MYSQL_TYPE_TINY:
    field= new Field_tiny((uchar*) 0, max_length, null_ptr, 0, Field::NONE,
			  name, 0, unsigned_flag);
    break;
  case MYSQL_TYPE_SHORT:
    field= new Field_short((uchar*) 0, max_length, null_ptr, 0, Field::NONE,
			   name, 0, unsigned_flag);
    break;
  case MYSQL_TYPE_LONG:
    field= new Field_long((uchar*) 0, max_length, null_ptr, 0, Field::NONE,
			  name, 0, unsigned_flag);
    break;
#ifdef HAVE_LONG_LONG
  case MYSQL_TYPE_LONGLONG:
    field= new Field_longlong((uchar*) 0, max_length, null_ptr, 0, Field::NONE,
			      name, 0, unsigned_flag);
    break;
#endif
  case MYSQL_TYPE_FLOAT:
    field= new Field_float((uchar*) 0, max_length, null_ptr, 0, Field::NONE,
			   name, decimals, 0, unsigned_flag);
    break;
  case MYSQL_TYPE_DOUBLE:
    field= new Field_double((uchar*) 0, max_length, null_ptr, 0, Field::NONE,
			    name, decimals, 0, unsigned_flag);
    break;
  case MYSQL_TYPE_INT24:
    field= new Field_medium((uchar*) 0, max_length, null_ptr, 0, Field::NONE,
			    name, 0, unsigned_flag);
    break;
  case MYSQL_TYPE_NEWDATE:
  case MYSQL_TYPE_DATE:
    field= new Field_newdate(0, null_ptr, 0, Field::NONE, name, &my_charset_bin);
    break;
  case MYSQL_TYPE_TIME:
    field= new_Field_time(0, null_ptr, 0, Field::NONE, name,
                              decimals, &my_charset_bin);
    break;
  case MYSQL_TYPE_TIMESTAMP:
    field= new_Field_timestamp(0, null_ptr, 0,
                               Field::NONE, name, 0, decimals, &my_charset_bin);
    break;
  case MYSQL_TYPE_DATETIME:
    field= new_Field_datetime(0, null_ptr, 0, Field::NONE, name,
                              decimals, &my_charset_bin);
    break;
  case MYSQL_TYPE_YEAR:
    field= new Field_year((uchar*) 0, max_length, null_ptr, 0, Field::NONE,
			  name);
    break;
  case MYSQL_TYPE_BIT:
    field= new Field_bit_as_char(NULL, max_length, null_ptr, 0,
                                 Field::NONE, name);
    break;
  default:
    /* This case should never be chosen */
    DBUG_ASSERT(0);
    /* If something goes awfully wrong, it's better to get a string than die */
  case MYSQL_TYPE_STRING:
  case MYSQL_TYPE_NULL:
    if (fixed_length && !too_big_for_varchar())
    {
      field= new Field_string(max_length, maybe_null, name,
                              collation.collation);
      break;
    }
    /* fall through */
  case MYSQL_TYPE_ENUM:
  case MYSQL_TYPE_SET:
  case MYSQL_TYPE_VAR_STRING:
  case MYSQL_TYPE_VARCHAR:
    return make_string_field(table);
  case MYSQL_TYPE_TINY_BLOB:
  case MYSQL_TYPE_MEDIUM_BLOB:
  case MYSQL_TYPE_LONG_BLOB:
  case MYSQL_TYPE_BLOB:
    if (this->type() == Item::TYPE_HOLDER)
      field= new Field_blob(max_length, maybe_null, name, collation.collation,
                            1);
    else
      field= new Field_blob(max_length, maybe_null, name, collation.collation);
    break;					// Blob handled outside of case
#ifdef HAVE_SPATIAL
  case MYSQL_TYPE_GEOMETRY:
    field= new Field_geom(max_length, maybe_null,
                          name, table->s, get_geometry_type());
#endif /* HAVE_SPATIAL */
  }
  if (field)
    field->init(table);
  return field;
}

Project: server

String *Item_uint::val_str(String *str)
{
  // following assert is redundant, because fixed=1 assigned in constructor
  DBUG_ASSERT(fixed == 1);
  str->set((ulonglong) value, collation.collation);
  return str;
}

Project: server

Item_equal *Item_field::find_item_equal(COND_EQUAL *cond_equal)
{
  Item_equal *item= 0;
  while (cond_equal)
  {
    List_iterator_fast<Item_equal> li(cond_equal->current_level);
    while ((item= li++))
    {
      if (item->contains(field))
        return item;
    }
    /* 
      The field is not found in any of the multiple equalities
      of the current level. Look for it in upper levels
    */
    cond_equal= cond_equal->upper_levels;
  }
  return 0;
}

Project: server

Item_ident::Item_ident(THD *thd, Item_ident *item)
  :Item(thd, item),
   orig_db_name(item->orig_db_name),
   orig_table_name(item->orig_table_name), 
   orig_field_name(item->orig_field_name),
   context(item->context),
   db_name(item->db_name),
   table_name(item->table_name),
   field_name(item->field_name),
   alias_name_used(item->alias_name_used),
   cached_field_index(item->cached_field_index),
   cached_table(item->cached_table),
   depended_from(item->depended_from),
   can_be_depended(item->can_be_depended)
{}

Project: server

int Item_int::save_in_field(Field *field, bool no_conversions)
{
  return save_int_value_in_field (field, val_int(), null_value, unsigned_flag);
}

Project: server

table_map Item_field::all_used_tables() const
{
  return (get_depended_from() ? OUTER_REF_TABLE_BIT : field->table->map);
}

Project: server

Item *Item_direct_view_ref::equal_fields_propagator(uchar *arg)
{
  Item *field_item= real_item();
  if (field_item->type() != FIELD_ITEM)
    return this;
  Item *item= field_item->equal_fields_propagator(arg);
  set_item_equal(field_item->get_item_equal());
  field_item->set_item_equal(NULL);
  if (item != field_item)
    return item;
  return this;
}

Project: server

double Item_cache_temporal::val_real()
{
  DBUG_ASSERT(fixed == 1);
  if ((!value_cached && !cache_value()) || null_value)
  {
    null_value= true;
    return 0;
  }
  return val_real_from_date();
}

Project: server

bool  Item_cache_temporal::cache_value()
{
  if (!example)
    return false;

  value_cached= true;
 
  MYSQL_TIME ltime;
  if (example->get_date_result(&ltime, 0))
    value=0;
  else
    value= pack_time(&ltime);
  null_value= example->null_value;
  return true;
}

Project: server

longlong Item_null::val_int()
{
  // following assert is redundant, because fixed=1 assigned in constructor
  DBUG_ASSERT(fixed == 1);
  null_value=1;
  return 0;
}

Project: server

bool Item_cache_wrapper::val_bool()
{
  Item *cached_value;
  DBUG_ENTER("Item_cache_wrapper::val_bool");
  if (!expr_cache)
  {
    bool tmp= orig_item->val_bool();
    null_value= orig_item->null_value;
    DBUG_RETURN(tmp);
  }

  if ((cached_value= check_cache()))
  {
    bool tmp= cached_value->val_bool();
    null_value= cached_value->null_value;
    DBUG_RETURN(tmp);
  }
  cache();
  null_value= expr_value->null_value;
  DBUG_RETURN(expr_value->val_bool());
}

Project: server

table_map Item_ref_null_helper::used_tables() const
{
  return (get_depended_from() ?
          OUTER_REF_TABLE_BIT :
          (*ref)->used_tables() | RAND_TABLE_BIT);
}

Project: server

Item *Item_null::safe_charset_converter(CHARSET_INFO *tocs)
{
  collation.set(tocs);
  return this;
}

Project: server

bool Item_direct_view_ref::eq(const Item *item, bool binary_cmp) const
{
  if (item->type() == REF_ITEM)
  {
    Item_ref *item_ref= (Item_ref*) item;
    if (item_ref->ref_type() == VIEW_REF)
    {
      Item *item_ref_ref= *(item_ref->ref);
      return ((*ref)->real_item() == item_ref_ref->real_item());
    }
  }
  return FALSE;
}

Project: server

void Item_cache_row::bring_value()
{
  if (!example)
    return;
  example->bring_value();
  null_value= example->null_value;
  for (uint i= 0; i < item_count; i++)
    values[i]->bring_value();
}

Project: server

void Item_trigger_field::cleanup()
{
  want_privilege= original_privilege;
  /*
    Since special nature of Item_trigger_field we should not do most of
    things from Item_field::cleanup() or Item_ident::cleanup() here.
  */
  Item::cleanup();
}

Project: server

Hybrid_type_traits_decimal::val_int(Hybrid_type *val, bool unsigned_flag) const
{
  longlong result;
  my_decimal2int(E_DEC_FATAL_ERROR, &val->dec_buf[val->used_dec_buf_no],
                 unsigned_flag, &result);
  return result;
}

Project: server

bool Item_field::val_bool_result()
{
  if ((null_value= result_field->is_null()))
    return FALSE;
  switch (result_field->result_type()) {
  case INT_RESULT:
    return result_field->val_int() != 0;
  case DECIMAL_RESULT:
  {
    my_decimal decimal_value;
    my_decimal *val= result_field->val_decimal(&decimal_value);
    if (val)
      return !my_decimal_is_zero(val);
    return 0;
  }
  case REAL_RESULT:
  case STRING_RESULT:
    return result_field->val_real() != 0.0;
  case ROW_RESULT:
  case TIME_RESULT:
  case IMPOSSIBLE_RESULT:
    DBUG_ASSERT(0);
    return 0;                                   // Shut up compiler
  }
  return 0;
}

Project: server

longlong Item_decimal::val_int()
{
  longlong result;
  my_decimal2int(E_DEC_FATAL_ERROR, &decimal_value, unsigned_flag, &result);
  return result;
}

Project: server

void Item_outer_ref::fix_after_pullout(st_select_lex *new_parent, Item **ref)
{
  if (get_depended_from() == new_parent)
  {
    *ref= outer_ref;
    (*ref)->fix_after_pullout(new_parent, ref);
  }
}

Project: server

uint Item::temporal_precision(enum_field_types type)
{
  if (const_item() && result_type() == STRING_RESULT &&
      !is_temporal_type(field_type()))
  {
    MYSQL_TIME ltime;
    String buf, *tmp;
    int was_cut;
    DBUG_ASSERT(fixed);
    if ((tmp= val_str(&buf)) &&
        (type == MYSQL_TYPE_TIME ?
         str_to_time(tmp->charset(), tmp->ptr(), tmp->length(),
                     &ltime, TIME_TIME_ONLY, &was_cut) :
         str_to_datetime(tmp->charset(), tmp->ptr(), tmp->length(),
                         &ltime, TIME_FUZZY_DATES, &was_cut)) >
        MYSQL_TIMESTAMP_ERROR)
      return min(ms_to_precision(ltime.second_part), TIME_SECOND_PART_DIGITS);
  }
  return min(decimals, TIME_SECOND_PART_DIGITS);
}

Project: server

my_decimal *Item_cache_real::val_decimal(my_decimal *decimal_val)
{
  DBUG_ASSERT(fixed == 1);
  if (!has_value())
    return NULL;
  double2my_decimal(E_DEC_FATAL_ERROR, value, decimal_val);
  return decimal_val;
}

Project: server

bool Item_trigger_field::set_value(THD *thd, sp_rcontext * /*ctx*/, Item **it)
{
  Item *item= sp_prepare_func_item(thd, it);

  if (!item)
    return true;

  if (!fixed)
  {
    if (fix_fields(thd, NULL))
      return true;
  }

  // NOTE: field->table->copy_blobs should be false here, but let's
  // remember the value at runtime to avoid subtle bugs.
  bool copy_blobs_saved= field->table->copy_blobs;

  field->table->copy_blobs= true;

  int err_code= item->save_in_field(field, 0);

  field->table->copy_blobs= copy_blobs_saved;

  return err_code < 0;
}

Project: server

bool Item_ref::val_bool()
{
  DBUG_ASSERT(fixed);
  bool tmp= (*ref)->val_bool_result();
  null_value= (*ref)->null_value;
  return tmp;
}

Project: server

Item *Item_hex_constant::safe_charset_converter(CHARSET_INFO *tocs)
{
  Item_string *conv;
  String tmp, *str= val_str(&tmp);

  if (!(conv= new Item_string(str->ptr(), str->length(), tocs)))
    return NULL;
  conv->str_value.copy();
  conv->str_value.mark_as_const();
  return conv;
}

Project: server

bool Item_field::enumerate_field_refs_processor(uchar *arg)
{
  Field_enumerator *fe= (Field_enumerator*)arg;
  fe->visit_field(this);
  return FALSE;
}

Project: server

void Item_cache_wrapper::init_on_demand()
{
    if (!expr_cache->is_inited())
    {
      orig_item->get_cache_parameters(parameters);
      expr_cache->init();
    }
}

Project: server

void Item_cache::store(Item *item)
{
  example= item;
  if (!item)
    null_value= TRUE;
  value_cached= FALSE;
}

Project: server

bool Item_insert_value::eq(const Item *item, bool binary_cmp) const
{
  return item->type() == INSERT_VALUE_ITEM &&
    ((Item_default_value *)item)->arg->eq(arg, binary_cmp);
}

Project: server

void Item_ref::print(String *str, enum_query_type query_type)
{
  if (ref)
  {
    if ((*ref)->type() != Item::CACHE_ITEM && ref_type() != VIEW_REF &&
        !table_name && name && alias_name_used)
    {
      THD *thd= current_thd;
      append_identifier(thd, str, (*ref)->real_item()->name,
                        strlen((*ref)->real_item()->name));
    }
    else
      (*ref)->print(str, query_type);
  }
  else
    Item_ident::print(str, query_type);
}

Project: server

int Item_string::save_in_field(Field *field, bool no_conversions)
{
  String *result;
  result=val_str(&str_value);
  return save_str_value_in_field(field, result);
}

Project: server

double Item_ref::val_real()
{
  DBUG_ASSERT(fixed);
  double tmp=(*ref)->val_result();
  null_value=(*ref)->null_value;
  return tmp;
}

Project: server

void Item::set_name_no_truncate(const char *str, uint length, CHARSET_INFO *cs)
{
  if (!my_charset_same(cs, system_charset_info))
  {
    size_t res_length;
    name= sql_strmake_with_convert(str, length, cs,
				   UINT_MAX, system_charset_info,
				   &res_length);
    name_length= res_length;
  }
  else
    name= sql_strmake(str, (name_length= length));
}

Project: server

Item_ident::Item_ident(Name_resolution_context *context_arg,
                       const char *db_name_arg,const char *table_name_arg,
		       const char *field_name_arg)
  :orig_db_name(db_name_arg), orig_table_name(table_name_arg),
   orig_field_name(field_name_arg), context(context_arg),
   db_name(db_name_arg), table_name(table_name_arg),
   field_name(field_name_arg),
   alias_name_used(FALSE), cached_field_index(NO_CACHED_FIELD_INDEX),
   cached_table(0), depended_from(0), can_be_depended(TRUE)
{
  name = (char*) field_name_arg;
  name_length= name ? strlen(name) : 0;
}

Project: server

void Item_ref::cleanup()
{
  DBUG_ENTER("Item_ref::cleanup");
  Item_ident::cleanup();
  result_field= 0;
  if (reference_trough_name)
  {
    /* We have to reset the reference as it may been freed */
    ref= 0;
  }
  DBUG_VOID_RETURN;
}

Project: server

void Item_param::set_null()
{
  DBUG_ENTER("Item_param::set_null");
  /* These are cleared after each execution by reset() method */
  null_value= 1;
  /* 
    Because of NULL and string values we need to set max_length for each new
    placeholder value: user can submit NULL for any placeholder type, and 
    string length can be different in each execution.
  */
  max_length= 0;
  decimals= 0;
  state= NULL_VALUE;
  item_type= Item::NULL_ITEM;
  DBUG_VOID_RETURN;
}

Project: server

void Item_default_value::print(String *str, enum_query_type query_type)
{
  if (!arg)
  {
    str->append(STRING_WITH_LEN("default"));
    return;
  }
  str->append(STRING_WITH_LEN("default("));
  arg->print(str, query_type);
  str->append(')');
}

Project: server

longlong Item_string::val_int()
{
  DBUG_ASSERT(fixed == 1);
  return longlong_from_string_with_check(str_value.charset(), str_value.ptr(),
                                         str_value.ptr()+ str_value.length());
}

Project: server

void Item_field::save_org_in_field(Field *to)
{
  save_field_in_field(field, &null_value, to, TRUE);
}

Project: server

int Item_decimal::save_in_field(Field *field, bool no_conversions)
{
  field->set_notnull();
  return field->store_decimal(&decimal_value);
}

Project: server

Item* Item_ref::transform(Item_transformer transformer, uchar *arg)
{
  DBUG_ASSERT(!current_thd->stmt_arena->is_stmt_prepare());
  DBUG_ASSERT((*ref) != NULL);

  /* Transform the object we are referencing. */
  Item *new_item= (*ref)->transform(transformer, arg);
  if (!new_item)
    return NULL;

  /*
    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 (*ref != new_item)
    current_thd->change_item_tree(ref, new_item);

  /* Transform the item ref object. */
  return (this->*transformer)(arg);
}

Project: server

bool cmp_items(Item *a, Item *b)
{
  return a->eq(b, FALSE);
}

Project: server

my_decimal *Item_cache_str::val_decimal(my_decimal *decimal_val)
{
  DBUG_ASSERT(fixed == 1);
  if (!has_value())
    return NULL;
  if (value)
    string2my_decimal(E_DEC_FATAL_ERROR, value, decimal_val);
  else
    decimal_val= 0;
  return decimal_val;
}

Project: server

bool Item_name_const::is_null()
{
  return value_item->is_null();
}

Project: server

Item_result Item::cmp_type() const
{
  switch (field_type()) {
  case MYSQL_TYPE_DECIMAL:
  case MYSQL_TYPE_NEWDECIMAL:
                           return DECIMAL_RESULT;
  case MYSQL_TYPE_TINY:
  case MYSQL_TYPE_SHORT:
  case MYSQL_TYPE_LONG:
  case MYSQL_TYPE_LONGLONG:
  case MYSQL_TYPE_INT24:
  case MYSQL_TYPE_YEAR:
  case MYSQL_TYPE_BIT:
                           return INT_RESULT;
  case MYSQL_TYPE_FLOAT:
  case MYSQL_TYPE_DOUBLE:
                           return REAL_RESULT;
  case MYSQL_TYPE_NULL:
  case MYSQL_TYPE_VARCHAR:
  case MYSQL_TYPE_TINY_BLOB:
  case MYSQL_TYPE_MEDIUM_BLOB:
  case MYSQL_TYPE_LONG_BLOB:
  case MYSQL_TYPE_BLOB:
  case MYSQL_TYPE_VAR_STRING:
  case MYSQL_TYPE_STRING:
  case MYSQL_TYPE_ENUM:
  case MYSQL_TYPE_SET:
  case MYSQL_TYPE_GEOMETRY:
                           return STRING_RESULT;
  case MYSQL_TYPE_TIMESTAMP:
  case MYSQL_TYPE_DATE:
  case MYSQL_TYPE_TIME:
  case MYSQL_TYPE_DATETIME:
  case MYSQL_TYPE_NEWDATE:
                           return TIME_RESULT;
  };
  DBUG_ASSERT(0);
  return IMPOSSIBLE_RESULT;
}

Project: server

Item_decimal::Item_decimal(const char *str, const my_decimal *val_arg,
                           uint decimal_par, uint length)
{
  my_decimal2decimal(val_arg, &decimal_value);
  name= (char*) str;
  decimals= (uint8) decimal_par;
  max_length= length;
  fixed= 1;
}

Project: server

longlong Item_datetime::val_int()
{
  return TIME_to_ulonglong(&ltime);
}

Project: server

bool agg_item_charsets(DTCollation &coll, const char *fname,
                       Item **args, uint nargs, uint flags, int item_sep)
{
  if (agg_item_collations(coll, fname, args, nargs, flags, item_sep))
    return TRUE;

  return agg_item_set_converter(coll, fname, args, nargs, flags, item_sep);
}

Project: server

void Item_ref::update_used_tables()
{
  if (!get_depended_from())
    (*ref)->update_used_tables();
}

Project: server

Item_splocal::this_item()
{
  DBUG_ASSERT(m_sp == m_thd->spcont->sp);

  return m_thd->spcont->get_item(m_var_idx);
}

Project: server

void Item_uint::print(String *str, enum_query_type query_type)
{
  // latin1 is good enough for numbers
  str_value.set((ulonglong) value, default_charset());
  str->append(str_value);
}

Project: server

Item_bin_string::Item_bin_string(const char *str, uint str_length)
{
  const char *end= str + str_length - 1;
  uchar bits= 0;
  uint power= 1;

  max_length= (str_length + 7) >> 3;
  char *ptr= (char*) sql_alloc(max_length + 1);
  if (!ptr)
    return;
  str_value.set(ptr, max_length, &my_charset_bin);

  if (max_length > 0)
  {
    ptr+= max_length - 1;
    ptr[1]= 0;                     // Set end null for string
    for (; end >= str; end--)
    {
      if (power == 256)
      {
        power= 1;
        *ptr--= bits;
        bits= 0;
      }
      if (*end == '1')
        bits|= power;
      power<<= 1;
    }
    *ptr= (char) bits;
  }
  else
    ptr[0]= 0;

  collation.set(&my_charset_bin, DERIVATION_COERCIBLE);
  fixed= 1;
}

Project: server

my_decimal *Item::val_decimal_from_real(my_decimal *decimal_value)
{
  double nr= val_real();
  if (null_value)
    return 0;
  double2my_decimal(E_DEC_FATAL_ERROR, nr, decimal_value);
  return (decimal_value);
}

Project: server

String* Item_ref_null_helper::val_str(String* s)
{
  DBUG_ASSERT(fixed == 1);
  String* tmp= (*ref)->str_result(s);
  owner->was_null|= null_value= (*ref)->null_value;
  return tmp;
}

Project: server

void Item::print_item_w_name(String *str, enum_query_type query_type)
{
  print(str, query_type);

  if (name)
  {
    THD *thd= current_thd;
    str->append(STRING_WITH_LEN(" AS "));
    append_identifier(thd, str, name, (uint) strlen(name));
  }
}

Project: server

void Item_int::print(String *str, enum_query_type query_type)
{
  // my_charset_bin is good enough for numbers
  str_value.set_int(value, unsigned_flag, &my_charset_bin);
  str->append(str_value);
}

Project: server

static uint ms_to_precision(uint ms)
{
  uint cut, precision;
  for (cut= 10, precision= 6 ; precision > 0 ; cut*= 10, precision--)
  {
    if (ms % cut)
      return precision;
  }
  return 0;
}

Project: server

void my_coll_agg_error(DTCollation &c1, DTCollation &c2, const char *fname)
{
  my_error(ER_CANT_AGGREGATE_2COLLATIONS,MYF(0),
           c1.collation->name,c1.derivation_name(),
           c2.collation->name,c2.derivation_name(),
           fname);
}

Project: server

Hybrid_type_traits_decimal::fix_length_and_dec(Item *item, Item *arg) const
{
  item->decimals= arg->decimals;
  item->max_length= min(arg->max_length + DECIMAL_LONGLONG_DIGITS,
                        DECIMAL_MAX_STR_LENGTH);
}

Project: server

bool Item_field::send(Protocol *protocol, String *buffer)
{
  return protocol->store(result_field);
}

Project: server

Hybrid_type_traits_decimal::val_str(Hybrid_type *val, String *to,
                                    uint8 decimals) const
{
  my_decimal_round(E_DEC_FATAL_ERROR, &val->dec_buf[val->used_dec_buf_no],
                   decimals, FALSE, &val->dec_buf[2]);
  my_decimal2string(E_DEC_FATAL_ERROR, &val->dec_buf[2], 0, 0, 0, to);
  return to;
}

Project: server

void mark_select_range_as_dependent(THD *thd,
                                    SELECT_LEX *last_select,
                                    SELECT_LEX *current_sel,
                                    Field *found_field, Item *found_item,
                                    Item_ident *resolved_item)
{
  /*
    Go from current SELECT to SELECT where field was resolved (it
    have to be reachable from current SELECT, because it was already
    done once when we resolved this field and cached result of
    resolving)
  */
  SELECT_LEX *previous_select= current_sel;
  for (; previous_select->outer_select() != last_select;
       previous_select= previous_select->outer_select())
  {
    Item_subselect *prev_subselect_item=
      previous_select->master_unit()->item;
    prev_subselect_item->used_tables_cache|= OUTER_REF_TABLE_BIT;
    prev_subselect_item->const_item_cache= 0;
  }
  {
    Item_subselect *prev_subselect_item=
      previous_select->master_unit()->item;
    Item_ident *dependent= resolved_item;
    if (found_field == view_ref_found)
    {
      Item::Type type= found_item->type();
      prev_subselect_item->used_tables_cache|=
        found_item->used_tables();
      dependent= ((type == Item::REF_ITEM || type == Item::FIELD_ITEM) ?
                  (Item_ident*) found_item :
                  0);
    }
    else
      prev_subselect_item->used_tables_cache|=
        found_field->table->map;
    prev_subselect_item->const_item_cache= 0;
    mark_as_dependent(thd, last_select, current_sel, resolved_item,
                      dependent);
  }
}

Project: server

enum_field_types Item::string_field_type() const
{
  enum_field_types f_type= MYSQL_TYPE_VAR_STRING;
  if (max_length >= 16777216)
    f_type= MYSQL_TYPE_LONG_BLOB;
  else if (max_length >= 65536)
    f_type= MYSQL_TYPE_MEDIUM_BLOB;
  return f_type;
}

Project: server

void Item_ref_null_helper::save_val(Field *to)
{
  DBUG_ASSERT(fixed == 1);
  (*ref)->save_val(to);
  owner->was_null|= null_value= (*ref)->null_value;
}

Project: server

bool Item::get_date(MYSQL_TIME *ltime,ulonglong fuzzydate)
{
  if (field_type() == MYSQL_TYPE_TIME)
    fuzzydate|= TIME_TIME_ONLY;

  switch (result_type()) {
  case INT_RESULT:
  {
    longlong value= val_int();
    bool neg= !unsigned_flag && value < 0;
    if (field_type() == MYSQL_TYPE_YEAR)
    {
      if (max_length == 2)
      {
        if (value < 70)
          value+= 2000;
        else if (value <= 1900)
          value+= 1900;
      }
      value*= 10000; /* make it YYYYMMHH */
    }
    if (null_value || int_to_datetime_with_warn(neg, neg ? -value : value,
                                                ltime, fuzzydate,
                                                field_name_or_null()))
      goto err;
    break;
  }
  case REAL_RESULT:
  {
    double value= val_real();
    if (null_value || double_to_datetime_with_warn(value, ltime, fuzzydate,
                                                   field_name_or_null()))
      goto err;
    break;
  }
  case DECIMAL_RESULT:
  {
    my_decimal value, *res;
    if (!(res= val_decimal(&value)) ||
        decimal_to_datetime_with_warn(res, ltime, fuzzydate,
                                      field_name_or_null()))
      goto err;
    break;
  }
  case STRING_RESULT:
  {
    char buff[40];
    String tmp(buff,sizeof(buff), &my_charset_bin),*res;
    if (!(res=val_str(&tmp)) ||
        str_to_datetime_with_warn(res->charset(), res->ptr(), res->length(),
                                  ltime, fuzzydate) <= MYSQL_TIMESTAMP_ERROR)
      goto err;
    break;
  }
  default:
    DBUG_ASSERT(0);
  }

  return null_value= 0;

err:
  /*
    if the item was not null and convertion failed, we return a zero date
    if allowed, otherwise - null.
  */
  bzero((char*) ltime,sizeof(*ltime));
  return null_value|= !(fuzzydate & TIME_FUZZY_DATES);
}

Project: server

void Item_param::reset()
{
  DBUG_ENTER("Item_param::reset");
  /* Shrink string buffer if it's bigger than max possible CHAR column */
  if (str_value.alloced_length() > MAX_CHAR_WIDTH)
    str_value.free();
  else
    str_value.length(0);
  str_value_ptr.length(0);
  /*
    We must prevent all charset conversions until data has been written
    to the binary log.
  */
  str_value.set_charset(&my_charset_bin);
  collation.set(&my_charset_bin, DERIVATION_COERCIBLE);
  state= NO_VALUE;
  maybe_null= 1;
  null_value= 0;
  /*
    Don't reset item_type to PARAM_ITEM: it's only needed to guard
    us from item optimizations at prepare stage, when item doesn't yet
    contain a literal of some kind.
    In all other cases when this object is accessed its value is
    set (this assumption is guarded by 'state' and
    DBUG_ASSERTS(state != NO_VALUE) in all Item_param::get_*
    methods).
  */
  DBUG_VOID_RETURN;
}

Project: server

String *Item_copy_int::val_str(String *str)
{
  if (null_value)
    return (String *) 0;

  str->set(cached_value, &my_charset_bin);
  return str;
}

Project: server

void Item_ref::save_result(Field *to)
{
  if (result_field)
  {
    save_field_in_field(result_field, &null_value, to, TRUE);
    return;
  }
  (*ref)->save_result(to);
  null_value= (*ref)->null_value;
}

Project: server

void Item_direct_ref::save_val(Field *to)
{
  (*ref)->save_val(to);
  null_value=(*ref)->null_value;
}

Project: server

Item_int::Item_int(const char *str_arg, uint length)
{
  char *end_ptr= (char*) str_arg + length;
  int error;
  value= my_strtoll10(str_arg, &end_ptr, &error);
  max_length= (uint) (end_ptr - str_arg);
  name= (char*) str_arg;
  fixed= 1;
}

Project: server

void Item_decimal::set_decimal_value(my_decimal *value_par)
{
  my_decimal2decimal(value_par, &decimal_value);
  decimals= (uint8) decimal_value.frac;
  unsigned_flag= !decimal_value.sign();
  max_length= my_decimal_precision_to_length_no_truncation(decimal_value.intg +
                                                           decimals,
                                                           decimals,
                                                           unsigned_flag);
}

Project: server

my_decimal *Item_float::val_decimal(my_decimal *decimal_value)
{
  // following assert is redundant, because fixed=1 assigned in constructor
  DBUG_ASSERT(fixed == 1);
  double2my_decimal(E_DEC_FATAL_ERROR, value, decimal_value);
  return (decimal_value);
}

Project: server

Hybrid_type_traits_decimal::val_real(Hybrid_type *val) const
{
  my_decimal2double(E_DEC_FATAL_ERROR, &val->dec_buf[val->used_dec_buf_no],
                    &val->real);
  return val->real;
}

Project: server

  Item_aggregate_ref(Name_resolution_context *context_arg, Item **item,
                  const char *table_name_arg, const char *field_name_arg)
    :Item_ref(context_arg, item, table_name_arg, field_name_arg) {}

Project: server

void Item_cache_temporal::store_packed(longlong val_arg, Item *example)
{
  /* An explicit values is given, save it. */
  store(example);
  value_cached= true;
  value= val_arg;
  null_value= false;
}

Project: server

table_map Item_direct_view_ref::not_null_tables() const
{
  return get_depended_from() ?
         0 :
         ((view->is_merged_derived() || view->merged || !view->table) ?
          (*ref)->not_null_tables() :
          view->table->map);
}

Project: server

bool Item_ref_null_helper::get_date(MYSQL_TIME *ltime, ulonglong fuzzydate)
{  
  return (owner->was_null|= null_value= (*ref)->get_date_result(ltime, fuzzydate));
}

Project: server

void Item_param::set_decimal(const char *str, ulong length)
{
  char *end;
  DBUG_ENTER("Item_param::set_decimal");

  end= (char*) str+length;
  str2my_decimal(E_DEC_FATAL_ERROR, str, &decimal_value, &end);
  state= DECIMAL_VALUE;
  decimals= decimal_value.frac;
  max_length=
    my_decimal_precision_to_length_no_truncation(decimal_value.precision(),
                                                 decimals, unsigned_flag);
  maybe_null= 0;
  DBUG_VOID_RETURN;
}

Project: server

String *Item_cache_temporal::val_str(String *str)
{
  DBUG_ASSERT(fixed == 1);
  if (!has_value())
  {
    null_value= true;
    return NULL;
  }
  return val_string_from_date(str);
}

Project: server

int Item_datetime::save_in_field(Field *field, bool no_conversions)
{
  field->set_notnull();
  return field->store_time_dec(&ltime, decimals);
}

Project: server

Item* Item_ref::compile(Item_analyzer analyzer, uchar **arg_p,
                        Item_transformer transformer, uchar *arg_t)
{
  /* Analyze this Item object. */
  if (!(this->*analyzer)(arg_p))
    return NULL;

  /* Compile the Item we are referencing. */
  DBUG_ASSERT((*ref) != NULL);
  if (*arg_p)
  {
    uchar *arg_v= *arg_p;
    Item *new_item= (*ref)->compile(analyzer, &arg_v, transformer, arg_t);
    if (new_item && *ref != new_item)
      current_thd->change_item_tree(ref, new_item);
  }

  /* Transform this Item object. */
  return (this->*transformer)(arg_t);
}

Project: server

void item_init(void)
{
  item_user_lock_init();
  uuid_short_init();
}

Project: server

bool Item_string::eq(const Item *item, bool binary_cmp) const
{
  if (type() == item->type() && item->basic_const_item())
  {
    if (binary_cmp)
      return !stringcmp(&str_value, &item->str_value);
    return (collation.collation == item->collation.collation &&
	    !sortcmp(&str_value, &item->str_value, collation.collation));
  }
  return 0;
}

Project: server

void Item_param::print(String *str, enum_query_type query_type)
{
  if (state == NO_VALUE || query_type & QT_NO_DATA_EXPANSION)
  {
    str->append('?');
  }
  else
  {
    char buffer[STRING_BUFFER_USUAL_SIZE];
    String tmp(buffer, sizeof(buffer), &my_charset_bin);
    const String *res;
    res= query_val_str(current_thd, &tmp);
    str->append(*res);
  }
}

Project: server

longlong Item_ref::val_int_result()
{
  if (result_field)
  {
    if ((null_value= result_field->is_null()))
      return 0;
    return result_field->val_int();
  }
  return val_int();
}

Project: server

Item *Item_field::get_tmp_table_item(THD *thd)
{
  Item_field *new_item= new Item_field(thd, this);
  if (new_item)
    new_item->field= new_item->result_field;
  return new_item;
}

Project: server

default_set_param_func(Item_param *param,
                       uchar **pos __attribute__((unused)),
                       ulong len __attribute__((unused)))
{
  param->set_null();
}

Project: server

bool Item_splocal::set_value(THD *thd, sp_rcontext *ctx, Item **it)
{
  return ctx->set_variable(thd, get_var_idx(), it);
}

Project: server

bool Item_direct_ref::get_date(MYSQL_TIME *ltime,ulonglong fuzzydate)
{
  return (null_value=(*ref)->get_date(ltime,fuzzydate));
}

Project: server

void Item::rename(char *new_name)
{
  /*
    we can compare pointers to names here, because if name was not changed,
    pointer will be same
  */
  if (!orig_name && new_name != name)
    orig_name= name;
  name= new_name;
}

Project: server

inline uint char_val(char X)
{
  return (uint) (X >= '0' && X <= '9' ? X-'0' :
		 X >= 'A' && X <= 'Z' ? X-'A'+10 :
		 X-'a'+10);
}

Project: server

int Item::save_date_in_field(Field *field)
{
  MYSQL_TIME ltime;
  if (get_date(&ltime, (current_thd->variables.sql_mode &
                        (MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE |
                         MODE_INVALID_DATES))))
    return set_field_to_null_with_conversions(field, 0);
  field->set_notnull();
  return field->store_time_dec(&ltime, decimals);
}

Project: server

int Item_default_value::save_in_field(Field *field_arg, bool no_conversions)
{
  if (!arg)
  {
    if (field_arg->flags & NO_DEFAULT_VALUE_FLAG &&
        field_arg->real_type() != MYSQL_TYPE_ENUM)
    {
      if (field_arg->reset())
      {
        my_message(ER_CANT_CREATE_GEOMETRY_OBJECT,
                   ER(ER_CANT_CREATE_GEOMETRY_OBJECT), MYF(0));
        return -1;
      }

      if (context->error_processor == &view_error_processor)
      {
        TABLE_LIST *view= field_arg->table->pos_in_table_list->top_table();
        push_warning_printf(field_arg->table->in_use,
                            MYSQL_ERROR::WARN_LEVEL_WARN,
                            ER_NO_DEFAULT_FOR_VIEW_FIELD,
                            ER(ER_NO_DEFAULT_FOR_VIEW_FIELD),
                            view->view_db.str,
                            view->view_name.str);
      }
      else
      {
        push_warning_printf(field_arg->table->in_use,
                            MYSQL_ERROR::WARN_LEVEL_WARN,
                            ER_NO_DEFAULT_FOR_FIELD,
                            ER(ER_NO_DEFAULT_FOR_FIELD),
                            field_arg->field_name);
      }
      return 1;
    }
    field_arg->set_default();
    return 0;
  }
  return Item_field::save_in_field(field_arg, no_conversions);
}

Project: server

bool Item_int::eq(const Item *arg, bool binary_cmp) const
{
  /* No need to check for null value as basic constant can't be NULL */
  if (arg->basic_const_item() && arg->type() == type())
  {
    /*
      We need to cast off const to call val_int(). This should be OK for
      a basic constant.
    */
    Item *item= (Item*) arg;
    return (item->val_int() == value &&
            ((longlong) value >= 0 ||
             (item->unsigned_flag == unsigned_flag)));
  }
  return FALSE;
}

Project: server

int Item_cache_wrapper::save_in_field(Field *to, bool no_conversions)
{
  int res;
  DBUG_ASSERT(!result_field);
  res= orig_item->save_in_field(to, no_conversions);
  null_value= orig_item->null_value;
  return res;
}

Project: server

  virtual inline void print (String *str, enum_query_type query_type)
  {
    if (ref)
      (*ref)->print(str, query_type);
    else
      Item_ident::print(str, query_type);
  }

Project: server

Item_ref::Item_ref(TABLE_LIST *view_arg, Item **item,
                   const char *field_name_arg, bool alias_name_used_arg)
  :Item_ident(view_arg, field_name_arg),
   result_field(NULL), ref(item), reference_trough_name(0)
{
  alias_name_used= alias_name_used_arg;
  /*
    This constructor is used to create some internal references over fixed items
  */
  if ((set_properties_only= (ref && *ref && (*ref)->fixed)))
    set_properties();
}

Project: server

  virtual void visit_field(Item_field *item)
  {
    // Find which select the field is in. This is achieved by walking up 
    // the select tree and looking for the table of interest.
    st_select_lex *sel;
    for (sel= current_select;
         sel ;
         sel= (sel->context.outer_context ?
               sel->context.outer_context->select_lex:
               NULL))
    {
      List_iterator<TABLE_LIST> li(sel->leaf_tables);
      TABLE_LIST *tbl;
      while ((tbl= li++))
      {
        if (tbl->table == item->field->table)
        {
          if (sel != current_select)
            mark_as_dependent(thd, sel, current_select, item, item);
          return;
        }
      }
    }
  }

Project: server

bool Item_ref::val_bool_result()
{
  if (result_field)
  {
    if ((null_value= result_field->is_null()))
      return 0;
    switch (result_field->result_type()) {
    case INT_RESULT:
      return result_field->val_int() != 0;
    case DECIMAL_RESULT:
    {
      my_decimal decimal_value;
      my_decimal *val= result_field->val_decimal(&decimal_value);
      if (val)
        return !my_decimal_is_zero(val);
      return 0;
    }
    case REAL_RESULT:
    case STRING_RESULT:
      return result_field->val_real() != 0.0;
    case ROW_RESULT:
    case TIME_RESULT:
    case IMPOSSIBLE_RESULT:
      DBUG_ASSERT(0);
    }
  }
  return val_bool();
}

Project: server

enum_field_types Item_type_holder::get_real_type(Item *item)
{
  if (item->type() == REF_ITEM)
    item= item->real_item();
  switch(item->type())
  {
  case FIELD_ITEM:
  {
    /*
      Item_field::field_type ask Field_type() but sometimes field return
      a different type, like for enum/set, so we need to ask real type.
    */
    Field *field= ((Item_field *) item)->field;
    enum_field_types type= field->real_type();
    if (field->is_created_from_null_item)
      return MYSQL_TYPE_NULL;
    /* work around about varchar type field detection */
    if (type == MYSQL_TYPE_STRING && field->type() == MYSQL_TYPE_VAR_STRING)
      return MYSQL_TYPE_VAR_STRING;
    return type;
  }
  case SUM_FUNC_ITEM:
  {
    /*
      Argument of aggregate function sometimes should be asked about field
      type
    */
    Item_sum *item_sum= (Item_sum *) item;
    if (item_sum->keep_field_type())
      return get_real_type(item_sum->get_arg(0));
    break;
  }
  case FUNC_ITEM:
    if (((Item_func *) item)->functype() == Item_func::GUSERVAR_FUNC)
    {
      /*
        There are work around of problem with changing variable type on the
        fly and variable always report "string" as field type to get
        acceptable information for client in send_field, so we make field
        type from expression type.
      */
      switch (item->result_type()) {
      case STRING_RESULT:
        return MYSQL_TYPE_VAR_STRING;
      case INT_RESULT:
        return MYSQL_TYPE_LONGLONG;
      case REAL_RESULT:
        return MYSQL_TYPE_DOUBLE;
      case DECIMAL_RESULT:
        return MYSQL_TYPE_NEWDECIMAL;
      case ROW_RESULT:
      case TIME_RESULT:
      case IMPOSSIBLE_RESULT:
        DBUG_ASSERT(0);
        return MYSQL_TYPE_VAR_STRING;
      }
    }
    break;
  default:
    break;
  }
  return item->field_type();
}

Project: server

uint32 Item_type_holder::display_length(Item *item)
{
  if (item->type() == Item::FIELD_ITEM)
    return ((Item_field *)item)->max_disp_length();

  switch (item->field_type())
  {
  case MYSQL_TYPE_DECIMAL:
  case MYSQL_TYPE_TIMESTAMP:
  case MYSQL_TYPE_DATE:
  case MYSQL_TYPE_TIME:
  case MYSQL_TYPE_DATETIME:
  case MYSQL_TYPE_YEAR:
  case MYSQL_TYPE_NEWDATE:
  case MYSQL_TYPE_VARCHAR:
  case MYSQL_TYPE_BIT:
  case MYSQL_TYPE_NEWDECIMAL:
  case MYSQL_TYPE_ENUM:
  case MYSQL_TYPE_SET:
  case MYSQL_TYPE_TINY_BLOB:
  case MYSQL_TYPE_MEDIUM_BLOB:
  case MYSQL_TYPE_LONG_BLOB:
  case MYSQL_TYPE_BLOB:
  case MYSQL_TYPE_VAR_STRING:
  case MYSQL_TYPE_STRING:
  case MYSQL_TYPE_GEOMETRY:
    return item->max_length;
  case MYSQL_TYPE_TINY:
    return 4;
  case MYSQL_TYPE_SHORT:
    return 6;
  case MYSQL_TYPE_LONG:
    return MY_INT32_NUM_DECIMAL_DIGITS;
  case MYSQL_TYPE_FLOAT:
    return 25;
  case MYSQL_TYPE_DOUBLE:
    return 53;
  case MYSQL_TYPE_NULL:
    return 0;
  case MYSQL_TYPE_LONGLONG:
    return 20;
  case MYSQL_TYPE_INT24:
    return 8;
  default:
    DBUG_ASSERT(0); // we should never go there
    return 0;
  }
}

Project: server

Item *Item_static_string_func::safe_charset_converter(CHARSET_INFO *tocs)
{
  Item_string *conv;
  uint conv_errors;
  String tmp, cstr, *ostr= val_str(&tmp);
  cstr.copy(ostr->ptr(), ostr->length(), ostr->charset(), tocs, &conv_errors);
  if (conv_errors ||
      !(conv= new Item_static_string_func(func_name,
                                          cstr.ptr(), cstr.length(),
                                          cstr.charset(),
                                          collation.derivation)))
  {
    /*
      Safe conversion is not possible (or EOM).
      We could not convert a string into the requested character set
      without data loss. The target charset does not cover all the
      characters from the string. Operation cannot be done correctly.
    */
    return NULL;
  }
  conv->str_value.copy();
  /* Ensure that no one is going to change the result string */
  conv->str_value.mark_as_const();
  return conv;
}

Project: server

Item_cache_temporal::Item_cache_temporal(enum_field_types field_type_arg):
  Item_cache_int(field_type_arg)
{
  if (mysql_type_to_time_type(cached_field_type) == MYSQL_TIMESTAMP_ERROR)
    cached_field_type= MYSQL_TYPE_DATETIME;
}

Project: server

String *Item_ref::val_str(String* tmp)
{
  DBUG_ASSERT(fixed);
  tmp=(*ref)->str_result(tmp);
  null_value=(*ref)->null_value;
  return tmp;
}

Project: server

String *Item_copy_decimal::val_str(String *result)
{
  if (null_value)
    return (String *) 0;
  result->set_charset(&my_charset_bin);
  my_decimal2string(E_DEC_FATAL_ERROR, &cached_value, 0, 0, 0, result);
  return result;
}

Project: server

bool Item_direct_view_ref::send(Protocol *protocol, String *buffer)
{
  if (check_null_ref())
    return protocol->store_null();
  return Item_direct_ref::send(protocol, buffer);
}

Project: server

double Item_decimal::val_real()
{
  double result;
  my_decimal2double(E_DEC_FATAL_ERROR, &decimal_value, &result);
  return result;
}

Project: server

const String *Item_param::query_val_str(THD *thd, String* str) const
{
  switch (state) {
  case INT_VALUE:
    str->set_int(value.integer, unsigned_flag, &my_charset_bin);
    break;
  case REAL_VALUE:
    str->set_real(value.real, NOT_FIXED_DEC, &my_charset_bin);
    break;
  case DECIMAL_VALUE:
    if (my_decimal2string(E_DEC_FATAL_ERROR, &decimal_value,
                          0, 0, 0, str) > 1)
      return &my_null_string;
    break;
  case TIME_VALUE:
    {
      char *buf, *ptr;
      str->length(0);
      /*
        TODO: in case of error we need to notify replication
        that binary log contains wrong statement 
      */
      if (str->reserve(MAX_DATE_STRING_REP_LENGTH+3))
        break; 

      /* Create date string inplace */
      buf= str->c_ptr_quick();
      ptr= buf;
      *ptr++= '\'';
      ptr+= (uint) my_TIME_to_str(&value.time, ptr, decimals);
      *ptr++= '\'';
      str->length((uint32) (ptr - buf));
      break;
    }
  case STRING_VALUE:
  case LONG_DATA_VALUE:
    {
      str->length(0);
      append_query_string(thd, value.cs_info.character_set_client, &str_value,
                          str);
      break;
    }
  case NULL_VALUE:
    return &my_null_string;
  default:
    DBUG_ASSERT(0);
  }
  return str;
}

Project: server

inline void Item_cache_wrapper::cache()
{
  expr_value->store(orig_item);
  expr_value->cache_value();
  expr_cache->put_value(expr_value); // put in expr_cache
}

Project: server

bool Item_cache_row::null_inside()
{
  for (uint i= 0; i < item_count; i++)
  {
    if (values[i]->cols() > 1)
    {
      if (values[i]->null_inside())
	return 1;
    }
    else
    {
      values[i]->update_null_value();
      if (values[i]->null_value)
	return 1;
    }
  }
  return 0;
}

Project: server

my_decimal *Item_name_const::val_decimal(my_decimal *decimal_value)
{
  DBUG_ASSERT(fixed);
  my_decimal *val= value_item->val_decimal(decimal_value);
  null_value= value_item->null_value;
  return val;
}

Project: server

bool Item_direct_view_ref::subst_argument_checker(uchar **arg)
{
  bool res= FALSE;
  if (*arg)
  { 
    Item *item= real_item();
    if (item->type() == FIELD_ITEM &&
        (*arg == (uchar *) Item::ANY_SUBST || 
         result_type() != STRING_RESULT ||
         (((Item_field *) item)->field->flags & BINARY_FLAG)))
      res= TRUE;
  }
  /* Block any substitution into the wrapped object */
  if (*arg)
    *arg= NULL; 
  return res; 
}

Project: server

bool Item_ref::is_null_result()
{
  if (result_field)
    return (null_value=result_field->is_null());

  return is_null();
}

Project: server

String* Item_cache_real::val_str(String *str)
{
  DBUG_ASSERT(fixed == 1);
  if (!has_value())
    return NULL;
  str->set_real(value, decimals, default_charset());
  return str;
}

Project: server

longlong Item_param::val_int() 
{ 
  switch (state) {
  case REAL_VALUE:
    return (longlong) rint(value.real);
  case INT_VALUE:
    return value.integer;
  case DECIMAL_VALUE:
  {
    longlong i;
    my_decimal2int(E_DEC_FATAL_ERROR, &decimal_value, unsigned_flag, &i);
    return i;
  }
  case STRING_VALUE:
  case LONG_DATA_VALUE:
    {
      int dummy_err;
      return my_strntoll(str_value.charset(), str_value.ptr(),
                         str_value.length(), 10, (char**) 0, &dummy_err);
    }
  case TIME_VALUE:
    return (longlong) TIME_to_ulonglong(&value.time);
  case NULL_VALUE:
    return 0; 
  default:
    DBUG_ASSERT(0);
  }
  return 0;
}

Project: server

void Item_field::save_result(Field *to)
{
  save_field_in_field(result_field, &null_value, to, TRUE);
}

Project: server

String *Item_field::str_result(String *str)
{
  if ((null_value=result_field->is_null()))
    return 0;
  str->set_charset(str_value.charset());
  return result_field->val_str(str,&str_value);
}

Project: server

void Hybrid_type_traits_decimal::set_zero(Hybrid_type *val) const
{
  my_decimal_set_zero(&val->dec_buf[0]);
  val->used_dec_buf_no= 0;
}

Project: server

Item_decimal::Item_decimal(const char *str_arg, uint length,
                           CHARSET_INFO *charset)
{
  str2my_decimal(E_DEC_FATAL_ERROR, str_arg, length, charset, &decimal_value);
  name= (char*) str_arg;
  decimals= (uint8) decimal_value.frac;
  fixed= 1;
  max_length= my_decimal_precision_to_length_no_truncation(decimal_value.intg +
                                                           decimals,
                                                           decimals,
                                                           unsigned_flag);
}

Project: server

my_decimal *Item_param::val_decimal(my_decimal *dec)
{
  switch (state) {
  case DECIMAL_VALUE:
    return &decimal_value;
  case REAL_VALUE:
    double2my_decimal(E_DEC_FATAL_ERROR, value.real, dec);
    return dec;
  case INT_VALUE:
    int2my_decimal(E_DEC_FATAL_ERROR, value.integer, unsigned_flag, dec);
    return dec;
  case STRING_VALUE:
  case LONG_DATA_VALUE:
    string2my_decimal(E_DEC_FATAL_ERROR, &str_value, dec);
    return dec;
  case TIME_VALUE:
  {
    longlong i= (longlong) TIME_to_ulonglong(&value.time);
    int2my_decimal(E_DEC_FATAL_ERROR, i, 0, dec);
    return dec;
  }
  case NULL_VALUE:
    return 0; 
  default:
    DBUG_ASSERT(0);
  }
  return 0;
}

Project: server

my_decimal *Item_copy_string::val_decimal(my_decimal *decimal_value)
{
  // Item_copy_string is used without fix_fields call
  if (null_value)
    return (my_decimal *) 0;
  string2my_decimal(E_DEC_FATAL_ERROR, &str_value, decimal_value);
  return (decimal_value);
}

Project: server

Item_splocal::this_item() const
{
  DBUG_ASSERT(m_sp == m_thd->spcont->sp);

  return m_thd->spcont->get_item(m_var_idx);
}