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

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

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

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


/* Buffers to save and compare item values */

#include "mysql_priv.h"

/*
unknown's avatar
unknown committed
23
** Create right type of Cached_item for an item
unknown's avatar
unknown committed
24 25
*/

unknown's avatar
unknown committed
26
Cached_item *new_Cached_item(THD *thd, Item *item)
unknown's avatar
unknown committed
27 28 29
{
  if (item->type() == Item::FIELD_ITEM &&
      !(((Item_field *) item)->field->flags & BLOB_FLAG))
unknown's avatar
unknown committed
30
    return new Cached_item_field((Item_field *) item);
31
  switch (item->result_type()) {
unknown's avatar
unknown committed
32
  case STRING_RESULT:
unknown's avatar
unknown committed
33
    return new Cached_item_str(thd, (Item_field *) item);
unknown's avatar
unknown committed
34
  case INT_RESULT:
unknown's avatar
unknown committed
35
    return new Cached_item_int((Item_field *) item);
unknown's avatar
unknown committed
36
  case REAL_RESULT:
unknown's avatar
unknown committed
37
    return new Cached_item_real(item);
unknown's avatar
unknown committed
38
  case DECIMAL_RESULT:
unknown's avatar
unknown committed
39
    return new Cached_item_decimal(item);
unknown's avatar
unknown committed
40 41 42 43 44
  case ROW_RESULT:
  default:
    DBUG_ASSERT(0);
    return 0;
  }
unknown's avatar
unknown committed
45 46
}

unknown's avatar
unknown committed
47
Cached_item::~Cached_item() {}
unknown's avatar
unknown committed
48 49 50 51 52 53

/*
** Compare with old value and replace value with new value
** Return true if values have changed
*/

unknown's avatar
unknown committed
54
Cached_item_str::Cached_item_str(THD *thd, Item *arg)
unknown's avatar
unknown committed
55
  :item(arg), value(min(arg->max_length, thd->variables.max_sort_length))
56 57
{}

unknown's avatar
unknown committed
58
bool Cached_item_str::cmp(void)
unknown's avatar
unknown committed
59 60 61 62
{
  String *res;
  bool tmp;

unknown's avatar
unknown committed
63 64
  if ((res=item->val_str(&tmp_value)))
    res->length(min(res->length(), value.alloced_length()));
unknown's avatar
unknown committed
65 66 67 68 69 70 71 72 73
  if (null_value != item->null_value)
  {
    if ((null_value= item->null_value))
      return TRUE;				// New value was null
    tmp=TRUE;
  }
  else if (null_value)
    return 0;					// new and old value was null
  else
74
    tmp= sortcmp(&value,res,item->collation.collation) != 0;
unknown's avatar
unknown committed
75 76 77 78 79
  if (tmp)
    value.copy(*res);				// Remember for next cmp
  return tmp;
}

unknown's avatar
unknown committed
80
Cached_item_str::~Cached_item_str()
unknown's avatar
unknown committed
81 82 83 84
{
  item=0;					// Safety
}

unknown's avatar
unknown committed
85
bool Cached_item_real::cmp(void)
unknown's avatar
unknown committed
86
{
87
  double nr= item->val_real();
unknown's avatar
unknown committed
88 89 90 91 92 93 94 95 96
  if (null_value != item->null_value || nr != value)
  {
    null_value= item->null_value;
    value=nr;
    return TRUE;
  }
  return FALSE;
}

unknown's avatar
unknown committed
97
bool Cached_item_int::cmp(void)
unknown's avatar
unknown committed
98 99 100 101 102 103 104 105 106 107 108 109
{
  longlong nr=item->val_int();
  if (null_value != item->null_value || nr != value)
  {
    null_value= item->null_value;
    value=nr;
    return TRUE;
  }
  return FALSE;
}


unknown's avatar
unknown committed
110
bool Cached_item_field::cmp(void)
unknown's avatar
unknown committed
111 112 113
{
  bool tmp= field->cmp(buff) != 0;		// This is not a blob!
  if (tmp)
unknown's avatar
unknown committed
114
    field->get_image(buff,length,field->charset());
unknown's avatar
unknown committed
115 116 117 118 119 120 121 122 123
  if (null_value != field->is_null())
  {
    null_value= !null_value;
    tmp=TRUE;
  }
  return tmp;
}


unknown's avatar
unknown committed
124
Cached_item_decimal::Cached_item_decimal(Item *it)
unknown's avatar
unknown committed
125 126 127 128 129 130
  :item(it)
{
  my_decimal_set_zero(&value);
}


unknown's avatar
unknown committed
131
bool Cached_item_decimal::cmp()
unknown's avatar
unknown committed
132 133 134 135 136 137 138 139 140 141 142 143 144
{
  my_decimal tmp;
  my_decimal *ptmp= item->val_decimal(&tmp);
  if (null_value != item->null_value || my_decimal_cmp(&value, ptmp) == 0)
  {
    null_value= item->null_value;
    my_decimal2decimal(ptmp, &value);
    return TRUE;
  }
  return FALSE;
}


unknown's avatar
unknown committed
145 146 147 148
/*****************************************************************************
** Instansiate templates
*****************************************************************************/

149
#ifdef EXPLICIT_TEMPLATE_INSTANTIATION
unknown's avatar
unknown committed
150 151
template class List<Cached_item>;
template class List_iterator<Cached_item>;
unknown's avatar
unknown committed
152
#endif