MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
item_buff.cc
Go to the documentation of this file.
1 /* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
2 
3  This program is free software; you can redistribute it and/or modify
4  it under the terms of the GNU General Public License as published by
5  the Free Software Foundation; version 2 of the License.
6 
7  This program is distributed in the hope that it will be useful,
8  but WITHOUT ANY WARRANTY; without even the implied warranty of
9  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  GNU General Public License for more details.
11 
12  You should have received a copy of the GNU General Public License
13  along with this program; if not, write to the Free Software Foundation,
14  51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */
15 
16 
24 #include "sql_priv.h"
25 /*
26  It is necessary to include set_var.h instead of item.h because there
27  are dependencies on include order for set_var.h and item.h. This
28  will be resolved later.
29 */
30 #include "sql_class.h" // THD
31 #include "set_var.h" // Cached_item, Cached_item_field, ...
32 
33 using std::min;
34 using std::max;
35 
40 Cached_item *new_Cached_item(THD *thd, Item *item, bool use_result_field)
41 {
42  if (item->real_item()->type() == Item::FIELD_ITEM &&
43  !(((Item_field *) (item->real_item()))->field->flags & BLOB_FLAG))
44  {
45  Item_field *real_item= (Item_field *) item->real_item();
46  Field *cached_field= use_result_field ? real_item->result_field :
47  real_item->field;
48  return new Cached_item_field(cached_field);
49  }
50  switch (item->result_type()) {
51  case STRING_RESULT:
52  if (item->is_temporal())
53  return new Cached_item_temporal((Item_field *) item);
54  return new Cached_item_str(thd, (Item_field *) item);
55  case INT_RESULT:
56  return new Cached_item_int((Item_field *) item);
57  case REAL_RESULT:
58  return new Cached_item_real(item);
59  case DECIMAL_RESULT:
60  return new Cached_item_decimal(item);
61  case ROW_RESULT:
62  default:
63  DBUG_ASSERT(0);
64  return 0;
65  }
66 }
67 
68 Cached_item::~Cached_item() {}
69 
78  :item(arg),
79  value_max_length(min<uint32>(arg->max_length, thd->variables.max_sort_length)),
80  value(value_max_length)
81 {}
82 
83 bool Cached_item_str::cmp(void)
84 {
85  String *res;
86  bool tmp;
87 
88  DBUG_ENTER("Cached_item_str::cmp");
89  DBUG_ASSERT(!item->is_temporal());
90  if ((res=item->val_str(&tmp_value)))
91  res->length(min(res->length(), value_max_length));
92  DBUG_PRINT("info", ("old: %s, new: %s",
93  value.c_ptr_safe(), res ? res->c_ptr_safe() : ""));
94  if (null_value != item->null_value)
95  {
96  if ((null_value= item->null_value))
97  DBUG_RETURN(TRUE); // New value was null
98  tmp=TRUE;
99  }
100  else if (null_value)
101  DBUG_RETURN(0); // new and old value was null
102  else
103  tmp= sortcmp(&value,res,item->collation.collation) != 0;
104  if (tmp)
105  value.copy(*res); // Remember for next cmp
106  DBUG_RETURN(tmp);
107 }
108 
109 Cached_item_str::~Cached_item_str()
110 {
111  item=0; // Safety
112 }
113 
114 bool Cached_item_real::cmp(void)
115 {
116  DBUG_ENTER("Cached_item_real::cmp");
117  double nr= item->val_real();
118  DBUG_PRINT("info", ("old: %f, new: %f", value, nr));
119  if (null_value != item->null_value || nr != value)
120  {
121  null_value= item->null_value;
122  value=nr;
123  DBUG_RETURN(TRUE);
124  }
125  DBUG_RETURN(FALSE);
126 }
127 
128 bool Cached_item_int::cmp(void)
129 {
130  DBUG_ENTER("Cached_item_int::cmp");
131  longlong nr=item->val_int();
132  DBUG_PRINT("info", ("old: %lld, new: %lld", value, nr));
133  if (null_value != item->null_value || nr != value)
134  {
135  null_value= item->null_value;
136  value=nr;
137  DBUG_RETURN(TRUE);
138  }
139  DBUG_RETURN(FALSE);
140 }
141 
142 
143 bool Cached_item_temporal::cmp(void)
144 {
145  DBUG_ENTER("Cached_item_temporal::cmp");
146  longlong nr= item->val_temporal_by_field_type();
147  DBUG_PRINT("info", ("old: %lld, new: %lld", value, nr));
148  if (null_value != item->null_value || nr != value)
149  {
150  null_value= item->null_value;
151  value= nr;
152  DBUG_RETURN(TRUE);
153  }
154  DBUG_RETURN(FALSE);
155 }
156 
157 
158 bool Cached_item_field::cmp(void)
159 {
160  DBUG_ENTER("Cached_item_field::cmp");
161  DBUG_EXECUTE("info", dbug_print(););
162 
163  bool different= false;
164 
165  if (field->is_null())
166  {
167  if (!null_value)
168  {
169  different= true;
170  null_value= true;
171  }
172  }
173  else
174  {
175  if (null_value)
176  {
177  different= true;
178  null_value= false;
179  field->get_image(buff, length, field->charset());
180  }
181  else if (field->cmp(buff)) // Not a blob: cmp() is OK
182  {
183  different= true;
184  field->get_image(buff, length, field->charset());
185  }
186  }
187 
188  DBUG_RETURN(different);
189 }
190 
191 
192 Cached_item_decimal::Cached_item_decimal(Item *it)
193  :item(it)
194 {
195  my_decimal_set_zero(&value);
196 }
197 
198 
199 bool Cached_item_decimal::cmp()
200 {
201  my_decimal tmp;
202  my_decimal *ptmp= item->val_decimal(&tmp);
203  if (null_value != item->null_value ||
204  (!item->null_value && my_decimal_cmp(&value, ptmp)))
205  {
206  null_value= item->null_value;
207  /* Save only not null values */
208  if (!null_value)
209  {
210  my_decimal2decimal(ptmp, &value);
211  return TRUE;
212  }
213  return FALSE;
214  }
215  return FALSE;
216 }