1 | /* |
2 | Copyright (c) 2000, 2017, Oracle and/or its affiliates. |
3 | Copyright (c) 2008, 2017, MariaDB |
4 | |
5 | This program is free software; you can redistribute it and/or modify |
6 | it under the terms of the GNU General Public License as published by |
7 | the Free Software Foundation; version 2 of the License. |
8 | |
9 | This program is distributed in the hope that it will be useful, |
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
12 | GNU General Public License for more details. |
13 | |
14 | You should have received a copy of the GNU General Public License |
15 | along with this program; if not, write to the Free Software |
16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
17 | */ |
18 | |
19 | /** |
20 | @file |
21 | |
22 | @brief |
23 | This file implements classes defined in field.h |
24 | */ |
25 | |
26 | #ifdef USE_PRAGMA_IMPLEMENTATION |
27 | #pragma implementation // gcc: Class implementation |
28 | #endif |
29 | |
30 | #include "mariadb.h" |
31 | #include "sql_priv.h" |
32 | #include "sql_select.h" |
33 | #include "rpl_rli.h" // Pull in Relay_log_info |
34 | #include "slave.h" // Pull in rpl_master_has_bug() |
35 | #include "strfunc.h" // find_type2, find_set |
36 | #include "sql_time.h" // str_to_datetime_with_warn, |
37 | // str_to_time_with_warn, |
38 | // TIME_to_timestamp, |
39 | // make_time, make_date, |
40 | // make_truncated_value_warning |
41 | #include "tztime.h" // struct Time_zone |
42 | #include "filesort.h" // change_double_for_sort |
43 | #include "log_event.h" // class Table_map_log_event |
44 | #include <m_ctype.h> |
45 | |
46 | // Maximum allowed exponent value for converting string to decimal |
47 | #define MAX_EXPONENT 1024 |
48 | |
49 | /***************************************************************************** |
50 | Instansiate templates and static variables |
51 | *****************************************************************************/ |
52 | |
53 | static const char *zero_timestamp="0000-00-00 00:00:00.000000" ; |
54 | LEX_CSTRING temp_lex_str= {STRING_WITH_LEN("temp" )}; |
55 | |
56 | uchar Field_null::null[1]={1}; |
57 | const char field_separator=','; |
58 | |
59 | #define DOUBLE_TO_STRING_CONVERSION_BUFFER_SIZE FLOATING_POINT_BUFFER |
60 | #define LONGLONG_TO_STRING_CONVERSION_BUFFER_SIZE 128 |
61 | #define DECIMAL_TO_STRING_CONVERSION_BUFFER_SIZE 128 |
62 | #define BLOB_PACK_LENGTH_TO_MAX_LENGH(arg) \ |
63 | ((ulong) ((1LL << MY_MIN(arg, 4) * 8) - 1)) |
64 | |
65 | #define ASSERT_COLUMN_MARKED_FOR_READ DBUG_ASSERT(!table || (!table->read_set || bitmap_is_set(table->read_set, field_index))) |
66 | #define ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED DBUG_ASSERT(is_stat_field || !table || (!table->write_set || bitmap_is_set(table->write_set, field_index) || (table->vcol_set && bitmap_is_set(table->vcol_set, field_index)))) |
67 | |
68 | #define FLAGSTR(S,F) ((S) & (F) ? #F " " : "") |
69 | |
70 | /* |
71 | Rules for merging different types of fields in UNION |
72 | |
73 | NOTE: to avoid 256*256 table, gap in table types numeration is skiped |
74 | following #defines describe that gap and how to canculate number of fields |
75 | and index of field in this array. |
76 | */ |
77 | const int FIELDTYPE_TEAR_FROM= (MYSQL_TYPE_BIT + 1); |
78 | const int FIELDTYPE_TEAR_TO= (MYSQL_TYPE_NEWDECIMAL - 1); |
79 | const int FIELDTYPE_LAST= 254; |
80 | const int FIELDTYPE_NUM= FIELDTYPE_TEAR_FROM + (FIELDTYPE_LAST - |
81 | FIELDTYPE_TEAR_TO); |
82 | |
83 | static inline int field_type2index (enum_field_types field_type) |
84 | { |
85 | DBUG_ASSERT(real_type_to_type(field_type) < FIELDTYPE_TEAR_FROM || |
86 | real_type_to_type(field_type) > FIELDTYPE_TEAR_TO); |
87 | DBUG_ASSERT(field_type <= FIELDTYPE_LAST); |
88 | field_type= real_type_to_type(field_type); |
89 | if (field_type < FIELDTYPE_TEAR_FROM) |
90 | return field_type; |
91 | return FIELDTYPE_TEAR_FROM + (field_type - FIELDTYPE_TEAR_TO) - 1; |
92 | } |
93 | |
94 | |
95 | /** |
96 | Implements data type merge rules for the built-in traditional data types. |
97 | Used for operations such as: |
98 | - UNION |
99 | - CASE and its abbreviations COALESCE, IF, IFNULL |
100 | - LEAST/GREATEST |
101 | |
102 | Given Fields A and B of real_types a and b, we find the result type of |
103 | COALESCE(A, B) by querying: |
104 | field_types_merge_rules[field_type_to_index(a)][field_type_to_index(b)]. |
105 | */ |
106 | static enum_field_types field_types_merge_rules [FIELDTYPE_NUM][FIELDTYPE_NUM]= |
107 | { |
108 | /* MYSQL_TYPE_DECIMAL -> */ |
109 | { |
110 | //MYSQL_TYPE_DECIMAL MYSQL_TYPE_TINY |
111 | MYSQL_TYPE_NEWDECIMAL, MYSQL_TYPE_NEWDECIMAL, |
112 | //MYSQL_TYPE_SHORT MYSQL_TYPE_LONG |
113 | MYSQL_TYPE_NEWDECIMAL, MYSQL_TYPE_NEWDECIMAL, |
114 | //MYSQL_TYPE_FLOAT MYSQL_TYPE_DOUBLE |
115 | MYSQL_TYPE_DOUBLE, MYSQL_TYPE_DOUBLE, |
116 | //MYSQL_TYPE_NULL MYSQL_TYPE_TIMESTAMP |
117 | MYSQL_TYPE_NEWDECIMAL, MYSQL_TYPE_VARCHAR, |
118 | //MYSQL_TYPE_LONGLONG MYSQL_TYPE_INT24 |
119 | MYSQL_TYPE_NEWDECIMAL, MYSQL_TYPE_NEWDECIMAL, |
120 | //MYSQL_TYPE_DATE MYSQL_TYPE_TIME |
121 | MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, |
122 | //MYSQL_TYPE_DATETIME MYSQL_TYPE_YEAR |
123 | MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, |
124 | //MYSQL_TYPE_NEWDATE MYSQL_TYPE_VARCHAR |
125 | MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, |
126 | //MYSQL_TYPE_BIT <16>-<245> |
127 | MYSQL_TYPE_VARCHAR, |
128 | //MYSQL_TYPE_NEWDECIMAL MYSQL_TYPE_ENUM |
129 | MYSQL_TYPE_NEWDECIMAL, MYSQL_TYPE_VARCHAR, |
130 | //MYSQL_TYPE_SET MYSQL_TYPE_TINY_BLOB |
131 | MYSQL_TYPE_VARCHAR, MYSQL_TYPE_TINY_BLOB, |
132 | //MYSQL_TYPE_MEDIUM_BLOB MYSQL_TYPE_LONG_BLOB |
133 | MYSQL_TYPE_MEDIUM_BLOB, MYSQL_TYPE_LONG_BLOB, |
134 | //MYSQL_TYPE_BLOB MYSQL_TYPE_VAR_STRING |
135 | MYSQL_TYPE_BLOB, MYSQL_TYPE_VARCHAR, |
136 | //MYSQL_TYPE_STRING |
137 | MYSQL_TYPE_STRING |
138 | }, |
139 | /* MYSQL_TYPE_TINY -> */ |
140 | { |
141 | //MYSQL_TYPE_DECIMAL MYSQL_TYPE_TINY |
142 | MYSQL_TYPE_NEWDECIMAL, MYSQL_TYPE_TINY, |
143 | //MYSQL_TYPE_SHORT MYSQL_TYPE_LONG |
144 | MYSQL_TYPE_SHORT, MYSQL_TYPE_LONG, |
145 | //MYSQL_TYPE_FLOAT MYSQL_TYPE_DOUBLE |
146 | MYSQL_TYPE_FLOAT, MYSQL_TYPE_DOUBLE, |
147 | //MYSQL_TYPE_NULL MYSQL_TYPE_TIMESTAMP |
148 | MYSQL_TYPE_TINY, MYSQL_TYPE_VARCHAR, |
149 | //MYSQL_TYPE_LONGLONG MYSQL_TYPE_INT24 |
150 | MYSQL_TYPE_LONGLONG, MYSQL_TYPE_INT24, |
151 | //MYSQL_TYPE_DATE MYSQL_TYPE_TIME |
152 | MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, |
153 | //MYSQL_TYPE_DATETIME MYSQL_TYPE_YEAR |
154 | MYSQL_TYPE_VARCHAR, MYSQL_TYPE_TINY, |
155 | //MYSQL_TYPE_NEWDATE MYSQL_TYPE_VARCHAR |
156 | MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, |
157 | //MYSQL_TYPE_BIT <16>-<245> |
158 | MYSQL_TYPE_VARCHAR, |
159 | //MYSQL_TYPE_NEWDECIMAL MYSQL_TYPE_ENUM |
160 | MYSQL_TYPE_NEWDECIMAL, MYSQL_TYPE_VARCHAR, |
161 | //MYSQL_TYPE_SET MYSQL_TYPE_TINY_BLOB |
162 | MYSQL_TYPE_VARCHAR, MYSQL_TYPE_TINY_BLOB, |
163 | //MYSQL_TYPE_MEDIUM_BLOB MYSQL_TYPE_LONG_BLOB |
164 | MYSQL_TYPE_MEDIUM_BLOB, MYSQL_TYPE_LONG_BLOB, |
165 | //MYSQL_TYPE_BLOB MYSQL_TYPE_VAR_STRING |
166 | MYSQL_TYPE_BLOB, MYSQL_TYPE_VARCHAR, |
167 | //MYSQL_TYPE_STRING |
168 | MYSQL_TYPE_STRING |
169 | }, |
170 | /* MYSQL_TYPE_SHORT -> */ |
171 | { |
172 | //MYSQL_TYPE_DECIMAL MYSQL_TYPE_TINY |
173 | MYSQL_TYPE_NEWDECIMAL, MYSQL_TYPE_SHORT, |
174 | //MYSQL_TYPE_SHORT MYSQL_TYPE_LONG |
175 | MYSQL_TYPE_SHORT, MYSQL_TYPE_LONG, |
176 | //MYSQL_TYPE_FLOAT MYSQL_TYPE_DOUBLE |
177 | MYSQL_TYPE_FLOAT, MYSQL_TYPE_DOUBLE, |
178 | //MYSQL_TYPE_NULL MYSQL_TYPE_TIMESTAMP |
179 | MYSQL_TYPE_SHORT, MYSQL_TYPE_VARCHAR, |
180 | //MYSQL_TYPE_LONGLONG MYSQL_TYPE_INT24 |
181 | MYSQL_TYPE_LONGLONG, MYSQL_TYPE_INT24, |
182 | //MYSQL_TYPE_DATE MYSQL_TYPE_TIME |
183 | MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, |
184 | //MYSQL_TYPE_DATETIME MYSQL_TYPE_YEAR |
185 | MYSQL_TYPE_VARCHAR, MYSQL_TYPE_SHORT, |
186 | //MYSQL_TYPE_NEWDATE MYSQL_TYPE_VARCHAR |
187 | MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, |
188 | //MYSQL_TYPE_BIT <16>-<245> |
189 | MYSQL_TYPE_VARCHAR, |
190 | //MYSQL_TYPE_NEWDECIMAL MYSQL_TYPE_ENUM |
191 | MYSQL_TYPE_NEWDECIMAL, MYSQL_TYPE_VARCHAR, |
192 | //MYSQL_TYPE_SET MYSQL_TYPE_TINY_BLOB |
193 | MYSQL_TYPE_VARCHAR, MYSQL_TYPE_TINY_BLOB, |
194 | //MYSQL_TYPE_MEDIUM_BLOB MYSQL_TYPE_LONG_BLOB |
195 | MYSQL_TYPE_MEDIUM_BLOB, MYSQL_TYPE_LONG_BLOB, |
196 | //MYSQL_TYPE_BLOB MYSQL_TYPE_VAR_STRING |
197 | MYSQL_TYPE_BLOB, MYSQL_TYPE_VARCHAR, |
198 | //MYSQL_TYPE_STRING |
199 | MYSQL_TYPE_STRING |
200 | }, |
201 | /* MYSQL_TYPE_LONG -> */ |
202 | { |
203 | //MYSQL_TYPE_DECIMAL MYSQL_TYPE_TINY |
204 | MYSQL_TYPE_NEWDECIMAL, MYSQL_TYPE_LONG, |
205 | //MYSQL_TYPE_SHORT MYSQL_TYPE_LONG |
206 | MYSQL_TYPE_LONG, MYSQL_TYPE_LONG, |
207 | //MYSQL_TYPE_FLOAT MYSQL_TYPE_DOUBLE |
208 | MYSQL_TYPE_DOUBLE, MYSQL_TYPE_DOUBLE, |
209 | //MYSQL_TYPE_NULL MYSQL_TYPE_TIMESTAMP |
210 | MYSQL_TYPE_LONG, MYSQL_TYPE_VARCHAR, |
211 | //MYSQL_TYPE_LONGLONG MYSQL_TYPE_INT24 |
212 | MYSQL_TYPE_LONGLONG, MYSQL_TYPE_LONG, |
213 | //MYSQL_TYPE_DATE MYSQL_TYPE_TIME |
214 | MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, |
215 | //MYSQL_TYPE_DATETIME MYSQL_TYPE_YEAR |
216 | MYSQL_TYPE_VARCHAR, MYSQL_TYPE_LONG, |
217 | //MYSQL_TYPE_NEWDATE MYSQL_TYPE_VARCHAR |
218 | MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, |
219 | //MYSQL_TYPE_BIT <16>-<245> |
220 | MYSQL_TYPE_VARCHAR, |
221 | //MYSQL_TYPE_NEWDECIMAL MYSQL_TYPE_ENUM |
222 | MYSQL_TYPE_NEWDECIMAL, MYSQL_TYPE_VARCHAR, |
223 | //MYSQL_TYPE_SET MYSQL_TYPE_TINY_BLOB |
224 | MYSQL_TYPE_VARCHAR, MYSQL_TYPE_TINY_BLOB, |
225 | //MYSQL_TYPE_MEDIUM_BLOB MYSQL_TYPE_LONG_BLOB |
226 | MYSQL_TYPE_MEDIUM_BLOB, MYSQL_TYPE_LONG_BLOB, |
227 | //MYSQL_TYPE_BLOB MYSQL_TYPE_VAR_STRING |
228 | MYSQL_TYPE_BLOB, MYSQL_TYPE_VARCHAR, |
229 | //MYSQL_TYPE_STRING |
230 | MYSQL_TYPE_STRING |
231 | }, |
232 | /* MYSQL_TYPE_FLOAT -> */ |
233 | { |
234 | //MYSQL_TYPE_DECIMAL MYSQL_TYPE_TINY |
235 | MYSQL_TYPE_DOUBLE, MYSQL_TYPE_FLOAT, |
236 | //MYSQL_TYPE_SHORT MYSQL_TYPE_LONG |
237 | MYSQL_TYPE_FLOAT, MYSQL_TYPE_DOUBLE, |
238 | //MYSQL_TYPE_FLOAT MYSQL_TYPE_DOUBLE |
239 | MYSQL_TYPE_FLOAT, MYSQL_TYPE_DOUBLE, |
240 | //MYSQL_TYPE_NULL MYSQL_TYPE_TIMESTAMP |
241 | MYSQL_TYPE_FLOAT, MYSQL_TYPE_VARCHAR, |
242 | //MYSQL_TYPE_LONGLONG MYSQL_TYPE_INT24 |
243 | MYSQL_TYPE_DOUBLE, MYSQL_TYPE_FLOAT, |
244 | //MYSQL_TYPE_DATE MYSQL_TYPE_TIME |
245 | MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, |
246 | //MYSQL_TYPE_DATETIME MYSQL_TYPE_YEAR |
247 | MYSQL_TYPE_VARCHAR, MYSQL_TYPE_FLOAT, |
248 | //MYSQL_TYPE_NEWDATE MYSQL_TYPE_VARCHAR |
249 | MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, |
250 | //MYSQL_TYPE_BIT <16>-<245> |
251 | MYSQL_TYPE_VARCHAR, |
252 | //MYSQL_TYPE_NEWDECIMAL MYSQL_TYPE_ENUM |
253 | MYSQL_TYPE_DOUBLE, MYSQL_TYPE_VARCHAR, |
254 | //MYSQL_TYPE_SET MYSQL_TYPE_TINY_BLOB |
255 | MYSQL_TYPE_VARCHAR, MYSQL_TYPE_TINY_BLOB, |
256 | //MYSQL_TYPE_MEDIUM_BLOB MYSQL_TYPE_LONG_BLOB |
257 | MYSQL_TYPE_MEDIUM_BLOB, MYSQL_TYPE_LONG_BLOB, |
258 | //MYSQL_TYPE_BLOB MYSQL_TYPE_VAR_STRING |
259 | MYSQL_TYPE_BLOB, MYSQL_TYPE_VARCHAR, |
260 | //MYSQL_TYPE_STRING |
261 | MYSQL_TYPE_STRING |
262 | }, |
263 | /* MYSQL_TYPE_DOUBLE -> */ |
264 | { |
265 | //MYSQL_TYPE_DECIMAL MYSQL_TYPE_TINY |
266 | MYSQL_TYPE_DOUBLE, MYSQL_TYPE_DOUBLE, |
267 | //MYSQL_TYPE_SHORT MYSQL_TYPE_LONG |
268 | MYSQL_TYPE_DOUBLE, MYSQL_TYPE_DOUBLE, |
269 | //MYSQL_TYPE_FLOAT MYSQL_TYPE_DOUBLE |
270 | MYSQL_TYPE_DOUBLE, MYSQL_TYPE_DOUBLE, |
271 | //MYSQL_TYPE_NULL MYSQL_TYPE_TIMESTAMP |
272 | MYSQL_TYPE_DOUBLE, MYSQL_TYPE_VARCHAR, |
273 | //MYSQL_TYPE_LONGLONG MYSQL_TYPE_INT24 |
274 | MYSQL_TYPE_DOUBLE, MYSQL_TYPE_DOUBLE, |
275 | //MYSQL_TYPE_DATE MYSQL_TYPE_TIME |
276 | MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, |
277 | //MYSQL_TYPE_DATETIME MYSQL_TYPE_YEAR |
278 | MYSQL_TYPE_VARCHAR, MYSQL_TYPE_DOUBLE, |
279 | //MYSQL_TYPE_NEWDATE MYSQL_TYPE_VARCHAR |
280 | MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, |
281 | //MYSQL_TYPE_BIT <16>-<245> |
282 | MYSQL_TYPE_VARCHAR, |
283 | //MYSQL_TYPE_NEWDECIMAL MYSQL_TYPE_ENUM |
284 | MYSQL_TYPE_DOUBLE, MYSQL_TYPE_VARCHAR, |
285 | //MYSQL_TYPE_SET MYSQL_TYPE_TINY_BLOB |
286 | MYSQL_TYPE_VARCHAR, MYSQL_TYPE_TINY_BLOB, |
287 | //MYSQL_TYPE_MEDIUM_BLOB MYSQL_TYPE_LONG_BLOB |
288 | MYSQL_TYPE_MEDIUM_BLOB, MYSQL_TYPE_LONG_BLOB, |
289 | //MYSQL_TYPE_BLOB MYSQL_TYPE_VAR_STRING |
290 | MYSQL_TYPE_BLOB, MYSQL_TYPE_VARCHAR, |
291 | //MYSQL_TYPE_STRING |
292 | MYSQL_TYPE_STRING |
293 | }, |
294 | /* MYSQL_TYPE_NULL -> */ |
295 | { |
296 | //MYSQL_TYPE_DECIMAL MYSQL_TYPE_TINY |
297 | MYSQL_TYPE_NEWDECIMAL, MYSQL_TYPE_TINY, |
298 | //MYSQL_TYPE_SHORT MYSQL_TYPE_LONG |
299 | MYSQL_TYPE_SHORT, MYSQL_TYPE_LONG, |
300 | //MYSQL_TYPE_FLOAT MYSQL_TYPE_DOUBLE |
301 | MYSQL_TYPE_FLOAT, MYSQL_TYPE_DOUBLE, |
302 | //MYSQL_TYPE_NULL MYSQL_TYPE_TIMESTAMP |
303 | MYSQL_TYPE_NULL, MYSQL_TYPE_TIMESTAMP, |
304 | //MYSQL_TYPE_LONGLONG MYSQL_TYPE_INT24 |
305 | MYSQL_TYPE_LONGLONG, MYSQL_TYPE_LONGLONG, |
306 | //MYSQL_TYPE_DATE MYSQL_TYPE_TIME |
307 | MYSQL_TYPE_NEWDATE, MYSQL_TYPE_TIME, |
308 | //MYSQL_TYPE_DATETIME MYSQL_TYPE_YEAR |
309 | MYSQL_TYPE_DATETIME, MYSQL_TYPE_YEAR, |
310 | //MYSQL_TYPE_NEWDATE MYSQL_TYPE_VARCHAR |
311 | MYSQL_TYPE_NEWDATE, MYSQL_TYPE_VARCHAR, |
312 | //MYSQL_TYPE_BIT <16>-<245> |
313 | MYSQL_TYPE_BIT, |
314 | //MYSQL_TYPE_NEWDECIMAL MYSQL_TYPE_ENUM |
315 | MYSQL_TYPE_NEWDECIMAL, MYSQL_TYPE_ENUM, |
316 | //MYSQL_TYPE_SET MYSQL_TYPE_TINY_BLOB |
317 | MYSQL_TYPE_SET, MYSQL_TYPE_TINY_BLOB, |
318 | //MYSQL_TYPE_MEDIUM_BLOB MYSQL_TYPE_LONG_BLOB |
319 | MYSQL_TYPE_MEDIUM_BLOB, MYSQL_TYPE_LONG_BLOB, |
320 | //MYSQL_TYPE_BLOB MYSQL_TYPE_VAR_STRING |
321 | MYSQL_TYPE_BLOB, MYSQL_TYPE_VARCHAR, |
322 | //MYSQL_TYPE_STRING |
323 | MYSQL_TYPE_STRING |
324 | }, |
325 | /* MYSQL_TYPE_TIMESTAMP -> */ |
326 | { |
327 | //MYSQL_TYPE_DECIMAL MYSQL_TYPE_TINY |
328 | MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, |
329 | //MYSQL_TYPE_SHORT MYSQL_TYPE_LONG |
330 | MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, |
331 | //MYSQL_TYPE_FLOAT MYSQL_TYPE_DOUBLE |
332 | MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, |
333 | //MYSQL_TYPE_NULL MYSQL_TYPE_TIMESTAMP |
334 | MYSQL_TYPE_TIMESTAMP, MYSQL_TYPE_TIMESTAMP, |
335 | //MYSQL_TYPE_LONGLONG MYSQL_TYPE_INT24 |
336 | MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, |
337 | //MYSQL_TYPE_DATE MYSQL_TYPE_TIME |
338 | MYSQL_TYPE_DATETIME, MYSQL_TYPE_DATETIME, |
339 | //MYSQL_TYPE_DATETIME MYSQL_TYPE_YEAR |
340 | MYSQL_TYPE_DATETIME, MYSQL_TYPE_VARCHAR, |
341 | //MYSQL_TYPE_NEWDATE MYSQL_TYPE_VARCHAR |
342 | MYSQL_TYPE_NEWDATE, MYSQL_TYPE_VARCHAR, |
343 | //MYSQL_TYPE_BIT <16>-<245> |
344 | MYSQL_TYPE_VARCHAR, |
345 | //MYSQL_TYPE_NEWDECIMAL MYSQL_TYPE_ENUM |
346 | MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, |
347 | //MYSQL_TYPE_SET MYSQL_TYPE_TINY_BLOB |
348 | MYSQL_TYPE_VARCHAR, MYSQL_TYPE_TINY_BLOB, |
349 | //MYSQL_TYPE_MEDIUM_BLOB MYSQL_TYPE_LONG_BLOB |
350 | MYSQL_TYPE_MEDIUM_BLOB, MYSQL_TYPE_LONG_BLOB, |
351 | //MYSQL_TYPE_BLOB MYSQL_TYPE_VAR_STRING |
352 | MYSQL_TYPE_BLOB, MYSQL_TYPE_VARCHAR, |
353 | //MYSQL_TYPE_STRING |
354 | MYSQL_TYPE_STRING |
355 | }, |
356 | /* MYSQL_TYPE_LONGLONG -> */ |
357 | { |
358 | //MYSQL_TYPE_DECIMAL MYSQL_TYPE_TINY |
359 | MYSQL_TYPE_NEWDECIMAL, MYSQL_TYPE_LONGLONG, |
360 | //MYSQL_TYPE_SHORT MYSQL_TYPE_LONG |
361 | MYSQL_TYPE_LONGLONG, MYSQL_TYPE_LONGLONG, |
362 | //MYSQL_TYPE_FLOAT MYSQL_TYPE_DOUBLE |
363 | MYSQL_TYPE_DOUBLE, MYSQL_TYPE_DOUBLE, |
364 | //MYSQL_TYPE_NULL MYSQL_TYPE_TIMESTAMP |
365 | MYSQL_TYPE_LONGLONG, MYSQL_TYPE_VARCHAR, |
366 | //MYSQL_TYPE_LONGLONG MYSQL_TYPE_INT24 |
367 | MYSQL_TYPE_LONGLONG, MYSQL_TYPE_LONGLONG, |
368 | //MYSQL_TYPE_DATE MYSQL_TYPE_TIME |
369 | MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, |
370 | //MYSQL_TYPE_DATETIME MYSQL_TYPE_YEAR |
371 | MYSQL_TYPE_VARCHAR, MYSQL_TYPE_LONGLONG, |
372 | //MYSQL_TYPE_NEWDATE MYSQL_TYPE_VARCHAR |
373 | MYSQL_TYPE_NEWDATE, MYSQL_TYPE_VARCHAR, |
374 | //MYSQL_TYPE_BIT <16>-<245> |
375 | MYSQL_TYPE_VARCHAR, |
376 | //MYSQL_TYPE_NEWDECIMAL MYSQL_TYPE_ENUM |
377 | MYSQL_TYPE_NEWDECIMAL, MYSQL_TYPE_VARCHAR, |
378 | //MYSQL_TYPE_SET MYSQL_TYPE_TINY_BLOB |
379 | MYSQL_TYPE_VARCHAR, MYSQL_TYPE_TINY_BLOB, |
380 | //MYSQL_TYPE_MEDIUM_BLOB MYSQL_TYPE_LONG_BLOB |
381 | MYSQL_TYPE_MEDIUM_BLOB, MYSQL_TYPE_LONG_BLOB, |
382 | //MYSQL_TYPE_BLOB MYSQL_TYPE_VAR_STRING |
383 | MYSQL_TYPE_BLOB, MYSQL_TYPE_VARCHAR, |
384 | //MYSQL_TYPE_STRING |
385 | MYSQL_TYPE_STRING |
386 | }, |
387 | /* MYSQL_TYPE_INT24 -> */ |
388 | { |
389 | //MYSQL_TYPE_DECIMAL MYSQL_TYPE_TINY |
390 | MYSQL_TYPE_NEWDECIMAL, MYSQL_TYPE_INT24, |
391 | //MYSQL_TYPE_SHORT MYSQL_TYPE_LONG |
392 | MYSQL_TYPE_INT24, MYSQL_TYPE_LONG, |
393 | //MYSQL_TYPE_FLOAT MYSQL_TYPE_DOUBLE |
394 | MYSQL_TYPE_FLOAT, MYSQL_TYPE_DOUBLE, |
395 | //MYSQL_TYPE_NULL MYSQL_TYPE_TIMESTAMP |
396 | MYSQL_TYPE_INT24, MYSQL_TYPE_VARCHAR, |
397 | //MYSQL_TYPE_LONGLONG MYSQL_TYPE_INT24 |
398 | MYSQL_TYPE_LONGLONG, MYSQL_TYPE_INT24, |
399 | //MYSQL_TYPE_DATE MYSQL_TYPE_TIME |
400 | MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, |
401 | //MYSQL_TYPE_DATETIME MYSQL_TYPE_YEAR |
402 | MYSQL_TYPE_VARCHAR, MYSQL_TYPE_INT24, |
403 | //MYSQL_TYPE_NEWDATE MYSQL_TYPE_VARCHAR |
404 | MYSQL_TYPE_NEWDATE, MYSQL_TYPE_VARCHAR, |
405 | //MYSQL_TYPE_BIT <16>-<245> |
406 | MYSQL_TYPE_VARCHAR, |
407 | //MYSQL_TYPE_NEWDECIMAL MYSQL_TYPE_ENUM |
408 | MYSQL_TYPE_NEWDECIMAL, MYSQL_TYPE_VARCHAR, |
409 | //MYSQL_TYPE_SET MYSQL_TYPE_TINY_BLOB |
410 | MYSQL_TYPE_VARCHAR, MYSQL_TYPE_TINY_BLOB, |
411 | //MYSQL_TYPE_MEDIUM_BLOB MYSQL_TYPE_LONG_BLOB |
412 | MYSQL_TYPE_MEDIUM_BLOB, MYSQL_TYPE_LONG_BLOB, |
413 | //MYSQL_TYPE_BLOB MYSQL_TYPE_VAR_STRING |
414 | MYSQL_TYPE_BLOB, MYSQL_TYPE_VARCHAR, |
415 | //MYSQL_TYPE_STRING |
416 | MYSQL_TYPE_STRING |
417 | }, |
418 | /* MYSQL_TYPE_DATE -> */ |
419 | { |
420 | //MYSQL_TYPE_DECIMAL MYSQL_TYPE_TINY |
421 | MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, |
422 | //MYSQL_TYPE_SHORT MYSQL_TYPE_LONG |
423 | MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, |
424 | //MYSQL_TYPE_FLOAT MYSQL_TYPE_DOUBLE |
425 | MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, |
426 | //MYSQL_TYPE_NULL MYSQL_TYPE_TIMESTAMP |
427 | MYSQL_TYPE_NEWDATE, MYSQL_TYPE_DATETIME, |
428 | //MYSQL_TYPE_LONGLONG MYSQL_TYPE_INT24 |
429 | MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, |
430 | //MYSQL_TYPE_DATE MYSQL_TYPE_TIME |
431 | MYSQL_TYPE_NEWDATE, MYSQL_TYPE_DATETIME, |
432 | //MYSQL_TYPE_DATETIME MYSQL_TYPE_YEAR |
433 | MYSQL_TYPE_DATETIME, MYSQL_TYPE_VARCHAR, |
434 | //MYSQL_TYPE_NEWDATE MYSQL_TYPE_VARCHAR |
435 | MYSQL_TYPE_NEWDATE, MYSQL_TYPE_VARCHAR, |
436 | //MYSQL_TYPE_BIT <16>-<245> |
437 | MYSQL_TYPE_VARCHAR, |
438 | //MYSQL_TYPE_NEWDECIMAL MYSQL_TYPE_ENUM |
439 | MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, |
440 | //MYSQL_TYPE_SET MYSQL_TYPE_TINY_BLOB |
441 | MYSQL_TYPE_VARCHAR, MYSQL_TYPE_TINY_BLOB, |
442 | //MYSQL_TYPE_MEDIUM_BLOB MYSQL_TYPE_LONG_BLOB |
443 | MYSQL_TYPE_MEDIUM_BLOB, MYSQL_TYPE_LONG_BLOB, |
444 | //MYSQL_TYPE_BLOB MYSQL_TYPE_VAR_STRING |
445 | MYSQL_TYPE_BLOB, MYSQL_TYPE_VARCHAR, |
446 | //MYSQL_TYPE_STRING |
447 | MYSQL_TYPE_STRING |
448 | }, |
449 | /* MYSQL_TYPE_TIME -> */ |
450 | { |
451 | //MYSQL_TYPE_DECIMAL MYSQL_TYPE_TINY |
452 | MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, |
453 | //MYSQL_TYPE_SHORT MYSQL_TYPE_LONG |
454 | MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, |
455 | //MYSQL_TYPE_FLOAT MYSQL_TYPE_DOUBLE |
456 | MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, |
457 | //MYSQL_TYPE_NULL MYSQL_TYPE_TIMESTAMP |
458 | MYSQL_TYPE_TIME, MYSQL_TYPE_DATETIME, |
459 | //MYSQL_TYPE_LONGLONG MYSQL_TYPE_INT24 |
460 | MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, |
461 | //MYSQL_TYPE_DATE MYSQL_TYPE_TIME |
462 | MYSQL_TYPE_DATETIME, MYSQL_TYPE_TIME, |
463 | //MYSQL_TYPE_DATETIME MYSQL_TYPE_YEAR |
464 | MYSQL_TYPE_DATETIME, MYSQL_TYPE_VARCHAR, |
465 | //MYSQL_TYPE_NEWDATE MYSQL_TYPE_VARCHAR |
466 | MYSQL_TYPE_NEWDATE, MYSQL_TYPE_VARCHAR, |
467 | //MYSQL_TYPE_BIT <16>-<245> |
468 | MYSQL_TYPE_VARCHAR, |
469 | //MYSQL_TYPE_NEWDECIMAL MYSQL_TYPE_ENUM |
470 | MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, |
471 | //MYSQL_TYPE_SET MYSQL_TYPE_TINY_BLOB |
472 | MYSQL_TYPE_VARCHAR, MYSQL_TYPE_TINY_BLOB, |
473 | //MYSQL_TYPE_MEDIUM_BLOB MYSQL_TYPE_LONG_BLOB |
474 | MYSQL_TYPE_MEDIUM_BLOB, MYSQL_TYPE_LONG_BLOB, |
475 | //MYSQL_TYPE_BLOB MYSQL_TYPE_VAR_STRING |
476 | MYSQL_TYPE_BLOB, MYSQL_TYPE_VARCHAR, |
477 | //MYSQL_TYPE_STRING |
478 | MYSQL_TYPE_STRING |
479 | }, |
480 | /* MYSQL_TYPE_DATETIME -> */ |
481 | { |
482 | //MYSQL_TYPE_DECIMAL MYSQL_TYPE_TINY |
483 | MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, |
484 | //MYSQL_TYPE_SHORT MYSQL_TYPE_LONG |
485 | MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, |
486 | //MYSQL_TYPE_FLOAT MYSQL_TYPE_DOUBLE |
487 | MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, |
488 | //MYSQL_TYPE_NULL MYSQL_TYPE_TIMESTAMP |
489 | MYSQL_TYPE_DATETIME, MYSQL_TYPE_DATETIME, |
490 | //MYSQL_TYPE_LONGLONG MYSQL_TYPE_INT24 |
491 | MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, |
492 | //MYSQL_TYPE_DATE MYSQL_TYPE_TIME |
493 | MYSQL_TYPE_DATETIME, MYSQL_TYPE_DATETIME, |
494 | //MYSQL_TYPE_DATETIME MYSQL_TYPE_YEAR |
495 | MYSQL_TYPE_DATETIME, MYSQL_TYPE_VARCHAR, |
496 | //MYSQL_TYPE_NEWDATE MYSQL_TYPE_VARCHAR |
497 | MYSQL_TYPE_NEWDATE, MYSQL_TYPE_VARCHAR, |
498 | //MYSQL_TYPE_BIT <16>-<245> |
499 | MYSQL_TYPE_VARCHAR, |
500 | //MYSQL_TYPE_NEWDECIMAL MYSQL_TYPE_ENUM |
501 | MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, |
502 | //MYSQL_TYPE_SET MYSQL_TYPE_TINY_BLOB |
503 | MYSQL_TYPE_VARCHAR, MYSQL_TYPE_TINY_BLOB, |
504 | //MYSQL_TYPE_MEDIUM_BLOB MYSQL_TYPE_LONG_BLOB |
505 | MYSQL_TYPE_MEDIUM_BLOB, MYSQL_TYPE_LONG_BLOB, |
506 | //MYSQL_TYPE_BLOB MYSQL_TYPE_VAR_STRING |
507 | MYSQL_TYPE_BLOB, MYSQL_TYPE_VARCHAR, |
508 | //MYSQL_TYPE_STRING |
509 | MYSQL_TYPE_STRING |
510 | }, |
511 | /* MYSQL_TYPE_YEAR -> */ |
512 | { |
513 | //MYSQL_TYPE_DECIMAL MYSQL_TYPE_TINY |
514 | MYSQL_TYPE_NEWDECIMAL, MYSQL_TYPE_TINY, |
515 | //MYSQL_TYPE_SHORT MYSQL_TYPE_LONG |
516 | MYSQL_TYPE_SHORT, MYSQL_TYPE_LONG, |
517 | //MYSQL_TYPE_FLOAT MYSQL_TYPE_DOUBLE |
518 | MYSQL_TYPE_FLOAT, MYSQL_TYPE_DOUBLE, |
519 | //MYSQL_TYPE_NULL MYSQL_TYPE_TIMESTAMP |
520 | MYSQL_TYPE_YEAR, MYSQL_TYPE_VARCHAR, |
521 | //MYSQL_TYPE_LONGLONG MYSQL_TYPE_INT24 |
522 | MYSQL_TYPE_LONGLONG, MYSQL_TYPE_INT24, |
523 | //MYSQL_TYPE_DATE MYSQL_TYPE_TIME |
524 | MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, |
525 | //MYSQL_TYPE_DATETIME MYSQL_TYPE_YEAR |
526 | MYSQL_TYPE_VARCHAR, MYSQL_TYPE_YEAR, |
527 | //MYSQL_TYPE_NEWDATE MYSQL_TYPE_VARCHAR |
528 | MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, |
529 | //MYSQL_TYPE_BIT <16>-<245> |
530 | MYSQL_TYPE_VARCHAR, |
531 | //MYSQL_TYPE_NEWDECIMAL MYSQL_TYPE_ENUM |
532 | MYSQL_TYPE_NEWDECIMAL, MYSQL_TYPE_VARCHAR, |
533 | //MYSQL_TYPE_SET MYSQL_TYPE_TINY_BLOB |
534 | MYSQL_TYPE_VARCHAR, MYSQL_TYPE_TINY_BLOB, |
535 | //MYSQL_TYPE_MEDIUM_BLOB MYSQL_TYPE_LONG_BLOB |
536 | MYSQL_TYPE_MEDIUM_BLOB, MYSQL_TYPE_LONG_BLOB, |
537 | //MYSQL_TYPE_BLOB MYSQL_TYPE_VAR_STRING |
538 | MYSQL_TYPE_BLOB, MYSQL_TYPE_VARCHAR, |
539 | //MYSQL_TYPE_STRING |
540 | MYSQL_TYPE_STRING |
541 | }, |
542 | /* MYSQL_TYPE_NEWDATE -> */ |
543 | { |
544 | //MYSQL_TYPE_DECIMAL MYSQL_TYPE_TINY |
545 | MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, |
546 | //MYSQL_TYPE_SHORT MYSQL_TYPE_LONG |
547 | MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, |
548 | //MYSQL_TYPE_FLOAT MYSQL_TYPE_DOUBLE |
549 | MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, |
550 | //MYSQL_TYPE_NULL MYSQL_TYPE_TIMESTAMP |
551 | MYSQL_TYPE_NEWDATE, MYSQL_TYPE_DATETIME, |
552 | //MYSQL_TYPE_LONGLONG MYSQL_TYPE_INT24 |
553 | MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, |
554 | //MYSQL_TYPE_DATE MYSQL_TYPE_TIME |
555 | MYSQL_TYPE_NEWDATE, MYSQL_TYPE_DATETIME, |
556 | //MYSQL_TYPE_DATETIME MYSQL_TYPE_YEAR |
557 | MYSQL_TYPE_DATETIME, MYSQL_TYPE_VARCHAR, |
558 | //MYSQL_TYPE_NEWDATE MYSQL_TYPE_VARCHAR |
559 | MYSQL_TYPE_NEWDATE, MYSQL_TYPE_VARCHAR, |
560 | //MYSQL_TYPE_BIT <16>-<245> |
561 | MYSQL_TYPE_VARCHAR, |
562 | //MYSQL_TYPE_NEWDECIMAL MYSQL_TYPE_ENUM |
563 | MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, |
564 | //MYSQL_TYPE_SET MYSQL_TYPE_TINY_BLOB |
565 | MYSQL_TYPE_VARCHAR, MYSQL_TYPE_TINY_BLOB, |
566 | //MYSQL_TYPE_MEDIUM_BLOB MYSQL_TYPE_LONG_BLOB |
567 | MYSQL_TYPE_MEDIUM_BLOB, MYSQL_TYPE_LONG_BLOB, |
568 | //MYSQL_TYPE_BLOB MYSQL_TYPE_VAR_STRING |
569 | MYSQL_TYPE_BLOB, MYSQL_TYPE_VARCHAR, |
570 | //MYSQL_TYPE_STRING |
571 | MYSQL_TYPE_STRING |
572 | }, |
573 | /* MYSQL_TYPE_VARCHAR -> */ |
574 | { |
575 | //MYSQL_TYPE_DECIMAL MYSQL_TYPE_TINY |
576 | MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, |
577 | //MYSQL_TYPE_SHORT MYSQL_TYPE_LONG |
578 | MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, |
579 | //MYSQL_TYPE_FLOAT MYSQL_TYPE_DOUBLE |
580 | MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, |
581 | //MYSQL_TYPE_NULL MYSQL_TYPE_TIMESTAMP |
582 | MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, |
583 | //MYSQL_TYPE_LONGLONG MYSQL_TYPE_INT24 |
584 | MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, |
585 | //MYSQL_TYPE_DATE MYSQL_TYPE_TIME |
586 | MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, |
587 | //MYSQL_TYPE_DATETIME MYSQL_TYPE_YEAR |
588 | MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, |
589 | //MYSQL_TYPE_NEWDATE MYSQL_TYPE_VARCHAR |
590 | MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, |
591 | //MYSQL_TYPE_BIT <16>-<245> |
592 | MYSQL_TYPE_VARCHAR, |
593 | //MYSQL_TYPE_NEWDECIMAL MYSQL_TYPE_ENUM |
594 | MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, |
595 | //MYSQL_TYPE_SET MYSQL_TYPE_TINY_BLOB |
596 | MYSQL_TYPE_VARCHAR, MYSQL_TYPE_TINY_BLOB, |
597 | //MYSQL_TYPE_MEDIUM_BLOB MYSQL_TYPE_LONG_BLOB |
598 | MYSQL_TYPE_MEDIUM_BLOB, MYSQL_TYPE_LONG_BLOB, |
599 | //MYSQL_TYPE_BLOB MYSQL_TYPE_VAR_STRING |
600 | MYSQL_TYPE_BLOB, MYSQL_TYPE_VARCHAR, |
601 | //MYSQL_TYPE_STRING |
602 | MYSQL_TYPE_VARCHAR |
603 | }, |
604 | /* MYSQL_TYPE_BIT -> */ |
605 | { |
606 | //MYSQL_TYPE_DECIMAL MYSQL_TYPE_TINY |
607 | MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, |
608 | //MYSQL_TYPE_SHORT MYSQL_TYPE_LONG |
609 | MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, |
610 | //MYSQL_TYPE_FLOAT MYSQL_TYPE_DOUBLE |
611 | MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, |
612 | //MYSQL_TYPE_NULL MYSQL_TYPE_TIMESTAMP |
613 | MYSQL_TYPE_BIT, MYSQL_TYPE_VARCHAR, |
614 | //MYSQL_TYPE_LONGLONG MYSQL_TYPE_INT24 |
615 | MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, |
616 | //MYSQL_TYPE_DATE MYSQL_TYPE_TIME |
617 | MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, |
618 | //MYSQL_TYPE_DATETIME MYSQL_TYPE_YEAR |
619 | MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, |
620 | //MYSQL_TYPE_NEWDATE MYSQL_TYPE_VARCHAR |
621 | MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, |
622 | //MYSQL_TYPE_BIT <16>-<245> |
623 | MYSQL_TYPE_BIT, |
624 | //MYSQL_TYPE_NEWDECIMAL MYSQL_TYPE_ENUM |
625 | MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, |
626 | //MYSQL_TYPE_SET MYSQL_TYPE_TINY_BLOB |
627 | MYSQL_TYPE_VARCHAR, MYSQL_TYPE_TINY_BLOB, |
628 | //MYSQL_TYPE_MEDIUM_BLOB MYSQL_TYPE_LONG_BLOB |
629 | MYSQL_TYPE_MEDIUM_BLOB, MYSQL_TYPE_LONG_BLOB, |
630 | //MYSQL_TYPE_BLOB MYSQL_TYPE_VAR_STRING |
631 | MYSQL_TYPE_BLOB, MYSQL_TYPE_VARCHAR, |
632 | //MYSQL_TYPE_STRING |
633 | MYSQL_TYPE_STRING |
634 | }, |
635 | /* MYSQL_TYPE_NEWDECIMAL -> */ |
636 | { |
637 | //MYSQL_TYPE_DECIMAL MYSQL_TYPE_TINY |
638 | MYSQL_TYPE_NEWDECIMAL, MYSQL_TYPE_NEWDECIMAL, |
639 | //MYSQL_TYPE_SHORT MYSQL_TYPE_LONG |
640 | MYSQL_TYPE_NEWDECIMAL, MYSQL_TYPE_NEWDECIMAL, |
641 | //MYSQL_TYPE_FLOAT MYSQL_TYPE_DOUBLE |
642 | MYSQL_TYPE_DOUBLE, MYSQL_TYPE_DOUBLE, |
643 | //MYSQL_TYPE_NULL MYSQL_TYPE_TIMESTAMP |
644 | MYSQL_TYPE_NEWDECIMAL, MYSQL_TYPE_VARCHAR, |
645 | //MYSQL_TYPE_LONGLONG MYSQL_TYPE_INT24 |
646 | MYSQL_TYPE_NEWDECIMAL, MYSQL_TYPE_NEWDECIMAL, |
647 | //MYSQL_TYPE_DATE MYSQL_TYPE_TIME |
648 | MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, |
649 | //MYSQL_TYPE_DATETIME MYSQL_TYPE_YEAR |
650 | MYSQL_TYPE_VARCHAR, MYSQL_TYPE_NEWDECIMAL, |
651 | //MYSQL_TYPE_NEWDATE MYSQL_TYPE_VARCHAR |
652 | MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, |
653 | //MYSQL_TYPE_BIT <16>-<245> |
654 | MYSQL_TYPE_VARCHAR, |
655 | //MYSQL_TYPE_NEWDECIMAL MYSQL_TYPE_ENUM |
656 | MYSQL_TYPE_NEWDECIMAL, MYSQL_TYPE_VARCHAR, |
657 | //MYSQL_TYPE_SET MYSQL_TYPE_TINY_BLOB |
658 | MYSQL_TYPE_VARCHAR, MYSQL_TYPE_TINY_BLOB, |
659 | //MYSQL_TYPE_MEDIUM_BLOB MYSQL_TYPE_LONG_BLOB |
660 | MYSQL_TYPE_MEDIUM_BLOB, MYSQL_TYPE_LONG_BLOB, |
661 | //MYSQL_TYPE_BLOB MYSQL_TYPE_VAR_STRING |
662 | MYSQL_TYPE_BLOB, MYSQL_TYPE_VARCHAR, |
663 | //MYSQL_TYPE_STRING |
664 | MYSQL_TYPE_STRING |
665 | }, |
666 | /* MYSQL_TYPE_ENUM -> */ |
667 | { |
668 | //MYSQL_TYPE_DECIMAL MYSQL_TYPE_TINY |
669 | MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, |
670 | //MYSQL_TYPE_SHORT MYSQL_TYPE_LONG |
671 | MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, |
672 | //MYSQL_TYPE_FLOAT MYSQL_TYPE_DOUBLE |
673 | MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, |
674 | //MYSQL_TYPE_NULL MYSQL_TYPE_TIMESTAMP |
675 | MYSQL_TYPE_ENUM, MYSQL_TYPE_VARCHAR, |
676 | //MYSQL_TYPE_LONGLONG MYSQL_TYPE_INT24 |
677 | MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, |
678 | //MYSQL_TYPE_DATE MYSQL_TYPE_TIME |
679 | MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, |
680 | //MYSQL_TYPE_DATETIME MYSQL_TYPE_YEAR |
681 | MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, |
682 | //MYSQL_TYPE_NEWDATE MYSQL_TYPE_VARCHAR |
683 | MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, |
684 | //MYSQL_TYPE_BIT <16>-<245> |
685 | MYSQL_TYPE_VARCHAR, |
686 | //MYSQL_TYPE_NEWDECIMAL MYSQL_TYPE_ENUM |
687 | MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, |
688 | //MYSQL_TYPE_SET MYSQL_TYPE_TINY_BLOB |
689 | MYSQL_TYPE_VARCHAR, MYSQL_TYPE_TINY_BLOB, |
690 | //MYSQL_TYPE_MEDIUM_BLOB MYSQL_TYPE_LONG_BLOB |
691 | MYSQL_TYPE_MEDIUM_BLOB, MYSQL_TYPE_LONG_BLOB, |
692 | //MYSQL_TYPE_BLOB MYSQL_TYPE_VAR_STRING |
693 | MYSQL_TYPE_BLOB, MYSQL_TYPE_VARCHAR, |
694 | //MYSQL_TYPE_STRING |
695 | MYSQL_TYPE_STRING |
696 | }, |
697 | /* MYSQL_TYPE_SET -> */ |
698 | { |
699 | //MYSQL_TYPE_DECIMAL MYSQL_TYPE_TINY |
700 | MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, |
701 | //MYSQL_TYPE_SHORT MYSQL_TYPE_LONG |
702 | MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, |
703 | //MYSQL_TYPE_FLOAT MYSQL_TYPE_DOUBLE |
704 | MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, |
705 | //MYSQL_TYPE_NULL MYSQL_TYPE_TIMESTAMP |
706 | MYSQL_TYPE_SET, MYSQL_TYPE_VARCHAR, |
707 | //MYSQL_TYPE_LONGLONG MYSQL_TYPE_INT24 |
708 | MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, |
709 | //MYSQL_TYPE_DATE MYSQL_TYPE_TIME |
710 | MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, |
711 | //MYSQL_TYPE_DATETIME MYSQL_TYPE_YEAR |
712 | MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, |
713 | //MYSQL_TYPE_NEWDATE MYSQL_TYPE_VARCHAR |
714 | MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, |
715 | //MYSQL_TYPE_BIT <16>-<245> |
716 | MYSQL_TYPE_VARCHAR, |
717 | //MYSQL_TYPE_NEWDECIMAL MYSQL_TYPE_ENUM |
718 | MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, |
719 | //MYSQL_TYPE_SET MYSQL_TYPE_TINY_BLOB |
720 | MYSQL_TYPE_VARCHAR, MYSQL_TYPE_TINY_BLOB, |
721 | //MYSQL_TYPE_MEDIUM_BLOB MYSQL_TYPE_LONG_BLOB |
722 | MYSQL_TYPE_MEDIUM_BLOB, MYSQL_TYPE_LONG_BLOB, |
723 | //MYSQL_TYPE_BLOB MYSQL_TYPE_VAR_STRING |
724 | MYSQL_TYPE_BLOB, MYSQL_TYPE_VARCHAR, |
725 | //MYSQL_TYPE_STRING |
726 | MYSQL_TYPE_STRING |
727 | }, |
728 | /* MYSQL_TYPE_TINY_BLOB -> */ |
729 | { |
730 | //MYSQL_TYPE_DECIMAL MYSQL_TYPE_TINY |
731 | MYSQL_TYPE_TINY_BLOB, MYSQL_TYPE_TINY_BLOB, |
732 | //MYSQL_TYPE_SHORT MYSQL_TYPE_LONG |
733 | MYSQL_TYPE_TINY_BLOB, MYSQL_TYPE_TINY_BLOB, |
734 | //MYSQL_TYPE_FLOAT MYSQL_TYPE_DOUBLE |
735 | MYSQL_TYPE_TINY_BLOB, MYSQL_TYPE_TINY_BLOB, |
736 | //MYSQL_TYPE_NULL MYSQL_TYPE_TIMESTAMP |
737 | MYSQL_TYPE_TINY_BLOB, MYSQL_TYPE_TINY_BLOB, |
738 | //MYSQL_TYPE_LONGLONG MYSQL_TYPE_INT24 |
739 | MYSQL_TYPE_TINY_BLOB, MYSQL_TYPE_TINY_BLOB, |
740 | //MYSQL_TYPE_DATE MYSQL_TYPE_TIME |
741 | MYSQL_TYPE_TINY_BLOB, MYSQL_TYPE_TINY_BLOB, |
742 | //MYSQL_TYPE_DATETIME MYSQL_TYPE_YEAR |
743 | MYSQL_TYPE_TINY_BLOB, MYSQL_TYPE_TINY_BLOB, |
744 | //MYSQL_TYPE_NEWDATE MYSQL_TYPE_VARCHAR |
745 | MYSQL_TYPE_TINY_BLOB, MYSQL_TYPE_TINY_BLOB, |
746 | //MYSQL_TYPE_BIT <16>-<245> |
747 | MYSQL_TYPE_TINY_BLOB, |
748 | //MYSQL_TYPE_NEWDECIMAL MYSQL_TYPE_ENUM |
749 | MYSQL_TYPE_TINY_BLOB, MYSQL_TYPE_TINY_BLOB, |
750 | //MYSQL_TYPE_SET MYSQL_TYPE_TINY_BLOB |
751 | MYSQL_TYPE_TINY_BLOB, MYSQL_TYPE_TINY_BLOB, |
752 | //MYSQL_TYPE_MEDIUM_BLOB MYSQL_TYPE_LONG_BLOB |
753 | MYSQL_TYPE_MEDIUM_BLOB, MYSQL_TYPE_LONG_BLOB, |
754 | //MYSQL_TYPE_BLOB MYSQL_TYPE_VAR_STRING |
755 | MYSQL_TYPE_BLOB, MYSQL_TYPE_TINY_BLOB, |
756 | //MYSQL_TYPE_STRING |
757 | MYSQL_TYPE_TINY_BLOB |
758 | }, |
759 | /* MYSQL_TYPE_MEDIUM_BLOB -> */ |
760 | { |
761 | //MYSQL_TYPE_DECIMAL MYSQL_TYPE_TINY |
762 | MYSQL_TYPE_MEDIUM_BLOB, MYSQL_TYPE_MEDIUM_BLOB, |
763 | //MYSQL_TYPE_SHORT MYSQL_TYPE_LONG |
764 | MYSQL_TYPE_MEDIUM_BLOB, MYSQL_TYPE_MEDIUM_BLOB, |
765 | //MYSQL_TYPE_FLOAT MYSQL_TYPE_DOUBLE |
766 | MYSQL_TYPE_MEDIUM_BLOB, MYSQL_TYPE_MEDIUM_BLOB, |
767 | //MYSQL_TYPE_NULL MYSQL_TYPE_TIMESTAMP |
768 | MYSQL_TYPE_MEDIUM_BLOB, MYSQL_TYPE_MEDIUM_BLOB, |
769 | //MYSQL_TYPE_LONGLONG MYSQL_TYPE_INT24 |
770 | MYSQL_TYPE_MEDIUM_BLOB, MYSQL_TYPE_MEDIUM_BLOB, |
771 | //MYSQL_TYPE_DATE MYSQL_TYPE_TIME |
772 | MYSQL_TYPE_MEDIUM_BLOB, MYSQL_TYPE_MEDIUM_BLOB, |
773 | //MYSQL_TYPE_DATETIME MYSQL_TYPE_YEAR |
774 | MYSQL_TYPE_MEDIUM_BLOB, MYSQL_TYPE_MEDIUM_BLOB, |
775 | //MYSQL_TYPE_NEWDATE MYSQL_TYPE_VARCHAR |
776 | MYSQL_TYPE_MEDIUM_BLOB, MYSQL_TYPE_MEDIUM_BLOB, |
777 | //MYSQL_TYPE_BIT <16>-<245> |
778 | MYSQL_TYPE_MEDIUM_BLOB, |
779 | //MYSQL_TYPE_NEWDECIMAL MYSQL_TYPE_ENUM |
780 | MYSQL_TYPE_MEDIUM_BLOB, MYSQL_TYPE_MEDIUM_BLOB, |
781 | //MYSQL_TYPE_SET MYSQL_TYPE_TINY_BLOB |
782 | MYSQL_TYPE_MEDIUM_BLOB, MYSQL_TYPE_MEDIUM_BLOB, |
783 | //MYSQL_TYPE_MEDIUM_BLOB MYSQL_TYPE_LONG_BLOB |
784 | MYSQL_TYPE_MEDIUM_BLOB, MYSQL_TYPE_LONG_BLOB, |
785 | //MYSQL_TYPE_BLOB MYSQL_TYPE_VAR_STRING |
786 | MYSQL_TYPE_MEDIUM_BLOB, MYSQL_TYPE_MEDIUM_BLOB, |
787 | //MYSQL_TYPE_STRING |
788 | MYSQL_TYPE_MEDIUM_BLOB |
789 | }, |
790 | /* MYSQL_TYPE_LONG_BLOB -> */ |
791 | { |
792 | //MYSQL_TYPE_DECIMAL MYSQL_TYPE_TINY |
793 | MYSQL_TYPE_LONG_BLOB, MYSQL_TYPE_LONG_BLOB, |
794 | //MYSQL_TYPE_SHORT MYSQL_TYPE_LONG |
795 | MYSQL_TYPE_LONG_BLOB, MYSQL_TYPE_LONG_BLOB, |
796 | //MYSQL_TYPE_FLOAT MYSQL_TYPE_DOUBLE |
797 | MYSQL_TYPE_LONG_BLOB, MYSQL_TYPE_LONG_BLOB, |
798 | //MYSQL_TYPE_NULL MYSQL_TYPE_TIMESTAMP |
799 | MYSQL_TYPE_LONG_BLOB, MYSQL_TYPE_LONG_BLOB, |
800 | //MYSQL_TYPE_LONGLONG MYSQL_TYPE_INT24 |
801 | MYSQL_TYPE_LONG_BLOB, MYSQL_TYPE_LONG_BLOB, |
802 | //MYSQL_TYPE_DATE MYSQL_TYPE_TIME |
803 | MYSQL_TYPE_LONG_BLOB, MYSQL_TYPE_LONG_BLOB, |
804 | //MYSQL_TYPE_DATETIME MYSQL_TYPE_YEAR |
805 | MYSQL_TYPE_LONG_BLOB, MYSQL_TYPE_LONG_BLOB, |
806 | //MYSQL_TYPE_NEWDATE MYSQL_TYPE_VARCHAR |
807 | MYSQL_TYPE_LONG_BLOB, MYSQL_TYPE_LONG_BLOB, |
808 | //MYSQL_TYPE_BIT <16>-<245> |
809 | MYSQL_TYPE_LONG_BLOB, |
810 | //MYSQL_TYPE_NEWDECIMAL MYSQL_TYPE_ENUM |
811 | MYSQL_TYPE_LONG_BLOB, MYSQL_TYPE_LONG_BLOB, |
812 | //MYSQL_TYPE_SET MYSQL_TYPE_TINY_BLOB |
813 | MYSQL_TYPE_LONG_BLOB, MYSQL_TYPE_LONG_BLOB, |
814 | //MYSQL_TYPE_MEDIUM_BLOB MYSQL_TYPE_LONG_BLOB |
815 | MYSQL_TYPE_LONG_BLOB, MYSQL_TYPE_LONG_BLOB, |
816 | //MYSQL_TYPE_BLOB MYSQL_TYPE_VAR_STRING |
817 | MYSQL_TYPE_LONG_BLOB, MYSQL_TYPE_LONG_BLOB, |
818 | //MYSQL_TYPE_STRING |
819 | MYSQL_TYPE_LONG_BLOB |
820 | }, |
821 | /* MYSQL_TYPE_BLOB -> */ |
822 | { |
823 | //MYSQL_TYPE_DECIMAL MYSQL_TYPE_TINY |
824 | MYSQL_TYPE_BLOB, MYSQL_TYPE_BLOB, |
825 | //MYSQL_TYPE_SHORT MYSQL_TYPE_LONG |
826 | MYSQL_TYPE_BLOB, MYSQL_TYPE_BLOB, |
827 | //MYSQL_TYPE_FLOAT MYSQL_TYPE_DOUBLE |
828 | MYSQL_TYPE_BLOB, MYSQL_TYPE_BLOB, |
829 | //MYSQL_TYPE_NULL MYSQL_TYPE_TIMESTAMP |
830 | MYSQL_TYPE_BLOB, MYSQL_TYPE_BLOB, |
831 | //MYSQL_TYPE_LONGLONG MYSQL_TYPE_INT24 |
832 | MYSQL_TYPE_BLOB, MYSQL_TYPE_BLOB, |
833 | //MYSQL_TYPE_DATE MYSQL_TYPE_TIME |
834 | MYSQL_TYPE_BLOB, MYSQL_TYPE_BLOB, |
835 | //MYSQL_TYPE_DATETIME MYSQL_TYPE_YEAR |
836 | MYSQL_TYPE_BLOB, MYSQL_TYPE_BLOB, |
837 | //MYSQL_TYPE_NEWDATE MYSQL_TYPE_VARCHAR |
838 | MYSQL_TYPE_BLOB, MYSQL_TYPE_BLOB, |
839 | //MYSQL_TYPE_BIT <16>-<245> |
840 | MYSQL_TYPE_BLOB, |
841 | //MYSQL_TYPE_NEWDECIMAL MYSQL_TYPE_ENUM |
842 | MYSQL_TYPE_BLOB, MYSQL_TYPE_BLOB, |
843 | //MYSQL_TYPE_SET MYSQL_TYPE_TINY_BLOB |
844 | MYSQL_TYPE_BLOB, MYSQL_TYPE_BLOB, |
845 | //MYSQL_TYPE_MEDIUM_BLOB MYSQL_TYPE_LONG_BLOB |
846 | MYSQL_TYPE_MEDIUM_BLOB, MYSQL_TYPE_LONG_BLOB, |
847 | //MYSQL_TYPE_BLOB MYSQL_TYPE_VAR_STRING |
848 | MYSQL_TYPE_BLOB, MYSQL_TYPE_BLOB, |
849 | //MYSQL_TYPE_STRING |
850 | MYSQL_TYPE_BLOB |
851 | }, |
852 | /* MYSQL_TYPE_VAR_STRING -> */ |
853 | { |
854 | //MYSQL_TYPE_DECIMAL MYSQL_TYPE_TINY |
855 | MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, |
856 | //MYSQL_TYPE_SHORT MYSQL_TYPE_LONG |
857 | MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, |
858 | //MYSQL_TYPE_FLOAT MYSQL_TYPE_DOUBLE |
859 | MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, |
860 | //MYSQL_TYPE_NULL MYSQL_TYPE_TIMESTAMP |
861 | MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, |
862 | //MYSQL_TYPE_LONGLONG MYSQL_TYPE_INT24 |
863 | MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, |
864 | //MYSQL_TYPE_DATE MYSQL_TYPE_TIME |
865 | MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, |
866 | //MYSQL_TYPE_DATETIME MYSQL_TYPE_YEAR |
867 | MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, |
868 | //MYSQL_TYPE_NEWDATE MYSQL_TYPE_VARCHAR |
869 | MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, |
870 | //MYSQL_TYPE_BIT <16>-<245> |
871 | MYSQL_TYPE_VARCHAR, |
872 | //MYSQL_TYPE_NEWDECIMAL MYSQL_TYPE_ENUM |
873 | MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, |
874 | //MYSQL_TYPE_SET MYSQL_TYPE_TINY_BLOB |
875 | MYSQL_TYPE_VARCHAR, MYSQL_TYPE_TINY_BLOB, |
876 | //MYSQL_TYPE_MEDIUM_BLOB MYSQL_TYPE_LONG_BLOB |
877 | MYSQL_TYPE_MEDIUM_BLOB, MYSQL_TYPE_LONG_BLOB, |
878 | //MYSQL_TYPE_BLOB MYSQL_TYPE_VAR_STRING |
879 | MYSQL_TYPE_BLOB, MYSQL_TYPE_VARCHAR, |
880 | //MYSQL_TYPE_STRING |
881 | MYSQL_TYPE_VARCHAR |
882 | }, |
883 | /* MYSQL_TYPE_STRING -> */ |
884 | { |
885 | //MYSQL_TYPE_DECIMAL MYSQL_TYPE_TINY |
886 | MYSQL_TYPE_STRING, MYSQL_TYPE_STRING, |
887 | //MYSQL_TYPE_SHORT MYSQL_TYPE_LONG |
888 | MYSQL_TYPE_STRING, MYSQL_TYPE_STRING, |
889 | //MYSQL_TYPE_FLOAT MYSQL_TYPE_DOUBLE |
890 | MYSQL_TYPE_STRING, MYSQL_TYPE_STRING, |
891 | //MYSQL_TYPE_NULL MYSQL_TYPE_TIMESTAMP |
892 | MYSQL_TYPE_STRING, MYSQL_TYPE_STRING, |
893 | //MYSQL_TYPE_LONGLONG MYSQL_TYPE_INT24 |
894 | MYSQL_TYPE_STRING, MYSQL_TYPE_STRING, |
895 | //MYSQL_TYPE_DATE MYSQL_TYPE_TIME |
896 | MYSQL_TYPE_STRING, MYSQL_TYPE_STRING, |
897 | //MYSQL_TYPE_DATETIME MYSQL_TYPE_YEAR |
898 | MYSQL_TYPE_STRING, MYSQL_TYPE_STRING, |
899 | //MYSQL_TYPE_NEWDATE MYSQL_TYPE_VARCHAR |
900 | MYSQL_TYPE_STRING, MYSQL_TYPE_VARCHAR, |
901 | //MYSQL_TYPE_BIT <16>-<245> |
902 | MYSQL_TYPE_STRING, |
903 | //MYSQL_TYPE_NEWDECIMAL MYSQL_TYPE_ENUM |
904 | MYSQL_TYPE_STRING, MYSQL_TYPE_STRING, |
905 | //MYSQL_TYPE_SET MYSQL_TYPE_TINY_BLOB |
906 | MYSQL_TYPE_STRING, MYSQL_TYPE_TINY_BLOB, |
907 | //MYSQL_TYPE_MEDIUM_BLOB MYSQL_TYPE_LONG_BLOB |
908 | MYSQL_TYPE_MEDIUM_BLOB, MYSQL_TYPE_LONG_BLOB, |
909 | //MYSQL_TYPE_BLOB MYSQL_TYPE_VAR_STRING |
910 | MYSQL_TYPE_BLOB, MYSQL_TYPE_VARCHAR, |
911 | //MYSQL_TYPE_STRING |
912 | MYSQL_TYPE_STRING |
913 | } |
914 | }; |
915 | |
916 | /** |
917 | Return type of which can carry value of both given types in UNION result. |
918 | |
919 | @param a type for merging |
920 | @param b type for merging |
921 | |
922 | @return |
923 | type of field |
924 | */ |
925 | |
926 | enum_field_types Field::field_type_merge(enum_field_types a, |
927 | enum_field_types b) |
928 | { |
929 | return field_types_merge_rules[field_type2index(a)] |
930 | [field_type2index(b)]; |
931 | } |
932 | |
933 | const Type_handler * |
934 | Type_handler::aggregate_for_result_traditional(const Type_handler *a, |
935 | const Type_handler *b) |
936 | { |
937 | enum_field_types ta= a->real_field_type(); |
938 | enum_field_types tb= b->real_field_type(); |
939 | return |
940 | Type_handler::get_handler_by_real_type(Field::field_type_merge(ta, tb)); |
941 | } |
942 | |
943 | |
944 | /* |
945 | Test if the given string contains important data: |
946 | not spaces for character string, |
947 | or any data for binary string. |
948 | |
949 | SYNOPSIS |
950 | test_if_important_data() |
951 | cs Character set |
952 | str String to test |
953 | strend String end |
954 | |
955 | RETURN |
956 | FALSE - If string does not have important data |
957 | TRUE - If string has some important data |
958 | */ |
959 | |
960 | static bool |
961 | test_if_important_data(CHARSET_INFO *cs, const char *str, const char *strend) |
962 | { |
963 | if (cs != &my_charset_bin) |
964 | str+= cs->cset->scan(cs, str, strend, MY_SEQ_SPACES); |
965 | return (str < strend); |
966 | } |
967 | |
968 | |
969 | /** |
970 | Function to compare two unsigned integers for their relative order. |
971 | Used below. In an anonymous namespace to not clash with definitions |
972 | in other files. |
973 | */ |
974 | |
975 | CPP_UNNAMED_NS_START |
976 | |
977 | int compare(unsigned int a, unsigned int b) |
978 | { |
979 | if (a < b) |
980 | return -1; |
981 | if (b < a) |
982 | return 1; |
983 | return 0; |
984 | } |
985 | |
986 | CPP_UNNAMED_NS_END |
987 | |
988 | |
989 | /***************************************************************************** |
990 | Static help functions |
991 | *****************************************************************************/ |
992 | |
993 | |
994 | void Field::make_sort_key(uchar *buff,uint length) |
995 | { |
996 | if (maybe_null()) |
997 | { |
998 | if (is_null()) |
999 | { |
1000 | bzero(buff, length + 1); |
1001 | return; |
1002 | } |
1003 | *buff++= 1; |
1004 | } |
1005 | sort_string(buff, length); |
1006 | } |
1007 | |
1008 | |
1009 | /** |
1010 | @brief |
1011 | Determine the relative position of the field value in a numeric interval |
1012 | |
1013 | @details |
1014 | The function returns a double number between 0.0 and 1.0 as the relative |
1015 | position of the value of the this field in the numeric interval of [min,max]. |
1016 | If the value is not in the interval the the function returns 0.0 when |
1017 | the value is less than min, and, 1.0 when the value is greater than max. |
1018 | |
1019 | @param min value of the left end of the interval |
1020 | @param max value of the right end of the interval |
1021 | |
1022 | @return |
1023 | relative position of the field value in the numeric interval [min,max] |
1024 | */ |
1025 | |
1026 | double Field::pos_in_interval_val_real(Field *min, Field *max) |
1027 | { |
1028 | double n, d; |
1029 | n= val_real() - min->val_real(); |
1030 | if (n < 0) |
1031 | return 0.0; |
1032 | d= max->val_real() - min->val_real(); |
1033 | if (d <= 0) |
1034 | return 1.0; |
1035 | return MY_MIN(n/d, 1.0); |
1036 | } |
1037 | |
1038 | |
1039 | static |
1040 | inline ulonglong char_prefix_to_ulonglong(uchar *src) |
1041 | { |
1042 | uint sz= sizeof(ulonglong); |
1043 | for (uint i= 0; i < sz/2; i++) |
1044 | { |
1045 | uchar tmp= src[i]; |
1046 | src[i]= src[sz-1-i]; |
1047 | src[sz-1-i]= tmp; |
1048 | } |
1049 | return uint8korr(src); |
1050 | } |
1051 | |
1052 | /* |
1053 | Compute res = a - b, without losing precision and taking care that these are |
1054 | unsigned numbers. |
1055 | */ |
1056 | static inline double safe_substract(ulonglong a, ulonglong b) |
1057 | { |
1058 | return (a > b)? double(a - b) : -double(b - a); |
1059 | } |
1060 | |
1061 | |
1062 | /** |
1063 | @brief |
1064 | Determine the relative position of the field value in a string interval |
1065 | |
1066 | @details |
1067 | The function returns a double number between 0.0 and 1.0 as the relative |
1068 | position of the value of the this field in the string interval of [min,max]. |
1069 | If the value is not in the interval the the function returns 0.0 when |
1070 | the value is less than min, and, 1.0 when the value is greater than max. |
1071 | |
1072 | @note |
1073 | To calculate the relative position of the string value v in the interval |
1074 | [min, max] the function first converts the beginning of these three |
1075 | strings v, min, max into the strings that are used for byte comparison. |
1076 | For each string not more sizeof(ulonglong) first bytes are taken |
1077 | from the result of conversion. Then these bytes are interpreted as the |
1078 | big-endian representation of an ulonglong integer. The values of these |
1079 | integer numbers obtained for the strings v, min, max are used to calculate |
1080 | the position of v in [min,max] in the same way is it's done for numeric |
1081 | fields (see Field::pos_in_interval_val_real). |
1082 | |
1083 | @todo |
1084 | Improve the procedure for the case when min and max have the same |
1085 | beginning |
1086 | |
1087 | @param min value of the left end of the interval |
1088 | @param max value of the right end of the interval |
1089 | |
1090 | @return |
1091 | relative position of the field value in the string interval [min,max] |
1092 | */ |
1093 | |
1094 | double Field::pos_in_interval_val_str(Field *min, Field *max, uint data_offset) |
1095 | { |
1096 | uchar mp_prefix[sizeof(ulonglong)]; |
1097 | uchar minp_prefix[sizeof(ulonglong)]; |
1098 | uchar maxp_prefix[sizeof(ulonglong)]; |
1099 | ulonglong mp, minp, maxp; |
1100 | my_strnxfrm(charset(), mp_prefix, sizeof(mp), |
1101 | ptr + data_offset, |
1102 | data_length()); |
1103 | my_strnxfrm(charset(), minp_prefix, sizeof(minp), |
1104 | min->ptr + data_offset, |
1105 | min->data_length()); |
1106 | my_strnxfrm(charset(), maxp_prefix, sizeof(maxp), |
1107 | max->ptr + data_offset, |
1108 | max->data_length()); |
1109 | mp= char_prefix_to_ulonglong(mp_prefix); |
1110 | minp= char_prefix_to_ulonglong(minp_prefix); |
1111 | maxp= char_prefix_to_ulonglong(maxp_prefix); |
1112 | double n, d; |
1113 | n= safe_substract(mp, minp); |
1114 | if (n < 0) |
1115 | return 0.0; |
1116 | d= safe_substract(maxp, minp); |
1117 | if (d <= 0) |
1118 | return 1.0; |
1119 | return MY_MIN(n/d, 1.0); |
1120 | } |
1121 | |
1122 | |
1123 | bool Field::test_if_equality_guarantees_uniqueness(const Item *item) const |
1124 | { |
1125 | DBUG_ASSERT(cmp_type() != STRING_RESULT); // For STRING_RESULT see Field_str |
1126 | /* |
1127 | We use result_type() rather than cmp_type() in the below condition, |
1128 | because it covers a special case that string literals guarantee uniqueness |
1129 | for temporal columns, so the query: |
1130 | WHERE temporal_column='string' |
1131 | cannot return multiple distinct temporal values. |
1132 | |
1133 | TODO: perhaps we could allow INT/DECIMAL/DOUBLE types for temporal items. |
1134 | */ |
1135 | return result_type() == item->result_type(); |
1136 | } |
1137 | |
1138 | |
1139 | /** |
1140 | Check whether a field item can be substituted for an equal item |
1141 | |
1142 | @details |
1143 | The function checks whether a substitution of a field item for |
1144 | an equal item is valid. |
1145 | |
1146 | @param arg *arg != NULL <-> the field is in the context |
1147 | where substitution for an equal item is valid |
1148 | |
1149 | @note |
1150 | The following statement is not always true: |
1151 | @n |
1152 | x=y => F(x)=F(x/y). |
1153 | @n |
1154 | This means substitution of an item for an equal item not always |
1155 | yields an equavalent condition. Here's an example: |
1156 | @code |
1157 | 'a'='a ' |
1158 | (LENGTH('a')=1) != (LENGTH('a ')=2) |
1159 | @endcode |
1160 | Such a substitution is surely valid if either the substituted |
1161 | field is not of a STRING type or if it is an argument of |
1162 | a comparison predicate. |
1163 | |
1164 | @retval |
1165 | TRUE substitution is valid |
1166 | @retval |
1167 | FALSE otherwise |
1168 | */ |
1169 | |
1170 | bool Field::can_be_substituted_to_equal_item(const Context &ctx, |
1171 | const Item_equal *item_equal) |
1172 | { |
1173 | DBUG_ASSERT(item_equal->compare_type_handler()->cmp_type() != STRING_RESULT); |
1174 | DBUG_ASSERT(cmp_type() != STRING_RESULT); |
1175 | switch (ctx.subst_constraint()) { |
1176 | case ANY_SUBST: |
1177 | /* |
1178 | Disable const propagation for items used in different comparison contexts. |
1179 | This must be done because, for example, Item_hex_string->val_int() is not |
1180 | the same as (Item_hex_string->val_str() in BINARY column)->val_int(). |
1181 | We cannot simply disable the replacement in a particular context ( |
1182 | e.g. <bin_col> = <int_col> AND <bin_col> = <hex_string>) since |
1183 | Items don't know the context they are in and there are functions like |
1184 | IF (<hex_string>, 'yes', 'no'). |
1185 | */ |
1186 | return ctx.compare_type_handler() == item_equal->compare_type_handler(); |
1187 | case IDENTITY_SUBST: |
1188 | return true; |
1189 | } |
1190 | return false; |
1191 | } |
1192 | |
1193 | |
1194 | /* |
1195 | This handles all numeric and BIT data types. |
1196 | */ |
1197 | bool Field::can_optimize_keypart_ref(const Item_bool_func *cond, |
1198 | const Item *item) const |
1199 | { |
1200 | DBUG_ASSERT(cmp_type() != STRING_RESULT); |
1201 | DBUG_ASSERT(cmp_type() != TIME_RESULT); |
1202 | return item->cmp_type() != TIME_RESULT; |
1203 | } |
1204 | |
1205 | |
1206 | /* |
1207 | This handles all numeric and BIT data types. |
1208 | */ |
1209 | bool Field::can_optimize_group_min_max(const Item_bool_func *cond, |
1210 | const Item *const_item) const |
1211 | { |
1212 | DBUG_ASSERT(cmp_type() != STRING_RESULT); |
1213 | DBUG_ASSERT(cmp_type() != TIME_RESULT); |
1214 | return const_item->cmp_type() != TIME_RESULT; |
1215 | } |
1216 | |
1217 | |
1218 | /* |
1219 | This covers all numeric types, BIT |
1220 | */ |
1221 | bool Field::can_optimize_range(const Item_bool_func *cond, |
1222 | const Item *item, |
1223 | bool is_eq_func) const |
1224 | { |
1225 | DBUG_ASSERT(cmp_type() != TIME_RESULT); // Handled in Field_temporal |
1226 | DBUG_ASSERT(cmp_type() != STRING_RESULT); // Handled in Field_str descendants |
1227 | return item->cmp_type() != TIME_RESULT; |
1228 | } |
1229 | |
1230 | |
1231 | int Field::store_hex_hybrid(const char *str, size_t length) |
1232 | { |
1233 | DBUG_ASSERT(result_type() != STRING_RESULT); |
1234 | ulonglong nr; |
1235 | |
1236 | if (length > 8) |
1237 | { |
1238 | nr= flags & UNSIGNED_FLAG ? ULONGLONG_MAX : LONGLONG_MAX; |
1239 | goto warn; |
1240 | } |
1241 | nr= (ulonglong) longlong_from_hex_hybrid(str, length); |
1242 | if ((length == 8) && !(flags & UNSIGNED_FLAG) && (nr > LONGLONG_MAX)) |
1243 | { |
1244 | nr= LONGLONG_MAX; |
1245 | goto warn; |
1246 | } |
1247 | return store((longlong) nr, true); // Assume hex numbers are unsigned |
1248 | |
1249 | warn: |
1250 | if (!store((longlong) nr, true)) |
1251 | set_warning(Sql_condition::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1); |
1252 | return 1; |
1253 | } |
1254 | |
1255 | |
1256 | /** |
1257 | If a field does not have a corresponding data, it's behavior can vary: |
1258 | - In case of the fixed file format |
1259 | it's set to the default value for the data type, |
1260 | such as 0 for numbers or '' for strings. |
1261 | - In case of a non-fixed format |
1262 | it's set to NULL for nullable fields, and |
1263 | it's set to the default value for the data type for NOT NULL fields. |
1264 | This seems to be by design. |
1265 | */ |
1266 | bool Field::load_data_set_no_data(THD *thd, bool fixed_format) |
1267 | { |
1268 | reset(); // Do not use the DEFAULT value |
1269 | if (fixed_format) |
1270 | { |
1271 | set_notnull(); |
1272 | /* |
1273 | We're loading a fixed format file, e.g.: |
1274 | LOAD DATA INFILE 't1.txt' INTO TABLE t1 FIELDS TERMINATED BY ''; |
1275 | Suppose the file ended unexpectedly and no data was provided for an |
1276 | auto-increment column in the current row. |
1277 | Historically, if sql_mode=NO_AUTO_VALUE_ON_ZERO, then the column value |
1278 | is set to 0 in such case (the next auto_increment value is not used). |
1279 | This behaviour was introduced by the fix for "bug#12053" in mysql-4.1. |
1280 | Note, loading a delimited file works differently: |
1281 | "no data" is not converted to 0 on NO_AUTO_VALUE_ON_ZERO: |
1282 | it's considered as equal to setting the column to NULL, |
1283 | which is then replaced to the next auto_increment value. |
1284 | This difference seems to be intentional. |
1285 | */ |
1286 | if (this == table->next_number_field) |
1287 | table->auto_increment_field_not_null= true; |
1288 | } |
1289 | set_has_explicit_value(); // Do not auto-update this field |
1290 | return false; |
1291 | } |
1292 | |
1293 | |
1294 | bool Field::load_data_set_null(THD *thd) |
1295 | { |
1296 | reset(); |
1297 | set_null(); |
1298 | if (!maybe_null()) |
1299 | { |
1300 | if (this != table->next_number_field) |
1301 | set_warning(Sql_condition::WARN_LEVEL_WARN, ER_WARN_NULL_TO_NOTNULL, 1); |
1302 | } |
1303 | set_has_explicit_value(); // Do not auto-update this field |
1304 | return false; |
1305 | } |
1306 | |
1307 | |
1308 | void Field::load_data_set_value(const char *pos, uint length, |
1309 | CHARSET_INFO *cs) |
1310 | { |
1311 | /* |
1312 | Mark field as not null, we should do this for each row because of |
1313 | restore_record... |
1314 | */ |
1315 | set_notnull(); |
1316 | if (this == table->next_number_field) |
1317 | table->auto_increment_field_not_null= true; |
1318 | store(pos, length, cs); |
1319 | set_has_explicit_value(); // Do not auto-update this field |
1320 | } |
1321 | |
1322 | |
1323 | bool Field::sp_prepare_and_store_item(THD *thd, Item **value) |
1324 | { |
1325 | DBUG_ENTER("Field::sp_prepare_and_store_item" ); |
1326 | DBUG_ASSERT(value); |
1327 | |
1328 | Item *expr_item; |
1329 | |
1330 | if (!(expr_item= thd->sp_prepare_func_item(value, 1))) |
1331 | goto error; |
1332 | |
1333 | /* |
1334 | expr_item is now fixed, it's safe to call cmp_type() |
1335 | */ |
1336 | if (expr_item->cmp_type() == ROW_RESULT) |
1337 | { |
1338 | my_error(ER_OPERAND_COLUMNS, MYF(0), 1); |
1339 | goto error; |
1340 | } |
1341 | |
1342 | /* Save the value in the field. Convert the value if needed. */ |
1343 | |
1344 | expr_item->save_in_field(this, 0); |
1345 | |
1346 | if (likely(!thd->is_error())) |
1347 | DBUG_RETURN(false); |
1348 | |
1349 | error: |
1350 | /* |
1351 | In case of error during evaluation, leave the result field set to NULL. |
1352 | Sic: we can't do it in the beginning of the function because the |
1353 | result field might be needed for its own re-evaluation, e.g. case of |
1354 | set x = x + 1; |
1355 | */ |
1356 | set_null(); |
1357 | DBUG_ASSERT(thd->is_error()); |
1358 | DBUG_RETURN(true); |
1359 | } |
1360 | |
1361 | |
1362 | /** |
1363 | Numeric fields base class constructor. |
1364 | */ |
1365 | Field_num::Field_num(uchar *ptr_arg,uint32 len_arg, uchar *null_ptr_arg, |
1366 | uchar null_bit_arg, utype unireg_check_arg, |
1367 | const LEX_CSTRING *field_name_arg, |
1368 | uint8 dec_arg, bool zero_arg, bool unsigned_arg) |
1369 | :Field(ptr_arg, len_arg, null_ptr_arg, null_bit_arg, |
1370 | unireg_check_arg, field_name_arg), |
1371 | dec(dec_arg),zerofill(zero_arg),unsigned_flag(unsigned_arg) |
1372 | { |
1373 | if (zerofill) |
1374 | flags|=ZEROFILL_FLAG; |
1375 | if (unsigned_flag) |
1376 | flags|=UNSIGNED_FLAG; |
1377 | } |
1378 | |
1379 | |
1380 | void Field_num::prepend_zeros(String *value) const |
1381 | { |
1382 | int diff; |
1383 | if ((diff= (int) (field_length - value->length())) > 0) |
1384 | { |
1385 | const bool error= value->realloc(field_length); |
1386 | if (likely(!error)) |
1387 | { |
1388 | bmove_upp((uchar*) value->ptr()+field_length, |
1389 | (uchar*) value->ptr()+value->length(), |
1390 | value->length()); |
1391 | bfill((uchar*) value->ptr(),diff,'0'); |
1392 | value->length(field_length); |
1393 | } |
1394 | } |
1395 | } |
1396 | |
1397 | |
1398 | Item *Field_num::get_equal_zerofill_const_item(THD *thd, const Context &ctx, |
1399 | Item *const_item) |
1400 | { |
1401 | switch (ctx.subst_constraint()) { |
1402 | case IDENTITY_SUBST: |
1403 | return NULL; // Not safe to propagate if not in comparison. See MDEV-8369. |
1404 | case ANY_SUBST: |
1405 | break; |
1406 | } |
1407 | DBUG_ASSERT(const_item->const_item()); |
1408 | DBUG_ASSERT(ctx.compare_type_handler()->cmp_type() != STRING_RESULT); |
1409 | return const_item; |
1410 | } |
1411 | |
1412 | |
1413 | /** |
1414 | Contruct warning parameters using thd->no_errors |
1415 | to determine whether to generate or suppress warnings. |
1416 | We can get here in a query like this: |
1417 | SELECT COUNT(@@basedir); |
1418 | from Item_func_get_system_var::update_null_value(). |
1419 | */ |
1420 | Value_source::Warn_filter::Warn_filter(const THD *thd) |
1421 | :m_want_warning_edom(!thd->no_errors), |
1422 | m_want_note_truncated_spaces(!thd->no_errors) |
1423 | { } |
1424 | |
1425 | |
1426 | /** |
1427 | Check string-to-number conversion and produce a warning if |
1428 | - could not convert any digits (EDOM-alike error) |
1429 | - found garbage at the end of the string |
1430 | - found trailing spaces (a note) |
1431 | See also Field_num::check_edom_and_truncation() for a similar function. |
1432 | |
1433 | @param thd - the thread |
1434 | @param filter - which warnings/notes are allowed |
1435 | @param type - name of the data type (e.g. "INTEGER", "DECIMAL", "DOUBLE") |
1436 | @param cs - character set of the original string |
1437 | @param str - the original string |
1438 | @param end - the end of the string |
1439 | |
1440 | Unlike Field_num::check_edom_and_truncation(), this function does not |
1441 | distinguish between EDOM and truncation and reports the same warning for |
1442 | both cases. Perhaps we should eventually print different warnings, to make |
1443 | the explicit CAST work closer to the implicit cast in Field_xxx::store(). |
1444 | */ |
1445 | void |
1446 | Value_source::Converter_string_to_number::check_edom_and_truncation(THD *thd, |
1447 | Warn_filter filter, |
1448 | const char *type, |
1449 | CHARSET_INFO *cs, |
1450 | const char *str, |
1451 | size_t length) const |
1452 | { |
1453 | DBUG_ASSERT(str <= m_end_of_num); |
1454 | DBUG_ASSERT(m_end_of_num <= str + length); |
1455 | if (m_edom || (m_end_of_num < str + length && |
1456 | !check_if_only_end_space(cs, m_end_of_num, str + length))) |
1457 | { |
1458 | // EDOM or important trailing data truncation |
1459 | if (filter.want_warning_edom()) |
1460 | { |
1461 | /* |
1462 | We can use err.ptr() here as ErrConvString is guranteed to put an |
1463 | end \0 here. |
1464 | */ |
1465 | THD *wthd= thd ? thd : current_thd; |
1466 | push_warning_printf(wthd, Sql_condition::WARN_LEVEL_WARN, |
1467 | ER_TRUNCATED_WRONG_VALUE, |
1468 | ER_THD(wthd, ER_TRUNCATED_WRONG_VALUE), type, |
1469 | ErrConvString(str, length, cs).ptr()); |
1470 | } |
1471 | } |
1472 | else if (m_end_of_num < str + length) |
1473 | { |
1474 | // Unimportant trailing data (spaces) truncation |
1475 | if (filter.want_note_truncated_spaces()) |
1476 | { |
1477 | THD *wthd= thd ? thd : current_thd; |
1478 | push_warning_printf(wthd, Sql_condition::WARN_LEVEL_NOTE, |
1479 | ER_TRUNCATED_WRONG_VALUE, |
1480 | ER_THD(wthd, ER_TRUNCATED_WRONG_VALUE), type, |
1481 | ErrConvString(str, length, cs).ptr()); |
1482 | } |
1483 | } |
1484 | } |
1485 | |
1486 | |
1487 | /** |
1488 | Check a string-to-number conversion routine result and generate warnings |
1489 | in case when it: |
1490 | - could not convert any digits |
1491 | - found garbage at the end of the string. |
1492 | |
1493 | @param type Data type name (e.g. "decimal", "integer", "double") |
1494 | @param edom Indicates that the string-to-number routine retuned |
1495 | an error code equivalent to EDOM (value out of domain), |
1496 | i.e. the string fully consisted of garbage and the |
1497 | conversion routine could not get any digits from it. |
1498 | @param str The original string |
1499 | @param length Length of 'str' |
1500 | @param cs Character set |
1501 | @param end Pointer to char after last used digit |
1502 | |
1503 | @note |
1504 | This is called after one has called one of the following functions: |
1505 | - strntoull10rnd() |
1506 | - my_strntod() |
1507 | - str2my_decimal() |
1508 | |
1509 | @retval |
1510 | 0 OK |
1511 | @retval |
1512 | 1 error: could not scan any digits (EDOM), |
1513 | e.g. empty string, or garbage. |
1514 | @retval |
1515 | 2 error: scanned some digits, |
1516 | but then found garbage at the end of the string. |
1517 | */ |
1518 | |
1519 | |
1520 | int Field_num::check_edom_and_important_data_truncation(const char *type, |
1521 | bool edom, |
1522 | CHARSET_INFO *cs, |
1523 | const char *str, size_t length, |
1524 | const char *end) |
1525 | { |
1526 | /* Test if we get an empty string or garbage */ |
1527 | if (edom) |
1528 | { |
1529 | ErrConvString err(str, length, cs); |
1530 | set_warning_truncated_wrong_value(type, err.ptr()); |
1531 | return 1; |
1532 | } |
1533 | /* Test if we have garbage at the end of the given string. */ |
1534 | if (test_if_important_data(cs, end, str + length)) |
1535 | { |
1536 | set_warning(WARN_DATA_TRUNCATED, 1); |
1537 | return 2; |
1538 | } |
1539 | return 0; |
1540 | } |
1541 | |
1542 | |
1543 | int Field_num::check_edom_and_truncation(const char *type, bool edom, |
1544 | CHARSET_INFO *cs, |
1545 | const char *str, size_t length, |
1546 | const char *end) |
1547 | { |
1548 | int rc= check_edom_and_important_data_truncation(type, edom, |
1549 | cs, str, length, end); |
1550 | if (!rc && end < str + length) |
1551 | set_note(WARN_DATA_TRUNCATED, 1); |
1552 | return rc; |
1553 | } |
1554 | |
1555 | |
1556 | /* |
1557 | Conver a string to an integer then check bounds. |
1558 | |
1559 | SYNOPSIS |
1560 | Field_num::get_int |
1561 | cs Character set |
1562 | from String to convert |
1563 | len Length of the string |
1564 | rnd OUT longlong value |
1565 | unsigned_max max unsigned value |
1566 | signed_min min signed value |
1567 | signed_max max signed value |
1568 | |
1569 | DESCRIPTION |
1570 | The function calls strntoull10rnd() to get an integer value then |
1571 | check bounds and errors returned. In case of any error a warning |
1572 | is raised. |
1573 | |
1574 | RETURN |
1575 | 0 ok |
1576 | 1 error |
1577 | */ |
1578 | |
1579 | bool Field_num::get_int(CHARSET_INFO *cs, const char *from, size_t len, |
1580 | longlong *rnd, ulonglong unsigned_max, |
1581 | longlong signed_min, longlong signed_max) |
1582 | { |
1583 | char *end; |
1584 | int error; |
1585 | |
1586 | *rnd= (longlong) cs->cset->strntoull10rnd(cs, from, len, |
1587 | unsigned_flag, &end, |
1588 | &error); |
1589 | if (unsigned_flag) |
1590 | { |
1591 | |
1592 | if ((((ulonglong) *rnd > unsigned_max) && |
1593 | (*rnd= (longlong) unsigned_max)) || |
1594 | error == MY_ERRNO_ERANGE) |
1595 | { |
1596 | goto out_of_range; |
1597 | } |
1598 | } |
1599 | else |
1600 | { |
1601 | if (*rnd < signed_min) |
1602 | { |
1603 | *rnd= signed_min; |
1604 | goto out_of_range; |
1605 | } |
1606 | else if (*rnd > signed_max) |
1607 | { |
1608 | *rnd= signed_max; |
1609 | goto out_of_range; |
1610 | } |
1611 | } |
1612 | if (get_thd()->count_cuted_fields > CHECK_FIELD_EXPRESSION && |
1613 | check_int(cs, from, len, end, error)) |
1614 | return 1; |
1615 | return 0; |
1616 | |
1617 | out_of_range: |
1618 | set_warning(ER_WARN_DATA_OUT_OF_RANGE, 1); |
1619 | return 1; |
1620 | } |
1621 | |
1622 | |
1623 | double Field_real::get_double(const char *str, size_t length, CHARSET_INFO *cs, |
1624 | int *error) |
1625 | { |
1626 | char *end; |
1627 | double nr= my_strntod(cs,(char*) str, length, &end, error); |
1628 | if (unlikely(*error)) |
1629 | { |
1630 | set_warning(ER_WARN_DATA_OUT_OF_RANGE, 1); |
1631 | *error= 1; |
1632 | } |
1633 | else if (get_thd()->count_cuted_fields > CHECK_FIELD_EXPRESSION && |
1634 | check_edom_and_truncation("double" , str == end, |
1635 | cs, str, length, end)) |
1636 | *error= 1; |
1637 | return nr; |
1638 | } |
1639 | |
1640 | |
1641 | /** |
1642 | Process decimal library return codes and issue warnings for overflow and |
1643 | truncation. |
1644 | |
1645 | @param op_result decimal library return code (E_DEC_* see include/decimal.h) |
1646 | |
1647 | @retval |
1648 | 1 there was overflow |
1649 | @retval |
1650 | 0 no error or some other errors except overflow |
1651 | */ |
1652 | |
1653 | int Field::warn_if_overflow(int op_result) |
1654 | { |
1655 | if (op_result == E_DEC_OVERFLOW) |
1656 | { |
1657 | set_warning(ER_WARN_DATA_OUT_OF_RANGE, 1); |
1658 | return 1; |
1659 | } |
1660 | if (op_result == E_DEC_TRUNCATED) |
1661 | { |
1662 | set_note(WARN_DATA_TRUNCATED, 1); |
1663 | /* We return 0 here as this is not a critical issue */ |
1664 | } |
1665 | return 0; |
1666 | } |
1667 | |
1668 | |
1669 | /** |
1670 | Interpret field value as an integer but return the result as a string. |
1671 | |
1672 | This is used for printing bit_fields as numbers while debugging. |
1673 | */ |
1674 | |
1675 | String *Field::val_int_as_str(String *val_buffer, bool unsigned_val) |
1676 | { |
1677 | ASSERT_COLUMN_MARKED_FOR_READ; |
1678 | CHARSET_INFO *cs= &my_charset_bin; |
1679 | uint length; |
1680 | longlong value= val_int(); |
1681 | |
1682 | if (val_buffer->alloc(MY_INT64_NUM_DECIMAL_DIGITS)) |
1683 | return 0; |
1684 | length= (uint) (*cs->cset->longlong10_to_str)(cs, (char*) val_buffer->ptr(), |
1685 | MY_INT64_NUM_DECIMAL_DIGITS, |
1686 | unsigned_val ? 10 : -10, |
1687 | value); |
1688 | val_buffer->length(length); |
1689 | return val_buffer; |
1690 | } |
1691 | |
1692 | |
1693 | /// This is used as a table name when the table structure is not set up |
1694 | Field::Field(uchar *ptr_arg,uint32 length_arg,uchar *null_ptr_arg, |
1695 | uchar null_bit_arg, |
1696 | utype unireg_check_arg, const LEX_CSTRING *field_name_arg) |
1697 | :ptr(ptr_arg), invisible(VISIBLE), |
1698 | null_ptr(null_ptr_arg), table(0), orig_table(0), |
1699 | table_name(0), field_name(*field_name_arg), option_list(0), |
1700 | option_struct(0), key_start(0), part_of_key(0), |
1701 | part_of_key_not_clustered(0), part_of_sortkey(0), |
1702 | unireg_check(unireg_check_arg), field_length(length_arg), |
1703 | null_bit(null_bit_arg), is_created_from_null_item(FALSE), |
1704 | read_stats(NULL), collected_stats(0), vcol_info(0), check_constraint(0), |
1705 | default_value(0) |
1706 | { |
1707 | flags=null_ptr ? 0: NOT_NULL_FLAG; |
1708 | comment.str= (char*) "" ; |
1709 | comment.length=0; |
1710 | field_index= 0; |
1711 | is_stat_field= FALSE; |
1712 | cond_selectivity= 1.0; |
1713 | next_equal_field= NULL; |
1714 | } |
1715 | |
1716 | |
1717 | void Field::hash(ulong *nr, ulong *nr2) |
1718 | { |
1719 | if (is_null()) |
1720 | { |
1721 | *nr^= (*nr << 1) | 1; |
1722 | } |
1723 | else |
1724 | { |
1725 | uint len= pack_length(); |
1726 | CHARSET_INFO *cs= sort_charset(); |
1727 | cs->coll->hash_sort(cs, ptr, len, nr, nr2); |
1728 | } |
1729 | } |
1730 | |
1731 | size_t |
1732 | Field::do_last_null_byte() const |
1733 | { |
1734 | DBUG_ASSERT(null_ptr == NULL || null_ptr >= table->record[0]); |
1735 | if (null_ptr) |
1736 | return (size_t) (null_ptr - table->record[0]) + 1; |
1737 | return LAST_NULL_BYTE_UNDEF; |
1738 | } |
1739 | |
1740 | |
1741 | void Field::copy_from_tmp(int row_offset) |
1742 | { |
1743 | memcpy(ptr,ptr+row_offset,pack_length()); |
1744 | if (null_ptr) |
1745 | { |
1746 | *null_ptr= (uchar) ((null_ptr[0] & (uchar) ~(uint) null_bit) | |
1747 | (null_ptr[row_offset] & (uchar) null_bit)); |
1748 | } |
1749 | } |
1750 | |
1751 | |
1752 | bool Field::send_binary(Protocol *protocol) |
1753 | { |
1754 | char buff[MAX_FIELD_WIDTH]; |
1755 | String tmp(buff,sizeof(buff),charset()); |
1756 | val_str(&tmp); |
1757 | return protocol->store(tmp.ptr(), tmp.length(), tmp.charset()); |
1758 | } |
1759 | |
1760 | |
1761 | /** |
1762 | Check to see if field size is compatible with destination. |
1763 | |
1764 | This method is used in row-based replication to verify that the |
1765 | slave's field size is less than or equal to the master's field |
1766 | size. The encoded field metadata (from the master or source) is |
1767 | decoded and compared to the size of this field (the slave or |
1768 | destination). |
1769 | |
1770 | @note |
1771 | |
1772 | The comparison is made so that if the source data (from the master) |
1773 | is less than the target data (on the slave), -1 is returned in @c |
1774 | <code>*order_var</code>. This implies that a conversion is |
1775 | necessary, but that it is lossy and can result in truncation of the |
1776 | value. |
1777 | |
1778 | If the source data is strictly greater than the target data, 1 is |
1779 | returned in <code>*order_var</code>. This implies that the source |
1780 | type can is contained in the target type and that a conversion is |
1781 | necessary but is non-lossy. |
1782 | |
1783 | If no conversion is required to fit the source type in the target |
1784 | type, 0 is returned in <code>*order_var</code>. |
1785 | |
1786 | @param field_metadata Encoded size in field metadata |
1787 | @param mflags Flags from the table map event for the table. |
1788 | @param order_var Pointer to variable where the order |
1789 | between the source field and this field |
1790 | will be returned. |
1791 | |
1792 | @return @c true if this field's size is compatible with the |
1793 | master's field size, @c false otherwise. |
1794 | */ |
1795 | bool Field::compatible_field_size(uint field_metadata, |
1796 | Relay_log_info *rli_arg __attribute__((unused)), |
1797 | uint16 mflags __attribute__((unused)), |
1798 | int *order_var) |
1799 | { |
1800 | uint const source_size= pack_length_from_metadata(field_metadata); |
1801 | uint const destination_size= row_pack_length(); |
1802 | DBUG_PRINT("debug" , ("real_type: %d, source_size: %u, destination_size: %u" , |
1803 | real_type(), source_size, destination_size)); |
1804 | *order_var = compare(source_size, destination_size); |
1805 | return true; |
1806 | } |
1807 | |
1808 | |
1809 | int Field::store(const char *to, size_t length, CHARSET_INFO *cs, |
1810 | enum_check_fields check_level) |
1811 | { |
1812 | int res; |
1813 | THD *thd= get_thd(); |
1814 | enum_check_fields old_check_level= thd->count_cuted_fields; |
1815 | thd->count_cuted_fields= check_level; |
1816 | res= store(to, length, cs); |
1817 | thd->count_cuted_fields= old_check_level; |
1818 | return res; |
1819 | } |
1820 | |
1821 | |
1822 | int Field::store_timestamp(my_time_t ts, ulong sec_part) |
1823 | { |
1824 | MYSQL_TIME ltime; |
1825 | THD *thd= get_thd(); |
1826 | thd->timestamp_to_TIME(<ime, ts, sec_part, 0); |
1827 | return store_time_dec(<ime, decimals()); |
1828 | } |
1829 | |
1830 | /** |
1831 | Pack the field into a format suitable for storage and transfer. |
1832 | |
1833 | To implement packing functionality, only the virtual function |
1834 | should be overridden. The other functions are just convenience |
1835 | functions and hence should not be overridden. |
1836 | |
1837 | @note The default method for packing fields just copy the raw bytes |
1838 | of the record into the destination, but never more than |
1839 | <code>max_length</code> characters. |
1840 | |
1841 | @param to |
1842 | Pointer to memory area where representation of field should be put. |
1843 | |
1844 | @param from |
1845 | Pointer to memory area where record representation of field is |
1846 | stored. |
1847 | |
1848 | @param max_length |
1849 | Maximum length of the field, as given in the column definition. For |
1850 | example, for <code>CHAR(1000)</code>, the <code>max_length</code> |
1851 | is 1000. This information is sometimes needed to decide how to pack |
1852 | the data. |
1853 | |
1854 | */ |
1855 | uchar * |
1856 | Field::pack(uchar *to, const uchar *from, uint max_length) |
1857 | { |
1858 | uint32 length= pack_length(); |
1859 | set_if_smaller(length, max_length); |
1860 | memcpy(to, from, length); |
1861 | return to+length; |
1862 | } |
1863 | |
1864 | /** |
1865 | Unpack a field from row data. |
1866 | |
1867 | This method is used to unpack a field from a master whose size of |
1868 | the field is less than that of the slave. |
1869 | |
1870 | The <code>param_data</code> parameter is a two-byte integer (stored |
1871 | in the least significant 16 bits of the unsigned integer) usually |
1872 | consisting of two parts: the real type in the most significant byte |
1873 | and a original pack length in the least significant byte. |
1874 | |
1875 | The exact layout of the <code>param_data</code> field is given by |
1876 | the <code>Table_map_log_event::save_field_metadata()</code>. |
1877 | |
1878 | This is the default method for unpacking a field. It just copies |
1879 | the memory block in byte order (of original pack length bytes or |
1880 | length of field, whichever is smaller). |
1881 | |
1882 | @param to Destination of the data |
1883 | @param from Source of the data |
1884 | @param param_data Real type and original pack length of the field |
1885 | data |
1886 | |
1887 | @return New pointer into memory based on from + length of the data |
1888 | @return 0 if wrong data |
1889 | */ |
1890 | const uchar * |
1891 | Field::unpack(uchar* to, const uchar *from, const uchar *from_end, |
1892 | uint param_data) |
1893 | { |
1894 | uint length=pack_length(), len; |
1895 | int from_type= 0; |
1896 | /* |
1897 | If from length is > 255, it has encoded data in the upper bits. Need |
1898 | to mask it out. |
1899 | */ |
1900 | if (param_data > 255) |
1901 | { |
1902 | from_type= (param_data & 0xff00) >> 8U; // real_type. |
1903 | param_data= param_data & 0x00ff; // length. |
1904 | } |
1905 | |
1906 | if ((param_data == 0) || |
1907 | (length == param_data) || |
1908 | (from_type != real_type())) |
1909 | { |
1910 | if (from + length > from_end) |
1911 | return 0; // Error in data |
1912 | |
1913 | memcpy(to, from, length); |
1914 | return from+length; |
1915 | } |
1916 | |
1917 | len= (param_data && (param_data < length)) ? param_data : length; |
1918 | |
1919 | if (from + len > from_end) |
1920 | return 0; // Error in data |
1921 | |
1922 | memcpy(to, from, len); |
1923 | return from+len; |
1924 | } |
1925 | |
1926 | |
1927 | my_decimal *Field::val_decimal(my_decimal *decimal) |
1928 | { |
1929 | /* This never have to be called */ |
1930 | DBUG_ASSERT(0); |
1931 | return 0; |
1932 | } |
1933 | |
1934 | |
1935 | void Field_num::add_zerofill_and_unsigned(String &res) const |
1936 | { |
1937 | if (unsigned_flag) |
1938 | res.append(STRING_WITH_LEN(" unsigned" )); |
1939 | if (zerofill) |
1940 | res.append(STRING_WITH_LEN(" zerofill" )); |
1941 | } |
1942 | |
1943 | |
1944 | void Field::make_send_field(Send_field *field) |
1945 | { |
1946 | if (orig_table && orig_table->s->db.str && *orig_table->s->db.str) |
1947 | { |
1948 | field->db_name= orig_table->s->db.str; |
1949 | if (orig_table->pos_in_table_list && |
1950 | orig_table->pos_in_table_list->schema_table) |
1951 | field->org_table_name= (orig_table->pos_in_table_list-> |
1952 | schema_table->table_name); |
1953 | else |
1954 | field->org_table_name= orig_table->s->table_name.str; |
1955 | } |
1956 | else |
1957 | field->org_table_name= field->db_name= "" ; |
1958 | if (orig_table && orig_table->alias.ptr()) |
1959 | { |
1960 | field->table_name= orig_table->alias.ptr(); |
1961 | field->org_col_name= field_name; |
1962 | } |
1963 | else |
1964 | { |
1965 | field->table_name= "" ; |
1966 | field->org_col_name= empty_clex_str; |
1967 | } |
1968 | field->col_name= field_name; |
1969 | field->length=field_length; |
1970 | field->type=type(); |
1971 | field->flags=table->maybe_null ? (flags & ~NOT_NULL_FLAG) : flags; |
1972 | field->decimals= 0; |
1973 | } |
1974 | |
1975 | |
1976 | /** |
1977 | Conversion from decimal to longlong with checking overflow and |
1978 | setting correct value (min/max) in case of overflow. |
1979 | |
1980 | @param val value which have to be converted |
1981 | @param unsigned_flag type of integer in which we convert val |
1982 | @param err variable to pass error code |
1983 | |
1984 | @return |
1985 | value converted from val |
1986 | */ |
1987 | longlong Field::convert_decimal2longlong(const my_decimal *val, |
1988 | bool unsigned_flag, int *err) |
1989 | { |
1990 | longlong i; |
1991 | if (unsigned_flag) |
1992 | { |
1993 | if (val->sign()) |
1994 | { |
1995 | set_warning(ER_WARN_DATA_OUT_OF_RANGE, 1); |
1996 | i= 0; |
1997 | *err= 1; |
1998 | } |
1999 | else if (warn_if_overflow(my_decimal2int((E_DEC_ERROR & |
2000 | ~E_DEC_OVERFLOW & |
2001 | ~E_DEC_TRUNCATED), |
2002 | val, TRUE, &i))) |
2003 | { |
2004 | i= ~(longlong) 0; |
2005 | *err= 1; |
2006 | } |
2007 | } |
2008 | else if (warn_if_overflow(my_decimal2int((E_DEC_ERROR & |
2009 | ~E_DEC_OVERFLOW & |
2010 | ~E_DEC_TRUNCATED), |
2011 | val, FALSE, &i))) |
2012 | { |
2013 | i= (val->sign() ? LONGLONG_MIN : LONGLONG_MAX); |
2014 | *err= 1; |
2015 | } |
2016 | return i; |
2017 | } |
2018 | |
2019 | |
2020 | /** |
2021 | Storing decimal in integer fields. |
2022 | |
2023 | @param val value for storing |
2024 | |
2025 | @note |
2026 | This method is used by all integer fields, real/decimal redefine it |
2027 | |
2028 | @retval |
2029 | 0 OK |
2030 | @retval |
2031 | !=0 error |
2032 | */ |
2033 | |
2034 | int Field_int::store_decimal(const my_decimal *val) |
2035 | { |
2036 | ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; |
2037 | int err= 0; |
2038 | longlong i= convert_decimal2longlong(val, unsigned_flag, &err); |
2039 | return MY_TEST(err | store(i, unsigned_flag)); |
2040 | } |
2041 | |
2042 | |
2043 | /** |
2044 | Return decimal value of integer field. |
2045 | |
2046 | @param decimal_value buffer for storing decimal value |
2047 | |
2048 | @note |
2049 | This method is used by all integer fields, real/decimal redefine it. |
2050 | All longlong values fit in our decimal buffer which cal store 8*9=72 |
2051 | digits of integer number |
2052 | |
2053 | @return |
2054 | pointer to decimal buffer with value of field |
2055 | */ |
2056 | |
2057 | my_decimal* Field_int::val_decimal(my_decimal *decimal_value) |
2058 | { |
2059 | ASSERT_COLUMN_MARKED_FOR_READ; |
2060 | longlong nr= val_int(); |
2061 | int2my_decimal(E_DEC_FATAL_ERROR, nr, unsigned_flag, decimal_value); |
2062 | return decimal_value; |
2063 | } |
2064 | |
2065 | |
2066 | bool Field_int::get_date(MYSQL_TIME *ltime,ulonglong fuzzydate) |
2067 | { |
2068 | ASSERT_COLUMN_MARKED_FOR_READ; |
2069 | longlong nr= val_int(); |
2070 | bool neg= !(flags & UNSIGNED_FLAG) && nr < 0; |
2071 | return int_to_datetime_with_warn(neg, neg ? -nr : nr, ltime, fuzzydate, |
2072 | field_name.str); |
2073 | } |
2074 | |
2075 | |
2076 | bool Field_vers_trx_id::get_date(MYSQL_TIME *ltime, ulonglong fuzzydate, ulonglong trx_id) |
2077 | { |
2078 | ASSERT_COLUMN_MARKED_FOR_READ; |
2079 | DBUG_ASSERT(ltime); |
2080 | if (!table || !table->s) |
2081 | return true; |
2082 | DBUG_ASSERT(table->versioned(VERS_TRX_ID) || |
2083 | (table->versioned() && table->s->table_category == TABLE_CATEGORY_TEMPORARY)); |
2084 | if (!trx_id) |
2085 | return true; |
2086 | |
2087 | THD *thd= get_thd(); |
2088 | DBUG_ASSERT(thd); |
2089 | if (trx_id == ULONGLONG_MAX) |
2090 | { |
2091 | thd->variables.time_zone->gmt_sec_to_TIME(ltime, TIMESTAMP_MAX_VALUE); |
2092 | ltime->second_part= TIME_MAX_SECOND_PART; |
2093 | return false; |
2094 | } |
2095 | if (cached == trx_id) |
2096 | { |
2097 | *ltime= cache; |
2098 | return false; |
2099 | } |
2100 | |
2101 | TR_table trt(thd); |
2102 | bool found= trt.query(trx_id); |
2103 | if (found) |
2104 | { |
2105 | trt[TR_table::FLD_COMMIT_TS]->get_date(&cache, fuzzydate); |
2106 | *ltime= cache; |
2107 | cached= trx_id; |
2108 | return false; |
2109 | } |
2110 | |
2111 | push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, |
2112 | ER_VERS_NO_TRX_ID, ER_THD(thd, ER_VERS_NO_TRX_ID), |
2113 | (longlong) trx_id); |
2114 | return true; |
2115 | } |
2116 | |
2117 | |
2118 | Field_str::Field_str(uchar *ptr_arg,uint32 len_arg, uchar *null_ptr_arg, |
2119 | uchar null_bit_arg, utype unireg_check_arg, |
2120 | const LEX_CSTRING *field_name_arg, |
2121 | const DTCollation &collation) |
2122 | :Field(ptr_arg, len_arg, null_ptr_arg, null_bit_arg, |
2123 | unireg_check_arg, field_name_arg) |
2124 | { |
2125 | field_charset= collation.collation; |
2126 | if (collation.collation->state & MY_CS_BINSORT) |
2127 | flags|=BINARY_FLAG; |
2128 | field_derivation= collation.derivation; |
2129 | field_repertoire= collation.repertoire; |
2130 | } |
2131 | |
2132 | |
2133 | bool Field_str::test_if_equality_guarantees_uniqueness(const Item *item) const |
2134 | { |
2135 | /* |
2136 | Can't guarantee uniqueness when comparing a CHAR/VARCHAR/TEXT, |
2137 | BINARY/VARBINARY/BLOB, ENUM,SET columns to an item with cmp_type() |
2138 | of INT_RESULT, DOUBLE_RESULT, DECIMAL_RESULT or TIME_RESULT. |
2139 | Example: |
2140 | SELECT * FROM t1 WHERE varchar_column=DATE'2001-01-01' |
2141 | return non-unuque values, e.g. '2001-01-01' and '2001-01-01x'. |
2142 | */ |
2143 | if (!field_charset->coll->propagate(field_charset, 0, 0) || |
2144 | item->cmp_type() != STRING_RESULT) |
2145 | return false; |
2146 | /* |
2147 | Can't guarantee uniqueness when comparing to |
2148 | an item of a different collation. |
2149 | Example: |
2150 | SELECT * FROM t1 |
2151 | WHERE latin1_bin_column = _latin1'A' COLLATE latin1_swedish_ci |
2152 | return non-unique values 'a' and 'A'. |
2153 | */ |
2154 | DTCollation tmp(field_charset, field_derivation, repertoire()); |
2155 | return !tmp.aggregate(item->collation) && tmp.collation == field_charset; |
2156 | } |
2157 | |
2158 | |
2159 | bool Field_str::can_be_substituted_to_equal_item(const Context &ctx, |
2160 | const Item_equal *item_equal) |
2161 | { |
2162 | DBUG_ASSERT(item_equal->compare_type_handler()->cmp_type() == STRING_RESULT); |
2163 | switch (ctx.subst_constraint()) { |
2164 | case ANY_SUBST: |
2165 | return ctx.compare_type_handler() == item_equal->compare_type_handler() && |
2166 | (ctx.compare_type_handler()->cmp_type() != STRING_RESULT || |
2167 | ctx.compare_collation() == item_equal->compare_collation()); |
2168 | case IDENTITY_SUBST: |
2169 | return ((charset()->state & MY_CS_BINSORT) && |
2170 | (charset()->state & MY_CS_NOPAD)); |
2171 | } |
2172 | return false; |
2173 | } |
2174 | |
2175 | |
2176 | void Field_num::make_send_field(Send_field *field) |
2177 | { |
2178 | Field::make_send_field(field); |
2179 | field->decimals= dec; |
2180 | } |
2181 | |
2182 | /** |
2183 | Decimal representation of Field_str. |
2184 | |
2185 | @param d value for storing |
2186 | |
2187 | @note |
2188 | Field_str is the base class for fields like Field_enum, |
2189 | Field_date and some similar. Some dates use fraction and also |
2190 | string value should be converted to floating point value according |
2191 | our rules, so we use double to store value of decimal in string. |
2192 | |
2193 | @todo |
2194 | use decimal2string? |
2195 | |
2196 | @retval |
2197 | 0 OK |
2198 | @retval |
2199 | !=0 error |
2200 | */ |
2201 | |
2202 | int Field_str::store_decimal(const my_decimal *d) |
2203 | { |
2204 | ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; |
2205 | double val; |
2206 | /* TODO: use decimal2string? */ |
2207 | int err= warn_if_overflow(my_decimal2double(E_DEC_FATAL_ERROR & |
2208 | ~E_DEC_OVERFLOW, d, &val)); |
2209 | return err | store(val); |
2210 | } |
2211 | |
2212 | |
2213 | my_decimal *Field_str::val_decimal(my_decimal *decimal_value) |
2214 | { |
2215 | ASSERT_COLUMN_MARKED_FOR_READ; |
2216 | longlong nr= val_int(); |
2217 | int2my_decimal(E_DEC_FATAL_ERROR, nr, 0, decimal_value); |
2218 | return decimal_value; |
2219 | } |
2220 | |
2221 | |
2222 | uint Field::fill_cache_field(CACHE_FIELD *copy) |
2223 | { |
2224 | uint store_length; |
2225 | copy->str= ptr; |
2226 | copy->length= pack_length_in_rec(); |
2227 | copy->field= this; |
2228 | if (flags & BLOB_FLAG) |
2229 | { |
2230 | copy->type= CACHE_BLOB; |
2231 | copy->length-= portable_sizeof_char_ptr; |
2232 | return copy->length; |
2233 | } |
2234 | else if (!zero_pack() && |
2235 | (type() == MYSQL_TYPE_STRING && copy->length >= 4 && |
2236 | copy->length < 256)) |
2237 | { |
2238 | copy->type= CACHE_STRIPPED; /* Remove end space */ |
2239 | store_length= 2; |
2240 | } |
2241 | else if (type() == MYSQL_TYPE_VARCHAR) |
2242 | { |
2243 | copy->type= pack_length()-row_pack_length() == 1 ? CACHE_VARSTR1: |
2244 | CACHE_VARSTR2; |
2245 | store_length= 0; |
2246 | } |
2247 | else |
2248 | { |
2249 | copy->type= 0; |
2250 | store_length= 0; |
2251 | } |
2252 | return copy->length + store_length; |
2253 | } |
2254 | |
2255 | |
2256 | bool Field::get_date(MYSQL_TIME *ltime,ulonglong fuzzydate) |
2257 | { |
2258 | char buff[40]; |
2259 | String tmp(buff,sizeof(buff),&my_charset_bin),*res; |
2260 | if (!(res=val_str(&tmp)) || |
2261 | str_to_datetime_with_warn(res->charset(), res->ptr(), res->length(), |
2262 | ltime, fuzzydate)) |
2263 | return 1; |
2264 | return 0; |
2265 | } |
2266 | |
2267 | /** |
2268 | This is called when storing a date in a string. |
2269 | |
2270 | @note |
2271 | Needs to be changed if/when we want to support different time formats. |
2272 | */ |
2273 | |
2274 | int Field::store_time_dec(const MYSQL_TIME *ltime, uint dec) |
2275 | { |
2276 | ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; |
2277 | char buff[MAX_DATE_STRING_REP_LENGTH]; |
2278 | uint length= (uint) my_TIME_to_str(ltime, buff, dec); |
2279 | /* Avoid conversion when field character set is ASCII compatible */ |
2280 | return store(buff, length, (charset()->state & MY_CS_NONASCII) ? |
2281 | &my_charset_latin1 : charset()); |
2282 | } |
2283 | |
2284 | |
2285 | bool Field::optimize_range(uint idx, uint part) const |
2286 | { |
2287 | return MY_TEST(table->file->index_flags(idx, part, 1) & HA_READ_RANGE); |
2288 | } |
2289 | |
2290 | |
2291 | Field *Field::make_new_field(MEM_ROOT *root, TABLE *new_table, |
2292 | bool keep_type __attribute__((unused))) |
2293 | { |
2294 | Field *tmp; |
2295 | if (!(tmp= (Field*) memdup_root(root,(char*) this,size_of()))) |
2296 | return 0; |
2297 | |
2298 | if (tmp->table->maybe_null) |
2299 | tmp->flags&= ~NOT_NULL_FLAG; |
2300 | tmp->table= new_table; |
2301 | tmp->key_start.init(0); |
2302 | tmp->part_of_key.init(0); |
2303 | tmp->part_of_sortkey.init(0); |
2304 | /* |
2305 | TODO: it is not clear why this method needs to reset unireg_check. |
2306 | Try not to reset it, or explain why it needs to be reset. |
2307 | */ |
2308 | tmp->unireg_check= Field::NONE; |
2309 | tmp->flags&= (NOT_NULL_FLAG | BLOB_FLAG | UNSIGNED_FLAG | |
2310 | ZEROFILL_FLAG | BINARY_FLAG | ENUM_FLAG | SET_FLAG | |
2311 | VERS_SYS_START_FLAG | VERS_SYS_END_FLAG | |
2312 | VERS_UPDATE_UNVERSIONED_FLAG); |
2313 | tmp->reset_fields(); |
2314 | tmp->invisible= VISIBLE; |
2315 | return tmp; |
2316 | } |
2317 | |
2318 | |
2319 | Field *Field::new_key_field(MEM_ROOT *root, TABLE *new_table, |
2320 | uchar *new_ptr, uint32 length, |
2321 | uchar *new_null_ptr, uint new_null_bit) |
2322 | { |
2323 | Field *tmp; |
2324 | if ((tmp= make_new_field(root, new_table, table == new_table))) |
2325 | { |
2326 | tmp->ptr= new_ptr; |
2327 | tmp->null_ptr= new_null_ptr; |
2328 | tmp->null_bit= new_null_bit; |
2329 | } |
2330 | return tmp; |
2331 | } |
2332 | |
2333 | |
2334 | /* This is used to generate a field in TABLE from TABLE_SHARE */ |
2335 | |
2336 | Field *Field::clone(MEM_ROOT *root, TABLE *new_table) |
2337 | { |
2338 | Field *tmp; |
2339 | if ((tmp= (Field*) memdup_root(root,(char*) this,size_of()))) |
2340 | { |
2341 | tmp->init(new_table); |
2342 | tmp->move_field_offset((my_ptrdiff_t) (new_table->record[0] - |
2343 | new_table->s->default_values)); |
2344 | } |
2345 | return tmp; |
2346 | } |
2347 | |
2348 | |
2349 | |
2350 | Field *Field::clone(MEM_ROOT *root, TABLE *new_table, my_ptrdiff_t diff, |
2351 | bool stat_flag) |
2352 | { |
2353 | Field *tmp; |
2354 | if ((tmp= (Field*) memdup_root(root,(char*) this,size_of()))) |
2355 | { |
2356 | tmp->init(new_table); |
2357 | tmp->move_field_offset(diff); |
2358 | } |
2359 | tmp->is_stat_field= stat_flag; |
2360 | return tmp; |
2361 | } |
2362 | |
2363 | |
2364 | Field *Field::clone(MEM_ROOT *root, my_ptrdiff_t diff) |
2365 | { |
2366 | Field *tmp; |
2367 | if ((tmp= (Field*) memdup_root(root,(char*) this,size_of()))) |
2368 | { |
2369 | tmp->move_field_offset(diff); |
2370 | } |
2371 | return tmp; |
2372 | } |
2373 | |
2374 | int Field::set_default() |
2375 | { |
2376 | if (default_value) |
2377 | { |
2378 | Query_arena backup_arena; |
2379 | table->in_use->set_n_backup_active_arena(table->expr_arena, &backup_arena); |
2380 | int rc= default_value->expr->save_in_field(this, 0); |
2381 | table->in_use->restore_active_arena(table->expr_arena, &backup_arena); |
2382 | return rc; |
2383 | } |
2384 | /* Copy constant value stored in s->default_values */ |
2385 | my_ptrdiff_t l_offset= (my_ptrdiff_t) (table->s->default_values - |
2386 | table->record[0]); |
2387 | memcpy(ptr, ptr + l_offset, pack_length()); |
2388 | if (maybe_null_in_table()) |
2389 | *null_ptr= ((*null_ptr & (uchar) ~null_bit) | |
2390 | (null_ptr[l_offset] & null_bit)); |
2391 | return 0; |
2392 | } |
2393 | |
2394 | |
2395 | /**************************************************************************** |
2396 | Field_null, a field that always return NULL |
2397 | ****************************************************************************/ |
2398 | |
2399 | void Field_null::sql_type(String &res) const |
2400 | { |
2401 | res.set_ascii(STRING_WITH_LEN("null" )); |
2402 | } |
2403 | |
2404 | |
2405 | /**************************************************************************** |
2406 | Field_row, e.g. for ROW-type SP variables |
2407 | ****************************************************************************/ |
2408 | |
2409 | Field_row::~Field_row() |
2410 | { |
2411 | delete m_table; |
2412 | } |
2413 | |
2414 | |
2415 | bool Field_row::sp_prepare_and_store_item(THD *thd, Item **value) |
2416 | { |
2417 | DBUG_ENTER("Field_row::sp_prepare_and_store_item" ); |
2418 | |
2419 | if (value[0]->type() == Item::NULL_ITEM) |
2420 | { |
2421 | /* |
2422 | We're in a auto-generated sp_inst_set, to assign |
2423 | the explicit default NULL value to a ROW variable. |
2424 | */ |
2425 | m_table->set_all_fields_to_null(); |
2426 | DBUG_RETURN(false); |
2427 | } |
2428 | |
2429 | /** |
2430 | - In case if we're assigning a ROW variable from another ROW variable, |
2431 | value[0] points to Item_splocal. sp_fix_func_item() will return the |
2432 | fixed underlying Item_field pointing to Field_row. |
2433 | - In case if we're assigning from a ROW() value, src and value[0] will |
2434 | point to the same Item_row. |
2435 | */ |
2436 | Item *src; |
2437 | if (!(src= thd->sp_fix_func_item(value)) || |
2438 | src->cmp_type() != ROW_RESULT || |
2439 | src->cols() != m_table->s->fields) |
2440 | { |
2441 | my_error(ER_OPERAND_COLUMNS, MYF(0), m_table->s->fields); |
2442 | m_table->set_all_fields_to_null(); |
2443 | DBUG_RETURN(true); |
2444 | } |
2445 | |
2446 | DBUG_RETURN(m_table->sp_set_all_fields_from_item(thd, src)); |
2447 | } |
2448 | |
2449 | |
2450 | /**************************************************************************** |
2451 | Functions for the Field_decimal class |
2452 | This is an number stored as a pre-space (or pre-zero) string |
2453 | ****************************************************************************/ |
2454 | |
2455 | int |
2456 | Field_decimal::reset(void) |
2457 | { |
2458 | Field_decimal::store(STRING_WITH_LEN("0" ),&my_charset_bin); |
2459 | return 0; |
2460 | } |
2461 | |
2462 | void Field_decimal::overflow(bool negative) |
2463 | { |
2464 | uint len=field_length; |
2465 | uchar *to=ptr, filler= '9'; |
2466 | |
2467 | set_warning(ER_WARN_DATA_OUT_OF_RANGE, 1); |
2468 | if (negative) |
2469 | { |
2470 | if (!unsigned_flag) |
2471 | { |
2472 | /* Put - sign as a first digit so we'll have -999..999 or 999..999 */ |
2473 | *to++ = '-'; |
2474 | len--; |
2475 | } |
2476 | else |
2477 | { |
2478 | filler= '0'; // Fill up with 0 |
2479 | if (!zerofill) |
2480 | { |
2481 | /* |
2482 | Handle unsigned integer without zerofill, in which case |
2483 | the number should be of format ' 0' or ' 0.000' |
2484 | */ |
2485 | uint whole_part=field_length- (dec ? dec+2 : 1); |
2486 | // Fill with spaces up to the first digit |
2487 | bfill(to, whole_part, ' '); |
2488 | to+= whole_part; |
2489 | len-= whole_part; |
2490 | // The main code will also handle the 0 before the decimal point |
2491 | } |
2492 | } |
2493 | } |
2494 | bfill(to, len, filler); |
2495 | if (dec) |
2496 | ptr[field_length-dec-1]='.'; |
2497 | return; |
2498 | } |
2499 | |
2500 | |
2501 | int Field_decimal::store(const char *from_arg, size_t len, CHARSET_INFO *cs) |
2502 | { |
2503 | ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; |
2504 | char buff[STRING_BUFFER_USUAL_SIZE]; |
2505 | String tmp(buff,sizeof(buff), &my_charset_bin); |
2506 | const uchar *from= (uchar*) from_arg; |
2507 | |
2508 | /* Convert character set if the old one is multi uchar */ |
2509 | if (cs->mbmaxlen > 1) |
2510 | { |
2511 | uint dummy_errors; |
2512 | tmp.copy((char*) from, len, cs, &my_charset_bin, &dummy_errors); |
2513 | from= (uchar*) tmp.ptr(); |
2514 | len= tmp.length(); |
2515 | } |
2516 | |
2517 | const uchar *end= from+len; |
2518 | /* The pointer where the field value starts (i.e., "where to write") */ |
2519 | uchar *to= ptr; |
2520 | uint tmp_dec, tmp_uint; |
2521 | /* |
2522 | The sign of the number : will be 0 (means positive but sign not |
2523 | specified), '+' or '-' |
2524 | */ |
2525 | uchar sign_char=0; |
2526 | /* The pointers where prezeros start and stop */ |
2527 | const uchar *pre_zeros_from, *pre_zeros_end; |
2528 | /* The pointers where digits at the left of '.' start and stop */ |
2529 | const uchar *int_digits_from, *int_digits_end; |
2530 | /* The pointers where digits at the right of '.' start and stop */ |
2531 | const uchar *frac_digits_from, *frac_digits_end; |
2532 | /* The sign of the exponent : will be 0 (means no exponent), '+' or '-' */ |
2533 | char expo_sign_char=0; |
2534 | uint exponent=0; // value of the exponent |
2535 | /* |
2536 | Pointers used when digits move from the left of the '.' to the |
2537 | right of the '.' (explained below) |
2538 | */ |
2539 | const uchar *UNINIT_VAR(int_digits_tail_from); |
2540 | /* Number of 0 that need to be added at the left of the '.' (1E3: 3 zeros) */ |
2541 | uint UNINIT_VAR(int_digits_added_zeros); |
2542 | /* |
2543 | Pointer used when digits move from the right of the '.' to the left |
2544 | of the '.' |
2545 | */ |
2546 | const uchar *UNINIT_VAR(frac_digits_head_end); |
2547 | /* Number of 0 that need to be added at the right of the '.' (for 1E-3) */ |
2548 | uint UNINIT_VAR(frac_digits_added_zeros); |
2549 | uchar *pos,*tmp_left_pos,*tmp_right_pos; |
2550 | /* Pointers that are used as limits (begin and end of the field buffer) */ |
2551 | uchar *left_wall,*right_wall; |
2552 | uchar tmp_char; |
2553 | /* |
2554 | To remember if get_thd()->cuted_fields has already been incremented, |
2555 | to do that only once |
2556 | */ |
2557 | bool is_cuted_fields_incr=0; |
2558 | |
2559 | /* |
2560 | There are three steps in this function : |
2561 | - parse the input string |
2562 | - modify the position of digits around the decimal dot '.' |
2563 | according to the exponent value (if specified) |
2564 | - write the formatted number |
2565 | */ |
2566 | |
2567 | if ((tmp_dec=dec)) |
2568 | tmp_dec++; |
2569 | |
2570 | /* skip pre-space */ |
2571 | while (from != end && my_isspace(&my_charset_bin,*from)) |
2572 | from++; |
2573 | if (from == end) |
2574 | { |
2575 | set_warning(WARN_DATA_TRUNCATED, 1); |
2576 | is_cuted_fields_incr=1; |
2577 | } |
2578 | else if (*from == '+' || *from == '-') // Found some sign ? |
2579 | { |
2580 | sign_char= *from++; |
2581 | /* |
2582 | We allow "+" for unsigned decimal unless defined different |
2583 | Both options allowed as one may wish not to have "+" for unsigned numbers |
2584 | because of data processing issues |
2585 | */ |
2586 | if (unsigned_flag) |
2587 | { |
2588 | if (sign_char=='-') |
2589 | { |
2590 | Field_decimal::overflow(1); |
2591 | return 1; |
2592 | } |
2593 | /* |
2594 | Defining this will not store "+" for unsigned decimal type even if |
2595 | it is passed in numeric string. This will make some tests to fail |
2596 | */ |
2597 | #ifdef DONT_ALLOW_UNSIGNED_PLUS |
2598 | else |
2599 | sign_char=0; |
2600 | #endif |
2601 | } |
2602 | } |
2603 | |
2604 | pre_zeros_from= from; |
2605 | for (; from!=end && *from == '0'; from++) ; // Read prezeros |
2606 | pre_zeros_end=int_digits_from=from; |
2607 | /* Read non zero digits at the left of '.'*/ |
2608 | for (; from != end && my_isdigit(&my_charset_bin, *from) ; from++) ; |
2609 | int_digits_end=from; |
2610 | if (from!=end && *from == '.') // Some '.' ? |
2611 | from++; |
2612 | frac_digits_from= from; |
2613 | /* Read digits at the right of '.' */ |
2614 | for (;from!=end && my_isdigit(&my_charset_bin, *from); from++) ; |
2615 | frac_digits_end=from; |
2616 | // Some exponentiation symbol ? |
2617 | if (from != end && (*from == 'e' || *from == 'E')) |
2618 | { |
2619 | from++; |
2620 | if (from != end && (*from == '+' || *from == '-')) // Some exponent sign ? |
2621 | expo_sign_char= *from++; |
2622 | else |
2623 | expo_sign_char= '+'; |
2624 | /* |
2625 | Read digits of the exponent and compute its value. We must care about |
2626 | 'exponent' overflow, because as unsigned arithmetic is "modulo", big |
2627 | exponents will become small (e.g. 1e4294967296 will become 1e0, and the |
2628 | field will finally contain 1 instead of its max possible value). |
2629 | */ |
2630 | for (;from!=end && my_isdigit(&my_charset_bin, *from); from++) |
2631 | { |
2632 | exponent=10*exponent+(*from-'0'); |
2633 | if (exponent>MAX_EXPONENT) |
2634 | break; |
2635 | } |
2636 | } |
2637 | |
2638 | /* |
2639 | We only have to generate warnings if count_cuted_fields is set. |
2640 | This is to avoid extra checks of the number when they are not needed. |
2641 | Even if this flag is not set, it's OK to increment warnings, if |
2642 | it makes the code easer to read. |
2643 | */ |
2644 | |
2645 | if (get_thd()->count_cuted_fields > CHECK_FIELD_EXPRESSION) |
2646 | { |
2647 | // Skip end spaces |
2648 | for (;from != end && my_isspace(&my_charset_bin, *from); from++) ; |
2649 | if (from != end) // If still something left, warn |
2650 | { |
2651 | set_warning(WARN_DATA_TRUNCATED, 1); |
2652 | is_cuted_fields_incr=1; |
2653 | } |
2654 | } |
2655 | |
2656 | /* |
2657 | Now "move" digits around the decimal dot according to the exponent value, |
2658 | and add necessary zeros. |
2659 | Examples : |
2660 | - 1E+3 : needs 3 more zeros at the left of '.' (int_digits_added_zeros=3) |
2661 | - 1E-3 : '1' moves at the right of '.', and 2 more zeros are needed |
2662 | between '.' and '1' |
2663 | - 1234.5E-3 : '234' moves at the right of '.' |
2664 | These moves are implemented with pointers which point at the begin |
2665 | and end of each moved segment. Examples : |
2666 | - 1234.5E-3 : before the code below is executed, the int_digits part is |
2667 | from '1' to '4' and the frac_digits part from '5' to '5'. After the code |
2668 | below, the int_digits part is from '1' to '1', the frac_digits_head |
2669 | part is from '2' to '4', and the frac_digits part from '5' to '5'. |
2670 | - 1234.5E3 : before the code below is executed, the int_digits part is |
2671 | from '1' to '4' and the frac_digits part from '5' to '5'. After the code |
2672 | below, the int_digits part is from '1' to '4', the int_digits_tail |
2673 | part is from '5' to '5', the frac_digits part is empty, and |
2674 | int_digits_added_zeros=2 (to make 1234500). |
2675 | */ |
2676 | |
2677 | /* |
2678 | Below tmp_uint cannot overflow with small enough MAX_EXPONENT setting, |
2679 | as int_digits_added_zeros<=exponent<4G and |
2680 | (int_digits_end-int_digits_from)<=max_allowed_packet<=2G and |
2681 | (frac_digits_from-int_digits_tail_from)<=max_allowed_packet<=2G |
2682 | */ |
2683 | |
2684 | if (!expo_sign_char) |
2685 | tmp_uint=tmp_dec+(uint)(int_digits_end-int_digits_from); |
2686 | else if (expo_sign_char == '-') |
2687 | { |
2688 | tmp_uint=MY_MIN(exponent,(uint)(int_digits_end-int_digits_from)); |
2689 | frac_digits_added_zeros=exponent-tmp_uint; |
2690 | int_digits_end -= tmp_uint; |
2691 | frac_digits_head_end=int_digits_end+tmp_uint; |
2692 | tmp_uint=tmp_dec+(uint)(int_digits_end-int_digits_from); |
2693 | } |
2694 | else // (expo_sign_char=='+') |
2695 | { |
2696 | tmp_uint=MY_MIN(exponent,(uint)(frac_digits_end-frac_digits_from)); |
2697 | int_digits_added_zeros=exponent-tmp_uint; |
2698 | int_digits_tail_from=frac_digits_from; |
2699 | frac_digits_from=frac_digits_from+tmp_uint; |
2700 | /* |
2701 | We "eat" the heading zeros of the |
2702 | int_digits.int_digits_tail.int_digits_added_zeros concatenation |
2703 | (for example 0.003e3 must become 3 and not 0003) |
2704 | */ |
2705 | if (int_digits_from == int_digits_end) |
2706 | { |
2707 | /* |
2708 | There was nothing in the int_digits part, so continue |
2709 | eating int_digits_tail zeros |
2710 | */ |
2711 | for (; int_digits_tail_from != frac_digits_from && |
2712 | *int_digits_tail_from == '0'; int_digits_tail_from++) ; |
2713 | if (int_digits_tail_from == frac_digits_from) |
2714 | { |
2715 | // there were only zeros in int_digits_tail too |
2716 | int_digits_added_zeros=0; |
2717 | } |
2718 | } |
2719 | tmp_uint= (uint) (tmp_dec+(int_digits_end-int_digits_from)+ |
2720 | (uint)(frac_digits_from-int_digits_tail_from)+ |
2721 | int_digits_added_zeros); |
2722 | } |
2723 | |
2724 | /* |
2725 | Now write the formated number |
2726 | |
2727 | First the digits of the int_% parts. |
2728 | Do we have enough room to write these digits ? |
2729 | If the sign is defined and '-', we need one position for it |
2730 | */ |
2731 | |
2732 | if (field_length < tmp_uint + (int) (sign_char == '-')) |
2733 | { |
2734 | // too big number, change to max or min number |
2735 | Field_decimal::overflow(sign_char == '-'); |
2736 | return 1; |
2737 | } |
2738 | |
2739 | /* |
2740 | Tmp_left_pos is the position where the leftmost digit of |
2741 | the int_% parts will be written |
2742 | */ |
2743 | tmp_left_pos=pos=to+(uint)(field_length-tmp_uint); |
2744 | |
2745 | // Write all digits of the int_% parts |
2746 | while (int_digits_from != int_digits_end) |
2747 | *pos++ = *int_digits_from++ ; |
2748 | |
2749 | if (expo_sign_char == '+') |
2750 | { |
2751 | while (int_digits_tail_from != frac_digits_from) |
2752 | *pos++= *int_digits_tail_from++; |
2753 | while (int_digits_added_zeros-- >0) |
2754 | *pos++= '0'; |
2755 | } |
2756 | /* |
2757 | Note the position where the rightmost digit of the int_% parts has been |
2758 | written (this is to later check if the int_% parts contained nothing, |
2759 | meaning an extra 0 is needed). |
2760 | */ |
2761 | tmp_right_pos=pos; |
2762 | |
2763 | /* |
2764 | Step back to the position of the leftmost digit of the int_% parts, |
2765 | to write sign and fill with zeros or blanks or prezeros. |
2766 | */ |
2767 | pos=tmp_left_pos-1; |
2768 | if (zerofill) |
2769 | { |
2770 | left_wall=to-1; |
2771 | while (pos > left_wall) // Fill with zeros |
2772 | *pos--='0'; |
2773 | } |
2774 | else |
2775 | { |
2776 | left_wall=to+(sign_char != 0)-1; |
2777 | if (!expo_sign_char) // If exponent was specified, ignore prezeros |
2778 | { |
2779 | for (;pos > left_wall && pre_zeros_from !=pre_zeros_end; |
2780 | pre_zeros_from++) |
2781 | *pos--= '0'; |
2782 | } |
2783 | if (pos == tmp_right_pos-1) |
2784 | *pos--= '0'; // no 0 has ever been written, so write one |
2785 | left_wall= to-1; |
2786 | if (sign_char && pos != left_wall) |
2787 | { |
2788 | /* Write sign if possible (it is if sign is '-') */ |
2789 | *pos--= sign_char; |
2790 | } |
2791 | while (pos != left_wall) |
2792 | *pos--=' '; //fill with blanks |
2793 | } |
2794 | |
2795 | /* |
2796 | Write digits of the frac_% parts ; |
2797 | Depending on get_thd()->count_cutted_fields, we may also want |
2798 | to know if some non-zero tail of these parts will |
2799 | be truncated (for example, 0.002->0.00 will generate a warning, |
2800 | while 0.000->0.00 will not) |
2801 | (and 0E1000000000 will not, while 1E-1000000000 will) |
2802 | */ |
2803 | |
2804 | pos=to+(uint)(field_length-tmp_dec); // Calculate post to '.' |
2805 | right_wall=to+field_length; |
2806 | if (pos != right_wall) |
2807 | *pos++='.'; |
2808 | |
2809 | if (expo_sign_char == '-') |
2810 | { |
2811 | while (frac_digits_added_zeros-- > 0) |
2812 | { |
2813 | if (pos == right_wall) |
2814 | { |
2815 | if (get_thd()->count_cuted_fields > CHECK_FIELD_EXPRESSION && |
2816 | !is_cuted_fields_incr) |
2817 | break; // Go on below to see if we lose non zero digits |
2818 | return 0; |
2819 | } |
2820 | *pos++='0'; |
2821 | } |
2822 | while (int_digits_end != frac_digits_head_end) |
2823 | { |
2824 | tmp_char= *int_digits_end++; |
2825 | if (pos == right_wall) |
2826 | { |
2827 | if (tmp_char != '0') // Losing a non zero digit ? |
2828 | { |
2829 | if (!is_cuted_fields_incr) |
2830 | set_warning(WARN_DATA_TRUNCATED, 1); |
2831 | return 0; |
2832 | } |
2833 | continue; |
2834 | } |
2835 | *pos++= tmp_char; |
2836 | } |
2837 | } |
2838 | |
2839 | for (;frac_digits_from!=frac_digits_end;) |
2840 | { |
2841 | tmp_char= *frac_digits_from++; |
2842 | if (pos == right_wall) |
2843 | { |
2844 | if (tmp_char != '0') // Losing a non zero digit ? |
2845 | { |
2846 | if (!is_cuted_fields_incr) |
2847 | { |
2848 | /* |
2849 | This is a note, not a warning, as we don't want to abort |
2850 | when we cut decimals in strict mode |
2851 | */ |
2852 | set_note(WARN_DATA_TRUNCATED, 1); |
2853 | } |
2854 | return 0; |
2855 | } |
2856 | continue; |
2857 | } |
2858 | *pos++= tmp_char; |
2859 | } |
2860 | |
2861 | while (pos != right_wall) |
2862 | *pos++='0'; // Fill with zeros at right of '.' |
2863 | return 0; |
2864 | } |
2865 | |
2866 | |
2867 | int Field_decimal::store(double nr) |
2868 | { |
2869 | ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; |
2870 | if (unsigned_flag && nr < 0) |
2871 | { |
2872 | overflow(1); |
2873 | return 1; |
2874 | } |
2875 | |
2876 | if (!std::isfinite(nr)) // Handle infinity as special case |
2877 | { |
2878 | overflow(nr < 0.0); |
2879 | return 1; |
2880 | } |
2881 | |
2882 | size_t length; |
2883 | uchar fyllchar,*to; |
2884 | char buff[DOUBLE_TO_STRING_CONVERSION_BUFFER_SIZE]; |
2885 | |
2886 | fyllchar = zerofill ? (char) '0' : (char) ' '; |
2887 | length= my_fcvt(nr, dec, buff, NULL); |
2888 | |
2889 | if (length > field_length) |
2890 | { |
2891 | overflow(nr < 0.0); |
2892 | return 1; |
2893 | } |
2894 | else |
2895 | { |
2896 | to=ptr; |
2897 | for (size_t i=field_length-length ; i-- > 0 ;) |
2898 | *to++ = fyllchar; |
2899 | memcpy(to,buff,length); |
2900 | return 0; |
2901 | } |
2902 | } |
2903 | |
2904 | |
2905 | int Field_decimal::store(longlong nr, bool unsigned_val) |
2906 | { |
2907 | ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; |
2908 | char buff[22]; |
2909 | uint length, int_part; |
2910 | char fyllchar; |
2911 | uchar *to; |
2912 | |
2913 | if (nr < 0 && unsigned_flag && !unsigned_val) |
2914 | { |
2915 | overflow(1); |
2916 | return 1; |
2917 | } |
2918 | length= (uint) (longlong10_to_str(nr,buff,unsigned_val ? 10 : -10) - buff); |
2919 | int_part= field_length- (dec ? dec+1 : 0); |
2920 | |
2921 | if (length > int_part) |
2922 | { |
2923 | overflow(!unsigned_val && nr < 0L); /* purecov: inspected */ |
2924 | return 1; |
2925 | } |
2926 | |
2927 | fyllchar = zerofill ? (char) '0' : (char) ' '; |
2928 | to= ptr; |
2929 | for (uint i=int_part-length ; i-- > 0 ;) |
2930 | *to++ = fyllchar; |
2931 | memcpy(to,buff,length); |
2932 | if (dec) |
2933 | { |
2934 | to[length]='.'; |
2935 | bfill(to+length+1,dec,'0'); |
2936 | } |
2937 | return 0; |
2938 | } |
2939 | |
2940 | |
2941 | double Field_decimal::val_real(void) |
2942 | { |
2943 | ASSERT_COLUMN_MARKED_FOR_READ; |
2944 | int not_used; |
2945 | char *end_not_used; |
2946 | return my_strntod(&my_charset_bin, (char*) ptr, field_length, &end_not_used, |
2947 | ¬_used); |
2948 | } |
2949 | |
2950 | longlong Field_decimal::val_int(void) |
2951 | { |
2952 | ASSERT_COLUMN_MARKED_FOR_READ; |
2953 | int not_used; |
2954 | if (unsigned_flag) |
2955 | return my_strntoull(&my_charset_bin, (char*) ptr, field_length, 10, NULL, |
2956 | ¬_used); |
2957 | return my_strntoll(&my_charset_bin, (char*) ptr, field_length, 10, NULL, |
2958 | ¬_used); |
2959 | } |
2960 | |
2961 | |
2962 | String *Field_decimal::val_str(String *val_buffer __attribute__((unused)), |
2963 | String *val_ptr) |
2964 | { |
2965 | ASSERT_COLUMN_MARKED_FOR_READ; |
2966 | uchar *str; |
2967 | size_t tmp_length; |
2968 | |
2969 | for (str=ptr ; *str == ' ' ; str++) ; |
2970 | val_ptr->set_charset(&my_charset_numeric); |
2971 | tmp_length= (size_t) (str-ptr); |
2972 | if (field_length < tmp_length) // Error in data |
2973 | val_ptr->length(0); |
2974 | else |
2975 | val_ptr->set_ascii((const char*) str, field_length-tmp_length); |
2976 | return val_ptr; |
2977 | } |
2978 | |
2979 | /** |
2980 | Should be able to handle at least the following fixed decimal formats: |
2981 | 5.00 , -1.0, 05, -05, +5 with optional pre/end space |
2982 | */ |
2983 | |
2984 | int Field_decimal::cmp(const uchar *a_ptr,const uchar *b_ptr) |
2985 | { |
2986 | const uchar *end; |
2987 | int swap=0; |
2988 | /* First remove prefixes '0', ' ', and '-' */ |
2989 | for (end=a_ptr+field_length; |
2990 | a_ptr != end && |
2991 | (*a_ptr == *b_ptr || |
2992 | ((my_isspace(&my_charset_bin,*a_ptr) || *a_ptr == '+' || |
2993 | *a_ptr == '0') && |
2994 | (my_isspace(&my_charset_bin,*b_ptr) || *b_ptr == '+' || |
2995 | *b_ptr == '0'))); |
2996 | a_ptr++,b_ptr++) |
2997 | { |
2998 | if (*a_ptr == '-') // If both numbers are negative |
2999 | swap= -1 ^ 1; // Swap result |
3000 | } |
3001 | if (a_ptr == end) |
3002 | return 0; |
3003 | if (*a_ptr == '-') |
3004 | return -1; |
3005 | if (*b_ptr == '-') |
3006 | return 1; |
3007 | |
3008 | while (a_ptr != end) |
3009 | { |
3010 | if (*a_ptr++ != *b_ptr++) |
3011 | return swap ^ (a_ptr[-1] < b_ptr[-1] ? -1 : 1); // compare digits |
3012 | } |
3013 | return 0; |
3014 | } |
3015 | |
3016 | |
3017 | void Field_decimal::sort_string(uchar *to,uint length) |
3018 | { |
3019 | uchar *str,*end; |
3020 | for (str=ptr,end=ptr+length; |
3021 | str != end && |
3022 | ((my_isspace(&my_charset_bin,*str) || *str == '+' || |
3023 | *str == '0')) ; |
3024 | str++) |
3025 | *to++=' '; |
3026 | if (str == end) |
3027 | return; /* purecov: inspected */ |
3028 | |
3029 | if (*str == '-') |
3030 | { |
3031 | *to++=1; // Smaller than any number |
3032 | str++; |
3033 | while (str != end) |
3034 | if (my_isdigit(&my_charset_bin,*str)) |
3035 | *to++= (char) ('9' - *str++); |
3036 | else |
3037 | *to++= *str++; |
3038 | } |
3039 | else memcpy(to,str,(uint) (end-str)); |
3040 | } |
3041 | |
3042 | |
3043 | void Field_decimal::sql_type(String &res) const |
3044 | { |
3045 | CHARSET_INFO *cs=res.charset(); |
3046 | uint tmp=field_length; |
3047 | if (!unsigned_flag) |
3048 | tmp--; |
3049 | if (dec) |
3050 | tmp--; |
3051 | res.length(cs->cset->snprintf(cs,(char*) res.ptr(),res.alloced_length(), |
3052 | "decimal(%d,%d)/*old*/" ,tmp,dec)); |
3053 | add_zerofill_and_unsigned(res); |
3054 | } |
3055 | |
3056 | |
3057 | /**************************************************************************** |
3058 | ** Field_new_decimal |
3059 | ****************************************************************************/ |
3060 | |
3061 | Field_new_decimal::Field_new_decimal(uchar *ptr_arg, |
3062 | uint32 len_arg, uchar *null_ptr_arg, |
3063 | uchar null_bit_arg, |
3064 | enum utype unireg_check_arg, |
3065 | const LEX_CSTRING *field_name_arg, |
3066 | uint8 dec_arg,bool zero_arg, |
3067 | bool unsigned_arg) |
3068 | :Field_num(ptr_arg, len_arg, null_ptr_arg, null_bit_arg, |
3069 | unireg_check_arg, field_name_arg, dec_arg, zero_arg, unsigned_arg) |
3070 | { |
3071 | precision= my_decimal_length_to_precision(len_arg, dec_arg, unsigned_arg); |
3072 | set_if_smaller(precision, DECIMAL_MAX_PRECISION); |
3073 | DBUG_ASSERT((precision <= DECIMAL_MAX_PRECISION) && |
3074 | (dec <= DECIMAL_MAX_SCALE)); |
3075 | bin_size= my_decimal_get_binary_size(precision, dec); |
3076 | } |
3077 | |
3078 | |
3079 | int Field_new_decimal::reset(void) |
3080 | { |
3081 | store_value(&decimal_zero); |
3082 | return 0; |
3083 | } |
3084 | |
3085 | |
3086 | /** |
3087 | Generate max/min decimal value in case of overflow. |
3088 | |
3089 | @param decimal_value buffer for value |
3090 | @param sign sign of value which caused overflow |
3091 | */ |
3092 | |
3093 | void Field_new_decimal::set_value_on_overflow(my_decimal *decimal_value, |
3094 | bool sign) |
3095 | { |
3096 | DBUG_ENTER("Field_new_decimal::set_value_on_overflow" ); |
3097 | max_my_decimal(decimal_value, precision, decimals()); |
3098 | if (sign) |
3099 | { |
3100 | if (unsigned_flag) |
3101 | my_decimal_set_zero(decimal_value); |
3102 | else |
3103 | decimal_value->sign(TRUE); |
3104 | } |
3105 | DBUG_VOID_RETURN; |
3106 | } |
3107 | |
3108 | |
3109 | /** |
3110 | Store decimal value in the binary buffer. |
3111 | |
3112 | Checks if decimal_value fits into field size. |
3113 | If it does, stores the decimal in the buffer using binary format. |
3114 | Otherwise sets maximal number that can be stored in the field. |
3115 | |
3116 | @param decimal_value my_decimal |
3117 | @param [OUT] native_error the error returned by my_decimal2binary(). |
3118 | |
3119 | @retval |
3120 | 0 ok |
3121 | @retval |
3122 | 1 error |
3123 | */ |
3124 | |
3125 | bool Field_new_decimal::store_value(const my_decimal *decimal_value, |
3126 | int *native_error) |
3127 | { |
3128 | ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; |
3129 | int error= 0; |
3130 | DBUG_ENTER("Field_new_decimal::store_value" ); |
3131 | #ifndef DBUG_OFF |
3132 | { |
3133 | char dbug_buff[DECIMAL_MAX_STR_LENGTH+2]; |
3134 | DBUG_PRINT("enter" , ("value: %s" , dbug_decimal_as_string(dbug_buff, decimal_value))); |
3135 | } |
3136 | #endif |
3137 | |
3138 | /* check that we do not try to write negative value in unsigned field */ |
3139 | if (unsigned_flag && decimal_value->sign()) |
3140 | { |
3141 | DBUG_PRINT("info" , ("unsigned overflow" )); |
3142 | set_warning(ER_WARN_DATA_OUT_OF_RANGE, 1); |
3143 | error= 1; |
3144 | decimal_value= &decimal_zero; |
3145 | } |
3146 | #ifndef DBUG_OFF |
3147 | { |
3148 | char dbug_buff[DECIMAL_MAX_STR_LENGTH+2]; |
3149 | DBUG_PRINT("info" , ("saving with precision %d scale: %d value %s" , |
3150 | (int)precision, (int)dec, |
3151 | dbug_decimal_as_string(dbug_buff, decimal_value))); |
3152 | } |
3153 | #endif |
3154 | |
3155 | *native_error= my_decimal2binary(E_DEC_FATAL_ERROR & ~E_DEC_OVERFLOW, |
3156 | decimal_value, ptr, precision, dec); |
3157 | |
3158 | if (unlikely(*native_error == E_DEC_OVERFLOW)) |
3159 | { |
3160 | my_decimal buff; |
3161 | DBUG_PRINT("info" , ("overflow" )); |
3162 | set_warning(ER_WARN_DATA_OUT_OF_RANGE, 1); |
3163 | set_value_on_overflow(&buff, decimal_value->sign()); |
3164 | my_decimal2binary(E_DEC_FATAL_ERROR, &buff, ptr, precision, dec); |
3165 | error= 1; |
3166 | } |
3167 | DBUG_EXECUTE("info" , print_decimal_buff(decimal_value, (uchar *) ptr, |
3168 | bin_size);); |
3169 | DBUG_RETURN(error); |
3170 | } |
3171 | |
3172 | |
3173 | bool Field_new_decimal::store_value(const my_decimal *decimal_value) |
3174 | { |
3175 | int native_error; |
3176 | bool rc= store_value(decimal_value, &native_error); |
3177 | if (unlikely(!rc && native_error == E_DEC_TRUNCATED)) |
3178 | set_note(WARN_DATA_TRUNCATED, 1); |
3179 | return rc; |
3180 | } |
3181 | |
3182 | |
3183 | int Field_new_decimal::store(const char *from, size_t length, |
3184 | CHARSET_INFO *charset_arg) |
3185 | { |
3186 | ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; |
3187 | my_decimal decimal_value; |
3188 | THD *thd= get_thd(); |
3189 | DBUG_ENTER("Field_new_decimal::store(char*)" ); |
3190 | |
3191 | const char *end; |
3192 | int err= str2my_decimal(E_DEC_FATAL_ERROR & |
3193 | ~(E_DEC_OVERFLOW | E_DEC_BAD_NUM), |
3194 | from, length, charset_arg, |
3195 | &decimal_value, &end); |
3196 | |
3197 | if (err == E_DEC_OVERFLOW) // Too many digits (>81) in the integer part |
3198 | { |
3199 | set_warning(ER_WARN_DATA_OUT_OF_RANGE, 1); |
3200 | if (!thd->abort_on_warning) |
3201 | { |
3202 | set_value_on_overflow(&decimal_value, decimal_value.sign()); |
3203 | store_decimal(&decimal_value); |
3204 | } |
3205 | DBUG_RETURN(1); |
3206 | } |
3207 | |
3208 | if (thd->count_cuted_fields > CHECK_FIELD_EXPRESSION) |
3209 | { |
3210 | if (check_edom_and_important_data_truncation("decimal" , |
3211 | err && err != E_DEC_TRUNCATED, |
3212 | charset_arg, |
3213 | from, length, end)) |
3214 | { |
3215 | if (!thd->abort_on_warning) |
3216 | { |
3217 | if (err && err != E_DEC_TRUNCATED) |
3218 | { |
3219 | /* |
3220 | If check_decimal() failed because of EDOM-alike error, |
3221 | (e.g. E_DEC_BAD_NUM), we have to initialize decimal_value to zero. |
3222 | Note: if check_decimal() failed because of truncation, |
3223 | decimal_value is alreay properly initialized. |
3224 | */ |
3225 | my_decimal_set_zero(&decimal_value); |
3226 | /* |
3227 | TODO: check str2my_decimal() with HF. It seems to do |
3228 | decimal_make_zero() on fatal errors, so my_decimal_set_zero() |
3229 | is probably not needed here. |
3230 | */ |
3231 | } |
3232 | store_decimal(&decimal_value); |
3233 | } |
3234 | DBUG_RETURN(1); |
3235 | } |
3236 | } |
3237 | |
3238 | #ifndef DBUG_OFF |
3239 | char dbug_buff[DECIMAL_MAX_STR_LENGTH+2]; |
3240 | DBUG_PRINT("enter" , ("value: %s" , |
3241 | dbug_decimal_as_string(dbug_buff, &decimal_value))); |
3242 | #endif |
3243 | int err2; |
3244 | if (store_value(&decimal_value, &err2)) |
3245 | DBUG_RETURN(1); |
3246 | |
3247 | /* |
3248 | E_DEC_TRUNCATED means minor truncation, a note should be enough: |
3249 | - in err: str2my_decimal() truncated '1e-1000000000000' to 0.0 |
3250 | - in err2: store_value() truncated 1.123 to 1.12, e.g. for DECIMAL(10,2) |
3251 | Also, we send a note if a string had some trailing spaces: '1.12 ' |
3252 | */ |
3253 | if (thd->count_cuted_fields > CHECK_FIELD_EXPRESSION && |
3254 | (err == E_DEC_TRUNCATED || |
3255 | err2 == E_DEC_TRUNCATED || |
3256 | end < from + length)) |
3257 | set_note(WARN_DATA_TRUNCATED, 1); |
3258 | DBUG_RETURN(0); |
3259 | } |
3260 | |
3261 | |
3262 | /** |
3263 | @todo |
3264 | Fix following when double2my_decimal when double2decimal |
3265 | will return E_DEC_TRUNCATED always correctly |
3266 | */ |
3267 | |
3268 | int Field_new_decimal::store(double nr) |
3269 | { |
3270 | ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; |
3271 | my_decimal decimal_value; |
3272 | int err; |
3273 | THD *thd= get_thd(); |
3274 | DBUG_ENTER("Field_new_decimal::store(double)" ); |
3275 | |
3276 | err= double2my_decimal(E_DEC_FATAL_ERROR & ~E_DEC_OVERFLOW, nr, |
3277 | &decimal_value); |
3278 | if (err) |
3279 | { |
3280 | if (check_overflow(err)) |
3281 | set_value_on_overflow(&decimal_value, decimal_value.sign()); |
3282 | /* Only issue a warning if store_value doesn't issue an warning */ |
3283 | thd->got_warning= 0; |
3284 | } |
3285 | if (store_value(&decimal_value)) |
3286 | err= 1; |
3287 | else if (err && !thd->got_warning) |
3288 | err= warn_if_overflow(err); |
3289 | DBUG_RETURN(err); |
3290 | } |
3291 | |
3292 | |
3293 | int Field_new_decimal::store(longlong nr, bool unsigned_val) |
3294 | { |
3295 | ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; |
3296 | my_decimal decimal_value; |
3297 | int err; |
3298 | |
3299 | if ((err= int2my_decimal(E_DEC_FATAL_ERROR & ~E_DEC_OVERFLOW, |
3300 | nr, unsigned_val, &decimal_value))) |
3301 | { |
3302 | if (check_overflow(err)) |
3303 | set_value_on_overflow(&decimal_value, decimal_value.sign()); |
3304 | /* Only issue a warning if store_value doesn't issue an warning */ |
3305 | get_thd()->got_warning= 0; |
3306 | } |
3307 | if (store_value(&decimal_value)) |
3308 | err= 1; |
3309 | else if (err && !get_thd()->got_warning) |
3310 | err= warn_if_overflow(err); |
3311 | return err; |
3312 | } |
3313 | |
3314 | |
3315 | int Field_new_decimal::store_decimal(const my_decimal *decimal_value) |
3316 | { |
3317 | ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; |
3318 | return store_value(decimal_value); |
3319 | } |
3320 | |
3321 | |
3322 | int Field_new_decimal::store_time_dec(const MYSQL_TIME *ltime, uint dec_arg) |
3323 | { |
3324 | my_decimal decimal_value; |
3325 | return store_value(date2my_decimal(ltime, &decimal_value)); |
3326 | } |
3327 | |
3328 | |
3329 | double Field_new_decimal::val_real(void) |
3330 | { |
3331 | ASSERT_COLUMN_MARKED_FOR_READ; |
3332 | double dbl; |
3333 | my_decimal decimal_value; |
3334 | my_decimal2double(E_DEC_FATAL_ERROR, val_decimal(&decimal_value), &dbl); |
3335 | return dbl; |
3336 | } |
3337 | |
3338 | |
3339 | longlong Field_new_decimal::val_int(void) |
3340 | { |
3341 | ASSERT_COLUMN_MARKED_FOR_READ; |
3342 | longlong i; |
3343 | my_decimal decimal_value; |
3344 | my_decimal2int(E_DEC_FATAL_ERROR, val_decimal(&decimal_value), |
3345 | unsigned_flag, &i); |
3346 | return i; |
3347 | } |
3348 | |
3349 | |
3350 | my_decimal* Field_new_decimal::val_decimal(my_decimal *decimal_value) |
3351 | { |
3352 | ASSERT_COLUMN_MARKED_FOR_READ; |
3353 | DBUG_ENTER("Field_new_decimal::val_decimal" ); |
3354 | binary2my_decimal(E_DEC_FATAL_ERROR, ptr, decimal_value, |
3355 | precision, dec); |
3356 | DBUG_EXECUTE("info" , print_decimal_buff(decimal_value, (uchar *) ptr, |
3357 | bin_size);); |
3358 | DBUG_RETURN(decimal_value); |
3359 | } |
3360 | |
3361 | |
3362 | String *Field_new_decimal::val_str(String *val_buffer, |
3363 | String *val_ptr __attribute__((unused))) |
3364 | { |
3365 | ASSERT_COLUMN_MARKED_FOR_READ; |
3366 | my_decimal decimal_value; |
3367 | uint fixed_precision= zerofill ? precision : 0; |
3368 | my_decimal2string(E_DEC_FATAL_ERROR, val_decimal(&decimal_value), |
3369 | fixed_precision, dec, '0', val_buffer); |
3370 | val_buffer->set_charset(&my_charset_numeric); |
3371 | return val_buffer; |
3372 | } |
3373 | |
3374 | |
3375 | bool Field_new_decimal::get_date(MYSQL_TIME *ltime, ulonglong fuzzydate) |
3376 | { |
3377 | my_decimal value; |
3378 | return decimal_to_datetime_with_warn(val_decimal(&value), |
3379 | ltime, fuzzydate, field_name.str); |
3380 | } |
3381 | |
3382 | |
3383 | int Field_new_decimal::cmp(const uchar *a,const uchar*b) |
3384 | { |
3385 | return memcmp(a, b, bin_size); |
3386 | } |
3387 | |
3388 | |
3389 | void Field_new_decimal::sort_string(uchar *buff, |
3390 | uint) |
3391 | { |
3392 | memcpy(buff, ptr, bin_size); |
3393 | } |
3394 | |
3395 | |
3396 | void Field_new_decimal::sql_type(String &str) const |
3397 | { |
3398 | CHARSET_INFO *cs= str.charset(); |
3399 | str.length(cs->cset->snprintf(cs, (char*) str.ptr(), str.alloced_length(), |
3400 | "decimal(%d,%d)" , precision, (int)dec)); |
3401 | add_zerofill_and_unsigned(str); |
3402 | } |
3403 | |
3404 | |
3405 | /** |
3406 | Save the field metadata for new decimal fields. |
3407 | |
3408 | Saves the precision in the first byte and decimals() in the second |
3409 | byte of the field metadata array at index of *metadata_ptr and |
3410 | *(metadata_ptr + 1). |
3411 | |
3412 | @param metadata_ptr First byte of field metadata |
3413 | |
3414 | @returns number of bytes written to metadata_ptr |
3415 | */ |
3416 | int Field_new_decimal::save_field_metadata(uchar *metadata_ptr) |
3417 | { |
3418 | *metadata_ptr= precision; |
3419 | *(metadata_ptr + 1)= decimals(); |
3420 | return 2; |
3421 | } |
3422 | |
3423 | |
3424 | /** |
3425 | Returns the number of bytes field uses in row-based replication |
3426 | row packed size. |
3427 | |
3428 | This method is used in row-based replication to determine the number |
3429 | of bytes that the field consumes in the row record format. This is |
3430 | used to skip fields in the master that do not exist on the slave. |
3431 | |
3432 | @param field_metadata Encoded size in field metadata |
3433 | |
3434 | @returns The size of the field based on the field metadata. |
3435 | */ |
3436 | uint Field_new_decimal::pack_length_from_metadata(uint field_metadata) |
3437 | { |
3438 | uint const source_precision= (field_metadata >> 8U) & 0x00ff; |
3439 | uint const source_decimal= field_metadata & 0x00ff; |
3440 | uint const source_size= my_decimal_get_binary_size(source_precision, |
3441 | source_decimal); |
3442 | return (source_size); |
3443 | } |
3444 | |
3445 | |
3446 | bool Field_new_decimal::compatible_field_size(uint field_metadata, |
3447 | Relay_log_info * __attribute__((unused)), |
3448 | uint16 mflags __attribute__((unused)), |
3449 | int *order_var) |
3450 | { |
3451 | uint const source_precision= (field_metadata >> 8U) & 0x00ff; |
3452 | uint const source_decimal= field_metadata & 0x00ff; |
3453 | int order= compare(source_precision, precision); |
3454 | *order_var= order != 0 ? order : compare(source_decimal, dec); |
3455 | return true; |
3456 | } |
3457 | |
3458 | |
3459 | uint Field_new_decimal::is_equal(Create_field *new_field) |
3460 | { |
3461 | return ((new_field->type_handler() == type_handler()) && |
3462 | ((new_field->flags & UNSIGNED_FLAG) == |
3463 | (uint) (flags & UNSIGNED_FLAG)) && |
3464 | ((new_field->flags & AUTO_INCREMENT_FLAG) == |
3465 | (uint) (flags & AUTO_INCREMENT_FLAG)) && |
3466 | (new_field->length == max_display_length()) && |
3467 | (new_field->decimals == dec)); |
3468 | } |
3469 | |
3470 | |
3471 | /** |
3472 | Unpack a decimal field from row data. |
3473 | |
3474 | This method is used to unpack a decimal or numeric field from a master |
3475 | whose size of the field is less than that of the slave. |
3476 | |
3477 | @param to Destination of the data |
3478 | @param from Source of the data |
3479 | @param param_data Precision (upper) and decimal (lower) values |
3480 | |
3481 | @return New pointer into memory based on from + length of the data |
3482 | */ |
3483 | const uchar * |
3484 | Field_new_decimal::unpack(uchar* to, const uchar *from, const uchar *from_end, |
3485 | uint param_data) |
3486 | { |
3487 | if (param_data == 0) |
3488 | return Field::unpack(to, from, from_end, param_data); |
3489 | |
3490 | uint from_precision= (param_data & 0xff00) >> 8U; |
3491 | uint from_decimal= param_data & 0x00ff; |
3492 | uint length=pack_length(); |
3493 | uint from_pack_len= my_decimal_get_binary_size(from_precision, from_decimal); |
3494 | uint len= (param_data && (from_pack_len < length)) ? |
3495 | from_pack_len : length; |
3496 | if ((from_pack_len && (from_pack_len < length)) || |
3497 | (from_precision < precision) || |
3498 | (from_decimal < decimals())) |
3499 | { |
3500 | /* |
3501 | If the master's data is smaller than the slave, we need to convert |
3502 | the binary to decimal then resize the decimal converting it back to |
3503 | a decimal and write that to the raw data buffer. |
3504 | */ |
3505 | decimal_digit_t dec_buf[DECIMAL_MAX_PRECISION]; |
3506 | decimal_t dec_val; |
3507 | dec_val.len= from_precision; |
3508 | dec_val.buf= dec_buf; |
3509 | /* |
3510 | Note: bin2decimal does not change the length of the field. So it is |
3511 | just the first step the resizing operation. The second step does the |
3512 | resizing using the precision and decimals from the slave. |
3513 | */ |
3514 | bin2decimal((uchar *)from, &dec_val, from_precision, from_decimal); |
3515 | decimal2bin(&dec_val, to, precision, decimals()); |
3516 | } |
3517 | else |
3518 | { |
3519 | if (from + len > from_end) |
3520 | return 0; // Wrong data |
3521 | memcpy(to, from, len); // Sizes are the same, just copy the data. |
3522 | } |
3523 | return from+len; |
3524 | } |
3525 | |
3526 | |
3527 | Item *Field_new_decimal::get_equal_const_item(THD *thd, const Context &ctx, |
3528 | Item *const_item) |
3529 | { |
3530 | if (flags & ZEROFILL_FLAG) |
3531 | return Field_num::get_equal_zerofill_const_item(thd, ctx, const_item); |
3532 | switch (ctx.subst_constraint()) { |
3533 | case IDENTITY_SUBST: |
3534 | if (const_item->field_type() != MYSQL_TYPE_NEWDECIMAL || |
3535 | const_item->decimal_scale() != decimals()) |
3536 | { |
3537 | my_decimal *val, val_buffer, val_buffer2; |
3538 | if (!(val= const_item->val_decimal(&val_buffer))) |
3539 | { |
3540 | DBUG_ASSERT(0); |
3541 | return const_item; |
3542 | } |
3543 | /* |
3544 | Truncate or extend the decimal value to the scale of the field. |
3545 | See comments about truncation in the same place in |
3546 | Field_time::get_equal_const_item(). |
3547 | */ |
3548 | my_decimal_round(E_DEC_FATAL_ERROR, val, decimals(), true, &val_buffer2); |
3549 | return new (thd->mem_root) Item_decimal(thd, field_name.str, |
3550 | &val_buffer2, |
3551 | decimals(), field_length); |
3552 | } |
3553 | break; |
3554 | case ANY_SUBST: |
3555 | break; |
3556 | } |
3557 | return const_item; |
3558 | } |
3559 | |
3560 | |
3561 | int Field_int::store_time_dec(const MYSQL_TIME *ltime, uint dec_arg) |
3562 | { |
3563 | longlong v= TIME_to_ulonglong(ltime); |
3564 | if (ltime->neg == 0) |
3565 | return store(v, true); |
3566 | return store(-v, false); |
3567 | } |
3568 | |
3569 | |
3570 | /**************************************************************************** |
3571 | ** tiny int |
3572 | ****************************************************************************/ |
3573 | |
3574 | int Field_tiny::store(const char *from,size_t len,CHARSET_INFO *cs) |
3575 | { |
3576 | ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; |
3577 | int error; |
3578 | longlong rnd; |
3579 | |
3580 | error= get_int(cs, from, len, &rnd, 255, -128, 127); |
3581 | ptr[0]= unsigned_flag ? (char) (ulonglong) rnd : (char) rnd; |
3582 | return error; |
3583 | } |
3584 | |
3585 | |
3586 | int Field_tiny::store(double nr) |
3587 | { |
3588 | ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; |
3589 | int error= 0; |
3590 | nr=rint(nr); |
3591 | if (unsigned_flag) |
3592 | { |
3593 | if (nr < 0.0) |
3594 | { |
3595 | *ptr=0; |
3596 | set_warning(ER_WARN_DATA_OUT_OF_RANGE, 1); |
3597 | error= 1; |
3598 | } |
3599 | else if (nr > 255.0) |
3600 | { |
3601 | *ptr= (uchar) 255; |
3602 | set_warning(ER_WARN_DATA_OUT_OF_RANGE, 1); |
3603 | error= 1; |
3604 | } |
3605 | else |
3606 | *ptr= (uchar) nr; |
3607 | } |
3608 | else |
3609 | { |
3610 | if (nr < -128.0) |
3611 | { |
3612 | *ptr= (uchar) -128; |
3613 | set_warning(ER_WARN_DATA_OUT_OF_RANGE, 1); |
3614 | error= 1; |
3615 | } |
3616 | else if (nr > 127.0) |
3617 | { |
3618 | *ptr=127; |
3619 | set_warning(ER_WARN_DATA_OUT_OF_RANGE, 1); |
3620 | error= 1; |
3621 | } |
3622 | else |
3623 | *ptr=(uchar) (int) nr; |
3624 | } |
3625 | return error; |
3626 | } |
3627 | |
3628 | |
3629 | int Field_tiny::store(longlong nr, bool unsigned_val) |
3630 | { |
3631 | ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; |
3632 | int error= 0; |
3633 | |
3634 | if (unsigned_flag) |
3635 | { |
3636 | if (nr < 0 && !unsigned_val) |
3637 | { |
3638 | *ptr= 0; |
3639 | set_warning(ER_WARN_DATA_OUT_OF_RANGE, 1); |
3640 | error= 1; |
3641 | } |
3642 | else if ((ulonglong) nr > (ulonglong) 255) |
3643 | { |
3644 | *ptr= (char) 255; |
3645 | set_warning(ER_WARN_DATA_OUT_OF_RANGE, 1); |
3646 | error= 1; |
3647 | } |
3648 | else |
3649 | *ptr=(char) nr; |
3650 | } |
3651 | else |
3652 | { |
3653 | if (nr < 0 && unsigned_val) |
3654 | nr= 256; // Generate overflow |
3655 | if (nr < -128) |
3656 | { |
3657 | *ptr= (char) -128; |
3658 | set_warning(ER_WARN_DATA_OUT_OF_RANGE, 1); |
3659 | error= 1; |
3660 | } |
3661 | else if (nr > 127) |
3662 | { |
3663 | *ptr=127; |
3664 | set_warning(ER_WARN_DATA_OUT_OF_RANGE, 1); |
3665 | error= 1; |
3666 | } |
3667 | else |
3668 | *ptr=(char) nr; |
3669 | } |
3670 | return error; |
3671 | } |
3672 | |
3673 | |
3674 | double Field_tiny::val_real(void) |
3675 | { |
3676 | ASSERT_COLUMN_MARKED_FOR_READ; |
3677 | int tmp= unsigned_flag ? (int) ptr[0] : |
3678 | (int) ((signed char*) ptr)[0]; |
3679 | return (double) tmp; |
3680 | } |
3681 | |
3682 | |
3683 | longlong Field_tiny::val_int(void) |
3684 | { |
3685 | ASSERT_COLUMN_MARKED_FOR_READ; |
3686 | int tmp= unsigned_flag ? (int) ptr[0] : |
3687 | (int) ((signed char*) ptr)[0]; |
3688 | return (longlong) tmp; |
3689 | } |
3690 | |
3691 | |
3692 | String *Field_tiny::val_str(String *val_buffer, |
3693 | String *val_ptr __attribute__((unused))) |
3694 | { |
3695 | ASSERT_COLUMN_MARKED_FOR_READ; |
3696 | long nr= unsigned_flag ? (long) ptr[0] : (long) ((signed char*) ptr)[0]; |
3697 | return val_str_from_long(val_buffer, 5, -10, nr); |
3698 | } |
3699 | |
3700 | bool Field_tiny::send_binary(Protocol *protocol) |
3701 | { |
3702 | return protocol->store_tiny((longlong) (int8) ptr[0]); |
3703 | } |
3704 | |
3705 | int Field_tiny::cmp(const uchar *a_ptr, const uchar *b_ptr) |
3706 | { |
3707 | signed char a,b; |
3708 | a=(signed char) a_ptr[0]; b= (signed char) b_ptr[0]; |
3709 | if (unsigned_flag) |
3710 | return ((uchar) a < (uchar) b) ? -1 : ((uchar) a > (uchar) b) ? 1 : 0; |
3711 | return (a < b) ? -1 : (a > b) ? 1 : 0; |
3712 | } |
3713 | |
3714 | void Field_tiny::sort_string(uchar *to,uint length __attribute__((unused))) |
3715 | { |
3716 | if (unsigned_flag) |
3717 | *to= *ptr; |
3718 | else |
3719 | to[0] = (char) (ptr[0] ^ (uchar) 128); /* Revers signbit */ |
3720 | } |
3721 | |
3722 | void Field_tiny::sql_type(String &res) const |
3723 | { |
3724 | CHARSET_INFO *cs=res.charset(); |
3725 | res.length(cs->cset->snprintf(cs,(char*) res.ptr(),res.alloced_length(), |
3726 | "tinyint(%d)" ,(int) field_length)); |
3727 | add_zerofill_and_unsigned(res); |
3728 | } |
3729 | |
3730 | /**************************************************************************** |
3731 | Field type short int (2 byte) |
3732 | ****************************************************************************/ |
3733 | |
3734 | int Field_short::store(const char *from,size_t len,CHARSET_INFO *cs) |
3735 | { |
3736 | ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; |
3737 | int store_tmp; |
3738 | int error; |
3739 | longlong rnd; |
3740 | |
3741 | error= get_int(cs, from, len, &rnd, UINT_MAX16, INT_MIN16, INT_MAX16); |
3742 | store_tmp= unsigned_flag ? (int) (ulonglong) rnd : (int) rnd; |
3743 | int2store(ptr, store_tmp); |
3744 | return error; |
3745 | } |
3746 | |
3747 | |
3748 | int Field_short::store(double nr) |
3749 | { |
3750 | ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; |
3751 | int error= 0; |
3752 | int16 res; |
3753 | nr=rint(nr); |
3754 | if (unsigned_flag) |
3755 | { |
3756 | if (nr < 0) |
3757 | { |
3758 | res=0; |
3759 | set_warning(ER_WARN_DATA_OUT_OF_RANGE, 1); |
3760 | error= 1; |
3761 | } |
3762 | else if (nr > (double) UINT_MAX16) |
3763 | { |
3764 | res=(int16) UINT_MAX16; |
3765 | set_warning(ER_WARN_DATA_OUT_OF_RANGE, 1); |
3766 | error= 1; |
3767 | } |
3768 | else |
3769 | res=(int16) (uint16) nr; |
3770 | } |
3771 | else |
3772 | { |
3773 | if (nr < (double) INT_MIN16) |
3774 | { |
3775 | res=INT_MIN16; |
3776 | set_warning(ER_WARN_DATA_OUT_OF_RANGE, 1); |
3777 | error= 1; |
3778 | } |
3779 | else if (nr > (double) INT_MAX16) |
3780 | { |
3781 | res=INT_MAX16; |
3782 | set_warning(ER_WARN_DATA_OUT_OF_RANGE, 1); |
3783 | error= 1; |
3784 | } |
3785 | else |
3786 | res=(int16) (int) nr; |
3787 | } |
3788 | int2store(ptr,res); |
3789 | return error; |
3790 | } |
3791 | |
3792 | |
3793 | int Field_short::store(longlong nr, bool unsigned_val) |
3794 | { |
3795 | ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; |
3796 | int error= 0; |
3797 | int16 res; |
3798 | |
3799 | if (unsigned_flag) |
3800 | { |
3801 | if (nr < 0L && !unsigned_val) |
3802 | { |
3803 | res=0; |
3804 | set_warning(ER_WARN_DATA_OUT_OF_RANGE, 1); |
3805 | error= 1; |
3806 | } |
3807 | else if ((ulonglong) nr > (ulonglong) UINT_MAX16) |
3808 | { |
3809 | res=(int16) UINT_MAX16; |
3810 | set_warning(ER_WARN_DATA_OUT_OF_RANGE, 1); |
3811 | error= 1; |
3812 | } |
3813 | else |
3814 | res=(int16) (uint16) nr; |
3815 | } |
3816 | else |
3817 | { |
3818 | if (nr < 0 && unsigned_val) |
3819 | nr= UINT_MAX16+1; // Generate overflow |
3820 | |
3821 | if (nr < INT_MIN16) |
3822 | { |
3823 | res=INT_MIN16; |
3824 | set_warning(ER_WARN_DATA_OUT_OF_RANGE, 1); |
3825 | error= 1; |
3826 | } |
3827 | else if (nr > (longlong) INT_MAX16) |
3828 | { |
3829 | res=INT_MAX16; |
3830 | set_warning(ER_WARN_DATA_OUT_OF_RANGE, 1); |
3831 | error= 1; |
3832 | } |
3833 | else |
3834 | res=(int16) nr; |
3835 | } |
3836 | int2store(ptr,res); |
3837 | return error; |
3838 | } |
3839 | |
3840 | |
3841 | double Field_short::val_real(void) |
3842 | { |
3843 | ASSERT_COLUMN_MARKED_FOR_READ; |
3844 | short j; |
3845 | j=sint2korr(ptr); |
3846 | return unsigned_flag ? (double) (unsigned short) j : (double) j; |
3847 | } |
3848 | |
3849 | longlong Field_short::val_int(void) |
3850 | { |
3851 | ASSERT_COLUMN_MARKED_FOR_READ; |
3852 | short j; |
3853 | j=sint2korr(ptr); |
3854 | return unsigned_flag ? (longlong) (unsigned short) j : (longlong) j; |
3855 | } |
3856 | |
3857 | |
3858 | String *Field_short::val_str(String *val_buffer, |
3859 | String *val_ptr __attribute__((unused))) |
3860 | { |
3861 | ASSERT_COLUMN_MARKED_FOR_READ; |
3862 | short j= sint2korr(ptr); |
3863 | long nr= unsigned_flag ? (long) (unsigned short) j : (long) j; |
3864 | return val_str_from_long(val_buffer, 7, -10, nr); |
3865 | } |
3866 | |
3867 | |
3868 | bool Field_short::send_binary(Protocol *protocol) |
3869 | { |
3870 | return protocol->store_short(Field_short::val_int()); |
3871 | } |
3872 | |
3873 | |
3874 | int Field_short::cmp(const uchar *a_ptr, const uchar *b_ptr) |
3875 | { |
3876 | short a,b; |
3877 | a=sint2korr(a_ptr); |
3878 | b=sint2korr(b_ptr); |
3879 | |
3880 | if (unsigned_flag) |
3881 | return ((unsigned short) a < (unsigned short) b) ? -1 : |
3882 | ((unsigned short) a > (unsigned short) b) ? 1 : 0; |
3883 | return (a < b) ? -1 : (a > b) ? 1 : 0; |
3884 | } |
3885 | |
3886 | void Field_short::sort_string(uchar *to,uint length __attribute__((unused))) |
3887 | { |
3888 | if (unsigned_flag) |
3889 | to[0] = ptr[1]; |
3890 | else |
3891 | to[0] = (char) (ptr[1] ^ 128); /* Revers signbit */ |
3892 | to[1] = ptr[0]; |
3893 | } |
3894 | |
3895 | void Field_short::sql_type(String &res) const |
3896 | { |
3897 | CHARSET_INFO *cs=res.charset(); |
3898 | res.length(cs->cset->snprintf(cs,(char*) res.ptr(),res.alloced_length(), |
3899 | "smallint(%d)" ,(int) field_length)); |
3900 | add_zerofill_and_unsigned(res); |
3901 | } |
3902 | |
3903 | |
3904 | /**************************************************************************** |
3905 | Field type medium int (3 byte) |
3906 | ****************************************************************************/ |
3907 | |
3908 | int Field_medium::store(const char *from,size_t len,CHARSET_INFO *cs) |
3909 | { |
3910 | ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; |
3911 | int store_tmp; |
3912 | int error; |
3913 | longlong rnd; |
3914 | |
3915 | error= get_int(cs, from, len, &rnd, UINT_MAX24, INT_MIN24, INT_MAX24); |
3916 | store_tmp= unsigned_flag ? (int) (ulonglong) rnd : (int) rnd; |
3917 | int3store(ptr, store_tmp); |
3918 | return error; |
3919 | } |
3920 | |
3921 | |
3922 | int Field_medium::store(double nr) |
3923 | { |
3924 | ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; |
3925 | int error= 0; |
3926 | nr=rint(nr); |
3927 | if (unsigned_flag) |
3928 | { |
3929 | if (nr < 0) |
3930 | { |
3931 | int3store(ptr,0); |
3932 | set_warning(ER_WARN_DATA_OUT_OF_RANGE, 1); |
3933 | error= 1; |
3934 | } |
3935 | else if (nr >= (double) (long) (1L << 24)) |
3936 | { |
3937 | uint32 tmp=(uint32) (1L << 24)-1L; |
3938 | int3store(ptr,tmp); |
3939 | set_warning(ER_WARN_DATA_OUT_OF_RANGE, 1); |
3940 | error= 1; |
3941 | } |
3942 | else |
3943 | int3store(ptr,(uint32) nr); |
3944 | } |
3945 | else |
3946 | { |
3947 | if (nr < (double) INT_MIN24) |
3948 | { |
3949 | long tmp=(long) INT_MIN24; |
3950 | int3store(ptr,tmp); |
3951 | set_warning(ER_WARN_DATA_OUT_OF_RANGE, 1); |
3952 | error= 1; |
3953 | } |
3954 | else if (nr > (double) INT_MAX24) |
3955 | { |
3956 | long tmp=(long) INT_MAX24; |
3957 | int3store(ptr,tmp); |
3958 | set_warning(ER_WARN_DATA_OUT_OF_RANGE, 1); |
3959 | error= 1; |
3960 | } |
3961 | else |
3962 | int3store(ptr,(long) nr); |
3963 | } |
3964 | return error; |
3965 | } |
3966 | |
3967 | |
3968 | int Field_medium::store(longlong nr, bool unsigned_val) |
3969 | { |
3970 | ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; |
3971 | int error= 0; |
3972 | |
3973 | if (unsigned_flag) |
3974 | { |
3975 | if (nr < 0 && !unsigned_val) |
3976 | { |
3977 | int3store(ptr,0); |
3978 | set_warning(ER_WARN_DATA_OUT_OF_RANGE, 1); |
3979 | error= 1; |
3980 | } |
3981 | else if ((ulonglong) nr >= (ulonglong) (long) (1L << 24)) |
3982 | { |
3983 | long tmp= (long) (1L << 24)-1L; |
3984 | int3store(ptr,tmp); |
3985 | set_warning(ER_WARN_DATA_OUT_OF_RANGE, 1); |
3986 | error= 1; |
3987 | } |
3988 | else |
3989 | int3store(ptr,(uint32) nr); |
3990 | } |
3991 | else |
3992 | { |
3993 | if (nr < 0 && unsigned_val) |
3994 | nr= (ulonglong) (long) (1L << 24); // Generate overflow |
3995 | |
3996 | if (nr < (longlong) INT_MIN24) |
3997 | { |
3998 | long tmp= (long) INT_MIN24; |
3999 | int3store(ptr,tmp); |
4000 | set_warning(ER_WARN_DATA_OUT_OF_RANGE, 1); |
4001 | error= 1; |
4002 | } |
4003 | else if (nr > (longlong) INT_MAX24) |
4004 | { |
4005 | long tmp=(long) INT_MAX24; |
4006 | int3store(ptr,tmp); |
4007 | set_warning(ER_WARN_DATA_OUT_OF_RANGE, 1); |
4008 | error= 1; |
4009 | } |
4010 | else |
4011 | int3store(ptr,(long) nr); |
4012 | } |
4013 | return error; |
4014 | } |
4015 | |
4016 | |
4017 | double Field_medium::val_real(void) |
4018 | { |
4019 | ASSERT_COLUMN_MARKED_FOR_READ; |
4020 | long j= unsigned_flag ? (long) uint3korr(ptr) : sint3korr(ptr); |
4021 | return (double) j; |
4022 | } |
4023 | |
4024 | |
4025 | longlong Field_medium::val_int(void) |
4026 | { |
4027 | ASSERT_COLUMN_MARKED_FOR_READ; |
4028 | long j= unsigned_flag ? (long) uint3korr(ptr) : sint3korr(ptr); |
4029 | return (longlong) j; |
4030 | } |
4031 | |
4032 | |
4033 | String *Field_medium::val_str(String *val_buffer, |
4034 | String *val_ptr __attribute__((unused))) |
4035 | { |
4036 | ASSERT_COLUMN_MARKED_FOR_READ; |
4037 | long nr= unsigned_flag ? (long) uint3korr(ptr) : sint3korr(ptr); |
4038 | return val_str_from_long(val_buffer, 10, -10, nr); |
4039 | } |
4040 | |
4041 | |
4042 | String *Field_int::val_str_from_long(String *val_buffer, |
4043 | uint max_char_length, |
4044 | int radix, long nr) |
4045 | { |
4046 | CHARSET_INFO *cs= &my_charset_numeric; |
4047 | uint length; |
4048 | uint mlength= MY_MAX(field_length + 1, max_char_length * cs->mbmaxlen); |
4049 | val_buffer->alloc(mlength); |
4050 | char *to=(char*) val_buffer->ptr(); |
4051 | length= (uint) cs->cset->long10_to_str(cs, to, mlength, radix, nr); |
4052 | val_buffer->length(length); |
4053 | if (zerofill) |
4054 | prepend_zeros(val_buffer); /* purecov: inspected */ |
4055 | val_buffer->set_charset(cs); |
4056 | return val_buffer; |
4057 | } |
4058 | |
4059 | |
4060 | bool Field_medium::send_binary(Protocol *protocol) |
4061 | { |
4062 | ASSERT_COLUMN_MARKED_FOR_READ; |
4063 | return protocol->store_long(Field_medium::val_int()); |
4064 | } |
4065 | |
4066 | |
4067 | int Field_medium::cmp(const uchar *a_ptr, const uchar *b_ptr) |
4068 | { |
4069 | long a,b; |
4070 | if (unsigned_flag) |
4071 | { |
4072 | a=uint3korr(a_ptr); |
4073 | b=uint3korr(b_ptr); |
4074 | } |
4075 | else |
4076 | { |
4077 | a=sint3korr(a_ptr); |
4078 | b=sint3korr(b_ptr); |
4079 | } |
4080 | return (a < b) ? -1 : (a > b) ? 1 : 0; |
4081 | } |
4082 | |
4083 | void Field_medium::sort_string(uchar *to,uint length __attribute__((unused))) |
4084 | { |
4085 | if (unsigned_flag) |
4086 | to[0] = ptr[2]; |
4087 | else |
4088 | to[0] = (uchar) (ptr[2] ^ 128); /* Revers signbit */ |
4089 | to[1] = ptr[1]; |
4090 | to[2] = ptr[0]; |
4091 | } |
4092 | |
4093 | |
4094 | void Field_medium::sql_type(String &res) const |
4095 | { |
4096 | CHARSET_INFO *cs=res.charset(); |
4097 | res.length(cs->cset->snprintf(cs,(char*) res.ptr(),res.alloced_length(), |
4098 | "mediumint(%d)" ,(int) field_length)); |
4099 | add_zerofill_and_unsigned(res); |
4100 | } |
4101 | |
4102 | /**************************************************************************** |
4103 | ** long int |
4104 | ****************************************************************************/ |
4105 | |
4106 | int Field_long::store(const char *from,size_t len,CHARSET_INFO *cs) |
4107 | { |
4108 | ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; |
4109 | long store_tmp; |
4110 | int error; |
4111 | longlong rnd; |
4112 | |
4113 | error= get_int(cs, from, len, &rnd, UINT_MAX32, INT_MIN32, INT_MAX32); |
4114 | store_tmp= unsigned_flag ? (long) (ulonglong) rnd : (long) rnd; |
4115 | int4store(ptr, store_tmp); |
4116 | return error; |
4117 | } |
4118 | |
4119 | |
4120 | int Field_long::store(double nr) |
4121 | { |
4122 | ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; |
4123 | int error= 0; |
4124 | int32 res; |
4125 | nr=rint(nr); |
4126 | if (unsigned_flag) |
4127 | { |
4128 | if (nr < 0) |
4129 | { |
4130 | res=0; |
4131 | error= 1; |
4132 | } |
4133 | else if (nr > (double) UINT_MAX32) |
4134 | { |
4135 | res= UINT_MAX32; |
4136 | set_warning(ER_WARN_DATA_OUT_OF_RANGE, 1); |
4137 | error= 1; |
4138 | } |
4139 | else |
4140 | res=(int32) (ulong) nr; |
4141 | } |
4142 | else |
4143 | { |
4144 | if (nr < (double) INT_MIN32) |
4145 | { |
4146 | res=(int32) INT_MIN32; |
4147 | error= 1; |
4148 | } |
4149 | else if (nr > (double) INT_MAX32) |
4150 | { |
4151 | res=(int32) INT_MAX32; |
4152 | error= 1; |
4153 | } |
4154 | else |
4155 | res=(int32) (longlong) nr; |
4156 | } |
4157 | if (unlikely(error)) |
4158 | set_warning(ER_WARN_DATA_OUT_OF_RANGE, 1); |
4159 | |
4160 | int4store(ptr,res); |
4161 | return error; |
4162 | } |
4163 | |
4164 | |
4165 | int Field_long::store(longlong nr, bool unsigned_val) |
4166 | { |
4167 | ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; |
4168 | int error= 0; |
4169 | int32 res; |
4170 | |
4171 | if (unsigned_flag) |
4172 | { |
4173 | if (nr < 0 && !unsigned_val) |
4174 | { |
4175 | res=0; |
4176 | error= 1; |
4177 | } |
4178 | else if ((ulonglong) nr >= (1LL << 32)) |
4179 | { |
4180 | res=(int32) (uint32) ~0L; |
4181 | error= 1; |
4182 | } |
4183 | else |
4184 | res=(int32) (uint32) nr; |
4185 | } |
4186 | else |
4187 | { |
4188 | if (nr < 0 && unsigned_val) |
4189 | nr= ((longlong) INT_MAX32) + 1; // Generate overflow |
4190 | if (nr < (longlong) INT_MIN32) |
4191 | { |
4192 | res=(int32) INT_MIN32; |
4193 | error= 1; |
4194 | } |
4195 | else if (nr > (longlong) INT_MAX32) |
4196 | { |
4197 | res=(int32) INT_MAX32; |
4198 | error= 1; |
4199 | } |
4200 | else |
4201 | res=(int32) nr; |
4202 | } |
4203 | if (unlikely(error)) |
4204 | set_warning(ER_WARN_DATA_OUT_OF_RANGE, 1); |
4205 | |
4206 | int4store(ptr,res); |
4207 | return error; |
4208 | } |
4209 | |
4210 | |
4211 | double Field_long::val_real(void) |
4212 | { |
4213 | ASSERT_COLUMN_MARKED_FOR_READ; |
4214 | int32 j; |
4215 | j=sint4korr(ptr); |
4216 | return unsigned_flag ? (double) (uint32) j : (double) j; |
4217 | } |
4218 | |
4219 | longlong Field_long::val_int(void) |
4220 | { |
4221 | ASSERT_COLUMN_MARKED_FOR_READ; |
4222 | int32 j; |
4223 | /* See the comment in Field_long::store(long long) */ |
4224 | DBUG_ASSERT(!table || table->in_use == current_thd); |
4225 | j=sint4korr(ptr); |
4226 | return unsigned_flag ? (longlong) (uint32) j : (longlong) j; |
4227 | } |
4228 | |
4229 | |
4230 | String *Field_long::val_str(String *val_buffer, |
4231 | String *val_ptr __attribute__((unused))) |
4232 | { |
4233 | ASSERT_COLUMN_MARKED_FOR_READ; |
4234 | long nr= unsigned_flag ? (long) uint4korr(ptr) : sint4korr(ptr); |
4235 | return val_str_from_long(val_buffer, 12, unsigned_flag ? 10 : -10, nr); |
4236 | } |
4237 | |
4238 | |
4239 | bool Field_long::send_binary(Protocol *protocol) |
4240 | { |
4241 | ASSERT_COLUMN_MARKED_FOR_READ; |
4242 | return protocol->store_long(Field_long::val_int()); |
4243 | } |
4244 | |
4245 | int Field_long::cmp(const uchar *a_ptr, const uchar *b_ptr) |
4246 | { |
4247 | int32 a,b; |
4248 | a=sint4korr(a_ptr); |
4249 | b=sint4korr(b_ptr); |
4250 | if (unsigned_flag) |
4251 | return ((uint32) a < (uint32) b) ? -1 : ((uint32) a > (uint32) b) ? 1 : 0; |
4252 | return (a < b) ? -1 : (a > b) ? 1 : 0; |
4253 | } |
4254 | |
4255 | void Field_long::sort_string(uchar *to,uint length __attribute__((unused))) |
4256 | { |
4257 | if (unsigned_flag) |
4258 | to[0] = ptr[3]; |
4259 | else |
4260 | to[0] = (char) (ptr[3] ^ 128); /* Revers signbit */ |
4261 | to[1] = ptr[2]; |
4262 | to[2] = ptr[1]; |
4263 | to[3] = ptr[0]; |
4264 | } |
4265 | |
4266 | |
4267 | void Field_long::sql_type(String &res) const |
4268 | { |
4269 | CHARSET_INFO *cs=res.charset(); |
4270 | res.length(cs->cset->snprintf(cs,(char*) res.ptr(),res.alloced_length(), |
4271 | "int(%d)" ,(int) field_length)); |
4272 | add_zerofill_and_unsigned(res); |
4273 | } |
4274 | |
4275 | /**************************************************************************** |
4276 | Field type longlong int (8 bytes) |
4277 | ****************************************************************************/ |
4278 | |
4279 | int Field_longlong::store(const char *from,size_t len,CHARSET_INFO *cs) |
4280 | { |
4281 | ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; |
4282 | int error= 0; |
4283 | char *end; |
4284 | ulonglong tmp; |
4285 | |
4286 | tmp= cs->cset->strntoull10rnd(cs,from,len,unsigned_flag,&end,&error); |
4287 | if (unlikely(error == MY_ERRNO_ERANGE)) |
4288 | { |
4289 | set_warning(ER_WARN_DATA_OUT_OF_RANGE, 1); |
4290 | error= 1; |
4291 | } |
4292 | else if (get_thd()->count_cuted_fields > CHECK_FIELD_EXPRESSION && |
4293 | check_int(cs, from, len, end, error)) |
4294 | error= 1; |
4295 | else |
4296 | error= 0; |
4297 | int8store(ptr,tmp); |
4298 | return error; |
4299 | } |
4300 | |
4301 | |
4302 | int Field_longlong::store(double nr) |
4303 | { |
4304 | ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; |
4305 | Converter_double_to_longlong conv(nr, unsigned_flag); |
4306 | |
4307 | if (unlikely(conv.error())) |
4308 | set_warning(ER_WARN_DATA_OUT_OF_RANGE, 1); |
4309 | |
4310 | int8store(ptr, conv.result()); |
4311 | return conv.error(); |
4312 | } |
4313 | |
4314 | |
4315 | int Field_longlong::store(longlong nr, bool unsigned_val) |
4316 | { |
4317 | ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; |
4318 | int error= 0; |
4319 | |
4320 | if (unlikely(nr < 0)) // Only possible error |
4321 | { |
4322 | /* |
4323 | if field is unsigned and value is signed (< 0) or |
4324 | if field is signed and value is unsigned we have an overflow |
4325 | */ |
4326 | if (unsigned_flag != unsigned_val) |
4327 | { |
4328 | nr= unsigned_flag ? (ulonglong) 0 : (ulonglong) LONGLONG_MAX; |
4329 | set_warning(ER_WARN_DATA_OUT_OF_RANGE, 1); |
4330 | error= 1; |
4331 | } |
4332 | } |
4333 | |
4334 | int8store(ptr,nr); |
4335 | return error; |
4336 | } |
4337 | |
4338 | |
4339 | double Field_longlong::val_real(void) |
4340 | { |
4341 | ASSERT_COLUMN_MARKED_FOR_READ; |
4342 | longlong j; |
4343 | j=sint8korr(ptr); |
4344 | /* The following is open coded to avoid a bug in gcc 3.3 */ |
4345 | if (unsigned_flag) |
4346 | { |
4347 | ulonglong tmp= (ulonglong) j; |
4348 | return ulonglong2double(tmp); |
4349 | } |
4350 | return (double) j; |
4351 | } |
4352 | |
4353 | |
4354 | longlong Field_longlong::val_int(void) |
4355 | { |
4356 | ASSERT_COLUMN_MARKED_FOR_READ; |
4357 | longlong j; |
4358 | j=sint8korr(ptr); |
4359 | return j; |
4360 | } |
4361 | |
4362 | |
4363 | String *Field_longlong::val_str(String *val_buffer, |
4364 | String *val_ptr __attribute__((unused))) |
4365 | { |
4366 | CHARSET_INFO *cs= &my_charset_numeric; |
4367 | uint length; |
4368 | uint mlength=MY_MAX(field_length+1,22*cs->mbmaxlen); |
4369 | val_buffer->alloc(mlength); |
4370 | char *to=(char*) val_buffer->ptr(); |
4371 | longlong j; |
4372 | j=sint8korr(ptr); |
4373 | |
4374 | length=(uint) (cs->cset->longlong10_to_str)(cs,to,mlength, |
4375 | unsigned_flag ? 10 : -10, j); |
4376 | val_buffer->length(length); |
4377 | if (zerofill) |
4378 | prepend_zeros(val_buffer); |
4379 | val_buffer->set_charset(cs); |
4380 | return val_buffer; |
4381 | } |
4382 | |
4383 | |
4384 | bool Field_longlong::send_binary(Protocol *protocol) |
4385 | { |
4386 | ASSERT_COLUMN_MARKED_FOR_READ; |
4387 | return protocol->store_longlong(Field_longlong::val_int(), unsigned_flag); |
4388 | } |
4389 | |
4390 | |
4391 | int Field_longlong::cmp(const uchar *a_ptr, const uchar *b_ptr) |
4392 | { |
4393 | longlong a,b; |
4394 | a=sint8korr(a_ptr); |
4395 | b=sint8korr(b_ptr); |
4396 | if (unsigned_flag) |
4397 | return ((ulonglong) a < (ulonglong) b) ? -1 : |
4398 | ((ulonglong) a > (ulonglong) b) ? 1 : 0; |
4399 | return (a < b) ? -1 : (a > b) ? 1 : 0; |
4400 | } |
4401 | |
4402 | void Field_longlong::sort_string(uchar *to,uint length __attribute__((unused))) |
4403 | { |
4404 | if (unsigned_flag) |
4405 | to[0] = ptr[7]; |
4406 | else |
4407 | to[0] = (char) (ptr[7] ^ 128); /* Revers signbit */ |
4408 | to[1] = ptr[6]; |
4409 | to[2] = ptr[5]; |
4410 | to[3] = ptr[4]; |
4411 | to[4] = ptr[3]; |
4412 | to[5] = ptr[2]; |
4413 | to[6] = ptr[1]; |
4414 | to[7] = ptr[0]; |
4415 | } |
4416 | |
4417 | |
4418 | void Field_longlong::sql_type(String &res) const |
4419 | { |
4420 | CHARSET_INFO *cs=res.charset(); |
4421 | res.length(cs->cset->snprintf(cs,(char*) res.ptr(),res.alloced_length(), |
4422 | "bigint(%d)" ,(int) field_length)); |
4423 | add_zerofill_and_unsigned(res); |
4424 | } |
4425 | |
4426 | void Field_longlong::set_max() |
4427 | { |
4428 | ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; |
4429 | set_notnull(); |
4430 | int8store(ptr, unsigned_flag ? ULONGLONG_MAX : LONGLONG_MAX); |
4431 | } |
4432 | |
4433 | bool Field_longlong::is_max() |
4434 | { |
4435 | ASSERT_COLUMN_MARKED_FOR_READ; |
4436 | if (unsigned_flag) |
4437 | { |
4438 | ulonglong j; |
4439 | j= uint8korr(ptr); |
4440 | return j == ULONGLONG_MAX; |
4441 | } |
4442 | longlong j; |
4443 | j= sint8korr(ptr); |
4444 | return j == LONGLONG_MAX; |
4445 | } |
4446 | |
4447 | /* |
4448 | Floating-point numbers |
4449 | */ |
4450 | |
4451 | /**************************************************************************** |
4452 | single precision float |
4453 | ****************************************************************************/ |
4454 | |
4455 | int Field_float::store(const char *from,size_t len,CHARSET_INFO *cs) |
4456 | { |
4457 | int error; |
4458 | Field_float::store(get_double(from, len, cs, &error)); |
4459 | return error; |
4460 | } |
4461 | |
4462 | |
4463 | int Field_float::store(double nr) |
4464 | { |
4465 | ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; |
4466 | int error= truncate_double(&nr, field_length, |
4467 | not_fixed ? NOT_FIXED_DEC : dec, |
4468 | unsigned_flag, FLT_MAX); |
4469 | if (unlikely(error)) |
4470 | { |
4471 | set_warning(ER_WARN_DATA_OUT_OF_RANGE, 1); |
4472 | if (error < 0) // Wrong double value |
4473 | { |
4474 | error= 1; |
4475 | set_null(); |
4476 | } |
4477 | } |
4478 | float j= (float)nr; |
4479 | |
4480 | float4store(ptr,j); |
4481 | return error; |
4482 | } |
4483 | |
4484 | |
4485 | int Field_float::store(longlong nr, bool unsigned_val) |
4486 | { |
4487 | return Field_float::store(unsigned_val ? ulonglong2double((ulonglong) nr) : |
4488 | (double) nr); |
4489 | } |
4490 | |
4491 | |
4492 | double Field_float::val_real(void) |
4493 | { |
4494 | ASSERT_COLUMN_MARKED_FOR_READ; |
4495 | float j; |
4496 | float4get(j,ptr); |
4497 | return ((double) j); |
4498 | } |
4499 | |
4500 | longlong Field_float::val_int(void) |
4501 | { |
4502 | float j; |
4503 | float4get(j,ptr); |
4504 | return (longlong) rint(j); |
4505 | } |
4506 | |
4507 | |
4508 | String *Field_float::val_str(String *val_buffer, |
4509 | String *val_ptr __attribute__((unused))) |
4510 | { |
4511 | ASSERT_COLUMN_MARKED_FOR_READ; |
4512 | DBUG_ASSERT(!zerofill || field_length <= MAX_FIELD_CHARLENGTH); |
4513 | float nr; |
4514 | float4get(nr,ptr); |
4515 | |
4516 | uint to_length= 70; |
4517 | if (val_buffer->alloc(to_length)) |
4518 | { |
4519 | my_error(ER_OUT_OF_RESOURCES, MYF(0)); |
4520 | return val_buffer; |
4521 | } |
4522 | |
4523 | char *to=(char*) val_buffer->ptr(); |
4524 | size_t len; |
4525 | |
4526 | if (dec >= FLOATING_POINT_DECIMALS) |
4527 | len= my_gcvt(nr, MY_GCVT_ARG_FLOAT, to_length - 1, to, NULL); |
4528 | else |
4529 | { |
4530 | /* |
4531 | We are safe here because the buffer length is 70, and |
4532 | fabs(float) < 10^39, dec < FLOATING_POINT_DECIMALS. So the resulting string |
4533 | will be not longer than 69 chars + terminating '\0'. |
4534 | */ |
4535 | len= my_fcvt(nr, dec, to, NULL); |
4536 | } |
4537 | val_buffer->length((uint) len); |
4538 | if (zerofill) |
4539 | prepend_zeros(val_buffer); |
4540 | val_buffer->set_charset(&my_charset_numeric); |
4541 | return val_buffer; |
4542 | } |
4543 | |
4544 | |
4545 | int Field_float::cmp(const uchar *a_ptr, const uchar *b_ptr) |
4546 | { |
4547 | float a,b; |
4548 | float4get(a,a_ptr); |
4549 | float4get(b,b_ptr); |
4550 | return (a < b) ? -1 : (a > b) ? 1 : 0; |
4551 | } |
4552 | |
4553 | #define FLT_EXP_DIG (sizeof(float)*8-FLT_MANT_DIG) |
4554 | |
4555 | void Field_float::sort_string(uchar *to,uint length __attribute__((unused))) |
4556 | { |
4557 | float nr; |
4558 | float4get(nr,ptr); |
4559 | |
4560 | uchar *tmp= to; |
4561 | if (nr == (float) 0.0) |
4562 | { /* Change to zero string */ |
4563 | tmp[0]=(uchar) 128; |
4564 | bzero((char*) tmp+1,sizeof(nr)-1); |
4565 | } |
4566 | else |
4567 | { |
4568 | #ifdef WORDS_BIGENDIAN |
4569 | memcpy(tmp, &nr, sizeof(nr)); |
4570 | #else |
4571 | tmp[0]= ptr[3]; tmp[1]=ptr[2]; tmp[2]= ptr[1]; tmp[3]=ptr[0]; |
4572 | #endif |
4573 | if (tmp[0] & 128) /* Negative */ |
4574 | { /* make complement */ |
4575 | uint i; |
4576 | for (i=0 ; i < sizeof(nr); i++) |
4577 | tmp[i]= (uchar) (tmp[i] ^ (uchar) 255); |
4578 | } |
4579 | else |
4580 | { |
4581 | ushort exp_part=(((ushort) tmp[0] << 8) | (ushort) tmp[1] | |
4582 | (ushort) 32768); |
4583 | exp_part+= (ushort) 1 << (16-1-FLT_EXP_DIG); |
4584 | tmp[0]= (uchar) (exp_part >> 8); |
4585 | tmp[1]= (uchar) exp_part; |
4586 | } |
4587 | } |
4588 | } |
4589 | |
4590 | |
4591 | bool Field_float::send_binary(Protocol *protocol) |
4592 | { |
4593 | ASSERT_COLUMN_MARKED_FOR_READ; |
4594 | return protocol->store((float) Field_float::val_real(), dec, (String*) 0); |
4595 | } |
4596 | |
4597 | |
4598 | /** |
4599 | Save the field metadata for float fields. |
4600 | |
4601 | Saves the pack length in the first byte. |
4602 | |
4603 | @param metadata_ptr First byte of field metadata |
4604 | |
4605 | @returns number of bytes written to metadata_ptr |
4606 | */ |
4607 | int Field_float::save_field_metadata(uchar *metadata_ptr) |
4608 | { |
4609 | *metadata_ptr= pack_length(); |
4610 | return 1; |
4611 | } |
4612 | |
4613 | |
4614 | void Field_float::sql_type(String &res) const |
4615 | { |
4616 | if (dec >= FLOATING_POINT_DECIMALS) |
4617 | { |
4618 | res.set_ascii(STRING_WITH_LEN("float" )); |
4619 | } |
4620 | else |
4621 | { |
4622 | CHARSET_INFO *cs= res.charset(); |
4623 | res.length(cs->cset->snprintf(cs,(char*) res.ptr(),res.alloced_length(), |
4624 | "float(%d,%d)" ,(int) field_length,dec)); |
4625 | } |
4626 | add_zerofill_and_unsigned(res); |
4627 | } |
4628 | |
4629 | |
4630 | /**************************************************************************** |
4631 | double precision floating point numbers |
4632 | ****************************************************************************/ |
4633 | |
4634 | int Field_double::store(const char *from,size_t len,CHARSET_INFO *cs) |
4635 | { |
4636 | int error; |
4637 | Field_double::store(get_double(from, len, cs, &error)); |
4638 | return error; |
4639 | } |
4640 | |
4641 | |
4642 | int Field_double::store(double nr) |
4643 | { |
4644 | ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; |
4645 | int error= truncate_double(&nr, field_length, |
4646 | not_fixed ? NOT_FIXED_DEC : dec, |
4647 | unsigned_flag, DBL_MAX); |
4648 | if (unlikely(error)) |
4649 | { |
4650 | set_warning(ER_WARN_DATA_OUT_OF_RANGE, 1); |
4651 | if (error < 0) // Wrong double value |
4652 | { |
4653 | error= 1; |
4654 | set_null(); |
4655 | } |
4656 | } |
4657 | |
4658 | float8store(ptr,nr); |
4659 | return error; |
4660 | } |
4661 | |
4662 | |
4663 | int Field_double::store(longlong nr, bool unsigned_val) |
4664 | { |
4665 | return Field_double::store(unsigned_val ? ulonglong2double((ulonglong) nr) : |
4666 | (double) nr); |
4667 | } |
4668 | |
4669 | /* |
4670 | If a field has fixed length, truncate the double argument pointed to by 'nr' |
4671 | appropriately. |
4672 | Also ensure that the argument is within [-max_value; max_value] range. |
4673 | |
4674 | return |
4675 | 0 ok |
4676 | -1 Illegal double value |
4677 | 1 Value was truncated |
4678 | */ |
4679 | |
4680 | int truncate_double(double *nr, uint field_length, uint dec, |
4681 | bool unsigned_flag, double max_value) |
4682 | { |
4683 | int error= 0; |
4684 | double res= *nr; |
4685 | |
4686 | if (isnan(res)) |
4687 | { |
4688 | *nr= 0; |
4689 | return -1; |
4690 | } |
4691 | else if (unsigned_flag && res < 0) |
4692 | { |
4693 | *nr= 0; |
4694 | return 1; |
4695 | } |
4696 | |
4697 | if (dec < FLOATING_POINT_DECIMALS) |
4698 | { |
4699 | uint order= field_length - dec; |
4700 | uint step= array_elements(log_10) - 1; |
4701 | max_value= 1.0; |
4702 | for (; order > step; order-= step) |
4703 | max_value*= log_10[step]; |
4704 | max_value*= log_10[order]; |
4705 | max_value-= 1.0 / log_10[dec]; |
4706 | |
4707 | /* Check for infinity so we don't get NaN in calculations */ |
4708 | if (!my_isinf(res)) |
4709 | { |
4710 | double tmp= rint((res - floor(res)) * log_10[dec]) / log_10[dec]; |
4711 | res= floor(res) + tmp; |
4712 | } |
4713 | } |
4714 | |
4715 | if (res < -max_value) |
4716 | { |
4717 | res= -max_value; |
4718 | error= 1; |
4719 | } |
4720 | else if (res > max_value) |
4721 | { |
4722 | res= max_value; |
4723 | error= 1; |
4724 | } |
4725 | |
4726 | *nr= res; |
4727 | return error; |
4728 | } |
4729 | |
4730 | /* |
4731 | Convert double to longlong / ulonglong. |
4732 | If double is outside of the supported range, |
4733 | adjust m_result and set m_error. |
4734 | |
4735 | @param nr Number to convert |
4736 | @param unsigned_flag true if result is unsigned |
4737 | */ |
4738 | |
4739 | Value_source:: |
4740 | Converter_double_to_longlong::Converter_double_to_longlong(double nr, |
4741 | bool unsigned_flag) |
4742 | :m_error(false) |
4743 | { |
4744 | nr= rint(nr); |
4745 | if (unsigned_flag) |
4746 | { |
4747 | if (nr < 0) |
4748 | { |
4749 | m_result= 0; |
4750 | m_error= true; |
4751 | } |
4752 | else if (nr >= (double) ULONGLONG_MAX) |
4753 | { |
4754 | m_result= ~(longlong) 0; |
4755 | m_error= true; |
4756 | } |
4757 | else |
4758 | m_result= (longlong) double2ulonglong(nr); |
4759 | } |
4760 | else |
4761 | { |
4762 | if (nr <= (double) LONGLONG_MIN) |
4763 | { |
4764 | m_result= LONGLONG_MIN; |
4765 | m_error= (nr < (double) LONGLONG_MIN); |
4766 | } |
4767 | else if (nr >= (double) (ulonglong) LONGLONG_MAX) |
4768 | { |
4769 | m_result= LONGLONG_MAX; |
4770 | m_error= (nr > (double) LONGLONG_MAX); |
4771 | } |
4772 | else |
4773 | m_result= (longlong) nr; |
4774 | } |
4775 | } |
4776 | |
4777 | |
4778 | void Value_source:: |
4779 | Converter_double_to_longlong::push_warning(THD *thd, |
4780 | double nr, |
4781 | bool unsigned_flag) |
4782 | { |
4783 | push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, |
4784 | ER_DATA_OVERFLOW, ER_THD(thd, ER_DATA_OVERFLOW), |
4785 | ErrConvDouble(nr).ptr(), |
4786 | unsigned_flag ? "UNSIGNED INT" : "INT" ); |
4787 | } |
4788 | |
4789 | |
4790 | int Field_real::store_decimal(const my_decimal *dm) |
4791 | { |
4792 | double dbl; |
4793 | my_decimal2double(E_DEC_FATAL_ERROR, dm, &dbl); |
4794 | return store(dbl); |
4795 | } |
4796 | |
4797 | int Field_real::store_time_dec(const MYSQL_TIME *ltime, uint dec_arg) |
4798 | { |
4799 | return store(TIME_to_double(ltime)); |
4800 | } |
4801 | |
4802 | |
4803 | double Field_double::val_real(void) |
4804 | { |
4805 | ASSERT_COLUMN_MARKED_FOR_READ; |
4806 | double j; |
4807 | float8get(j,ptr); |
4808 | return j; |
4809 | } |
4810 | |
4811 | |
4812 | longlong Field_double::val_int_from_real(bool want_unsigned_result) |
4813 | { |
4814 | Converter_double_to_longlong conv(val_real(), want_unsigned_result); |
4815 | if (unlikely(!want_unsigned_result && conv.error())) |
4816 | conv.push_warning(get_thd(), Field_double::val_real(), false); |
4817 | return conv.result(); |
4818 | } |
4819 | |
4820 | |
4821 | my_decimal *Field_real::val_decimal(my_decimal *decimal_value) |
4822 | { |
4823 | ASSERT_COLUMN_MARKED_FOR_READ; |
4824 | double2my_decimal(E_DEC_FATAL_ERROR, val_real(), decimal_value); |
4825 | return decimal_value; |
4826 | } |
4827 | |
4828 | |
4829 | bool Field_real::get_date(MYSQL_TIME *ltime,ulonglong fuzzydate) |
4830 | { |
4831 | ASSERT_COLUMN_MARKED_FOR_READ; |
4832 | double nr= val_real(); |
4833 | return double_to_datetime_with_warn(nr, ltime, fuzzydate, field_name.str); |
4834 | } |
4835 | |
4836 | |
4837 | Item *Field_real::get_equal_const_item(THD *thd, const Context &ctx, |
4838 | Item *const_item) |
4839 | { |
4840 | if (flags & ZEROFILL_FLAG) |
4841 | return Field_num::get_equal_zerofill_const_item(thd, ctx, const_item); |
4842 | switch (ctx.subst_constraint()) { |
4843 | case IDENTITY_SUBST: |
4844 | if (const_item->decimal_scale() != Field_real::decimals()) |
4845 | { |
4846 | double val= const_item->val_real(); |
4847 | return new (thd->mem_root) Item_float(thd, val, Field_real::decimals()); |
4848 | } |
4849 | break; |
4850 | case ANY_SUBST: |
4851 | break; |
4852 | } |
4853 | return const_item; |
4854 | } |
4855 | |
4856 | |
4857 | String *Field_double::val_str(String *val_buffer, |
4858 | String *val_ptr __attribute__((unused))) |
4859 | { |
4860 | ASSERT_COLUMN_MARKED_FOR_READ; |
4861 | DBUG_ASSERT(!zerofill || field_length <= MAX_FIELD_CHARLENGTH); |
4862 | double nr; |
4863 | float8get(nr,ptr); |
4864 | |
4865 | uint to_length= DOUBLE_TO_STRING_CONVERSION_BUFFER_SIZE; |
4866 | if (val_buffer->alloc(to_length)) |
4867 | { |
4868 | my_error(ER_OUT_OF_RESOURCES, MYF(0)); |
4869 | return val_buffer; |
4870 | } |
4871 | |
4872 | char *to=(char*) val_buffer->ptr(); |
4873 | size_t len; |
4874 | |
4875 | if (dec >= FLOATING_POINT_DECIMALS) |
4876 | len= my_gcvt(nr, MY_GCVT_ARG_DOUBLE, to_length - 1, to, NULL); |
4877 | else |
4878 | len= my_fcvt(nr, dec, to, NULL); |
4879 | |
4880 | val_buffer->length((uint) len); |
4881 | if (zerofill) |
4882 | prepend_zeros(val_buffer); |
4883 | val_buffer->set_charset(&my_charset_numeric); |
4884 | return val_buffer; |
4885 | } |
4886 | |
4887 | bool Field_double::send_binary(Protocol *protocol) |
4888 | { |
4889 | return protocol->store((double) Field_double::val_real(), dec, (String*) 0); |
4890 | } |
4891 | |
4892 | |
4893 | int Field_double::cmp(const uchar *a_ptr, const uchar *b_ptr) |
4894 | { |
4895 | double a,b; |
4896 | float8get(a,a_ptr); |
4897 | float8get(b,b_ptr); |
4898 | return (a < b) ? -1 : (a > b) ? 1 : 0; |
4899 | } |
4900 | |
4901 | |
4902 | #define DBL_EXP_DIG (sizeof(double)*8-DBL_MANT_DIG) |
4903 | |
4904 | /* The following should work for IEEE */ |
4905 | |
4906 | void Field_double::sort_string(uchar *to,uint length __attribute__((unused))) |
4907 | { |
4908 | double nr; |
4909 | float8get(nr,ptr); |
4910 | change_double_for_sort(nr, to); |
4911 | } |
4912 | |
4913 | |
4914 | /** |
4915 | Save the field metadata for double fields. |
4916 | |
4917 | Saves the pack length in the first byte of the field metadata array |
4918 | at index of *metadata_ptr. |
4919 | |
4920 | @param metadata_ptr First byte of field metadata |
4921 | |
4922 | @returns number of bytes written to metadata_ptr |
4923 | */ |
4924 | int Field_double::save_field_metadata(uchar *metadata_ptr) |
4925 | { |
4926 | *metadata_ptr= pack_length(); |
4927 | return 1; |
4928 | } |
4929 | |
4930 | |
4931 | void Field_double::sql_type(String &res) const |
4932 | { |
4933 | CHARSET_INFO *cs=res.charset(); |
4934 | if (dec >= FLOATING_POINT_DECIMALS) |
4935 | { |
4936 | res.set_ascii(STRING_WITH_LEN("double" )); |
4937 | } |
4938 | else |
4939 | { |
4940 | res.length(cs->cset->snprintf(cs,(char*) res.ptr(),res.alloced_length(), |
4941 | "double(%d,%d)" ,(int) field_length,dec)); |
4942 | } |
4943 | add_zerofill_and_unsigned(res); |
4944 | } |
4945 | |
4946 | |
4947 | /** |
4948 | TIMESTAMP type holds datetime values in range from 1970-01-01 00:00:01 UTC to |
4949 | 2038-01-01 00:00:00 UTC stored as number of seconds since Unix |
4950 | Epoch in UTC. |
4951 | |
4952 | Actually SQL-99 says that we should allow niladic functions (like NOW()) |
4953 | as defaults for any field. The current limitation (only NOW() and only |
4954 | for TIMESTAMP and DATETIME fields) are because of restricted binary .frm |
4955 | format and should go away in the future. |
4956 | |
4957 | Also because of this limitation of binary .frm format we use 5 different |
4958 | unireg_check values with TIMESTAMP field to distinguish various cases of |
4959 | DEFAULT or ON UPDATE values. These values are: |
4960 | |
4961 | TIMESTAMP_OLD_FIELD - old timestamp, if there was not any fields with |
4962 | auto-set-on-update (or now() as default) in this table before, then this |
4963 | field has NOW() as default and is updated when row changes, else it is |
4964 | field which has 0 as default value and is not automatically updated. |
4965 | TIMESTAMP_DN_FIELD - field with NOW() as default but not set on update |
4966 | automatically (TIMESTAMP DEFAULT NOW()), not used in Field since 10.2.2 |
4967 | TIMESTAMP_UN_FIELD - field which is set on update automatically but has not |
4968 | NOW() as default (but it may has 0 or some other const timestamp as |
4969 | default) (TIMESTAMP ON UPDATE NOW()). |
4970 | TIMESTAMP_DNUN_FIELD - field which has now() as default and is auto-set on |
4971 | update. (TIMESTAMP DEFAULT NOW() ON UPDATE NOW()), not used in Field since 10.2.2 |
4972 | NONE - field which is not auto-set on update with some other than NOW() |
4973 | default value (TIMESTAMP DEFAULT 0). |
4974 | |
4975 | Note that TIMESTAMP_OLD_FIELDs are never created explicitly now, they are |
4976 | left only for preserving ability to read old tables. Such fields replaced |
4977 | with their newer analogs in CREATE TABLE and in SHOW CREATE TABLE. This is |
4978 | because we want to prefer NONE unireg_check before TIMESTAMP_OLD_FIELD for |
4979 | "TIMESTAMP DEFAULT 'Const'" field. (Old timestamps allowed such |
4980 | specification too but ignored default value for first timestamp, which of |
4981 | course is non-standard.) In most cases user won't notice any change, only |
4982 | exception is different behavior of old/new timestamps during ALTER TABLE. |
4983 | */ |
4984 | |
4985 | Field_timestamp::Field_timestamp(uchar *ptr_arg, uint32 len_arg, |
4986 | uchar *null_ptr_arg, uchar null_bit_arg, |
4987 | enum utype unireg_check_arg, |
4988 | const LEX_CSTRING *field_name_arg, |
4989 | TABLE_SHARE *share) |
4990 | :Field_temporal(ptr_arg, len_arg, null_ptr_arg, null_bit_arg, |
4991 | unireg_check_arg, field_name_arg) |
4992 | { |
4993 | /* For 4.0 MYD and 4.0 InnoDB compatibility */ |
4994 | flags|= UNSIGNED_FLAG; |
4995 | if (unireg_check != NONE) |
4996 | { |
4997 | /* |
4998 | We mark the flag with TIMESTAMP_FLAG to indicate to the client that |
4999 | this field will be automaticly updated on insert. |
5000 | */ |
5001 | flags|= TIMESTAMP_FLAG; |
5002 | if (unireg_check != TIMESTAMP_DN_FIELD) |
5003 | flags|= ON_UPDATE_NOW_FLAG; |
5004 | } |
5005 | } |
5006 | |
5007 | |
5008 | int Field_timestamp::save_in_field(Field *to) |
5009 | { |
5010 | ulong sec_part; |
5011 | my_time_t ts= get_timestamp(&sec_part); |
5012 | return to->store_timestamp(ts, sec_part); |
5013 | } |
5014 | |
5015 | my_time_t Field_timestamp::get_timestamp(const uchar *pos, |
5016 | ulong *sec_part) const |
5017 | { |
5018 | ASSERT_COLUMN_MARKED_FOR_READ; |
5019 | *sec_part= 0; |
5020 | return sint4korr(pos); |
5021 | } |
5022 | |
5023 | |
5024 | int Field_timestamp::store_TIME_with_warning(THD *thd, MYSQL_TIME *l_time, |
5025 | const ErrConv *str, |
5026 | int was_cut, |
5027 | bool have_smth_to_conv) |
5028 | { |
5029 | ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; |
5030 | uint error = 0; |
5031 | my_time_t timestamp; |
5032 | |
5033 | if (MYSQL_TIME_WARN_HAVE_WARNINGS(was_cut) || !have_smth_to_conv) |
5034 | { |
5035 | error= 1; |
5036 | set_datetime_warning(WARN_DATA_TRUNCATED, |
5037 | str, MYSQL_TIMESTAMP_DATETIME, 1); |
5038 | } |
5039 | else if (MYSQL_TIME_WARN_HAVE_NOTES(was_cut)) |
5040 | { |
5041 | error= 3; |
5042 | set_datetime_warning(Sql_condition::WARN_LEVEL_NOTE, WARN_DATA_TRUNCATED, |
5043 | str, MYSQL_TIMESTAMP_DATETIME, 1); |
5044 | } |
5045 | /* Only convert a correct date (not a zero date) */ |
5046 | if (have_smth_to_conv && l_time->month) |
5047 | { |
5048 | uint conversion_error; |
5049 | timestamp= TIME_to_timestamp(thd, l_time, &conversion_error); |
5050 | if (timestamp == 0 && l_time->second_part == 0) |
5051 | conversion_error= ER_WARN_DATA_OUT_OF_RANGE; |
5052 | if (unlikely(conversion_error)) |
5053 | { |
5054 | set_datetime_warning(conversion_error, |
5055 | str, MYSQL_TIMESTAMP_DATETIME, !error); |
5056 | error= 1; |
5057 | } |
5058 | } |
5059 | else |
5060 | { |
5061 | timestamp= 0; |
5062 | l_time->second_part= 0; |
5063 | } |
5064 | store_TIME(timestamp, l_time->second_part); |
5065 | return error; |
5066 | } |
5067 | |
5068 | |
5069 | static bool |
5070 | copy_or_convert_to_datetime(THD *thd, const MYSQL_TIME *from, MYSQL_TIME *to) |
5071 | { |
5072 | if (from->time_type == MYSQL_TIMESTAMP_TIME) |
5073 | return time_to_datetime(thd, from, to); |
5074 | *to= *from; |
5075 | return false; |
5076 | } |
5077 | |
5078 | |
5079 | sql_mode_t Field_timestamp::sql_mode_for_timestamp(THD *thd) const |
5080 | { |
5081 | // We don't want to store invalid or fuzzy datetime values in TIMESTAMP |
5082 | return (thd->variables.sql_mode & MODE_NO_ZERO_DATE) | MODE_NO_ZERO_IN_DATE; |
5083 | } |
5084 | |
5085 | |
5086 | int Field_timestamp::store_time_dec(const MYSQL_TIME *ltime, uint dec) |
5087 | { |
5088 | int unused; |
5089 | ErrConvTime str(ltime); |
5090 | THD *thd= get_thd(); |
5091 | MYSQL_TIME l_time; |
5092 | bool valid= !copy_or_convert_to_datetime(thd, ltime, &l_time) && |
5093 | !check_date(&l_time, pack_time(&l_time) != 0, |
5094 | sql_mode_for_timestamp(thd), &unused); |
5095 | return store_TIME_with_warning(thd, &l_time, &str, false, valid); |
5096 | } |
5097 | |
5098 | |
5099 | int Field_timestamp::store(const char *from,size_t len,CHARSET_INFO *cs) |
5100 | { |
5101 | MYSQL_TIME l_time; |
5102 | MYSQL_TIME_STATUS status; |
5103 | bool have_smth_to_conv; |
5104 | ErrConvString str(from, len, cs); |
5105 | THD *thd= get_thd(); |
5106 | |
5107 | have_smth_to_conv= !str_to_datetime(cs, from, len, &l_time, |
5108 | sql_mode_for_timestamp(thd), &status); |
5109 | return store_TIME_with_warning(thd, &l_time, &str, |
5110 | status.warnings, have_smth_to_conv); |
5111 | } |
5112 | |
5113 | |
5114 | int Field_timestamp::store(double nr) |
5115 | { |
5116 | MYSQL_TIME l_time; |
5117 | int error; |
5118 | ErrConvDouble str(nr); |
5119 | THD *thd= get_thd(); |
5120 | |
5121 | longlong tmp= double_to_datetime(nr, &l_time, sql_mode_for_timestamp(thd), |
5122 | &error); |
5123 | return store_TIME_with_warning(thd, &l_time, &str, error, tmp != -1); |
5124 | } |
5125 | |
5126 | |
5127 | int Field_timestamp::store(longlong nr, bool unsigned_val) |
5128 | { |
5129 | MYSQL_TIME l_time; |
5130 | int error; |
5131 | ErrConvInteger str(nr, unsigned_val); |
5132 | THD *thd= get_thd(); |
5133 | |
5134 | longlong tmp= number_to_datetime(nr, 0, &l_time, sql_mode_for_timestamp(thd), |
5135 | &error); |
5136 | return store_TIME_with_warning(thd, &l_time, &str, error, tmp != -1); |
5137 | } |
5138 | |
5139 | |
5140 | int Field_timestamp::store_timestamp(my_time_t ts, ulong sec_part) |
5141 | { |
5142 | store_TIME(ts, sec_part); |
5143 | if (ts == 0 && sec_part == 0 && |
5144 | get_thd()->variables.sql_mode & TIME_NO_ZERO_DATE) |
5145 | { |
5146 | ErrConvString s( |
5147 | STRING_WITH_LEN("0000-00-00 00:00:00.000000" ) - (decimals() ? 6 - decimals() : 7), |
5148 | system_charset_info); |
5149 | set_datetime_warning(WARN_DATA_TRUNCATED, &s, MYSQL_TIMESTAMP_DATETIME, 1); |
5150 | return 1; |
5151 | } |
5152 | return 0; |
5153 | } |
5154 | |
5155 | |
5156 | double Field_timestamp::val_real(void) |
5157 | { |
5158 | return (double) Field_timestamp::val_int(); |
5159 | } |
5160 | |
5161 | |
5162 | longlong Field_timestamp::val_int(void) |
5163 | { |
5164 | MYSQL_TIME ltime; |
5165 | if (get_date(<ime, TIME_NO_ZERO_DATE)) |
5166 | return 0; |
5167 | |
5168 | return ltime.year * 10000000000LL + ltime.month * 100000000LL + |
5169 | ltime.day * 1000000L + ltime.hour * 10000L + |
5170 | ltime.minute * 100 + ltime.second; |
5171 | } |
5172 | |
5173 | |
5174 | String *Field_timestamp::val_str(String *val_buffer, String *val_ptr) |
5175 | { |
5176 | MYSQL_TIME ltime; |
5177 | uint32 temp, temp2; |
5178 | uint dec; |
5179 | char *to; |
5180 | |
5181 | val_buffer->alloc(field_length+1); |
5182 | to= (char*) val_buffer->ptr(); |
5183 | val_buffer->length(field_length); |
5184 | |
5185 | if (get_date(<ime, TIME_NO_ZERO_DATE)) |
5186 | { /* Zero time is "000000" */ |
5187 | val_ptr->set(zero_timestamp, field_length, &my_charset_numeric); |
5188 | return val_ptr; |
5189 | } |
5190 | val_buffer->set_charset(&my_charset_numeric); // Safety |
5191 | |
5192 | temp= ltime.year % 100; |
5193 | if (temp < YY_PART_YEAR - 1) |
5194 | { |
5195 | *to++= '2'; |
5196 | *to++= '0'; |
5197 | } |
5198 | else |
5199 | { |
5200 | *to++= '1'; |
5201 | *to++= '9'; |
5202 | } |
5203 | temp2=temp/10; temp=temp-temp2*10; |
5204 | *to++= (char) ('0'+(char) (temp2)); |
5205 | *to++= (char) ('0'+(char) (temp)); |
5206 | *to++= '-'; |
5207 | temp=ltime.month; |
5208 | temp2=temp/10; temp=temp-temp2*10; |
5209 | *to++= (char) ('0'+(char) (temp2)); |
5210 | *to++= (char) ('0'+(char) (temp)); |
5211 | *to++= '-'; |
5212 | temp=ltime.day; |
5213 | temp2=temp/10; temp=temp-temp2*10; |
5214 | *to++= (char) ('0'+(char) (temp2)); |
5215 | *to++= (char) ('0'+(char) (temp)); |
5216 | *to++= ' '; |
5217 | temp=ltime.hour; |
5218 | temp2=temp/10; temp=temp-temp2*10; |
5219 | *to++= (char) ('0'+(char) (temp2)); |
5220 | *to++= (char) ('0'+(char) (temp)); |
5221 | *to++= ':'; |
5222 | temp=ltime.minute; |
5223 | temp2=temp/10; temp=temp-temp2*10; |
5224 | *to++= (char) ('0'+(char) (temp2)); |
5225 | *to++= (char) ('0'+(char) (temp)); |
5226 | *to++= ':'; |
5227 | temp=ltime.second; |
5228 | temp2=temp/10; temp=temp-temp2*10; |
5229 | *to++= (char) ('0'+(char) (temp2)); |
5230 | *to++= (char) ('0'+(char) (temp)); |
5231 | *to= 0; |
5232 | val_buffer->set_charset(&my_charset_numeric); |
5233 | |
5234 | if ((dec= decimals())) |
5235 | { |
5236 | ulong sec_part= (ulong) sec_part_shift(ltime.second_part, dec); |
5237 | char *buf= const_cast<char*>(val_buffer->ptr() + MAX_DATETIME_WIDTH); |
5238 | for (int i= dec; i > 0; i--, sec_part/= 10) |
5239 | buf[i]= (char)(sec_part % 10) + '0'; |
5240 | buf[0]= '.'; |
5241 | buf[dec + 1]= 0; |
5242 | } |
5243 | return val_buffer; |
5244 | } |
5245 | |
5246 | |
5247 | bool |
5248 | Field_timestamp::validate_value_in_record(THD *thd, const uchar *record) const |
5249 | { |
5250 | DBUG_ASSERT(!is_null_in_record(record)); |
5251 | ulong sec_part; |
5252 | return !get_timestamp(ptr_in_record(record), &sec_part) && !sec_part && |
5253 | (sql_mode_for_dates(thd) & TIME_NO_ZERO_DATE) != 0; |
5254 | } |
5255 | |
5256 | |
5257 | bool Field_timestamp::get_date(MYSQL_TIME *ltime, ulonglong fuzzydate) |
5258 | { |
5259 | ulong sec_part; |
5260 | my_time_t ts= get_timestamp(&sec_part); |
5261 | return get_thd()->timestamp_to_TIME(ltime, ts, sec_part, fuzzydate); |
5262 | } |
5263 | |
5264 | |
5265 | bool Field_timestamp::send_binary(Protocol *protocol) |
5266 | { |
5267 | MYSQL_TIME ltime; |
5268 | Field_timestamp::get_date(<ime, 0); |
5269 | return protocol->store(<ime, 0); |
5270 | } |
5271 | |
5272 | |
5273 | int Field_timestamp::cmp(const uchar *a_ptr, const uchar *b_ptr) |
5274 | { |
5275 | int32 a,b; |
5276 | a=sint4korr(a_ptr); |
5277 | b=sint4korr(b_ptr); |
5278 | return ((uint32) a < (uint32) b) ? -1 : ((uint32) a > (uint32) b) ? 1 : 0; |
5279 | } |
5280 | |
5281 | |
5282 | void Field_timestamp::sort_string(uchar *to,uint length __attribute__((unused))) |
5283 | { |
5284 | to[0] = ptr[3]; |
5285 | to[1] = ptr[2]; |
5286 | to[2] = ptr[1]; |
5287 | to[3] = ptr[0]; |
5288 | } |
5289 | |
5290 | |
5291 | void Field_timestamp::sql_type(String &res) const |
5292 | { |
5293 | if (!decimals()) |
5294 | { |
5295 | res.set_ascii(STRING_WITH_LEN("timestamp" )); |
5296 | return; |
5297 | } |
5298 | CHARSET_INFO *cs=res.charset(); |
5299 | res.length(cs->cset->snprintf(cs, (char*) res.ptr(), res.alloced_length(), |
5300 | "timestamp(%u)" , decimals())); |
5301 | } |
5302 | |
5303 | |
5304 | int Field_timestamp::set_time() |
5305 | { |
5306 | set_notnull(); |
5307 | store_TIME(get_thd()->query_start(), 0); |
5308 | return 0; |
5309 | } |
5310 | |
5311 | |
5312 | bool Field_timestamp::load_data_set_no_data(THD *thd, bool fixed_format) |
5313 | { |
5314 | if (!maybe_null()) |
5315 | { |
5316 | /* |
5317 | Timestamp fields that are NOT NULL are autoupdated if there is no |
5318 | corresponding value in the data file. |
5319 | */ |
5320 | set_time(); |
5321 | set_has_explicit_value(); |
5322 | return false; |
5323 | } |
5324 | return Field::load_data_set_no_data(thd, fixed_format); |
5325 | } |
5326 | |
5327 | |
5328 | bool Field_timestamp::load_data_set_null(THD *thd) |
5329 | { |
5330 | if (!maybe_null()) |
5331 | { |
5332 | /* |
5333 | Timestamp fields that are NOT NULL are autoupdated if there is no |
5334 | corresponding value in the data file. |
5335 | */ |
5336 | set_time(); |
5337 | } |
5338 | else |
5339 | { |
5340 | reset(); |
5341 | set_null(); |
5342 | } |
5343 | set_has_explicit_value(); // Do not auto-update this field |
5344 | return false; |
5345 | } |
5346 | |
5347 | |
5348 | #ifdef NOT_USED |
5349 | static void store_native(ulonglong num, uchar *to, uint bytes) |
5350 | { |
5351 | switch(bytes) { |
5352 | case 1: *to= (uchar)num; break; |
5353 | case 2: shortstore(to, (ushort)num); break; |
5354 | case 3: int3store(to, num); /* Sic!*/ break; |
5355 | case 4: longstore(to, (ulong)num); break; |
5356 | case 8: longlongstore(to, num); break; |
5357 | default: DBUG_ASSERT(0); |
5358 | } |
5359 | } |
5360 | |
5361 | static longlong read_native(const uchar *from, uint bytes) |
5362 | { |
5363 | switch(bytes) { |
5364 | case 1: return from[0]; |
5365 | case 2: { uint16 tmp; shortget(tmp, from); return tmp; } |
5366 | case 3: return uint3korr(from); |
5367 | case 4: { uint32 tmp; longget(tmp, from); return tmp; } |
5368 | case 8: { longlong tmp; longlongget(tmp, from); return tmp; } |
5369 | default: DBUG_ASSERT(0); return 0; |
5370 | } |
5371 | } |
5372 | #endif |
5373 | |
5374 | static void store_lowendian(ulonglong num, uchar *to, uint bytes) |
5375 | { |
5376 | switch(bytes) { |
5377 | case 1: *to= (uchar)num; break; |
5378 | case 2: int2store(to, num); break; |
5379 | case 3: int3store(to, num); break; |
5380 | case 4: int4store(to, num); break; |
5381 | case 8: int8store(to, num); break; |
5382 | default: DBUG_ASSERT(0); |
5383 | } |
5384 | } |
5385 | |
5386 | static longlong read_lowendian(const uchar *from, uint bytes) |
5387 | { |
5388 | switch(bytes) { |
5389 | case 1: return from[0]; |
5390 | case 2: return uint2korr(from); |
5391 | case 3: return uint3korr(from); |
5392 | case 4: return uint4korr(from); |
5393 | case 8: return sint8korr(from); |
5394 | default: DBUG_ASSERT(0); return 0; |
5395 | } |
5396 | } |
5397 | |
5398 | void Field_timestamp_hires::store_TIME(my_time_t timestamp, ulong sec_part) |
5399 | { |
5400 | mi_int4store(ptr, timestamp); |
5401 | store_bigendian(sec_part_shift(sec_part, dec), ptr+4, sec_part_bytes(dec)); |
5402 | } |
5403 | |
5404 | my_time_t Field_timestamp_hires::get_timestamp(const uchar *pos, |
5405 | ulong *sec_part) const |
5406 | { |
5407 | ASSERT_COLUMN_MARKED_FOR_READ; |
5408 | *sec_part= (long)sec_part_unshift(read_bigendian(pos+4, sec_part_bytes(dec)), dec); |
5409 | return mi_uint4korr(pos); |
5410 | } |
5411 | |
5412 | double Field_timestamp_with_dec::val_real(void) |
5413 | { |
5414 | MYSQL_TIME ltime; |
5415 | if (get_date(<ime, TIME_NO_ZERO_DATE)) |
5416 | return 0; |
5417 | |
5418 | return ltime.year * 1e10 + ltime.month * 1e8 + |
5419 | ltime.day * 1e6 + ltime.hour * 1e4 + |
5420 | ltime.minute * 1e2 + ltime.second + ltime.second_part*1e-6; |
5421 | } |
5422 | |
5423 | my_decimal *Field_timestamp_with_dec::val_decimal(my_decimal *d) |
5424 | { |
5425 | MYSQL_TIME ltime; |
5426 | get_date(<ime, 0); |
5427 | return TIME_to_my_decimal(<ime, d); |
5428 | } |
5429 | |
5430 | int Field_timestamp::store_decimal(const my_decimal *d) |
5431 | { |
5432 | ulonglong nr; |
5433 | ulong sec_part; |
5434 | int error; |
5435 | MYSQL_TIME ltime; |
5436 | longlong tmp; |
5437 | THD *thd= get_thd(); |
5438 | ErrConvDecimal str(d); |
5439 | |
5440 | if (my_decimal2seconds(d, &nr, &sec_part)) |
5441 | { |
5442 | tmp= -1; |
5443 | error= 2; |
5444 | } |
5445 | else |
5446 | tmp= number_to_datetime(nr, sec_part, <ime, sql_mode_for_timestamp(thd), |
5447 | &error); |
5448 | return store_TIME_with_warning(thd, <ime, &str, error, tmp != -1); |
5449 | } |
5450 | |
5451 | int Field_timestamp_with_dec::set_time() |
5452 | { |
5453 | THD *thd= get_thd(); |
5454 | set_notnull(); |
5455 | // Avoid writing microseconds into binlog for FSP=0 |
5456 | store_TIME(thd->query_start(), decimals() ? thd->query_start_sec_part() : 0); |
5457 | return 0; |
5458 | } |
5459 | |
5460 | bool Field_timestamp_with_dec::send_binary(Protocol *protocol) |
5461 | { |
5462 | MYSQL_TIME ltime; |
5463 | Field_timestamp::get_date(<ime, 0); |
5464 | return protocol->store(<ime, dec); |
5465 | } |
5466 | |
5467 | |
5468 | int Field_timestamp_hires::cmp(const uchar *a_ptr, const uchar *b_ptr) |
5469 | { |
5470 | int32 a,b; |
5471 | ulong a_sec_part, b_sec_part; |
5472 | a= mi_uint4korr(a_ptr); |
5473 | a_sec_part= (ulong)read_bigendian(a_ptr+4, sec_part_bytes(dec)); |
5474 | b= mi_uint4korr(b_ptr); |
5475 | b_sec_part= (ulong)read_bigendian(b_ptr+4, sec_part_bytes(dec)); |
5476 | return ((uint32) a < (uint32) b) ? -1 : ((uint32) a > (uint32) b) ? 1 : |
5477 | a_sec_part < b_sec_part ? -1 : a_sec_part > b_sec_part ? 1 : 0; |
5478 | } |
5479 | |
5480 | |
5481 | void Field_timestamp_with_dec::make_send_field(Send_field *field) |
5482 | { |
5483 | Field::make_send_field(field); |
5484 | field->decimals= dec; |
5485 | } |
5486 | |
5487 | |
5488 | /************************************************************* |
5489 | ** MySQL-5.6 compatible TIMESTAMP(N) |
5490 | **************************************************************/ |
5491 | |
5492 | void Field_timestampf::store_TIME(my_time_t timestamp, ulong sec_part) |
5493 | { |
5494 | struct timeval tm; |
5495 | tm.tv_sec= timestamp; |
5496 | tm.tv_usec= sec_part; |
5497 | my_timeval_trunc(&tm, dec); |
5498 | my_timestamp_to_binary(&tm, ptr, dec); |
5499 | } |
5500 | |
5501 | void Field_timestampf::set_max() |
5502 | { |
5503 | DBUG_ENTER("Field_timestampf::set_max" ); |
5504 | ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; |
5505 | DBUG_ASSERT(dec == TIME_SECOND_PART_DIGITS); |
5506 | |
5507 | set_notnull(); |
5508 | mi_int4store(ptr, TIMESTAMP_MAX_VALUE); |
5509 | mi_int3store(ptr + 4, TIME_MAX_SECOND_PART); |
5510 | |
5511 | DBUG_VOID_RETURN; |
5512 | } |
5513 | |
5514 | bool Field_timestampf::is_max() |
5515 | { |
5516 | DBUG_ENTER("Field_timestampf::is_max" ); |
5517 | ASSERT_COLUMN_MARKED_FOR_READ; |
5518 | |
5519 | DBUG_RETURN(mi_sint4korr(ptr) == TIMESTAMP_MAX_VALUE && |
5520 | mi_sint3korr(ptr + 4) == TIME_MAX_SECOND_PART); |
5521 | } |
5522 | |
5523 | my_time_t Field_timestampf::get_timestamp(const uchar *pos, |
5524 | ulong *sec_part) const |
5525 | { |
5526 | struct timeval tm; |
5527 | my_timestamp_from_binary(&tm, pos, dec); |
5528 | *sec_part= tm.tv_usec; |
5529 | return tm.tv_sec; |
5530 | } |
5531 | |
5532 | |
5533 | /*************************************************************/ |
5534 | uint Field_temporal::is_equal(Create_field *new_field) |
5535 | { |
5536 | return new_field->type_handler() == type_handler() && |
5537 | new_field->length == max_display_length(); |
5538 | } |
5539 | |
5540 | |
5541 | void Field_temporal::set_warnings(Sql_condition::enum_warning_level trunc_level, |
5542 | const ErrConv *str, int was_cut, |
5543 | timestamp_type ts_type) |
5544 | { |
5545 | /* |
5546 | error code logic: |
5547 | MYSQL_TIME_WARN_TRUNCATED means that the value was not a date/time at all. |
5548 | it will be stored as zero date/time. |
5549 | MYSQL_TIME_WARN_OUT_OF_RANGE means that the value was a date/time, |
5550 | that is, it was parsed as such, but the value was invalid. |
5551 | |
5552 | Also, MYSQL_TIME_WARN_TRUNCATED is used when storing a DATETIME in |
5553 | a DATE field and non-zero time part is thrown away. |
5554 | */ |
5555 | if (was_cut & MYSQL_TIME_WARN_TRUNCATED) |
5556 | set_datetime_warning(trunc_level, WARN_DATA_TRUNCATED, str, ts_type, 1); |
5557 | if (was_cut & MYSQL_TIME_WARN_OUT_OF_RANGE) |
5558 | set_datetime_warning(ER_WARN_DATA_OUT_OF_RANGE, str, ts_type, 1); |
5559 | } |
5560 | |
5561 | |
5562 | /* |
5563 | Store string into a date/time field |
5564 | |
5565 | RETURN |
5566 | 0 ok |
5567 | 1 Value was cut during conversion |
5568 | 2 value was out of range |
5569 | 3 Datetime value that was cut (warning level NOTE) |
5570 | This is used by opt_range.cc:get_mm_leaf(). |
5571 | */ |
5572 | int Field_temporal_with_date::store_TIME_with_warning(MYSQL_TIME *ltime, |
5573 | const ErrConv *str, |
5574 | int was_cut, |
5575 | int have_smth_to_conv) |
5576 | { |
5577 | Sql_condition::enum_warning_level trunc_level= Sql_condition::WARN_LEVEL_WARN; |
5578 | int ret= 2; |
5579 | |
5580 | ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; |
5581 | |
5582 | if (was_cut == 0 && have_smth_to_conv == 0) // special case: zero date |
5583 | { |
5584 | was_cut= MYSQL_TIME_WARN_OUT_OF_RANGE; |
5585 | } |
5586 | else if (!have_smth_to_conv) |
5587 | { |
5588 | bzero(ltime, sizeof(*ltime)); |
5589 | was_cut= MYSQL_TIME_WARN_TRUNCATED; |
5590 | ret= 1; |
5591 | } |
5592 | else if (!MYSQL_TIME_WARN_HAVE_WARNINGS(was_cut) && |
5593 | (MYSQL_TIME_WARN_HAVE_NOTES(was_cut) || |
5594 | (type_handler()->mysql_timestamp_type() == MYSQL_TIMESTAMP_DATE && |
5595 | (ltime->hour || ltime->minute || ltime->second || ltime->second_part)))) |
5596 | { |
5597 | trunc_level= Sql_condition::WARN_LEVEL_NOTE; |
5598 | was_cut|= MYSQL_TIME_WARN_TRUNCATED; |
5599 | ret= 3; |
5600 | } |
5601 | set_warnings(trunc_level, str, was_cut, |
5602 | type_handler()->mysql_timestamp_type()); |
5603 | store_TIME(ltime); |
5604 | return was_cut ? ret : 0; |
5605 | } |
5606 | |
5607 | |
5608 | int Field_temporal_with_date::store(const char *from, size_t len, CHARSET_INFO *cs) |
5609 | { |
5610 | MYSQL_TIME ltime; |
5611 | MYSQL_TIME_STATUS status; |
5612 | THD *thd= get_thd(); |
5613 | ErrConvString str(from, len, cs); |
5614 | bool func_res= !str_to_datetime(cs, from, len, <ime, |
5615 | sql_mode_for_dates(thd), |
5616 | &status); |
5617 | return store_TIME_with_warning(<ime, &str, status.warnings, func_res); |
5618 | } |
5619 | |
5620 | |
5621 | int Field_temporal_with_date::store(double nr) |
5622 | { |
5623 | int error= 0; |
5624 | MYSQL_TIME ltime; |
5625 | THD *thd= get_thd(); |
5626 | ErrConvDouble str(nr); |
5627 | |
5628 | longlong tmp= double_to_datetime(nr, <ime, |
5629 | (uint) sql_mode_for_dates(thd), &error); |
5630 | return store_TIME_with_warning(<ime, &str, error, tmp != -1); |
5631 | } |
5632 | |
5633 | |
5634 | int Field_temporal_with_date::store(longlong nr, bool unsigned_val) |
5635 | { |
5636 | int error; |
5637 | MYSQL_TIME ltime; |
5638 | longlong tmp; |
5639 | THD *thd= get_thd(); |
5640 | ErrConvInteger str(nr, unsigned_val); |
5641 | |
5642 | tmp= number_to_datetime(nr, 0, <ime, sql_mode_for_dates(thd), &error); |
5643 | |
5644 | return store_TIME_with_warning(<ime, &str, error, tmp != -1); |
5645 | } |
5646 | |
5647 | |
5648 | int Field_temporal_with_date::store_time_dec(const MYSQL_TIME *ltime, uint dec) |
5649 | { |
5650 | int error= 0, have_smth_to_conv= 1; |
5651 | ErrConvTime str(ltime); |
5652 | MYSQL_TIME l_time; |
5653 | |
5654 | if (copy_or_convert_to_datetime(get_thd(), ltime, &l_time)) |
5655 | { |
5656 | /* |
5657 | Set have_smth_to_conv and error in a way to have |
5658 | store_TIME_with_warning do bzero(). |
5659 | */ |
5660 | have_smth_to_conv= false; |
5661 | error= MYSQL_TIME_WARN_OUT_OF_RANGE; |
5662 | } |
5663 | else |
5664 | { |
5665 | /* |
5666 | We don't perform range checking here since values stored in TIME |
5667 | structure always fit into DATETIME range. |
5668 | */ |
5669 | have_smth_to_conv= !check_date(&l_time, pack_time(&l_time) != 0, |
5670 | sql_mode_for_dates(get_thd()), &error); |
5671 | } |
5672 | return store_TIME_with_warning(&l_time, &str, error, have_smth_to_conv); |
5673 | } |
5674 | |
5675 | |
5676 | bool |
5677 | Field_temporal_with_date::validate_value_in_record(THD *thd, |
5678 | const uchar *record) const |
5679 | { |
5680 | DBUG_ASSERT(!is_null_in_record(record)); |
5681 | MYSQL_TIME ltime; |
5682 | return get_TIME(<ime, ptr_in_record(record), sql_mode_for_dates(thd)); |
5683 | } |
5684 | |
5685 | |
5686 | my_decimal *Field_temporal::val_decimal(my_decimal *d) |
5687 | { |
5688 | MYSQL_TIME ltime; |
5689 | if (get_date(<ime, 0)) |
5690 | { |
5691 | bzero(<ime, sizeof(ltime)); |
5692 | ltime.time_type= type_handler()->mysql_timestamp_type(); |
5693 | } |
5694 | return TIME_to_my_decimal(<ime, d); |
5695 | } |
5696 | |
5697 | |
5698 | bool Field_temporal::can_optimize_keypart_ref(const Item_bool_func *cond, |
5699 | const Item *value) const |
5700 | { |
5701 | return true; // Field is of TIME_RESULT, which supersedes everything else. |
5702 | } |
5703 | |
5704 | |
5705 | bool Field_temporal::can_optimize_group_min_max(const Item_bool_func *cond, |
5706 | const Item *const_item) const |
5707 | { |
5708 | return true; // Field is of TIME_RESULT, which supersedes everything else. |
5709 | } |
5710 | |
5711 | |
5712 | Item *Field_temporal::get_equal_const_item_datetime(THD *thd, |
5713 | const Context &ctx, |
5714 | Item *const_item) |
5715 | { |
5716 | switch (ctx.subst_constraint()) { |
5717 | case IDENTITY_SUBST: |
5718 | if ((const_item->field_type() != MYSQL_TYPE_DATETIME && |
5719 | const_item->field_type() != MYSQL_TYPE_TIMESTAMP) || |
5720 | const_item->decimals != decimals()) |
5721 | { |
5722 | Datetime dt(thd, const_item, 0); |
5723 | if (!dt.is_valid_datetime()) |
5724 | return NULL; |
5725 | /* |
5726 | See comments about truncation in the same place in |
5727 | Field_time::get_equal_const_item(). |
5728 | */ |
5729 | return new (thd->mem_root) Item_datetime_literal(thd, |
5730 | dt.get_mysql_time(), |
5731 | decimals()); |
5732 | } |
5733 | break; |
5734 | case ANY_SUBST: |
5735 | if (!is_temporal_type_with_date(const_item->field_type())) |
5736 | { |
5737 | Datetime dt(thd, const_item, TIME_FUZZY_DATES | TIME_INVALID_DATES); |
5738 | if (!dt.is_valid_datetime()) |
5739 | return NULL; |
5740 | return new (thd->mem_root) |
5741 | Item_datetime_literal_for_invalid_dates(thd, dt.get_mysql_time(), |
5742 | dt.get_mysql_time()-> |
5743 | second_part ? |
5744 | TIME_SECOND_PART_DIGITS : 0); |
5745 | } |
5746 | break; |
5747 | } |
5748 | return const_item; |
5749 | } |
5750 | |
5751 | |
5752 | /**************************************************************************** |
5753 | ** time type |
5754 | ** In string context: HH:MM:SS |
5755 | ** In number context: HHMMSS |
5756 | ** Stored as a 3 byte unsigned int |
5757 | ****************************************************************************/ |
5758 | int Field_time::store_TIME_with_warning(MYSQL_TIME *ltime, |
5759 | const ErrConv *str, |
5760 | int was_cut, |
5761 | int have_smth_to_conv) |
5762 | { |
5763 | ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; |
5764 | |
5765 | if (!have_smth_to_conv) |
5766 | { |
5767 | bzero(ltime, sizeof(*ltime)); |
5768 | store_TIME(ltime); |
5769 | set_warnings(Sql_condition::WARN_LEVEL_WARN, str, MYSQL_TIME_WARN_TRUNCATED); |
5770 | return 1; |
5771 | } |
5772 | if (ltime->year != 0 || ltime->month != 0) |
5773 | { |
5774 | ltime->year= ltime->month= ltime->day= 0; |
5775 | was_cut|= MYSQL_TIME_NOTE_TRUNCATED; |
5776 | } |
5777 | my_time_trunc(ltime, decimals()); |
5778 | store_TIME(ltime); |
5779 | if (!MYSQL_TIME_WARN_HAVE_WARNINGS(was_cut) && |
5780 | MYSQL_TIME_WARN_HAVE_NOTES(was_cut)) |
5781 | { |
5782 | set_warnings(Sql_condition::WARN_LEVEL_NOTE, str, |
5783 | was_cut | MYSQL_TIME_WARN_TRUNCATED); |
5784 | return 3; |
5785 | } |
5786 | set_warnings(Sql_condition::WARN_LEVEL_WARN, str, was_cut); |
5787 | return was_cut ? 2 : 0; |
5788 | } |
5789 | |
5790 | |
5791 | void Field_time::store_TIME(const MYSQL_TIME *ltime) |
5792 | { |
5793 | DBUG_ASSERT(ltime->year == 0); |
5794 | DBUG_ASSERT(ltime->month == 0); |
5795 | long tmp= (ltime->day*24L+ltime->hour)*10000L + |
5796 | (ltime->minute*100+ltime->second); |
5797 | if (ltime->neg) |
5798 | tmp= -tmp; |
5799 | int3store(ptr,tmp); |
5800 | } |
5801 | |
5802 | int Field_time::store(const char *from,size_t len,CHARSET_INFO *cs) |
5803 | { |
5804 | MYSQL_TIME ltime; |
5805 | MYSQL_TIME_STATUS status; |
5806 | ErrConvString str(from, len, cs); |
5807 | bool have_smth_to_conv= |
5808 | !str_to_time(cs, from, len, <ime, sql_mode_for_dates(get_thd()), |
5809 | &status); |
5810 | |
5811 | return store_TIME_with_warning(<ime, &str, |
5812 | status.warnings, have_smth_to_conv); |
5813 | } |
5814 | |
5815 | |
5816 | /** |
5817 | subtract a given number of days from DATETIME, return TIME |
5818 | |
5819 | optimized version of calc_time_diff() |
5820 | |
5821 | @note it might generate TIME values outside of the valid TIME range! |
5822 | */ |
5823 | static void calc_datetime_days_diff(MYSQL_TIME *ltime, long days) |
5824 | { |
5825 | long daydiff= calc_daynr(ltime->year, ltime->month, ltime->day) - days; |
5826 | ltime->year= ltime->month= 0; |
5827 | if (daydiff >=0 ) |
5828 | { |
5829 | ltime->day= daydiff; |
5830 | ltime->time_type= MYSQL_TIMESTAMP_TIME; |
5831 | } |
5832 | else |
5833 | { |
5834 | longlong timediff= ((((daydiff * 24LL + |
5835 | ltime->hour) * 60LL + |
5836 | ltime->minute) * 60LL + |
5837 | ltime->second) * 1000000LL + |
5838 | ltime->second_part); |
5839 | unpack_time(timediff, ltime, MYSQL_TIMESTAMP_TIME); |
5840 | } |
5841 | } |
5842 | |
5843 | |
5844 | int Field_time::store_time_dec(const MYSQL_TIME *ltime, uint dec) |
5845 | { |
5846 | MYSQL_TIME l_time= *ltime; |
5847 | ErrConvTime str(ltime); |
5848 | int was_cut= 0; |
5849 | |
5850 | if (curdays && l_time.time_type != MYSQL_TIMESTAMP_TIME) |
5851 | calc_datetime_days_diff(&l_time, curdays); |
5852 | |
5853 | int have_smth_to_conv= !check_time_range(&l_time, decimals(), &was_cut); |
5854 | return store_TIME_with_warning(&l_time, &str, was_cut, have_smth_to_conv); |
5855 | } |
5856 | |
5857 | |
5858 | int Field_time::store(double nr) |
5859 | { |
5860 | MYSQL_TIME ltime; |
5861 | ErrConvDouble str(nr); |
5862 | int was_cut; |
5863 | bool neg= nr < 0; |
5864 | if (neg) |
5865 | nr= -nr; |
5866 | int have_smth_to_conv= !number_to_time(neg, (ulonglong) nr, |
5867 | (ulong)((nr - floor(nr)) * TIME_SECOND_PART_FACTOR), |
5868 | <ime, &was_cut); |
5869 | |
5870 | return store_TIME_with_warning(<ime, &str, was_cut, have_smth_to_conv); |
5871 | } |
5872 | |
5873 | |
5874 | int Field_time::store(longlong nr, bool unsigned_val) |
5875 | { |
5876 | MYSQL_TIME ltime; |
5877 | ErrConvInteger str(nr, unsigned_val); |
5878 | int was_cut; |
5879 | if (nr < 0 && unsigned_val) |
5880 | nr= 99991231235959LL + 1; |
5881 | int have_smth_to_conv= !number_to_time(nr < 0, |
5882 | (ulonglong) (nr < 0 ? -nr : nr), |
5883 | 0, <ime, &was_cut); |
5884 | |
5885 | return store_TIME_with_warning(<ime, &str, was_cut, have_smth_to_conv); |
5886 | } |
5887 | |
5888 | |
5889 | void Field_time::set_curdays(THD *thd) |
5890 | { |
5891 | MYSQL_TIME ltime; |
5892 | set_current_date(thd, <ime); |
5893 | curdays= calc_daynr(ltime.year, ltime.month, ltime.day); |
5894 | } |
5895 | |
5896 | |
5897 | Field *Field_time::new_key_field(MEM_ROOT *root, TABLE *new_table, |
5898 | uchar *new_ptr, uint32 length, |
5899 | uchar *new_null_ptr, uint new_null_bit) |
5900 | { |
5901 | THD *thd= get_thd(); |
5902 | Field_time *res= |
5903 | (Field_time*) Field::new_key_field(root, new_table, new_ptr, length, |
5904 | new_null_ptr, new_null_bit); |
5905 | if (!(thd->variables.old_behavior & OLD_MODE_ZERO_DATE_TIME_CAST) && res) |
5906 | res->set_curdays(thd); |
5907 | return res; |
5908 | } |
5909 | |
5910 | |
5911 | double Field_time::val_real(void) |
5912 | { |
5913 | ASSERT_COLUMN_MARKED_FOR_READ; |
5914 | uint32 j= (uint32) uint3korr(ptr); |
5915 | return (double) j; |
5916 | } |
5917 | |
5918 | longlong Field_time::val_int(void) |
5919 | { |
5920 | ASSERT_COLUMN_MARKED_FOR_READ; |
5921 | return (longlong) sint3korr(ptr); |
5922 | } |
5923 | |
5924 | |
5925 | /** |
5926 | @note |
5927 | This function is multi-byte safe as the result string is always of type |
5928 | my_charset_bin |
5929 | */ |
5930 | |
5931 | String *Field_time::val_str(String *str, |
5932 | String *unused __attribute__((unused))) |
5933 | { |
5934 | ASSERT_COLUMN_MARKED_FOR_READ; |
5935 | MYSQL_TIME ltime; |
5936 | get_date(<ime, TIME_TIME_ONLY); |
5937 | str->alloc(field_length + 1); |
5938 | str->length(my_time_to_str(<ime, const_cast<char*>(str->ptr()), decimals())); |
5939 | str->set_charset(&my_charset_numeric); |
5940 | return str; |
5941 | } |
5942 | |
5943 | |
5944 | bool Field_time::check_zero_in_date_with_warn(ulonglong fuzzydate) |
5945 | { |
5946 | if (!(fuzzydate & TIME_TIME_ONLY) && (fuzzydate & TIME_NO_ZERO_IN_DATE)) |
5947 | { |
5948 | THD *thd= get_thd(); |
5949 | push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, |
5950 | ER_WARN_DATA_OUT_OF_RANGE, |
5951 | ER_THD(thd, ER_WARN_DATA_OUT_OF_RANGE), field_name.str, |
5952 | thd->get_stmt_da()->current_row_for_warning()); |
5953 | return true; |
5954 | } |
5955 | return false; |
5956 | } |
5957 | |
5958 | |
5959 | /** |
5960 | @note |
5961 | Normally we would not consider 'time' as a valid date, but we allow |
5962 | get_date() here to be able to do things like |
5963 | DATE_FORMAT(time, "%l.%i %p") |
5964 | */ |
5965 | |
5966 | bool Field_time::get_date(MYSQL_TIME *ltime, ulonglong fuzzydate) |
5967 | { |
5968 | if (check_zero_in_date_with_warn(fuzzydate)) |
5969 | return true; |
5970 | long tmp=(long) sint3korr(ptr); |
5971 | ltime->neg=0; |
5972 | if (tmp < 0) |
5973 | { |
5974 | ltime->neg= 1; |
5975 | tmp=-tmp; |
5976 | } |
5977 | ltime->year= ltime->month= ltime->day= 0; |
5978 | ltime->hour= (int) (tmp/10000); |
5979 | tmp-=ltime->hour*10000; |
5980 | ltime->minute= (int) tmp/100; |
5981 | ltime->second= (int) tmp % 100; |
5982 | ltime->second_part=0; |
5983 | ltime->time_type= MYSQL_TIMESTAMP_TIME; |
5984 | return 0; |
5985 | } |
5986 | |
5987 | |
5988 | bool Field_time::send_binary(Protocol *protocol) |
5989 | { |
5990 | MYSQL_TIME ltime; |
5991 | get_date(<ime, TIME_TIME_ONLY); |
5992 | return protocol->store_time(<ime, decimals()); |
5993 | } |
5994 | |
5995 | |
5996 | int Field_time::cmp(const uchar *a_ptr, const uchar *b_ptr) |
5997 | { |
5998 | int32 a,b; |
5999 | a=(int32) sint3korr(a_ptr); |
6000 | b=(int32) sint3korr(b_ptr); |
6001 | return (a < b) ? -1 : (a > b) ? 1 : 0; |
6002 | } |
6003 | |
6004 | void Field_time::sort_string(uchar *to,uint length __attribute__((unused))) |
6005 | { |
6006 | to[0] = (uchar) (ptr[2] ^ 128); |
6007 | to[1] = ptr[1]; |
6008 | to[2] = ptr[0]; |
6009 | } |
6010 | |
6011 | void Field_time::sql_type(String &res) const |
6012 | { |
6013 | if (decimals() == 0) |
6014 | { |
6015 | res.set_ascii(STRING_WITH_LEN("time" )); |
6016 | return; |
6017 | } |
6018 | CHARSET_INFO *cs= res.charset(); |
6019 | res.length(cs->cset->snprintf(cs, (char*) res.ptr(), res.alloced_length(), |
6020 | "time(%d)" , decimals())); |
6021 | } |
6022 | |
6023 | int Field_time_hires::reset() |
6024 | { |
6025 | store_bigendian(zero_point, ptr, Field_time_hires::pack_length()); |
6026 | return 0; |
6027 | } |
6028 | |
6029 | |
6030 | void Field_time_hires::store_TIME(const MYSQL_TIME *ltime) |
6031 | { |
6032 | DBUG_ASSERT(ltime->year == 0); |
6033 | DBUG_ASSERT(ltime->month == 0); |
6034 | ulonglong packed= sec_part_shift(pack_time(ltime), dec) + zero_point; |
6035 | store_bigendian(packed, ptr, Field_time_hires::pack_length()); |
6036 | } |
6037 | |
6038 | int Field_time::store_decimal(const my_decimal *d) |
6039 | { |
6040 | ulonglong nr; |
6041 | ulong sec_part; |
6042 | ErrConvDecimal str(d); |
6043 | MYSQL_TIME ltime; |
6044 | int was_cut; |
6045 | bool neg= my_decimal2seconds(d, &nr, &sec_part); |
6046 | |
6047 | int have_smth_to_conv= !number_to_time(neg, nr, sec_part, <ime, &was_cut); |
6048 | |
6049 | return store_TIME_with_warning(<ime, &str, was_cut, have_smth_to_conv); |
6050 | } |
6051 | |
6052 | |
6053 | bool Field_time::can_be_substituted_to_equal_item(const Context &ctx, |
6054 | const Item_equal *item_equal) |
6055 | { |
6056 | DBUG_ASSERT(item_equal->compare_type_handler()->cmp_type() != STRING_RESULT); |
6057 | switch (ctx.subst_constraint()) { |
6058 | case ANY_SUBST: |
6059 | /* |
6060 | A TIME field in a DATETIME comparison can be substituted to |
6061 | Item_equal with TIME comparison. |
6062 | |
6063 | SET timestamp=UNIX_TIMESTAMP('2015-08-30 10:20:30'); |
6064 | CREATE OR REPLACE TABLE t1 (a TIME); |
6065 | INSERT INTO t1 VALUES ('00:00:00'),('00:00:01'); |
6066 | SELECT * FROM t1 WHERE a>=TIMESTAMP'2015-08-30 00:00:00' |
6067 | AND a='00:00:00'; |
6068 | |
6069 | The above query can be simplified to: |
6070 | SELECT * FROM t1 WHERE TIME'00:00:00'>=TIMESTAMP'2015-08-30 00:00:00' |
6071 | AND a='00:00:00'; |
6072 | And further to: |
6073 | SELECT * FROM t1 WHERE a=TIME'00:00:00'; |
6074 | */ |
6075 | if (ctx.compare_type_handler() == &type_handler_datetime && |
6076 | item_equal->compare_type_handler() == &type_handler_time) |
6077 | return true; |
6078 | return ctx.compare_type_handler() == item_equal->compare_type_handler(); |
6079 | case IDENTITY_SUBST: |
6080 | return true; |
6081 | } |
6082 | return false; |
6083 | } |
6084 | |
6085 | |
6086 | Item *Field_time::get_equal_const_item(THD *thd, const Context &ctx, |
6087 | Item *const_item) |
6088 | { |
6089 | switch (ctx.subst_constraint()) { |
6090 | case ANY_SUBST: |
6091 | if (const_item->field_type() != MYSQL_TYPE_TIME) |
6092 | { |
6093 | MYSQL_TIME ltime; |
6094 | // Get the value of const_item with conversion from DATETIME to TIME |
6095 | ulonglong fuzzydate= Time::comparison_flags_for_get_date(); |
6096 | if (const_item->get_time_with_conversion(thd, <ime, fuzzydate)) |
6097 | return NULL; |
6098 | /* |
6099 | Replace a DATE/DATETIME constant to a TIME constant: |
6100 | WHERE LENGTH(time_column)=8 |
6101 | AND time_column=TIMESTAMP'2015-08-30 10:20:30'; |
6102 | to: |
6103 | WHERE LENGTH(time_column)=10 |
6104 | AND time_column=TIME'10:20:30' |
6105 | |
6106 | (assuming CURRENT_DATE is '2015-08-30' |
6107 | */ |
6108 | return new (thd->mem_root) Item_time_literal(thd, <ime, |
6109 | ltime.second_part ? |
6110 | TIME_SECOND_PART_DIGITS : |
6111 | 0); |
6112 | } |
6113 | break; |
6114 | case IDENTITY_SUBST: |
6115 | if (const_item->field_type() != MYSQL_TYPE_TIME || |
6116 | const_item->decimals != decimals()) |
6117 | { |
6118 | MYSQL_TIME ltime; |
6119 | if (const_item->get_time_with_conversion(thd, <ime, TIME_TIME_ONLY)) |
6120 | return NULL; |
6121 | /* |
6122 | Note, the value returned in "ltime" can have more fractional |
6123 | digits that decimals(). The Item_time_literal constructor will |
6124 | truncate these digits. We could disallow propagation is such |
6125 | cases, but it's still useful (and safe) to optimize: |
6126 | WHERE time0_column='00:00:00.123' AND LENGTH(a)=12 |
6127 | to |
6128 | WHERE time0_column='00:00:00.123' AND LENGTH(TIME'00:00:00')=12 |
6129 | and then to |
6130 | WHERE FALSE |
6131 | The original WHERE would do the full table scan (in case of no keys). |
6132 | The optimized WHERE will return with "Impossible WHERE", without |
6133 | having to do the full table scan. |
6134 | */ |
6135 | return new (thd->mem_root) Item_time_literal(thd, <ime, decimals()); |
6136 | } |
6137 | break; |
6138 | } |
6139 | return const_item; |
6140 | } |
6141 | |
6142 | |
6143 | longlong Field_time_with_dec::val_int(void) |
6144 | { |
6145 | ASSERT_COLUMN_MARKED_FOR_READ; |
6146 | MYSQL_TIME ltime; |
6147 | get_date(<ime, TIME_TIME_ONLY); |
6148 | longlong val= TIME_to_ulonglong_time(<ime); |
6149 | return ltime.neg ? -val : val; |
6150 | } |
6151 | |
6152 | double Field_time_with_dec::val_real(void) |
6153 | { |
6154 | ASSERT_COLUMN_MARKED_FOR_READ; |
6155 | MYSQL_TIME ltime; |
6156 | get_date(<ime, TIME_TIME_ONLY); |
6157 | return TIME_to_double(<ime); |
6158 | } |
6159 | |
6160 | bool Field_time_hires::get_date(MYSQL_TIME *ltime, ulonglong fuzzydate) |
6161 | { |
6162 | if (check_zero_in_date_with_warn(fuzzydate)) |
6163 | return true; |
6164 | uint32 len= pack_length(); |
6165 | longlong packed= read_bigendian(ptr, len); |
6166 | |
6167 | packed= sec_part_unshift(packed - zero_point, dec); |
6168 | |
6169 | unpack_time(packed, ltime, MYSQL_TIMESTAMP_TIME); |
6170 | return false; |
6171 | } |
6172 | |
6173 | |
6174 | int Field_time_hires::cmp(const uchar *a_ptr, const uchar *b_ptr) |
6175 | { |
6176 | ulonglong a=read_bigendian(a_ptr, Field_time_hires::pack_length()); |
6177 | ulonglong b=read_bigendian(b_ptr, Field_time_hires::pack_length()); |
6178 | return (a < b) ? -1 : (a > b) ? 1 : 0; |
6179 | } |
6180 | |
6181 | void Field_time_hires::sort_string(uchar *to,uint length __attribute__((unused))) |
6182 | { |
6183 | DBUG_ASSERT(length == Field_time_hires::pack_length()); |
6184 | memcpy(to, ptr, length); |
6185 | to[0]^= 128; |
6186 | } |
6187 | |
6188 | void Field_time_with_dec::make_send_field(Send_field *field) |
6189 | { |
6190 | Field::make_send_field(field); |
6191 | field->decimals= dec; |
6192 | } |
6193 | |
6194 | /**************************************************************************** |
6195 | ** time type with fsp (MySQL-5.6 version) |
6196 | ** In string context: HH:MM:SS.FFFFFF |
6197 | ** In number context: HHMMSS.FFFFFF |
6198 | ****************************************************************************/ |
6199 | |
6200 | int Field_timef::reset() |
6201 | { |
6202 | my_time_packed_to_binary(0, ptr, dec); |
6203 | return 0; |
6204 | } |
6205 | |
6206 | void Field_timef::store_TIME(const MYSQL_TIME *ltime) |
6207 | { |
6208 | longlong tmp= TIME_to_longlong_time_packed(ltime); |
6209 | my_time_packed_to_binary(tmp, ptr, dec); |
6210 | } |
6211 | |
6212 | bool Field_timef::get_date(MYSQL_TIME *ltime, ulonglong fuzzydate) |
6213 | { |
6214 | if (check_zero_in_date_with_warn(fuzzydate)) |
6215 | return true; |
6216 | longlong tmp= my_time_packed_from_binary(ptr, dec); |
6217 | TIME_from_longlong_time_packed(ltime, tmp); |
6218 | return false; |
6219 | } |
6220 | |
6221 | /**************************************************************************** |
6222 | ** year type |
6223 | ** Save in a byte the year 0, 1901->2155 |
6224 | ** Can handle 2 byte or 4 byte years! |
6225 | ****************************************************************************/ |
6226 | |
6227 | int Field_year::store(const char *from, size_t len,CHARSET_INFO *cs) |
6228 | { |
6229 | ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; |
6230 | char *end; |
6231 | int error; |
6232 | longlong nr= cs->cset->strntoull10rnd(cs, from, len, 0, &end, &error); |
6233 | |
6234 | if (nr < 0 || (nr >= 100 && nr <= 1900) || nr > 2155 || |
6235 | error == MY_ERRNO_ERANGE) |
6236 | { |
6237 | *ptr=0; |
6238 | set_warning(ER_WARN_DATA_OUT_OF_RANGE, 1); |
6239 | return 1; |
6240 | } |
6241 | if (get_thd()->count_cuted_fields > CHECK_FIELD_EXPRESSION && |
6242 | (error= check_int(cs, from, len, end, error))) |
6243 | { |
6244 | if (unlikely(error == 1) /* empty or incorrect string */) |
6245 | { |
6246 | *ptr= 0; |
6247 | return 1; |
6248 | } |
6249 | error= 1; |
6250 | } |
6251 | |
6252 | if (nr != 0 || len != 4) |
6253 | { |
6254 | if (nr < YY_PART_YEAR) |
6255 | nr+=100; // 2000 - 2069 |
6256 | else if (nr > 1900) |
6257 | nr-= 1900; |
6258 | } |
6259 | *ptr= (char) (uchar) nr; |
6260 | return error; |
6261 | } |
6262 | |
6263 | |
6264 | int Field_year::store(double nr) |
6265 | { |
6266 | if (nr < 0.0 || nr > 2155.0) |
6267 | { |
6268 | (void) Field_year::store((longlong) -1, FALSE); |
6269 | return 1; |
6270 | } |
6271 | return Field_year::store((longlong) nr, FALSE); |
6272 | } |
6273 | |
6274 | |
6275 | int Field_year::store(longlong nr, bool unsigned_val) |
6276 | { |
6277 | ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; |
6278 | if (nr < 0 || (nr >= 100 && nr <= 1900) || nr > 2155) |
6279 | { |
6280 | *ptr= 0; |
6281 | set_warning(ER_WARN_DATA_OUT_OF_RANGE, 1); |
6282 | return 1; |
6283 | } |
6284 | if (nr != 0 || field_length != 4) // 0000 -> 0; 00 -> 2000 |
6285 | { |
6286 | if (nr < YY_PART_YEAR) |
6287 | nr+=100; // 2000 - 2069 |
6288 | else if (nr > 1900) |
6289 | nr-= 1900; |
6290 | } |
6291 | *ptr= (char) (uchar) nr; |
6292 | return 0; |
6293 | } |
6294 | |
6295 | |
6296 | int Field_year::store_time_dec(const MYSQL_TIME *ltime, uint dec_arg) |
6297 | { |
6298 | ErrConvTime str(ltime); |
6299 | if (Field_year::store(ltime->year, 0)) |
6300 | return 1; |
6301 | |
6302 | set_datetime_warning(WARN_DATA_TRUNCATED, &str, ltime->time_type, 1); |
6303 | return 0; |
6304 | } |
6305 | |
6306 | bool Field_year::send_binary(Protocol *protocol) |
6307 | { |
6308 | ASSERT_COLUMN_MARKED_FOR_READ; |
6309 | ulonglong tmp= Field_year::val_int(); |
6310 | return protocol->store_short(tmp); |
6311 | } |
6312 | |
6313 | |
6314 | double Field_year::val_real(void) |
6315 | { |
6316 | return (double) Field_year::val_int(); |
6317 | } |
6318 | |
6319 | |
6320 | longlong Field_year::val_int(void) |
6321 | { |
6322 | ASSERT_COLUMN_MARKED_FOR_READ; |
6323 | DBUG_ASSERT(field_length == 2 || field_length == 4); |
6324 | int tmp= (int) ptr[0]; |
6325 | if (field_length != 4) |
6326 | tmp%=100; // Return last 2 char |
6327 | else if (tmp) |
6328 | tmp+=1900; |
6329 | return (longlong) tmp; |
6330 | } |
6331 | |
6332 | |
6333 | String *Field_year::val_str(String *val_buffer, |
6334 | String *val_ptr __attribute__((unused))) |
6335 | { |
6336 | DBUG_ASSERT(field_length < 5); |
6337 | val_buffer->alloc(5); |
6338 | val_buffer->length(field_length); |
6339 | char *to=(char*) val_buffer->ptr(); |
6340 | sprintf(to,field_length == 2 ? "%02d" : "%04d" ,(int) Field_year::val_int()); |
6341 | val_buffer->set_charset(&my_charset_numeric); |
6342 | return val_buffer; |
6343 | } |
6344 | |
6345 | |
6346 | bool Field_year::get_date(MYSQL_TIME *ltime,ulonglong fuzzydate) |
6347 | { |
6348 | int tmp= (int) ptr[0]; |
6349 | if (tmp || field_length != 4) |
6350 | tmp+= 1900; |
6351 | return int_to_datetime_with_warn(false, tmp * 10000, |
6352 | ltime, fuzzydate, field_name.str); |
6353 | } |
6354 | |
6355 | |
6356 | void Field_year::sql_type(String &res) const |
6357 | { |
6358 | CHARSET_INFO *cs=res.charset(); |
6359 | res.length(cs->cset->snprintf(cs,(char*)res.ptr(),res.alloced_length(), |
6360 | "year(%d)" ,(int) field_length)); |
6361 | } |
6362 | |
6363 | |
6364 | /**************************************************************************** |
6365 | ** date type |
6366 | ** In string context: YYYY-MM-DD |
6367 | ** In number context: YYYYMMDD |
6368 | ** Stored as a 4 byte unsigned int |
6369 | ****************************************************************************/ |
6370 | |
6371 | void Field_date::store_TIME(MYSQL_TIME *ltime) |
6372 | { |
6373 | uint tmp= ltime->year*10000L + ltime->month*100+ltime->day; |
6374 | int4store(ptr,tmp); |
6375 | } |
6376 | |
6377 | bool Field_date::send_binary(Protocol *protocol) |
6378 | { |
6379 | longlong tmp= Field_date::val_int(); |
6380 | MYSQL_TIME tm; |
6381 | tm.year= (uint32) tmp/10000L % 10000; |
6382 | tm.month= (uint32) tmp/100 % 100; |
6383 | tm.day= (uint32) tmp % 100; |
6384 | return protocol->store_date(&tm); |
6385 | } |
6386 | |
6387 | |
6388 | double Field_date::val_real(void) |
6389 | { |
6390 | ASSERT_COLUMN_MARKED_FOR_READ; |
6391 | int32 j; |
6392 | j=sint4korr(ptr); |
6393 | return (double) (uint32) j; |
6394 | } |
6395 | |
6396 | |
6397 | longlong Field_date::val_int(void) |
6398 | { |
6399 | ASSERT_COLUMN_MARKED_FOR_READ; |
6400 | int32 j; |
6401 | j=sint4korr(ptr); |
6402 | return (longlong) (uint32) j; |
6403 | } |
6404 | |
6405 | |
6406 | bool Field_date::get_TIME(MYSQL_TIME *ltime, const uchar *pos, |
6407 | ulonglong fuzzydate) const |
6408 | { |
6409 | ASSERT_COLUMN_MARKED_FOR_READ; |
6410 | int32 tmp= sint4korr(pos); |
6411 | ltime->year= (int) ((uint32) tmp/10000L % 10000); |
6412 | ltime->month= (int) ((uint32) tmp/100 % 100); |
6413 | ltime->day= (int) ((uint32) tmp % 100); |
6414 | ltime->time_type= MYSQL_TIMESTAMP_DATE; |
6415 | ltime->hour= ltime->minute= ltime->second= ltime->second_part= ltime->neg= 0; |
6416 | return validate_MMDD(tmp, ltime->month, ltime->day, fuzzydate); |
6417 | } |
6418 | |
6419 | |
6420 | String *Field_date::val_str(String *val_buffer, |
6421 | String *val_ptr __attribute__((unused))) |
6422 | { |
6423 | MYSQL_TIME ltime; |
6424 | get_TIME(<ime, ptr, 0); |
6425 | val_buffer->alloc(MAX_DATE_STRING_REP_LENGTH); |
6426 | uint length= (uint) my_date_to_str(<ime, |
6427 | const_cast<char*>(val_buffer->ptr())); |
6428 | val_buffer->length(length); |
6429 | val_buffer->set_charset(&my_charset_numeric); |
6430 | |
6431 | return val_buffer; |
6432 | } |
6433 | |
6434 | |
6435 | int Field_date::cmp(const uchar *a_ptr, const uchar *b_ptr) |
6436 | { |
6437 | int32 a,b; |
6438 | a=sint4korr(a_ptr); |
6439 | b=sint4korr(b_ptr); |
6440 | return ((uint32) a < (uint32) b) ? -1 : ((uint32) a > (uint32) b) ? 1 : 0; |
6441 | } |
6442 | |
6443 | |
6444 | void Field_date::sort_string(uchar *to,uint length __attribute__((unused))) |
6445 | { |
6446 | to[0] = ptr[3]; |
6447 | to[1] = ptr[2]; |
6448 | to[2] = ptr[1]; |
6449 | to[3] = ptr[0]; |
6450 | } |
6451 | |
6452 | void Field_date::sql_type(String &res) const |
6453 | { |
6454 | res.set_ascii(STRING_WITH_LEN("date" )); |
6455 | } |
6456 | |
6457 | |
6458 | /**************************************************************************** |
6459 | ** The new date type |
6460 | ** This is identical to the old date type, but stored on 3 bytes instead of 4 |
6461 | ** In number context: YYYYMMDD |
6462 | ****************************************************************************/ |
6463 | |
6464 | void Field_newdate::store_TIME(MYSQL_TIME *ltime) |
6465 | { |
6466 | uint tmp= ltime->year*16*32 + ltime->month*32+ltime->day; |
6467 | int3store(ptr,tmp); |
6468 | } |
6469 | |
6470 | |
6471 | bool Field_newdate::send_binary(Protocol *protocol) |
6472 | { |
6473 | MYSQL_TIME tm; |
6474 | Field_newdate::get_date(&tm,0); |
6475 | return protocol->store_date(&tm); |
6476 | } |
6477 | |
6478 | |
6479 | double Field_newdate::val_real(void) |
6480 | { |
6481 | ASSERT_COLUMN_MARKED_FOR_READ; |
6482 | return (double) Field_newdate::val_int(); |
6483 | } |
6484 | |
6485 | |
6486 | longlong Field_newdate::val_int(void) |
6487 | { |
6488 | ASSERT_COLUMN_MARKED_FOR_READ; |
6489 | ulong j= uint3korr(ptr); |
6490 | j= (j % 32L)+(j / 32L % 16L)*100L + (j/(16L*32L))*10000L; |
6491 | return (longlong) j; |
6492 | } |
6493 | |
6494 | |
6495 | String *Field_newdate::val_str(String *val_buffer, |
6496 | String *val_ptr __attribute__((unused))) |
6497 | { |
6498 | ASSERT_COLUMN_MARKED_FOR_READ; |
6499 | val_buffer->alloc(field_length); |
6500 | val_buffer->length(field_length); |
6501 | uint32 tmp=(uint32) uint3korr(ptr); |
6502 | int part; |
6503 | char *pos=(char*) val_buffer->ptr()+10; |
6504 | |
6505 | /* Open coded to get more speed */ |
6506 | *pos--=0; // End NULL |
6507 | part=(int) (tmp & 31); |
6508 | *pos--= (char) ('0'+part%10); |
6509 | *pos--= (char) ('0'+part/10); |
6510 | *pos--= '-'; |
6511 | part=(int) (tmp >> 5 & 15); |
6512 | *pos--= (char) ('0'+part%10); |
6513 | *pos--= (char) ('0'+part/10); |
6514 | *pos--= '-'; |
6515 | part=(int) (tmp >> 9); |
6516 | *pos--= (char) ('0'+part%10); part/=10; |
6517 | *pos--= (char) ('0'+part%10); part/=10; |
6518 | *pos--= (char) ('0'+part%10); part/=10; |
6519 | *pos= (char) ('0'+part); |
6520 | val_buffer->set_charset(&my_charset_numeric); |
6521 | return val_buffer; |
6522 | } |
6523 | |
6524 | |
6525 | bool Field_newdate::get_TIME(MYSQL_TIME *ltime, const uchar *pos, |
6526 | ulonglong fuzzydate) const |
6527 | { |
6528 | ASSERT_COLUMN_MARKED_FOR_READ; |
6529 | uint32 tmp=(uint32) uint3korr(pos); |
6530 | ltime->day= tmp & 31; |
6531 | ltime->month= (tmp >> 5) & 15; |
6532 | ltime->year= (tmp >> 9); |
6533 | ltime->time_type= MYSQL_TIMESTAMP_DATE; |
6534 | ltime->hour= ltime->minute= ltime->second= ltime->second_part= ltime->neg= 0; |
6535 | return validate_MMDD(tmp, ltime->month, ltime->day, fuzzydate); |
6536 | } |
6537 | |
6538 | |
6539 | int Field_newdate::cmp(const uchar *a_ptr, const uchar *b_ptr) |
6540 | { |
6541 | uint32 a,b; |
6542 | a=(uint32) uint3korr(a_ptr); |
6543 | b=(uint32) uint3korr(b_ptr); |
6544 | return (a < b) ? -1 : (a > b) ? 1 : 0; |
6545 | } |
6546 | |
6547 | |
6548 | void Field_newdate::sort_string(uchar *to,uint length __attribute__((unused))) |
6549 | { |
6550 | to[0] = ptr[2]; |
6551 | to[1] = ptr[1]; |
6552 | to[2] = ptr[0]; |
6553 | } |
6554 | |
6555 | |
6556 | void Field_newdate::sql_type(String &res) const |
6557 | { |
6558 | res.set_ascii(STRING_WITH_LEN("date" )); |
6559 | } |
6560 | |
6561 | |
6562 | Item *Field_newdate::get_equal_const_item(THD *thd, const Context &ctx, |
6563 | Item *const_item) |
6564 | { |
6565 | switch (ctx.subst_constraint()) { |
6566 | case ANY_SUBST: |
6567 | if (!is_temporal_type_with_date(const_item->field_type())) |
6568 | { |
6569 | // Get the value of const_item with conversion from TIME to DATETIME |
6570 | Datetime dt(thd, const_item, TIME_FUZZY_DATES | TIME_INVALID_DATES); |
6571 | if (!dt.is_valid_datetime()) |
6572 | return NULL; |
6573 | /* |
6574 | Replace the constant to a DATE or DATETIME constant. |
6575 | Example: |
6576 | WHERE LENGTH(date_column)=10 |
6577 | AND date_column=TIME'10:20:30'; |
6578 | to: |
6579 | WHERE LENGTH(date_column)=10 |
6580 | AND date_column=TIMESTAMP'2015-08-30 10:20:30' |
6581 | |
6582 | (assuming CURRENT_DATE is '2015-08-30' |
6583 | */ |
6584 | if (!dt.hhmmssff_is_zero()) |
6585 | return new (thd->mem_root) |
6586 | Item_datetime_literal_for_invalid_dates(thd, dt.get_mysql_time(), |
6587 | dt.get_mysql_time()-> |
6588 | second_part ? |
6589 | TIME_SECOND_PART_DIGITS : 0); |
6590 | return new (thd->mem_root) |
6591 | Item_date_literal_for_invalid_dates(thd, Date(&dt).get_mysql_time()); |
6592 | } |
6593 | break; |
6594 | case IDENTITY_SUBST: |
6595 | if (const_item->field_type() != MYSQL_TYPE_DATE) |
6596 | { |
6597 | Date d(thd, const_item, 0); |
6598 | if (!d.is_valid_date()) |
6599 | return NULL; |
6600 | return new (thd->mem_root) Item_date_literal(thd, d.get_mysql_time()); |
6601 | } |
6602 | break; |
6603 | } |
6604 | return const_item; |
6605 | } |
6606 | |
6607 | |
6608 | /**************************************************************************** |
6609 | ** datetime type |
6610 | ** In string context: YYYY-MM-DD HH:MM:DD |
6611 | ** In number context: YYYYMMDDHHMMDD |
6612 | ** Stored as a 8 byte unsigned int. Should sometimes be change to a 6 byte int. |
6613 | ****************************************************************************/ |
6614 | |
6615 | void Field_datetime::store_TIME(MYSQL_TIME *ltime) |
6616 | { |
6617 | ulonglong tmp= TIME_to_ulonglong_datetime(ltime); |
6618 | int8store(ptr,tmp); |
6619 | } |
6620 | |
6621 | bool Field_datetime::send_binary(Protocol *protocol) |
6622 | { |
6623 | MYSQL_TIME tm; |
6624 | Field_datetime::get_date(&tm, 0); |
6625 | return protocol->store(&tm, 0); |
6626 | } |
6627 | |
6628 | |
6629 | double Field_datetime::val_real(void) |
6630 | { |
6631 | return (double) Field_datetime::val_int(); |
6632 | } |
6633 | |
6634 | longlong Field_datetime::val_int(void) |
6635 | { |
6636 | ASSERT_COLUMN_MARKED_FOR_READ; |
6637 | longlong j; |
6638 | j=sint8korr(ptr); |
6639 | return j; |
6640 | } |
6641 | |
6642 | |
6643 | String *Field_datetime::val_str(String *val_buffer, |
6644 | String *val_ptr __attribute__((unused))) |
6645 | { |
6646 | val_buffer->alloc(field_length); |
6647 | val_buffer->length(field_length); |
6648 | |
6649 | ASSERT_COLUMN_MARKED_FOR_READ; |
6650 | ulonglong tmp; |
6651 | long part1,part2; |
6652 | char *pos; |
6653 | int part3; |
6654 | |
6655 | tmp= Field_datetime::val_int(); |
6656 | |
6657 | /* |
6658 | Avoid problem with slow longlong arithmetic and sprintf |
6659 | */ |
6660 | |
6661 | part1=(long) (tmp/1000000LL); |
6662 | part2=(long) (tmp - (ulonglong) part1*1000000LL); |
6663 | |
6664 | pos=(char*) val_buffer->ptr() + MAX_DATETIME_WIDTH; |
6665 | *pos--=0; |
6666 | *pos--= (char) ('0'+(char) (part2%10)); part2/=10; |
6667 | *pos--= (char) ('0'+(char) (part2%10)); part3= (int) (part2 / 10); |
6668 | *pos--= ':'; |
6669 | *pos--= (char) ('0'+(char) (part3%10)); part3/=10; |
6670 | *pos--= (char) ('0'+(char) (part3%10)); part3/=10; |
6671 | *pos--= ':'; |
6672 | *pos--= (char) ('0'+(char) (part3%10)); part3/=10; |
6673 | *pos--= (char) ('0'+(char) part3); |
6674 | *pos--= ' '; |
6675 | *pos--= (char) ('0'+(char) (part1%10)); part1/=10; |
6676 | *pos--= (char) ('0'+(char) (part1%10)); part1/=10; |
6677 | *pos--= '-'; |
6678 | *pos--= (char) ('0'+(char) (part1%10)); part1/=10; |
6679 | *pos--= (char) ('0'+(char) (part1%10)); part3= (int) (part1/10); |
6680 | *pos--= '-'; |
6681 | *pos--= (char) ('0'+(char) (part3%10)); part3/=10; |
6682 | *pos--= (char) ('0'+(char) (part3%10)); part3/=10; |
6683 | *pos--= (char) ('0'+(char) (part3%10)); part3/=10; |
6684 | *pos=(char) ('0'+(char) part3); |
6685 | val_buffer->set_charset(&my_charset_numeric); |
6686 | return val_buffer; |
6687 | } |
6688 | |
6689 | bool Field_datetime::get_TIME(MYSQL_TIME *ltime, const uchar *pos, |
6690 | ulonglong fuzzydate) const |
6691 | { |
6692 | ASSERT_COLUMN_MARKED_FOR_READ; |
6693 | longlong tmp= sint8korr(pos); |
6694 | uint32 part1,part2; |
6695 | part1=(uint32) (tmp/1000000LL); |
6696 | part2=(uint32) (tmp - (ulonglong) part1*1000000LL); |
6697 | |
6698 | ltime->time_type= MYSQL_TIMESTAMP_DATETIME; |
6699 | ltime->neg= 0; |
6700 | ltime->second_part= 0; |
6701 | ltime->second= (int) (part2%100); |
6702 | ltime->minute= (int) (part2/100%100); |
6703 | ltime->hour= (int) (part2/10000); |
6704 | ltime->day= (int) (part1%100); |
6705 | ltime->month= (int) (part1/100%100); |
6706 | ltime->year= (int) (part1/10000); |
6707 | return validate_MMDD(tmp, ltime->month, ltime->day, fuzzydate); |
6708 | } |
6709 | |
6710 | |
6711 | int Field_datetime::cmp(const uchar *a_ptr, const uchar *b_ptr) |
6712 | { |
6713 | longlong a,b; |
6714 | a=sint8korr(a_ptr); |
6715 | b=sint8korr(b_ptr); |
6716 | return ((ulonglong) a < (ulonglong) b) ? -1 : |
6717 | ((ulonglong) a > (ulonglong) b) ? 1 : 0; |
6718 | } |
6719 | |
6720 | void Field_datetime::sort_string(uchar *to,uint length __attribute__((unused))) |
6721 | { |
6722 | to[0] = ptr[7]; |
6723 | to[1] = ptr[6]; |
6724 | to[2] = ptr[5]; |
6725 | to[3] = ptr[4]; |
6726 | to[4] = ptr[3]; |
6727 | to[5] = ptr[2]; |
6728 | to[6] = ptr[1]; |
6729 | to[7] = ptr[0]; |
6730 | } |
6731 | |
6732 | |
6733 | void Field_datetime::sql_type(String &res) const |
6734 | { |
6735 | if (decimals() == 0) |
6736 | { |
6737 | res.set_ascii(STRING_WITH_LEN("datetime" )); |
6738 | return; |
6739 | } |
6740 | CHARSET_INFO *cs= res.charset(); |
6741 | res.length(cs->cset->snprintf(cs, (char*) res.ptr(), res.alloced_length(), |
6742 | "datetime(%u)" , decimals())); |
6743 | } |
6744 | |
6745 | |
6746 | int Field_datetime::set_time() |
6747 | { |
6748 | THD *thd= table->in_use; |
6749 | MYSQL_TIME now_time; |
6750 | thd->variables.time_zone->gmt_sec_to_TIME(&now_time, thd->query_start()); |
6751 | now_time.second_part= thd->query_start_sec_part(); |
6752 | set_notnull(); |
6753 | store_TIME(&now_time); |
6754 | thd->time_zone_used= 1; |
6755 | return 0; |
6756 | } |
6757 | |
6758 | |
6759 | void Field_datetime_hires::store_TIME(MYSQL_TIME *ltime) |
6760 | { |
6761 | ulonglong packed= sec_part_shift(pack_time(ltime), dec); |
6762 | store_bigendian(packed, ptr, Field_datetime_hires::pack_length()); |
6763 | } |
6764 | |
6765 | int Field_temporal_with_date::store_decimal(const my_decimal *d) |
6766 | { |
6767 | ulonglong nr; |
6768 | ulong sec_part; |
6769 | int error; |
6770 | MYSQL_TIME ltime; |
6771 | longlong tmp; |
6772 | THD *thd= get_thd(); |
6773 | ErrConvDecimal str(d); |
6774 | |
6775 | if (my_decimal2seconds(d, &nr, &sec_part)) |
6776 | { |
6777 | tmp= -1; |
6778 | error= 2; |
6779 | } |
6780 | else |
6781 | tmp= number_to_datetime(nr, sec_part, <ime, sql_mode_for_dates(thd), |
6782 | &error); |
6783 | |
6784 | return store_TIME_with_warning(<ime, &str, error, tmp != -1); |
6785 | } |
6786 | |
6787 | bool Field_datetime_with_dec::send_binary(Protocol *protocol) |
6788 | { |
6789 | MYSQL_TIME ltime; |
6790 | get_date(<ime, 0); |
6791 | return protocol->store(<ime, dec); |
6792 | } |
6793 | |
6794 | |
6795 | double Field_datetime_with_dec::val_real(void) |
6796 | { |
6797 | MYSQL_TIME ltime; |
6798 | get_date(<ime, 0); |
6799 | return TIME_to_double(<ime); |
6800 | } |
6801 | |
6802 | longlong Field_datetime_with_dec::val_int(void) |
6803 | { |
6804 | MYSQL_TIME ltime; |
6805 | get_date(<ime, 0); |
6806 | return TIME_to_ulonglong_datetime(<ime); |
6807 | } |
6808 | |
6809 | |
6810 | String *Field_datetime_with_dec::val_str(String *str, |
6811 | String *unused __attribute__((unused))) |
6812 | { |
6813 | MYSQL_TIME ltime; |
6814 | get_date(<ime, 0); |
6815 | str->alloc(field_length+1); |
6816 | str->length(field_length); |
6817 | my_datetime_to_str(<ime, (char*) str->ptr(), dec); |
6818 | str->set_charset(&my_charset_numeric); |
6819 | return str; |
6820 | } |
6821 | |
6822 | |
6823 | bool Field_datetime_hires::get_TIME(MYSQL_TIME *ltime, const uchar *pos, |
6824 | ulonglong fuzzydate) const |
6825 | { |
6826 | ASSERT_COLUMN_MARKED_FOR_READ; |
6827 | ulonglong packed= read_bigendian(pos, Field_datetime_hires::pack_length()); |
6828 | unpack_time(sec_part_unshift(packed, dec), ltime, MYSQL_TIMESTAMP_DATETIME); |
6829 | return validate_MMDD(packed, ltime->month, ltime->day, fuzzydate); |
6830 | } |
6831 | |
6832 | |
6833 | int Field_datetime_hires::cmp(const uchar *a_ptr, const uchar *b_ptr) |
6834 | { |
6835 | ulonglong a=read_bigendian(a_ptr, Field_datetime_hires::pack_length()); |
6836 | ulonglong b=read_bigendian(b_ptr, Field_datetime_hires::pack_length()); |
6837 | return a < b ? -1 : a > b ? 1 : 0; |
6838 | } |
6839 | |
6840 | void Field_datetime_with_dec::make_send_field(Send_field *field) |
6841 | { |
6842 | Field::make_send_field(field); |
6843 | field->decimals= dec; |
6844 | } |
6845 | |
6846 | |
6847 | /**************************************************************************** |
6848 | ** MySQL-5.6 compatible DATETIME(N) |
6849 | ** |
6850 | ****************************************************************************/ |
6851 | int Field_datetimef::reset() |
6852 | { |
6853 | my_datetime_packed_to_binary(0, ptr, dec); |
6854 | return 0; |
6855 | } |
6856 | |
6857 | void Field_datetimef::store_TIME(MYSQL_TIME *ltime) |
6858 | { |
6859 | my_time_trunc(ltime, decimals()); |
6860 | longlong tmp= TIME_to_longlong_datetime_packed(ltime); |
6861 | my_datetime_packed_to_binary(tmp, ptr, dec); |
6862 | } |
6863 | |
6864 | bool Field_datetimef::get_TIME(MYSQL_TIME *ltime, const uchar *pos, |
6865 | ulonglong fuzzydate) const |
6866 | { |
6867 | ASSERT_COLUMN_MARKED_FOR_READ; |
6868 | longlong tmp= my_datetime_packed_from_binary(pos, dec); |
6869 | TIME_from_longlong_datetime_packed(ltime, tmp); |
6870 | return validate_MMDD(tmp, ltime->month, ltime->day, fuzzydate); |
6871 | } |
6872 | |
6873 | /**************************************************************************** |
6874 | ** string type |
6875 | ** A string may be varchar or binary |
6876 | ****************************************************************************/ |
6877 | |
6878 | /* |
6879 | Report "not well formed" or "cannot convert" error |
6880 | after storing a character string info a field. |
6881 | |
6882 | SYNOPSIS |
6883 | check_string_copy_error() |
6884 | copier - the conversion status |
6885 | end - the very end of the source string |
6886 | that was just copied |
6887 | cs - character set of the string |
6888 | |
6889 | NOTES |
6890 | As of version 5.0 both cases return the same error: |
6891 | |
6892 | "Invalid string value: 'xxx' for column 't' at row 1" |
6893 | |
6894 | Future versions will possibly introduce a new error message: |
6895 | |
6896 | "Cannot convert character string: 'xxx' for column 't' at row 1" |
6897 | |
6898 | RETURN |
6899 | FALSE - If errors didn't happen |
6900 | TRUE - If an error happened |
6901 | */ |
6902 | |
6903 | bool |
6904 | Field_longstr::check_string_copy_error(const String_copier *copier, |
6905 | const char *end, |
6906 | CHARSET_INFO *cs) |
6907 | { |
6908 | const char *pos; |
6909 | char tmp[32]; |
6910 | |
6911 | if (likely(!(pos= copier->most_important_error_pos()))) |
6912 | return FALSE; |
6913 | |
6914 | convert_to_printable(tmp, sizeof(tmp), pos, (end - pos), cs, 6); |
6915 | set_warning_truncated_wrong_value("string" , tmp); |
6916 | return TRUE; |
6917 | } |
6918 | |
6919 | |
6920 | /* |
6921 | Check if we lost any important data and send a truncation error/warning |
6922 | |
6923 | SYNOPSIS |
6924 | Field_longstr::report_if_important_data() |
6925 | pstr - Truncated rest of string |
6926 | end - End of truncated string |
6927 | count_spaces - Treat traling spaces as important data |
6928 | |
6929 | RETURN VALUES |
6930 | 0 - None was truncated (or we don't count cut fields) |
6931 | 2 - Some bytes was truncated |
6932 | |
6933 | NOTE |
6934 | Check if we lost any important data (anything in a binary string, |
6935 | or any non-space in others). If only trailing spaces was lost, |
6936 | send a truncation note, otherwise send a truncation error. |
6937 | Silently ignore traling spaces if the count_space parameter is FALSE. |
6938 | */ |
6939 | |
6940 | int |
6941 | Field_longstr::report_if_important_data(const char *pstr, const char *end, |
6942 | bool count_spaces) |
6943 | { |
6944 | THD *thd= get_thd(); |
6945 | if ((pstr < end) && thd->count_cuted_fields > CHECK_FIELD_EXPRESSION) |
6946 | { |
6947 | if (test_if_important_data(field_charset, pstr, end)) |
6948 | { |
6949 | if (thd->abort_on_warning) |
6950 | set_warning(ER_DATA_TOO_LONG, 1); |
6951 | else |
6952 | set_warning(WARN_DATA_TRUNCATED, 1); |
6953 | return 2; |
6954 | } |
6955 | else if (count_spaces) |
6956 | { /* If we lost only spaces then produce a NOTE, not a WARNING */ |
6957 | set_note(WARN_DATA_TRUNCATED, 1); |
6958 | return 2; |
6959 | } |
6960 | } |
6961 | return 0; |
6962 | } |
6963 | |
6964 | |
6965 | /* Copy a string and fill with space */ |
6966 | |
6967 | int Field_string::store(const char *from, size_t length,CHARSET_INFO *cs) |
6968 | { |
6969 | ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; |
6970 | uint copy_length; |
6971 | int rc; |
6972 | |
6973 | /* See the comment for Field_long::store(long long) */ |
6974 | DBUG_ASSERT(!table || table->in_use == current_thd); |
6975 | |
6976 | rc= well_formed_copy_with_check((char*) ptr, field_length, |
6977 | cs, from, length, |
6978 | field_length / field_charset->mbmaxlen, |
6979 | false, ©_length); |
6980 | |
6981 | /* Append spaces if the string was shorter than the field. */ |
6982 | if (copy_length < field_length) |
6983 | field_charset->cset->fill(field_charset,(char*) ptr+copy_length, |
6984 | field_length-copy_length, |
6985 | field_charset->pad_char); |
6986 | |
6987 | return rc; |
6988 | } |
6989 | |
6990 | |
6991 | int Field_str::store(longlong nr, bool unsigned_val) |
6992 | { |
6993 | char buff[64]; |
6994 | uint length; |
6995 | length= (uint) (field_charset->cset->longlong10_to_str)(field_charset, |
6996 | buff, |
6997 | sizeof(buff), |
6998 | (unsigned_val ? 10: |
6999 | -10), |
7000 | nr); |
7001 | return store(buff, length, field_charset); |
7002 | } |
7003 | |
7004 | |
7005 | /** |
7006 | Store double value in Field_string or Field_varstring. |
7007 | |
7008 | Pretty prints double number into field_length characters buffer. |
7009 | |
7010 | @param nr number |
7011 | */ |
7012 | |
7013 | int Field_str::store(double nr) |
7014 | { |
7015 | ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; |
7016 | char buff[DOUBLE_TO_STRING_CONVERSION_BUFFER_SIZE]; |
7017 | uint local_char_length= MY_MIN(sizeof(buff), |
7018 | field_length / field_charset->mbmaxlen); |
7019 | size_t length= 0; |
7020 | my_bool error= (local_char_length == 0); |
7021 | |
7022 | // my_gcvt() requires width > 0, and we may have a CHAR(0) column. |
7023 | if (likely(!error)) |
7024 | length= my_gcvt(nr, MY_GCVT_ARG_DOUBLE, local_char_length, buff, &error); |
7025 | |
7026 | if (unlikely(error)) |
7027 | { |
7028 | if (get_thd()->abort_on_warning) |
7029 | set_warning(ER_DATA_TOO_LONG, 1); |
7030 | else |
7031 | set_warning(WARN_DATA_TRUNCATED, 1); |
7032 | } |
7033 | return store(buff, (uint)length, &my_charset_numeric); |
7034 | } |
7035 | |
7036 | uint Field::is_equal(Create_field *new_field) |
7037 | { |
7038 | return new_field->type_handler() == type_handler(); |
7039 | } |
7040 | |
7041 | |
7042 | uint Field_str::is_equal(Create_field *new_field) |
7043 | { |
7044 | return new_field->type_handler() == type_handler() && |
7045 | new_field->charset == field_charset && |
7046 | new_field->length == max_display_length(); |
7047 | } |
7048 | |
7049 | |
7050 | int Field_longstr::store_decimal(const my_decimal *d) |
7051 | { |
7052 | char buff[DECIMAL_MAX_STR_LENGTH+1]; |
7053 | String str(buff, sizeof(buff), &my_charset_numeric); |
7054 | my_decimal2string(E_DEC_FATAL_ERROR, d, 0, 0, 0, &str); |
7055 | return store(str.ptr(), str.length(), str.charset()); |
7056 | } |
7057 | |
7058 | uint32 Field_longstr::max_data_length() const |
7059 | { |
7060 | return field_length + (field_length > 255 ? 2 : 1); |
7061 | } |
7062 | |
7063 | |
7064 | bool |
7065 | Field_longstr::cmp_to_string_with_same_collation(const Item_bool_func *cond, |
7066 | const Item *item) const |
7067 | { |
7068 | return item->cmp_type() == STRING_RESULT && |
7069 | charset() == cond->compare_collation(); |
7070 | } |
7071 | |
7072 | |
7073 | bool |
7074 | Field_longstr::cmp_to_string_with_stricter_collation(const Item_bool_func *cond, |
7075 | const Item *item) const |
7076 | { |
7077 | return item->cmp_type() == STRING_RESULT && |
7078 | (charset() == cond->compare_collation() || |
7079 | cond->compare_collation()->state & MY_CS_BINSORT); |
7080 | } |
7081 | |
7082 | |
7083 | bool Field_longstr::can_optimize_keypart_ref(const Item_bool_func *cond, |
7084 | const Item *item) const |
7085 | { |
7086 | DBUG_ASSERT(cmp_type() == STRING_RESULT); |
7087 | return cmp_to_string_with_stricter_collation(cond, item); |
7088 | } |
7089 | |
7090 | |
7091 | bool Field_longstr::can_optimize_hash_join(const Item_bool_func *cond, |
7092 | const Item *item) const |
7093 | { |
7094 | DBUG_ASSERT(cmp_type() == STRING_RESULT); |
7095 | return cmp_to_string_with_same_collation(cond, item); |
7096 | } |
7097 | |
7098 | |
7099 | bool Field_longstr::can_optimize_group_min_max(const Item_bool_func *cond, |
7100 | const Item *const_item) const |
7101 | { |
7102 | /* |
7103 | Can't use indexes when comparing a string to a number or a date |
7104 | Don't use an index when comparing strings of different collations. |
7105 | */ |
7106 | DBUG_ASSERT(cmp_type() == STRING_RESULT); |
7107 | return cmp_to_string_with_same_collation(cond, const_item); |
7108 | } |
7109 | |
7110 | |
7111 | bool Field_longstr::can_optimize_range(const Item_bool_func *cond, |
7112 | const Item *item, |
7113 | bool is_eq_func) const |
7114 | { |
7115 | return is_eq_func ? |
7116 | cmp_to_string_with_stricter_collation(cond, item) : |
7117 | cmp_to_string_with_same_collation(cond, item); |
7118 | } |
7119 | |
7120 | |
7121 | /** |
7122 | This overrides the default behavior of the parent constructor |
7123 | Warn_filter(thd) to suppress notes about trailing spaces in case of CHAR(N), |
7124 | as they are truncated during val_str(). |
7125 | We still do want truncation notes in case of BINARY(N), |
7126 | as trailing spaces are not truncated in val_str(). |
7127 | */ |
7128 | Field_string::Warn_filter_string::Warn_filter_string(const THD *thd, |
7129 | const Field_string *field) |
7130 | :Warn_filter(!thd->no_errors, |
7131 | !thd->no_errors && |
7132 | field->Field_string::charset() == &my_charset_bin) |
7133 | { } |
7134 | |
7135 | |
7136 | double Field_string::val_real(void) |
7137 | { |
7138 | ASSERT_COLUMN_MARKED_FOR_READ; |
7139 | THD *thd= get_thd(); |
7140 | return Converter_strntod_with_warn(get_thd(), |
7141 | Warn_filter_string(thd, this), |
7142 | Field_string::charset(), |
7143 | (const char *) ptr, |
7144 | field_length).result(); |
7145 | } |
7146 | |
7147 | |
7148 | longlong Field_string::val_int(void) |
7149 | { |
7150 | ASSERT_COLUMN_MARKED_FOR_READ; |
7151 | THD *thd= get_thd(); |
7152 | return Converter_strntoll_with_warn(thd, Warn_filter_string(thd, this), |
7153 | Field_string::charset(), |
7154 | (const char *) ptr, |
7155 | field_length).result(); |
7156 | } |
7157 | |
7158 | |
7159 | String *Field_string::val_str(String *val_buffer __attribute__((unused)), |
7160 | String *val_ptr) |
7161 | { |
7162 | ASSERT_COLUMN_MARKED_FOR_READ; |
7163 | /* See the comment for Field_long::store(long long) */ |
7164 | DBUG_ASSERT(!table || table->in_use == current_thd); |
7165 | size_t length; |
7166 | if (get_thd()->variables.sql_mode & |
7167 | MODE_PAD_CHAR_TO_FULL_LENGTH) |
7168 | length= my_charpos(field_charset, ptr, ptr + field_length, |
7169 | field_length / field_charset->mbmaxlen); |
7170 | else |
7171 | length= field_charset->cset->lengthsp(field_charset, (const char*) ptr, |
7172 | field_length); |
7173 | val_ptr->set((const char*) ptr, length, field_charset); |
7174 | return val_ptr; |
7175 | } |
7176 | |
7177 | |
7178 | my_decimal *Field_string::val_decimal(my_decimal *decimal_value) |
7179 | { |
7180 | ASSERT_COLUMN_MARKED_FOR_READ; |
7181 | THD *thd= get_thd(); |
7182 | Converter_str2my_decimal_with_warn(thd, |
7183 | Warn_filter_string(thd, this), |
7184 | E_DEC_FATAL_ERROR, |
7185 | Field_string::charset(), |
7186 | (const char *) ptr, |
7187 | field_length, decimal_value); |
7188 | return decimal_value; |
7189 | } |
7190 | |
7191 | |
7192 | struct Check_field_param { |
7193 | Field *field; |
7194 | }; |
7195 | |
7196 | #ifdef HAVE_REPLICATION |
7197 | static bool |
7198 | check_field_for_37426(const void *param_arg) |
7199 | { |
7200 | Check_field_param *param= (Check_field_param*) param_arg; |
7201 | DBUG_ASSERT(param->field->real_type() == MYSQL_TYPE_STRING); |
7202 | DBUG_PRINT("debug" , ("Field %s - type: %d, size: %d" , |
7203 | param->field->field_name.str, |
7204 | param->field->real_type(), |
7205 | param->field->row_pack_length())); |
7206 | return param->field->row_pack_length() > 255; |
7207 | } |
7208 | #endif |
7209 | |
7210 | bool |
7211 | Field_string::compatible_field_size(uint field_metadata, |
7212 | Relay_log_info *rli_arg, |
7213 | uint16 mflags __attribute__((unused)), |
7214 | int *order_var) |
7215 | { |
7216 | #ifdef HAVE_REPLICATION |
7217 | const Check_field_param check_param = { this }; |
7218 | if (rpl_master_has_bug(rli_arg, 37426, TRUE, |
7219 | check_field_for_37426, &check_param)) |
7220 | return FALSE; // Not compatible field sizes |
7221 | #endif |
7222 | return Field::compatible_field_size(field_metadata, rli_arg, mflags, order_var); |
7223 | } |
7224 | |
7225 | |
7226 | int Field_string::cmp(const uchar *a_ptr, const uchar *b_ptr) |
7227 | { |
7228 | size_t a_len, b_len; |
7229 | |
7230 | if (field_charset->mbmaxlen != 1) |
7231 | { |
7232 | size_t char_len= field_length/field_charset->mbmaxlen; |
7233 | a_len= my_charpos(field_charset, a_ptr, a_ptr + field_length, char_len); |
7234 | b_len= my_charpos(field_charset, b_ptr, b_ptr + field_length, char_len); |
7235 | } |
7236 | else |
7237 | a_len= b_len= field_length; |
7238 | /* |
7239 | We have to remove end space to be able to compare multi-byte-characters |
7240 | like in latin_de 'ae' and 0xe4 |
7241 | */ |
7242 | return field_charset->coll->strnncollsp(field_charset, |
7243 | a_ptr, a_len, |
7244 | b_ptr, b_len); |
7245 | } |
7246 | |
7247 | |
7248 | void Field_string::sort_string(uchar *to,uint length) |
7249 | { |
7250 | IF_DBUG(size_t tmp= ,) |
7251 | field_charset->coll->strnxfrm(field_charset, |
7252 | to, length, |
7253 | char_length() * |
7254 | field_charset->strxfrm_multiply, |
7255 | ptr, field_length, |
7256 | MY_STRXFRM_PAD_WITH_SPACE | |
7257 | MY_STRXFRM_PAD_TO_MAXLEN); |
7258 | DBUG_ASSERT(tmp == length); |
7259 | } |
7260 | |
7261 | |
7262 | void Field_string::sql_type(String &res) const |
7263 | { |
7264 | THD *thd= table->in_use; |
7265 | CHARSET_INFO *cs=res.charset(); |
7266 | size_t length; |
7267 | |
7268 | length= cs->cset->snprintf(cs,(char*) res.ptr(), |
7269 | res.alloced_length(), "%s(%d)" , |
7270 | (type() == MYSQL_TYPE_VAR_STRING ? |
7271 | (has_charset() ? "varchar" : "varbinary" ) : |
7272 | (has_charset() ? "char" : "binary" )), |
7273 | (int) field_length / charset()->mbmaxlen); |
7274 | res.length(length); |
7275 | if ((thd->variables.sql_mode & (MODE_MYSQL323 | MODE_MYSQL40)) && |
7276 | has_charset() && (charset()->state & MY_CS_BINSORT)) |
7277 | res.append(STRING_WITH_LEN(" binary" )); |
7278 | } |
7279 | |
7280 | |
7281 | uchar *Field_string::pack(uchar *to, const uchar *from, uint max_length) |
7282 | { |
7283 | size_t length= MY_MIN(field_length,max_length); |
7284 | size_t local_char_length= max_length/field_charset->mbmaxlen; |
7285 | DBUG_PRINT("debug" , ("Packing field '%s' - length: %zu " , field_name.str, |
7286 | length)); |
7287 | |
7288 | if (length > local_char_length) |
7289 | local_char_length= my_charpos(field_charset, from, from+length, |
7290 | local_char_length); |
7291 | set_if_smaller(length, local_char_length); |
7292 | |
7293 | /* |
7294 | TODO: change charset interface to add a new function that does |
7295 | the following or add a flag to lengthsp to do it itself |
7296 | (this is for not packing padding adding bytes in BINARY |
7297 | fields). |
7298 | */ |
7299 | if (field_charset->mbmaxlen == 1) |
7300 | { |
7301 | while (length && from[length-1] == field_charset->pad_char) |
7302 | length --; |
7303 | } |
7304 | else |
7305 | length= field_charset->cset->lengthsp(field_charset, (const char*) from, length); |
7306 | |
7307 | // Length always stored little-endian |
7308 | *to++= (uchar) length; |
7309 | if (field_length > 255) |
7310 | *to++= (uchar) (length >> 8); |
7311 | |
7312 | // Store the actual bytes of the string |
7313 | memcpy(to, from, length); |
7314 | return to+length; |
7315 | } |
7316 | |
7317 | |
7318 | /** |
7319 | Unpack a string field from row data. |
7320 | |
7321 | This method is used to unpack a string field from a master whose size |
7322 | of the field is less than that of the slave. Note that there can be a |
7323 | variety of field types represented with this class. Certain types like |
7324 | ENUM or SET are processed differently. Hence, the upper byte of the |
7325 | @c param_data argument contains the result of field->real_type() from |
7326 | the master. |
7327 | |
7328 | @note For information about how the length is packed, see @c |
7329 | Field_string::save_field_metadata |
7330 | |
7331 | @param to Destination of the data |
7332 | @param from Source of the data |
7333 | @param param_data Real type (upper) and length (lower) values |
7334 | |
7335 | @return New pointer into memory based on from + length of the data |
7336 | */ |
7337 | const uchar * |
7338 | Field_string::unpack(uchar *to, const uchar *from, const uchar *from_end, |
7339 | uint param_data) |
7340 | { |
7341 | uint from_length, length; |
7342 | |
7343 | /* |
7344 | Compute the declared length of the field on the master. This is |
7345 | used to decide if one or two bytes should be read as length. |
7346 | */ |
7347 | if (param_data) |
7348 | from_length= (((param_data >> 4) & 0x300) ^ 0x300) + (param_data & 0x00ff); |
7349 | else |
7350 | from_length= field_length; |
7351 | |
7352 | DBUG_PRINT("debug" , |
7353 | ("param_data: 0x%x, field_length: %u, from_length: %u" , |
7354 | param_data, field_length, from_length)); |
7355 | /* |
7356 | Compute the actual length of the data by reading one or two bits |
7357 | (depending on the declared field length on the master). |
7358 | */ |
7359 | if (from_length > 255) |
7360 | { |
7361 | if (from + 2 > from_end) |
7362 | return 0; |
7363 | length= uint2korr(from); |
7364 | from+= 2; |
7365 | } |
7366 | else |
7367 | { |
7368 | if (from + 1 > from_end) |
7369 | return 0; |
7370 | length= (uint) *from++; |
7371 | } |
7372 | if (from + length > from_end || length > field_length) |
7373 | return 0; |
7374 | |
7375 | memcpy(to, from, length); |
7376 | // Pad the string with the pad character of the fields charset |
7377 | field_charset->cset->fill(field_charset, (char*) to + length, field_length - length, field_charset->pad_char); |
7378 | return from+length; |
7379 | } |
7380 | |
7381 | |
7382 | /** |
7383 | Save the field metadata for string fields. |
7384 | |
7385 | Saves the real type in the first byte and the field length in the |
7386 | second byte of the field metadata array at index of *metadata_ptr and |
7387 | *(metadata_ptr + 1). |
7388 | |
7389 | @note In order to be able to handle lengths exceeding 255 and be |
7390 | backwards-compatible with pre-5.1.26 servers, an extra two bits of |
7391 | the length has been added to the metadata in such a way that if |
7392 | they are set, a new unrecognized type is generated. This will |
7393 | cause pre-5.1-26 servers to stop due to a field type mismatch, |
7394 | while new servers will be able to extract the extra bits. If the |
7395 | length is <256, there will be no difference and both a new and an |
7396 | old server will be able to handle it. |
7397 | |
7398 | @note The extra two bits are added to bits 13 and 14 of the |
7399 | parameter data (with 1 being the least siginficant bit and 16 the |
7400 | most significant bit of the word) by xoring the extra length bits |
7401 | with the real type. Since all allowable types have 0xF as most |
7402 | significant bits of the metadata word, lengths <256 will not affect |
7403 | the real type at all, while all other values will result in a |
7404 | non-existant type in the range 17-244. |
7405 | |
7406 | @see Field_string::unpack |
7407 | |
7408 | @param metadata_ptr First byte of field metadata |
7409 | |
7410 | @returns number of bytes written to metadata_ptr |
7411 | */ |
7412 | int Field_string::save_field_metadata(uchar *metadata_ptr) |
7413 | { |
7414 | DBUG_ASSERT(field_length < 1024); |
7415 | DBUG_ASSERT((real_type() & 0xF0) == 0xF0); |
7416 | DBUG_PRINT("debug" , ("field_length: %u, real_type: %u" , |
7417 | field_length, real_type())); |
7418 | *metadata_ptr= (real_type() ^ ((field_length & 0x300) >> 4)); |
7419 | *(metadata_ptr + 1)= field_length & 0xFF; |
7420 | return 2; |
7421 | } |
7422 | |
7423 | |
7424 | uint Field_string::packed_col_length(const uchar *data_ptr, uint length) |
7425 | { |
7426 | if (length > 255) |
7427 | return uint2korr(data_ptr)+2; |
7428 | return (uint) *data_ptr + 1; |
7429 | } |
7430 | |
7431 | |
7432 | uint Field_string::max_packed_col_length(uint max_length) |
7433 | { |
7434 | return (max_length > 255 ? 2 : 1)+max_length; |
7435 | } |
7436 | |
7437 | |
7438 | uint Field_string::get_key_image(uchar *buff, uint length, imagetype type_arg) |
7439 | { |
7440 | size_t bytes = my_charpos(field_charset, (char*) ptr, |
7441 | (char*) ptr + field_length, |
7442 | length / field_charset->mbmaxlen); |
7443 | memcpy(buff, ptr, bytes); |
7444 | if (bytes < length) |
7445 | field_charset->cset->fill(field_charset, (char*) buff + bytes, |
7446 | length - bytes, field_charset->pad_char); |
7447 | return (uint)bytes; |
7448 | } |
7449 | |
7450 | |
7451 | Field *Field_string::make_new_field(MEM_ROOT *root, TABLE *new_table, |
7452 | bool keep_type) |
7453 | { |
7454 | Field *field; |
7455 | if (type() != MYSQL_TYPE_VAR_STRING || keep_type) |
7456 | field= Field::make_new_field(root, new_table, keep_type); |
7457 | else if ((field= new (root) Field_varstring(field_length, maybe_null(), |
7458 | &field_name, |
7459 | new_table->s, charset()))) |
7460 | { |
7461 | /* |
7462 | Old VARCHAR field which should be modified to a VARCHAR on copy |
7463 | This is done to ensure that ALTER TABLE will convert old VARCHAR fields |
7464 | to now VARCHAR fields. |
7465 | */ |
7466 | field->init(new_table); |
7467 | /* |
7468 | Normally orig_table is different from table only if field was |
7469 | created via ::make_new_field. Here we alter the type of field, |
7470 | so ::make_new_field is not applicable. But we still need to |
7471 | preserve the original field metadata for the client-server |
7472 | protocol. |
7473 | */ |
7474 | field->orig_table= orig_table; |
7475 | } |
7476 | return field; |
7477 | } |
7478 | |
7479 | |
7480 | /**************************************************************************** |
7481 | VARCHAR type |
7482 | Data in field->ptr is stored as: |
7483 | 1 or 2 bytes length-prefix-header (from Field_varstring::length_bytes) |
7484 | data |
7485 | |
7486 | NOTE: |
7487 | When VARCHAR is stored in a key (for handler::index_read() etc) it's always |
7488 | stored with a 2 byte prefix. (Just like blob keys). |
7489 | |
7490 | Normally length_bytes is calculated as (field_length < 256 : 1 ? 2) |
7491 | The exception is if there is a prefix key field that is part of a long |
7492 | VARCHAR, in which case field_length for this may be 1 but the length_bytes |
7493 | is 2. |
7494 | ****************************************************************************/ |
7495 | |
7496 | const uint Field_varstring::MAX_SIZE= UINT_MAX16; |
7497 | |
7498 | /** |
7499 | Save the field metadata for varstring fields. |
7500 | |
7501 | Saves the field length in the first byte. Note: may consume |
7502 | 2 bytes. Caller must ensure second byte is contiguous with |
7503 | first byte (e.g. array index 0,1). |
7504 | |
7505 | @param metadata_ptr First byte of field metadata |
7506 | |
7507 | @returns number of bytes written to metadata_ptr |
7508 | */ |
7509 | int Field_varstring::save_field_metadata(uchar *metadata_ptr) |
7510 | { |
7511 | DBUG_ASSERT(field_length <= 65535); |
7512 | int2store((char*)metadata_ptr, field_length); |
7513 | return 2; |
7514 | } |
7515 | |
7516 | int Field_varstring::store(const char *from,size_t length,CHARSET_INFO *cs) |
7517 | { |
7518 | ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; |
7519 | uint copy_length; |
7520 | int rc; |
7521 | |
7522 | rc= well_formed_copy_with_check((char*) get_data(), field_length, |
7523 | cs, from, length, |
7524 | field_length / field_charset->mbmaxlen, |
7525 | true, ©_length); |
7526 | |
7527 | store_length(copy_length); |
7528 | |
7529 | return rc; |
7530 | } |
7531 | |
7532 | |
7533 | double Field_varstring::val_real(void) |
7534 | { |
7535 | ASSERT_COLUMN_MARKED_FOR_READ; |
7536 | THD *thd= get_thd(); |
7537 | return Converter_strntod_with_warn(thd, Warn_filter(thd), |
7538 | Field_varstring::charset(), |
7539 | (const char *) get_data(), |
7540 | get_length()).result(); |
7541 | } |
7542 | |
7543 | |
7544 | longlong Field_varstring::val_int(void) |
7545 | { |
7546 | ASSERT_COLUMN_MARKED_FOR_READ; |
7547 | THD *thd= get_thd(); |
7548 | return Converter_strntoll_with_warn(thd, Warn_filter(thd), |
7549 | Field_varstring::charset(), |
7550 | (const char *) get_data(), |
7551 | get_length()).result(); |
7552 | } |
7553 | |
7554 | |
7555 | String *Field_varstring::val_str(String *val_buffer __attribute__((unused)), |
7556 | String *val_ptr) |
7557 | { |
7558 | ASSERT_COLUMN_MARKED_FOR_READ; |
7559 | val_ptr->set((const char*) get_data(), get_length(), field_charset); |
7560 | return val_ptr; |
7561 | } |
7562 | |
7563 | |
7564 | my_decimal *Field_varstring::val_decimal(my_decimal *decimal_value) |
7565 | { |
7566 | ASSERT_COLUMN_MARKED_FOR_READ; |
7567 | THD *thd= get_thd(); |
7568 | Converter_str2my_decimal_with_warn(thd, Warn_filter(thd), |
7569 | E_DEC_FATAL_ERROR, |
7570 | Field_varstring::charset(), |
7571 | (const char *) get_data(), |
7572 | get_length(), decimal_value); |
7573 | return decimal_value; |
7574 | |
7575 | } |
7576 | |
7577 | |
7578 | int Field_varstring::cmp_max(const uchar *a_ptr, const uchar *b_ptr, |
7579 | uint max_len) |
7580 | { |
7581 | uint a_length, b_length; |
7582 | int diff; |
7583 | |
7584 | if (length_bytes == 1) |
7585 | { |
7586 | a_length= (uint) *a_ptr; |
7587 | b_length= (uint) *b_ptr; |
7588 | } |
7589 | else |
7590 | { |
7591 | a_length= uint2korr(a_ptr); |
7592 | b_length= uint2korr(b_ptr); |
7593 | } |
7594 | set_if_smaller(a_length, max_len); |
7595 | set_if_smaller(b_length, max_len); |
7596 | diff= field_charset->coll->strnncollsp(field_charset, |
7597 | a_ptr+ |
7598 | length_bytes, |
7599 | a_length, |
7600 | b_ptr+ |
7601 | length_bytes, |
7602 | b_length); |
7603 | return diff; |
7604 | } |
7605 | |
7606 | |
7607 | /** |
7608 | @note |
7609 | varstring and blob keys are ALWAYS stored with a 2 byte length prefix |
7610 | */ |
7611 | |
7612 | int Field_varstring::key_cmp(const uchar *key_ptr, uint max_key_length) |
7613 | { |
7614 | size_t length= length_bytes == 1 ? (uint) *ptr : uint2korr(ptr); |
7615 | size_t local_char_length= max_key_length / field_charset->mbmaxlen; |
7616 | |
7617 | local_char_length= my_charpos(field_charset, ptr + length_bytes, |
7618 | ptr + length_bytes + length, local_char_length); |
7619 | set_if_smaller(length, local_char_length); |
7620 | return field_charset->coll->strnncollsp(field_charset, |
7621 | ptr + length_bytes, |
7622 | length, |
7623 | key_ptr+ |
7624 | HA_KEY_BLOB_LENGTH, |
7625 | uint2korr(key_ptr)); |
7626 | } |
7627 | |
7628 | |
7629 | /** |
7630 | Compare to key segments (always 2 byte length prefix). |
7631 | |
7632 | @note |
7633 | This is used only to compare key segments created for index_read(). |
7634 | (keys are created and compared in key.cc) |
7635 | */ |
7636 | |
7637 | int Field_varstring::key_cmp(const uchar *a,const uchar *b) |
7638 | { |
7639 | return field_charset->coll->strnncollsp(field_charset, |
7640 | a + HA_KEY_BLOB_LENGTH, |
7641 | uint2korr(a), |
7642 | b + HA_KEY_BLOB_LENGTH, |
7643 | uint2korr(b)); |
7644 | } |
7645 | |
7646 | |
7647 | void Field_varstring::sort_string(uchar *to,uint length) |
7648 | { |
7649 | String buf; |
7650 | |
7651 | val_str(&buf, &buf); |
7652 | |
7653 | if (field_charset == &my_charset_bin) |
7654 | { |
7655 | /* Store length last in high-byte order to sort longer strings first */ |
7656 | if (length_bytes == 1) |
7657 | to[length - 1]= buf.length(); |
7658 | else |
7659 | mi_int2store(to + length - 2, buf.length()); |
7660 | length-= length_bytes; |
7661 | } |
7662 | |
7663 | #ifndef DBUG_OFF |
7664 | size_t rc= |
7665 | #endif |
7666 | field_charset->coll->strnxfrm(field_charset, to, length, |
7667 | char_length() * field_charset->strxfrm_multiply, |
7668 | (const uchar*) buf.ptr(), buf.length(), |
7669 | MY_STRXFRM_PAD_WITH_SPACE | |
7670 | MY_STRXFRM_PAD_TO_MAXLEN); |
7671 | DBUG_ASSERT(rc == length); |
7672 | } |
7673 | |
7674 | |
7675 | enum ha_base_keytype Field_varstring::key_type() const |
7676 | { |
7677 | enum ha_base_keytype res; |
7678 | |
7679 | if (binary()) |
7680 | res= length_bytes == 1 ? HA_KEYTYPE_VARBINARY1 : HA_KEYTYPE_VARBINARY2; |
7681 | else |
7682 | res= length_bytes == 1 ? HA_KEYTYPE_VARTEXT1 : HA_KEYTYPE_VARTEXT2; |
7683 | return res; |
7684 | } |
7685 | |
7686 | |
7687 | /* |
7688 | Compressed columns need one extra byte to store the compression method. |
7689 | This byte is invisible to the end user, but not for the storage engine. |
7690 | */ |
7691 | |
7692 | void Field_varstring::sql_type(String &res) const |
7693 | { |
7694 | THD *thd= table->in_use; |
7695 | CHARSET_INFO *cs=res.charset(); |
7696 | size_t length; |
7697 | |
7698 | length= cs->cset->snprintf(cs,(char*) res.ptr(), |
7699 | res.alloced_length(), "%s(%d)" , |
7700 | (has_charset() ? "varchar" : "varbinary" ), |
7701 | (int) field_length / charset()->mbmaxlen - |
7702 | MY_TEST(compression_method())); |
7703 | res.length(length); |
7704 | if ((thd->variables.sql_mode & (MODE_MYSQL323 | MODE_MYSQL40)) && |
7705 | has_charset() && (charset()->state & MY_CS_BINSORT)) |
7706 | res.append(STRING_WITH_LEN(" binary" )); |
7707 | } |
7708 | |
7709 | |
7710 | uint32 Field_varstring::data_length() |
7711 | { |
7712 | return length_bytes == 1 ? (uint32) *ptr : uint2korr(ptr); |
7713 | } |
7714 | |
7715 | /* |
7716 | Functions to create a packed row. |
7717 | Here the number of length bytes are depending on the given max_length |
7718 | */ |
7719 | |
7720 | uchar *Field_varstring::pack(uchar *to, const uchar *from, uint max_length) |
7721 | { |
7722 | uint length= length_bytes == 1 ? (uint) *from : uint2korr(from); |
7723 | set_if_smaller(max_length, field_length); |
7724 | if (length > max_length) |
7725 | length=max_length; |
7726 | |
7727 | /* Length always stored little-endian */ |
7728 | *to++= length & 0xFF; |
7729 | if (max_length > 255) |
7730 | *to++= (length >> 8) & 0xFF; |
7731 | |
7732 | /* Store bytes of string */ |
7733 | if (length > 0) |
7734 | memcpy(to, from+length_bytes, length); |
7735 | return to+length; |
7736 | } |
7737 | |
7738 | |
7739 | /** |
7740 | Unpack a varstring field from row data. |
7741 | |
7742 | This method is used to unpack a varstring field from a master |
7743 | whose size of the field is less than that of the slave. |
7744 | |
7745 | @note |
7746 | The string length is always packed little-endian. |
7747 | |
7748 | @param to Destination of the data |
7749 | @param from Source of the data |
7750 | @param param_data Length bytes from the master's field data |
7751 | |
7752 | @return New pointer into memory based on from + length of the data |
7753 | */ |
7754 | const uchar * |
7755 | Field_varstring::unpack(uchar *to, const uchar *from, const uchar *from_end, |
7756 | uint param_data) |
7757 | { |
7758 | uint length; |
7759 | uint l_bytes= (param_data && (param_data < field_length)) ? |
7760 | (param_data <= 255) ? 1 : 2 : length_bytes; |
7761 | |
7762 | if (from + l_bytes > from_end) |
7763 | return 0; // Error in data |
7764 | |
7765 | if (l_bytes == 1) |
7766 | { |
7767 | to[0]= *from++; |
7768 | length= to[0]; |
7769 | if (length_bytes == 2) |
7770 | to[1]= 0; |
7771 | } |
7772 | else /* l_bytes == 2 */ |
7773 | { |
7774 | length= uint2korr(from); |
7775 | to[0]= *from++; |
7776 | to[1]= *from++; |
7777 | } |
7778 | if (length) |
7779 | { |
7780 | if (from + length > from_end || length > field_length) |
7781 | return 0; // Error in data |
7782 | memcpy(to+ length_bytes, from, length); |
7783 | } |
7784 | return from+length; |
7785 | } |
7786 | |
7787 | |
7788 | uint Field_varstring::packed_col_length(const uchar *data_ptr, uint length) |
7789 | { |
7790 | if (length > 255) |
7791 | return uint2korr(data_ptr)+2; |
7792 | return (uint) *data_ptr + 1; |
7793 | } |
7794 | |
7795 | |
7796 | uint Field_varstring::max_packed_col_length(uint max_length) |
7797 | { |
7798 | return (max_length > 255 ? 2 : 1)+max_length; |
7799 | } |
7800 | |
7801 | uint Field_varstring::get_key_image(uchar *buff, uint length, |
7802 | imagetype type_arg) |
7803 | { |
7804 | String val; |
7805 | uint local_char_length; |
7806 | my_bitmap_map *old_map; |
7807 | |
7808 | old_map= dbug_tmp_use_all_columns(table, table->read_set); |
7809 | val_str(&val, &val); |
7810 | dbug_tmp_restore_column_map(table->read_set, old_map); |
7811 | |
7812 | local_char_length= val.charpos(length / field_charset->mbmaxlen); |
7813 | if (local_char_length < val.length()) |
7814 | val.length(local_char_length); |
7815 | /* Key is always stored with 2 bytes */ |
7816 | int2store(buff, val.length()); |
7817 | memcpy(buff + HA_KEY_BLOB_LENGTH, val.ptr(), val.length()); |
7818 | if (val.length() < length) |
7819 | { |
7820 | /* |
7821 | Must clear this as we do a memcmp in opt_range.cc to detect |
7822 | identical keys |
7823 | */ |
7824 | memset(buff + HA_KEY_BLOB_LENGTH + val.length(), 0, length - val.length()); |
7825 | } |
7826 | return HA_KEY_BLOB_LENGTH + val.length(); |
7827 | } |
7828 | |
7829 | |
7830 | void Field_varstring::set_key_image(const uchar *buff,uint length) |
7831 | { |
7832 | length= uint2korr(buff); // Real length is here |
7833 | (void) store((const char*) buff + HA_KEY_BLOB_LENGTH, length, field_charset); |
7834 | } |
7835 | |
7836 | |
7837 | int Field_varstring::cmp_binary(const uchar *a_ptr, const uchar *b_ptr, |
7838 | uint32 max_length) |
7839 | { |
7840 | uint32 a_length,b_length; |
7841 | |
7842 | if (length_bytes == 1) |
7843 | { |
7844 | a_length= (uint) *a_ptr; |
7845 | b_length= (uint) *b_ptr; |
7846 | } |
7847 | else |
7848 | { |
7849 | a_length= uint2korr(a_ptr); |
7850 | b_length= uint2korr(b_ptr); |
7851 | } |
7852 | set_if_smaller(a_length, max_length); |
7853 | set_if_smaller(b_length, max_length); |
7854 | if (a_length != b_length) |
7855 | return 1; |
7856 | return memcmp(a_ptr+length_bytes, b_ptr+length_bytes, a_length); |
7857 | } |
7858 | |
7859 | |
7860 | Field *Field_varstring::make_new_field(MEM_ROOT *root, TABLE *new_table, |
7861 | bool keep_type) |
7862 | { |
7863 | Field_varstring *res= (Field_varstring*) Field::make_new_field(root, |
7864 | new_table, |
7865 | keep_type); |
7866 | if (res) |
7867 | res->length_bytes= length_bytes; |
7868 | return res; |
7869 | } |
7870 | |
7871 | |
7872 | Field *Field_varstring::new_key_field(MEM_ROOT *root, TABLE *new_table, |
7873 | uchar *new_ptr, uint32 length, |
7874 | uchar *new_null_ptr, uint new_null_bit) |
7875 | { |
7876 | Field_varstring *res; |
7877 | if ((res= (Field_varstring*) Field::new_key_field(root, new_table, |
7878 | new_ptr, length, |
7879 | new_null_ptr, new_null_bit))) |
7880 | { |
7881 | /* Keys length prefixes are always packed with 2 bytes */ |
7882 | res->length_bytes= 2; |
7883 | } |
7884 | return res; |
7885 | } |
7886 | |
7887 | uint Field_varstring::is_equal(Create_field *new_field) |
7888 | { |
7889 | if (new_field->type_handler() == type_handler() && |
7890 | new_field->charset == field_charset && |
7891 | !new_field->compression_method() == !compression_method()) |
7892 | { |
7893 | if (new_field->length == field_length) |
7894 | return IS_EQUAL_YES; |
7895 | if (new_field->length > field_length && |
7896 | ((new_field->length <= 255 && field_length <= 255) || |
7897 | (new_field->length > 255 && field_length > 255))) |
7898 | return IS_EQUAL_PACK_LENGTH; // VARCHAR, longer variable length |
7899 | } |
7900 | return IS_EQUAL_NO; |
7901 | } |
7902 | |
7903 | |
7904 | void Field_varstring::hash(ulong *nr, ulong *nr2) |
7905 | { |
7906 | if (is_null()) |
7907 | { |
7908 | *nr^= (*nr << 1) | 1; |
7909 | } |
7910 | else |
7911 | { |
7912 | uint len= length_bytes == 1 ? (uint) *ptr : uint2korr(ptr); |
7913 | CHARSET_INFO *cs= charset(); |
7914 | cs->coll->hash_sort(cs, ptr + length_bytes, len, nr, nr2); |
7915 | } |
7916 | } |
7917 | |
7918 | |
7919 | /** |
7920 | Compress field |
7921 | |
7922 | @param[out] to destination buffer for compressed data |
7923 | @param[in] to_length size of to |
7924 | @param[in] from data to compress |
7925 | @param[in] length from length |
7926 | @param[in] max_length truncate `from' to this length |
7927 | @param[out] out_length compessed data length |
7928 | @param[in] cs from character set |
7929 | @param[in] nchars copy no more than "nchars" characters |
7930 | |
7931 | In worst case (no compression performed) storage requirement is increased by |
7932 | 1 byte to store header. If it exceeds field length, normal data truncation is |
7933 | performed. |
7934 | |
7935 | Generic compressed header format (1 byte): |
7936 | |
7937 | Bits 1-4: method specific bits |
7938 | Bits 5-8: compression method |
7939 | |
7940 | If compression method is 0 then header is immediately followed by |
7941 | uncompressed data. |
7942 | |
7943 | If compression method is zlib: |
7944 | |
7945 | Bits 1-3: number of bytes occupied by original data length |
7946 | Bits 4: true if zlib wrapper not present |
7947 | Bits 5-8: store 8 (zlib) |
7948 | |
7949 | Header is immediately followed by original data length, |
7950 | followed by compressed data. |
7951 | */ |
7952 | |
7953 | int Field_longstr::compress(char *to, uint to_length, |
7954 | const char *from, uint length, |
7955 | uint max_length, |
7956 | uint *out_length, |
7957 | CHARSET_INFO *cs, size_t nchars) |
7958 | { |
7959 | THD *thd= get_thd(); |
7960 | char *buf; |
7961 | uint buf_length; |
7962 | int rc= 0; |
7963 | |
7964 | if (String::needs_conversion_on_storage(length, cs, field_charset) || |
7965 | max_length < length) |
7966 | { |
7967 | set_if_smaller(max_length, static_cast<ulonglong>(field_charset->mbmaxlen) * length + 1); |
7968 | if (!(buf= (char*) my_malloc(max_length, MYF(MY_WME)))) |
7969 | { |
7970 | *out_length= 0; |
7971 | return -1; |
7972 | } |
7973 | |
7974 | rc= well_formed_copy_with_check(buf, max_length, cs, from, length, |
7975 | nchars, true, &buf_length); |
7976 | } |
7977 | else |
7978 | { |
7979 | buf= const_cast<char*>(from); |
7980 | buf_length= length; |
7981 | } |
7982 | |
7983 | if (buf_length == 0) |
7984 | *out_length= 0; |
7985 | else if (buf_length >= thd->variables.column_compression_threshold && |
7986 | (*out_length= compression_method()->compress(thd, to, buf, buf_length))) |
7987 | status_var_increment(thd->status_var.column_compressions); |
7988 | else |
7989 | { |
7990 | /* Store uncompressed */ |
7991 | to[0]= 0; |
7992 | if (buf_length < to_length) |
7993 | memcpy(to + 1, buf, buf_length); |
7994 | else |
7995 | { |
7996 | /* Storing string at blob capacity, e.g. 255 bytes string to TINYBLOB. */ |
7997 | rc= well_formed_copy_with_check(to + 1, to_length - 1, cs, from, length, |
7998 | nchars, true, &buf_length); |
7999 | } |
8000 | *out_length= buf_length + 1; |
8001 | } |
8002 | |
8003 | if (buf != from) |
8004 | my_free(buf); |
8005 | return rc; |
8006 | } |
8007 | |
8008 | |
8009 | /* |
8010 | Memory is allocated only when original data was actually compressed. |
8011 | Otherwise val_ptr points at data located immediately after header. |
8012 | |
8013 | Data can be stored uncompressed if data was shorter than threshold |
8014 | or compressed data was longer than original data. |
8015 | */ |
8016 | |
8017 | String *Field_longstr::uncompress(String *val_buffer, String *val_ptr, |
8018 | const uchar *from, uint from_length) |
8019 | { |
8020 | if (from_length) |
8021 | { |
8022 | uchar method= (*from & 0xF0) >> 4; |
8023 | |
8024 | /* Uncompressed data */ |
8025 | if (!method) |
8026 | { |
8027 | val_ptr->set((const char*) from + 1, from_length - 1, field_charset); |
8028 | return val_ptr; |
8029 | } |
8030 | |
8031 | if (compression_methods[method].uncompress) |
8032 | { |
8033 | if (!compression_methods[method].uncompress(val_buffer, from, from_length, |
8034 | field_length)) |
8035 | { |
8036 | val_buffer->set_charset(field_charset); |
8037 | status_var_increment(get_thd()->status_var.column_decompressions); |
8038 | return val_buffer; |
8039 | } |
8040 | } |
8041 | } |
8042 | |
8043 | /* |
8044 | It would be better to return 0 in case of errors, but to take the |
8045 | safer route, let's return a zero string and let the general |
8046 | handler catch the error. |
8047 | */ |
8048 | val_ptr->set("" , 0, field_charset); |
8049 | return val_ptr; |
8050 | } |
8051 | |
8052 | |
8053 | int Field_varstring_compressed::store(const char *from, size_t length, |
8054 | CHARSET_INFO *cs) |
8055 | { |
8056 | ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; |
8057 | uint compressed_length; |
8058 | int rc= compress((char*) get_data(), field_length, from, (uint) length, |
8059 | Field_varstring_compressed::max_display_length(), |
8060 | &compressed_length, cs, |
8061 | Field_varstring_compressed::char_length()); |
8062 | store_length(compressed_length); |
8063 | return rc; |
8064 | } |
8065 | |
8066 | |
8067 | String *Field_varstring_compressed::val_str(String *val_buffer, String *val_ptr) |
8068 | { |
8069 | ASSERT_COLUMN_MARKED_FOR_READ; |
8070 | return uncompress(val_buffer, val_ptr, get_data(), get_length()); |
8071 | } |
8072 | |
8073 | |
8074 | double Field_varstring_compressed::val_real(void) |
8075 | { |
8076 | ASSERT_COLUMN_MARKED_FOR_READ; |
8077 | THD *thd= get_thd(); |
8078 | String buf; |
8079 | val_str(&buf, &buf); |
8080 | return Converter_strntod_with_warn(thd, Warn_filter(thd), field_charset, |
8081 | buf.ptr(), buf.length()).result(); |
8082 | } |
8083 | |
8084 | |
8085 | longlong Field_varstring_compressed::val_int(void) |
8086 | { |
8087 | ASSERT_COLUMN_MARKED_FOR_READ; |
8088 | THD *thd= get_thd(); |
8089 | String buf; |
8090 | val_str(&buf, &buf); |
8091 | return Converter_strntoll_with_warn(thd, Warn_filter(thd), field_charset, |
8092 | buf.ptr(), buf.length()).result(); |
8093 | } |
8094 | |
8095 | |
8096 | int Field_varstring_compressed::cmp_max(const uchar *a_ptr, const uchar *b_ptr, |
8097 | uint max_len) |
8098 | { |
8099 | String a, b; |
8100 | uint a_length, b_length; |
8101 | |
8102 | if (length_bytes == 1) |
8103 | { |
8104 | a_length= (uint) *a_ptr; |
8105 | b_length= (uint) *b_ptr; |
8106 | } |
8107 | else |
8108 | { |
8109 | a_length= uint2korr(a_ptr); |
8110 | b_length= uint2korr(b_ptr); |
8111 | } |
8112 | |
8113 | uncompress(&a, &a, a_ptr + length_bytes, a_length); |
8114 | uncompress(&b, &b, b_ptr + length_bytes, b_length); |
8115 | |
8116 | if (a.length() > max_len) |
8117 | a.length(max_len); |
8118 | if (b.length() > max_len) |
8119 | b.length(max_len); |
8120 | |
8121 | return sortcmp(&a, &b, field_charset); |
8122 | } |
8123 | |
8124 | |
8125 | /**************************************************************************** |
8126 | ** blob type |
8127 | ** A blob is saved as a length and a pointer. The length is stored in the |
8128 | ** packlength slot and may be from 1-4. |
8129 | ****************************************************************************/ |
8130 | |
8131 | Field_blob::Field_blob(uchar *ptr_arg, uchar *null_ptr_arg, uchar null_bit_arg, |
8132 | enum utype unireg_check_arg, |
8133 | const LEX_CSTRING *field_name_arg, |
8134 | TABLE_SHARE *share, uint blob_pack_length, |
8135 | const DTCollation &collation) |
8136 | :Field_longstr(ptr_arg, BLOB_PACK_LENGTH_TO_MAX_LENGH(blob_pack_length), |
8137 | null_ptr_arg, null_bit_arg, unireg_check_arg, field_name_arg, |
8138 | collation), |
8139 | packlength(blob_pack_length) |
8140 | { |
8141 | DBUG_ASSERT(blob_pack_length <= 4); // Only pack lengths 1-4 supported currently |
8142 | flags|= BLOB_FLAG; |
8143 | share->blob_fields++; |
8144 | /* TODO: why do not fill table->s->blob_field array here? */ |
8145 | } |
8146 | |
8147 | |
8148 | void Field_blob::store_length(uchar *i_ptr, uint i_packlength, uint32 i_number) |
8149 | { |
8150 | store_lowendian(i_number, i_ptr, i_packlength); |
8151 | } |
8152 | |
8153 | |
8154 | uint32 Field_blob::get_length(const uchar *pos, uint packlength_arg) const |
8155 | { |
8156 | return (uint32)read_lowendian(pos, packlength_arg); |
8157 | } |
8158 | |
8159 | |
8160 | /** |
8161 | Copy a value from another BLOB field of the same character set. |
8162 | This method is used by Copy_field, e.g. during ALTER TABLE. |
8163 | */ |
8164 | int Field_blob::copy_value(Field_blob *from) |
8165 | { |
8166 | DBUG_ASSERT(field_charset == from->charset()); |
8167 | DBUG_ASSERT(!compression_method() == !from->compression_method()); |
8168 | int rc= 0; |
8169 | uint32 length= from->get_length(); |
8170 | uchar *data= from->get_ptr(); |
8171 | if (packlength < from->packlength) |
8172 | { |
8173 | set_if_smaller(length, Field_blob::max_data_length()); |
8174 | length= (uint32) Well_formed_prefix(field_charset, |
8175 | (const char *) data, length).length(); |
8176 | rc= report_if_important_data((const char *) data + length, |
8177 | (const char *) data + from->get_length(), |
8178 | true); |
8179 | } |
8180 | store_length(length); |
8181 | bmove(ptr + packlength, (uchar*) &data, sizeof(char*)); |
8182 | return rc; |
8183 | } |
8184 | |
8185 | |
8186 | int Field_blob::store(const char *from,size_t length,CHARSET_INFO *cs) |
8187 | { |
8188 | ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; |
8189 | size_t copy_length, new_length; |
8190 | uint copy_len; |
8191 | char *tmp; |
8192 | char buff[STRING_BUFFER_USUAL_SIZE]; |
8193 | String tmpstr(buff,sizeof(buff), &my_charset_bin); |
8194 | int rc; |
8195 | |
8196 | if (!length) |
8197 | { |
8198 | bzero(ptr,Field_blob::pack_length()); |
8199 | return 0; |
8200 | } |
8201 | |
8202 | if (table->blob_storage) // GROUP_CONCAT with ORDER BY | DISTINCT |
8203 | { |
8204 | DBUG_ASSERT(!f_is_hex_escape(flags)); |
8205 | DBUG_ASSERT(field_charset == cs); |
8206 | DBUG_ASSERT(length <= max_data_length()); |
8207 | |
8208 | new_length= length; |
8209 | copy_length= (size_t)MY_MIN(UINT_MAX,table->in_use->variables.group_concat_max_len); |
8210 | if (new_length > copy_length) |
8211 | { |
8212 | new_length= Well_formed_prefix(cs, |
8213 | from, copy_length, new_length).length(); |
8214 | table->blob_storage->set_truncated_value(true); |
8215 | } |
8216 | if (!(tmp= table->blob_storage->store(from, new_length))) |
8217 | goto oom_error; |
8218 | |
8219 | Field_blob::store_length(new_length); |
8220 | bmove(ptr + packlength, (uchar*) &tmp, sizeof(char*)); |
8221 | return 0; |
8222 | } |
8223 | |
8224 | /* |
8225 | If the 'from' address is in the range of the temporary 'value'- |
8226 | object we need to copy the content to a different location or it will be |
8227 | invalidated when the 'value'-object is reallocated to make room for |
8228 | the new character set. |
8229 | */ |
8230 | if (from >= value.ptr() && from <= value.ptr()+value.length()) |
8231 | { |
8232 | /* |
8233 | If content of the 'from'-address is cached in the 'value'-object |
8234 | it is possible that the content needs a character conversion. |
8235 | */ |
8236 | if (!String::needs_conversion_on_storage(length, cs, field_charset)) |
8237 | { |
8238 | Field_blob::store_length(length); |
8239 | bmove(ptr + packlength, &from, sizeof(char*)); |
8240 | return 0; |
8241 | } |
8242 | if (tmpstr.copy(from, length, cs)) |
8243 | goto oom_error; |
8244 | from= tmpstr.ptr(); |
8245 | } |
8246 | |
8247 | new_length= MY_MIN(max_data_length(), field_charset->mbmaxlen * length); |
8248 | if (value.alloc(new_length)) |
8249 | goto oom_error; |
8250 | tmp= const_cast<char*>(value.ptr()); |
8251 | |
8252 | if (f_is_hex_escape(flags)) |
8253 | { |
8254 | copy_length= my_copy_with_hex_escaping(field_charset, |
8255 | tmp, new_length, |
8256 | from, length); |
8257 | Field_blob::store_length(copy_length); |
8258 | bmove(ptr + packlength, (uchar*) &tmp, sizeof(char*)); |
8259 | return 0; |
8260 | } |
8261 | rc= well_formed_copy_with_check((char*) value.ptr(), (uint) new_length, |
8262 | cs, from, length, |
8263 | length, true, ©_len); |
8264 | Field_blob::store_length(copy_len); |
8265 | bmove(ptr+packlength,(uchar*) &tmp,sizeof(char*)); |
8266 | |
8267 | return rc; |
8268 | |
8269 | oom_error: |
8270 | /* Fatal OOM error */ |
8271 | bzero(ptr,Field_blob::pack_length()); |
8272 | return -1; |
8273 | } |
8274 | |
8275 | |
8276 | double Field_blob::val_real(void) |
8277 | { |
8278 | ASSERT_COLUMN_MARKED_FOR_READ; |
8279 | char *blob; |
8280 | memcpy(&blob, ptr+packlength, sizeof(char*)); |
8281 | if (!blob) |
8282 | return 0.0; |
8283 | THD *thd= get_thd(); |
8284 | return Converter_strntod_with_warn(thd, Warn_filter(thd), |
8285 | Field_blob::charset(), |
8286 | blob, get_length(ptr)).result(); |
8287 | } |
8288 | |
8289 | |
8290 | longlong Field_blob::val_int(void) |
8291 | { |
8292 | ASSERT_COLUMN_MARKED_FOR_READ; |
8293 | char *blob; |
8294 | memcpy(&blob, ptr+packlength, sizeof(char*)); |
8295 | if (!blob) |
8296 | return 0; |
8297 | THD *thd= get_thd(); |
8298 | return Converter_strntoll_with_warn(thd, Warn_filter(thd), |
8299 | Field_blob::charset(), |
8300 | blob, get_length(ptr)).result(); |
8301 | } |
8302 | |
8303 | |
8304 | String *Field_blob::val_str(String *val_buffer __attribute__((unused)), |
8305 | String *val_ptr) |
8306 | { |
8307 | ASSERT_COLUMN_MARKED_FOR_READ; |
8308 | char *blob; |
8309 | memcpy(&blob, ptr+packlength, sizeof(char*)); |
8310 | if (!blob) |
8311 | val_ptr->set("" ,0,charset()); // A bit safer than ->length(0) |
8312 | else |
8313 | val_ptr->set((const char*) blob,get_length(ptr),charset()); |
8314 | return val_ptr; |
8315 | } |
8316 | |
8317 | |
8318 | my_decimal *Field_blob::val_decimal(my_decimal *decimal_value) |
8319 | { |
8320 | ASSERT_COLUMN_MARKED_FOR_READ; |
8321 | const char *blob; |
8322 | size_t length; |
8323 | memcpy(&blob, ptr+packlength, sizeof(const uchar*)); |
8324 | if (!blob) |
8325 | { |
8326 | blob= "" ; |
8327 | length= 0; |
8328 | } |
8329 | else |
8330 | length= get_length(ptr); |
8331 | |
8332 | THD *thd= get_thd(); |
8333 | Converter_str2my_decimal_with_warn(thd, Warn_filter(thd), |
8334 | E_DEC_FATAL_ERROR, |
8335 | Field_blob::charset(), |
8336 | blob, length, decimal_value); |
8337 | return decimal_value; |
8338 | } |
8339 | |
8340 | |
8341 | int Field_blob::cmp(const uchar *a,uint32 a_length, const uchar *b, |
8342 | uint32 b_length) |
8343 | { |
8344 | return field_charset->coll->strnncollsp(field_charset, |
8345 | a, a_length, b, b_length); |
8346 | } |
8347 | |
8348 | |
8349 | int Field_blob::cmp_max(const uchar *a_ptr, const uchar *b_ptr, |
8350 | uint max_length) |
8351 | { |
8352 | uchar *blob1,*blob2; |
8353 | memcpy(&blob1, a_ptr+packlength, sizeof(char*)); |
8354 | memcpy(&blob2, b_ptr+packlength, sizeof(char*)); |
8355 | uint a_len= get_length(a_ptr), b_len= get_length(b_ptr); |
8356 | set_if_smaller(a_len, max_length); |
8357 | set_if_smaller(b_len, max_length); |
8358 | return Field_blob::cmp(blob1,a_len,blob2,b_len); |
8359 | } |
8360 | |
8361 | |
8362 | int Field_blob::cmp_binary(const uchar *a_ptr, const uchar *b_ptr, |
8363 | uint32 max_length) |
8364 | { |
8365 | char *a,*b; |
8366 | uint diff; |
8367 | uint32 a_length,b_length; |
8368 | memcpy(&a, a_ptr+packlength, sizeof(char*)); |
8369 | memcpy(&b, b_ptr+packlength, sizeof(char*)); |
8370 | a_length=get_length(a_ptr); |
8371 | if (a_length > max_length) |
8372 | a_length=max_length; |
8373 | b_length=get_length(b_ptr); |
8374 | if (b_length > max_length) |
8375 | b_length=max_length; |
8376 | diff=memcmp(a,b,MY_MIN(a_length,b_length)); |
8377 | return diff ? diff : (int) (a_length - b_length); |
8378 | } |
8379 | |
8380 | |
8381 | /* The following is used only when comparing a key */ |
8382 | |
8383 | uint Field_blob::get_key_image(uchar *buff,uint length, imagetype type_arg) |
8384 | { |
8385 | size_t blob_length= get_length(ptr); |
8386 | uchar *blob; |
8387 | |
8388 | #ifdef HAVE_SPATIAL |
8389 | if (type_arg == itMBR) |
8390 | { |
8391 | const char *dummy; |
8392 | MBR mbr; |
8393 | Geometry_buffer buffer; |
8394 | Geometry *gobj; |
8395 | const uint image_length= SIZEOF_STORED_DOUBLE*4; |
8396 | |
8397 | if (blob_length < SRID_SIZE) |
8398 | { |
8399 | bzero(buff, image_length); |
8400 | return image_length; |
8401 | } |
8402 | blob= get_ptr(); |
8403 | gobj= Geometry::construct(&buffer, (char*) blob, (uint32)blob_length); |
8404 | if (!gobj || gobj->get_mbr(&mbr, &dummy)) |
8405 | bzero(buff, image_length); |
8406 | else |
8407 | { |
8408 | float8store(buff, mbr.xmin); |
8409 | float8store(buff+8, mbr.xmax); |
8410 | float8store(buff+16, mbr.ymin); |
8411 | float8store(buff+24, mbr.ymax); |
8412 | } |
8413 | return image_length; |
8414 | } |
8415 | #endif /*HAVE_SPATIAL*/ |
8416 | |
8417 | blob= get_ptr(); |
8418 | size_t local_char_length= length / field_charset->mbmaxlen; |
8419 | local_char_length= my_charpos(field_charset, blob, blob + blob_length, |
8420 | local_char_length); |
8421 | set_if_smaller(blob_length, local_char_length); |
8422 | |
8423 | if (length > blob_length) |
8424 | { |
8425 | /* |
8426 | Must clear this as we do a memcmp in opt_range.cc to detect |
8427 | identical keys |
8428 | */ |
8429 | bzero(buff+HA_KEY_BLOB_LENGTH+blob_length, (length-blob_length)); |
8430 | length=(uint) blob_length; |
8431 | } |
8432 | int2store(buff,length); |
8433 | memcpy(buff+HA_KEY_BLOB_LENGTH, blob, length); |
8434 | return HA_KEY_BLOB_LENGTH+length; |
8435 | } |
8436 | |
8437 | |
8438 | void Field_blob::set_key_image(const uchar *buff,uint length) |
8439 | { |
8440 | length= uint2korr(buff); |
8441 | (void) Field_blob::store((const char*) buff+HA_KEY_BLOB_LENGTH, length, |
8442 | field_charset); |
8443 | } |
8444 | |
8445 | |
8446 | int Field_blob::key_cmp(const uchar *key_ptr, uint max_key_length) |
8447 | { |
8448 | uchar *blob1; |
8449 | size_t blob_length=get_length(ptr); |
8450 | memcpy(&blob1, ptr+packlength, sizeof(char*)); |
8451 | CHARSET_INFO *cs= charset(); |
8452 | size_t local_char_length= max_key_length / cs->mbmaxlen; |
8453 | local_char_length= my_charpos(cs, blob1, blob1+blob_length, |
8454 | local_char_length); |
8455 | set_if_smaller(blob_length, local_char_length); |
8456 | return Field_blob::cmp(blob1, (uint32)blob_length, |
8457 | key_ptr+HA_KEY_BLOB_LENGTH, |
8458 | uint2korr(key_ptr)); |
8459 | } |
8460 | |
8461 | int Field_blob::key_cmp(const uchar *a,const uchar *b) |
8462 | { |
8463 | return Field_blob::cmp(a+HA_KEY_BLOB_LENGTH, uint2korr(a), |
8464 | b+HA_KEY_BLOB_LENGTH, uint2korr(b)); |
8465 | } |
8466 | |
8467 | |
8468 | Field *Field_blob::new_key_field(MEM_ROOT *root, TABLE *new_table, |
8469 | uchar *new_ptr, uint32 length, |
8470 | uchar *new_null_ptr, uint new_null_bit) |
8471 | { |
8472 | Field_varstring *res= new (root) Field_varstring(new_ptr, length, 2, |
8473 | new_null_ptr, |
8474 | new_null_bit, Field::NONE, |
8475 | &field_name, |
8476 | table->s, charset()); |
8477 | res->init(new_table); |
8478 | return res; |
8479 | } |
8480 | |
8481 | |
8482 | /** |
8483 | Save the field metadata for blob fields. |
8484 | |
8485 | Saves the pack length in the first byte of the field metadata array |
8486 | at index of *metadata_ptr. |
8487 | |
8488 | @param metadata_ptr First byte of field metadata |
8489 | |
8490 | @returns number of bytes written to metadata_ptr |
8491 | */ |
8492 | int Field_blob::save_field_metadata(uchar *metadata_ptr) |
8493 | { |
8494 | DBUG_ENTER("Field_blob::save_field_metadata" ); |
8495 | *metadata_ptr= pack_length_no_ptr(); |
8496 | DBUG_PRINT("debug" , ("metadata: %u (pack_length_no_ptr)" , *metadata_ptr)); |
8497 | DBUG_RETURN(1); |
8498 | } |
8499 | |
8500 | |
8501 | uint32 Field_blob::sort_length() const |
8502 | { |
8503 | return (uint32) (get_thd()->variables.max_sort_length + |
8504 | (field_charset == &my_charset_bin ? 0 : packlength)); |
8505 | } |
8506 | |
8507 | |
8508 | void Field_blob::sort_string(uchar *to,uint length) |
8509 | { |
8510 | String buf; |
8511 | |
8512 | val_str(&buf, &buf); |
8513 | if (!buf.length() && field_charset->pad_char == 0) |
8514 | bzero(to,length); |
8515 | else |
8516 | { |
8517 | if (field_charset == &my_charset_bin) |
8518 | { |
8519 | /* |
8520 | Store length of blob last in blob to shorter blobs before longer blobs |
8521 | */ |
8522 | length-= packlength; |
8523 | store_bigendian(buf.length(), to + length, packlength); |
8524 | } |
8525 | |
8526 | #ifndef DBUG_OFF |
8527 | size_t rc= |
8528 | #endif |
8529 | field_charset->coll->strnxfrm(field_charset, to, length, length, |
8530 | (const uchar*) buf.ptr(), buf.length(), |
8531 | MY_STRXFRM_PAD_WITH_SPACE | |
8532 | MY_STRXFRM_PAD_TO_MAXLEN); |
8533 | DBUG_ASSERT(rc == length); |
8534 | } |
8535 | } |
8536 | |
8537 | |
8538 | /* |
8539 | Return the data type handler, according to packlength. |
8540 | Implemented in field.cc rather than in field.h |
8541 | to avoid exporting type_handler_xxx with MYSQL_PLUGIN_IMPORT. |
8542 | */ |
8543 | const Type_handler *Field_blob::type_handler() const |
8544 | { |
8545 | switch (packlength) { |
8546 | case 1: return &type_handler_tiny_blob; |
8547 | case 2: return &type_handler_blob; |
8548 | case 3: return &type_handler_medium_blob; |
8549 | } |
8550 | return &type_handler_long_blob; |
8551 | } |
8552 | |
8553 | |
8554 | void Field_blob::sql_type(String &res) const |
8555 | { |
8556 | const char *str; |
8557 | uint length; |
8558 | switch (packlength) { |
8559 | default: str="tiny" ; length=4; break; |
8560 | case 2: str="" ; length=0; break; |
8561 | case 3: str="medium" ; length= 6; break; |
8562 | case 4: str="long" ; length=4; break; |
8563 | } |
8564 | res.set_ascii(str,length); |
8565 | if (charset() == &my_charset_bin) |
8566 | res.append(STRING_WITH_LEN("blob" )); |
8567 | else |
8568 | { |
8569 | res.append(STRING_WITH_LEN("text" )); |
8570 | } |
8571 | } |
8572 | |
8573 | uchar *Field_blob::pack(uchar *to, const uchar *from, uint max_length) |
8574 | { |
8575 | uchar *save= ptr; |
8576 | ptr= (uchar*) from; |
8577 | uint32 length=get_length(); // Length of from string |
8578 | |
8579 | /* |
8580 | Store max length, which will occupy packlength bytes. If the max |
8581 | length given is smaller than the actual length of the blob, we |
8582 | just store the initial bytes of the blob. |
8583 | */ |
8584 | store_length(to, packlength, MY_MIN(length, max_length)); |
8585 | |
8586 | /* |
8587 | Store the actual blob data, which will occupy 'length' bytes. |
8588 | */ |
8589 | if (length > 0) |
8590 | { |
8591 | from= get_ptr(); |
8592 | memcpy(to+packlength, from,length); |
8593 | } |
8594 | ptr=save; // Restore org row pointer |
8595 | return to+packlength+length; |
8596 | } |
8597 | |
8598 | |
8599 | /** |
8600 | Unpack a blob field from row data. |
8601 | |
8602 | This method is used to unpack a blob field from a master whose size of |
8603 | the field is less than that of the slave. Note: This method is included |
8604 | to satisfy inheritance rules, but is not needed for blob fields. It |
8605 | simply is used as a pass-through to the original unpack() method for |
8606 | blob fields. |
8607 | |
8608 | @param to Destination of the data |
8609 | @param from Source of the data |
8610 | @param param_data @c TRUE if base types should be stored in little- |
8611 | endian format, @c FALSE if native format should |
8612 | be used. |
8613 | |
8614 | @return New pointer into memory based on from + length of the data |
8615 | */ |
8616 | |
8617 | const uchar *Field_blob::unpack(uchar *to, const uchar *from, |
8618 | const uchar *from_end, uint param_data) |
8619 | { |
8620 | DBUG_ENTER("Field_blob::unpack" ); |
8621 | DBUG_PRINT("enter" , ("to: %p; from: %p; param_data: %u" , |
8622 | to, from, param_data)); |
8623 | uint const master_packlength= |
8624 | param_data > 0 ? param_data & 0xFF : packlength; |
8625 | if (from + master_packlength > from_end) |
8626 | DBUG_RETURN(0); // Error in data |
8627 | uint32 const length= get_length(from, master_packlength); |
8628 | DBUG_DUMP("packed" , from, length + master_packlength); |
8629 | if (from + master_packlength + length > from_end) |
8630 | DBUG_RETURN(0); |
8631 | set_ptr(length, const_cast<uchar*> (from) + master_packlength); |
8632 | DBUG_RETURN(from + master_packlength + length); |
8633 | } |
8634 | |
8635 | |
8636 | uint Field_blob::packed_col_length(const uchar *data_ptr, uint length) |
8637 | { |
8638 | if (length > 255) |
8639 | return uint2korr(data_ptr)+2; |
8640 | return (uint) *data_ptr + 1; |
8641 | } |
8642 | |
8643 | |
8644 | uint Field_blob::max_packed_col_length(uint max_length) |
8645 | { |
8646 | return (max_length > 255 ? 2 : 1)+max_length; |
8647 | } |
8648 | |
8649 | |
8650 | /* |
8651 | Blob fields are regarded equal if they have same character set, |
8652 | same blob store length and if either both are compressed or both are |
8653 | uncompressed. |
8654 | The logic for compression is that we don't have to uncompress and compress |
8655 | again an already compressed field just because compression method changes. |
8656 | */ |
8657 | |
8658 | uint Field_blob::is_equal(Create_field *new_field) |
8659 | { |
8660 | return new_field->type_handler() == type_handler() && |
8661 | new_field->charset == field_charset && |
8662 | new_field->pack_length == pack_length() && |
8663 | !new_field->compression_method() == !compression_method(); |
8664 | } |
8665 | |
8666 | |
8667 | int Field_blob_compressed::store(const char *from, size_t length, |
8668 | CHARSET_INFO *cs) |
8669 | { |
8670 | ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; |
8671 | uint compressed_length; |
8672 | uint max_length= max_data_length(); |
8673 | uint to_length= (uint) MY_MIN(max_length, |
8674 | field_charset->mbmaxlen * length + 1); |
8675 | String tmp(from, length, cs); |
8676 | int rc; |
8677 | |
8678 | if (from >= value.ptr() && from <= value.end() && tmp.copy(from, length, cs)) |
8679 | goto oom; |
8680 | |
8681 | if (value.alloc(to_length)) |
8682 | goto oom; |
8683 | |
8684 | rc= compress((char*) value.ptr(), to_length, tmp.ptr(), (uint) length, |
8685 | max_length, &compressed_length, cs, (uint) length); |
8686 | set_ptr(compressed_length, (uchar*) value.ptr()); |
8687 | return rc; |
8688 | |
8689 | oom: |
8690 | set_ptr((uint32) 0, NULL); |
8691 | return -1; |
8692 | } |
8693 | |
8694 | |
8695 | String *Field_blob_compressed::val_str(String *val_buffer, String *val_ptr) |
8696 | { |
8697 | ASSERT_COLUMN_MARKED_FOR_READ; |
8698 | return uncompress(val_buffer, val_ptr, get_ptr(), get_length()); |
8699 | } |
8700 | |
8701 | |
8702 | double Field_blob_compressed::val_real(void) |
8703 | { |
8704 | ASSERT_COLUMN_MARKED_FOR_READ; |
8705 | THD *thd= get_thd(); |
8706 | String buf; |
8707 | val_str(&buf, &buf); |
8708 | return Converter_strntod_with_warn(thd, Warn_filter(thd), field_charset, |
8709 | buf.ptr(), buf.length()).result(); |
8710 | } |
8711 | |
8712 | |
8713 | longlong Field_blob_compressed::val_int(void) |
8714 | { |
8715 | ASSERT_COLUMN_MARKED_FOR_READ; |
8716 | THD *thd= get_thd(); |
8717 | String buf; |
8718 | val_str(&buf, &buf); |
8719 | return Converter_strntoll_with_warn(thd, Warn_filter(thd), field_charset, |
8720 | buf.ptr(), buf.length()).result(); |
8721 | } |
8722 | |
8723 | |
8724 | #ifdef HAVE_SPATIAL |
8725 | /* Values 1-40 reserved for 1-byte options, |
8726 | 41-80 for 2-byte options, |
8727 | 81-120 for 4-byte options, |
8728 | 121-160 for 8-byte options, |
8729 | other - varied length in next 1-3 bytes. |
8730 | */ |
8731 | enum { |
8732 | FIELDGEOM_END=0, |
8733 | FIELDGEOM_STORAGE_MODEL=1, |
8734 | FIELDGEOM_PRECISION=2, |
8735 | FIELDGEOM_SCALE=3, |
8736 | FIELDGEOM_SRID=81, |
8737 | }; |
8738 | |
8739 | |
8740 | uint gis_field_options_image(uchar *buff, List<Create_field> &create_fields) |
8741 | { |
8742 | uint image_size= 0; |
8743 | List_iterator<Create_field> it(create_fields); |
8744 | Create_field *field; |
8745 | while ((field= it++)) |
8746 | { |
8747 | if (field->real_field_type() != MYSQL_TYPE_GEOMETRY) |
8748 | continue; |
8749 | if (buff) |
8750 | { |
8751 | uchar *cbuf= buff + image_size; |
8752 | |
8753 | cbuf[0]= FIELDGEOM_STORAGE_MODEL; |
8754 | cbuf[1]= (uchar) Field_geom::GEOM_STORAGE_WKB; |
8755 | |
8756 | cbuf[2]= FIELDGEOM_PRECISION; |
8757 | cbuf[3]= (uchar) field->length; |
8758 | |
8759 | cbuf[4]= FIELDGEOM_SCALE; |
8760 | cbuf[5]= (uchar) field->decimals; |
8761 | |
8762 | cbuf[6]= FIELDGEOM_SRID; |
8763 | int4store(cbuf + 7, ((uint32) field->srid)); |
8764 | |
8765 | cbuf[11]= FIELDGEOM_END; |
8766 | } |
8767 | image_size+= 12; |
8768 | } |
8769 | |
8770 | return image_size; |
8771 | } |
8772 | |
8773 | |
8774 | uint gis_field_options_read(const uchar *buf, size_t buf_len, |
8775 | Field_geom::storage_type *st_type,uint *precision, uint *scale, uint *srid) |
8776 | { |
8777 | const uchar *buf_end= buf + buf_len; |
8778 | const uchar *cbuf= buf; |
8779 | int option_id; |
8780 | |
8781 | *precision= *scale= *srid= 0; |
8782 | *st_type= Field_geom::GEOM_STORAGE_WKB; |
8783 | |
8784 | if (!buf) /* can only happen with the old FRM file */ |
8785 | goto end_of_record; |
8786 | |
8787 | while (cbuf < buf_end) |
8788 | { |
8789 | switch ((option_id= *(cbuf++))) |
8790 | { |
8791 | case FIELDGEOM_STORAGE_MODEL: |
8792 | *st_type= (Field_geom::storage_type) cbuf[0]; |
8793 | break; |
8794 | case FIELDGEOM_PRECISION: |
8795 | *precision= cbuf[0]; |
8796 | break; |
8797 | case FIELDGEOM_SCALE: |
8798 | *scale= cbuf[0]; |
8799 | break; |
8800 | case FIELDGEOM_SRID: |
8801 | *srid= uint4korr(cbuf); |
8802 | break; |
8803 | case FIELDGEOM_END: |
8804 | goto end_of_record; |
8805 | } |
8806 | if (option_id > 0 && option_id <= 40) |
8807 | cbuf+= 1; |
8808 | else if (option_id > 40 && option_id <= 80) |
8809 | cbuf+= 2; |
8810 | else if (option_id > 80 && option_id <= 120) |
8811 | cbuf+= 4; |
8812 | else if (option_id > 120 && option_id <= 160) |
8813 | cbuf+= 8; |
8814 | else /* > 160 and <=255 */ |
8815 | cbuf+= cbuf[0] ? 1 + cbuf[0] : 3 + uint2korr(cbuf+1); |
8816 | } |
8817 | |
8818 | end_of_record: |
8819 | return (uint)(cbuf - buf); |
8820 | } |
8821 | |
8822 | |
8823 | |
8824 | void Field_geom::sql_type(String &res) const |
8825 | { |
8826 | CHARSET_INFO *cs= &my_charset_latin1; |
8827 | switch (geom_type) |
8828 | { |
8829 | case GEOM_POINT: |
8830 | res.set(STRING_WITH_LEN("point" ), cs); |
8831 | break; |
8832 | case GEOM_LINESTRING: |
8833 | res.set(STRING_WITH_LEN("linestring" ), cs); |
8834 | break; |
8835 | case GEOM_POLYGON: |
8836 | res.set(STRING_WITH_LEN("polygon" ), cs); |
8837 | break; |
8838 | case GEOM_MULTIPOINT: |
8839 | res.set(STRING_WITH_LEN("multipoint" ), cs); |
8840 | break; |
8841 | case GEOM_MULTILINESTRING: |
8842 | res.set(STRING_WITH_LEN("multilinestring" ), cs); |
8843 | break; |
8844 | case GEOM_MULTIPOLYGON: |
8845 | res.set(STRING_WITH_LEN("multipolygon" ), cs); |
8846 | break; |
8847 | case GEOM_GEOMETRYCOLLECTION: |
8848 | res.set(STRING_WITH_LEN("geometrycollection" ), cs); |
8849 | break; |
8850 | default: |
8851 | res.set(STRING_WITH_LEN("geometry" ), cs); |
8852 | } |
8853 | } |
8854 | |
8855 | |
8856 | int Field_geom::store(double nr) |
8857 | { |
8858 | my_message(ER_CANT_CREATE_GEOMETRY_OBJECT, |
8859 | ER_THD(get_thd(), ER_CANT_CREATE_GEOMETRY_OBJECT), MYF(0)); |
8860 | return -1; |
8861 | } |
8862 | |
8863 | |
8864 | int Field_geom::store(longlong nr, bool unsigned_val) |
8865 | { |
8866 | my_message(ER_CANT_CREATE_GEOMETRY_OBJECT, |
8867 | ER_THD(get_thd(), ER_CANT_CREATE_GEOMETRY_OBJECT), MYF(0)); |
8868 | return -1; |
8869 | } |
8870 | |
8871 | |
8872 | int Field_geom::store_decimal(const my_decimal *) |
8873 | { |
8874 | my_message(ER_CANT_CREATE_GEOMETRY_OBJECT, |
8875 | ER_THD(get_thd(), ER_CANT_CREATE_GEOMETRY_OBJECT), MYF(0)); |
8876 | return -1; |
8877 | } |
8878 | |
8879 | |
8880 | int Field_geom::store(const char *from, size_t length, CHARSET_INFO *cs) |
8881 | { |
8882 | if (!length) |
8883 | bzero(ptr, Field_blob::pack_length()); |
8884 | else |
8885 | { |
8886 | if (from == Geometry::bad_geometry_data.ptr()) |
8887 | goto err; |
8888 | // Check given WKB |
8889 | uint32 wkb_type; |
8890 | if (length < SRID_SIZE + WKB_HEADER_SIZE + 4) |
8891 | goto err; |
8892 | wkb_type= uint4korr(from + SRID_SIZE + 1); |
8893 | if (wkb_type < (uint32) Geometry::wkb_point || |
8894 | wkb_type > (uint32) Geometry::wkb_last) |
8895 | goto err; |
8896 | |
8897 | if (geom_type != Field::GEOM_GEOMETRY && |
8898 | geom_type != Field::GEOM_GEOMETRYCOLLECTION && |
8899 | (uint32) geom_type != wkb_type) |
8900 | { |
8901 | my_error(ER_TRUNCATED_WRONG_VALUE_FOR_FIELD, MYF(0), |
8902 | Geometry::ci_collection[geom_type]->m_name.str, |
8903 | Geometry::ci_collection[wkb_type]->m_name.str, |
8904 | field_name.str, |
8905 | (ulong) table->in_use->get_stmt_da()-> |
8906 | current_row_for_warning()); |
8907 | goto err_exit; |
8908 | } |
8909 | |
8910 | Field_blob::store_length(length); |
8911 | if ((table->copy_blobs || length <= MAX_FIELD_WIDTH) && |
8912 | from != value.ptr()) |
8913 | { // Must make a copy |
8914 | value.copy(from, length, cs); |
8915 | from= value.ptr(); |
8916 | } |
8917 | bmove(ptr + packlength, &from, sizeof(char*)); |
8918 | } |
8919 | return 0; |
8920 | |
8921 | err: |
8922 | my_message(ER_CANT_CREATE_GEOMETRY_OBJECT, |
8923 | ER_THD(get_thd(), ER_CANT_CREATE_GEOMETRY_OBJECT), MYF(0)); |
8924 | err_exit: |
8925 | bzero(ptr, Field_blob::pack_length()); |
8926 | return -1; |
8927 | } |
8928 | |
8929 | Field::geometry_type Field_geom::geometry_type_merge(geometry_type a, |
8930 | geometry_type b) |
8931 | { |
8932 | if (a == b) |
8933 | return a; |
8934 | return Field::GEOM_GEOMETRY; |
8935 | } |
8936 | |
8937 | |
8938 | uint Field_geom::is_equal(Create_field *new_field) |
8939 | { |
8940 | return new_field->type_handler() == type_handler() && |
8941 | /* |
8942 | - Allow ALTER..INPLACE to supertype (GEOMETRY), |
8943 | e.g. POINT to GEOMETRY or POLYGON to GEOMETRY. |
8944 | - Allow ALTER..INPLACE to the same geometry type: POINT -> POINT |
8945 | */ |
8946 | (new_field->geom_type == geom_type || |
8947 | new_field->geom_type == GEOM_GEOMETRY); |
8948 | } |
8949 | |
8950 | |
8951 | bool Field_geom::can_optimize_range(const Item_bool_func *cond, |
8952 | const Item *item, |
8953 | bool is_eq_func) const |
8954 | { |
8955 | return item->cmp_type() == STRING_RESULT; |
8956 | } |
8957 | |
8958 | |
8959 | bool Field_geom::load_data_set_no_data(THD *thd, bool fixed_format) |
8960 | { |
8961 | return Field_geom::load_data_set_null(thd); |
8962 | } |
8963 | |
8964 | |
8965 | bool Field_geom::load_data_set_null(THD *thd) |
8966 | { |
8967 | Field_blob::reset(); |
8968 | if (!maybe_null()) |
8969 | { |
8970 | my_error(ER_WARN_NULL_TO_NOTNULL, MYF(0), field_name.str, |
8971 | thd->get_stmt_da()->current_row_for_warning()); |
8972 | return true; |
8973 | } |
8974 | set_null(); |
8975 | set_has_explicit_value(); // Do not auto-update this field |
8976 | return false; |
8977 | } |
8978 | |
8979 | |
8980 | #endif /*HAVE_SPATIAL*/ |
8981 | |
8982 | /**************************************************************************** |
8983 | ** enum type. |
8984 | ** This is a string which only can have a selection of different values. |
8985 | ** If one uses this string in a number context one gets the type number. |
8986 | ****************************************************************************/ |
8987 | |
8988 | enum ha_base_keytype Field_enum::key_type() const |
8989 | { |
8990 | switch (packlength) { |
8991 | default: return HA_KEYTYPE_BINARY; |
8992 | case 2: return HA_KEYTYPE_USHORT_INT; |
8993 | case 3: return HA_KEYTYPE_UINT24; |
8994 | case 4: return HA_KEYTYPE_ULONG_INT; |
8995 | case 8: return HA_KEYTYPE_ULONGLONG; |
8996 | } |
8997 | } |
8998 | |
8999 | void Field_enum::store_type(ulonglong value) |
9000 | { |
9001 | store_lowendian(value, ptr, packlength); |
9002 | } |
9003 | |
9004 | |
9005 | /** |
9006 | @note |
9007 | Storing a empty string in a enum field gives a warning |
9008 | (if there isn't a empty value in the enum) |
9009 | */ |
9010 | |
9011 | int Field_enum::store(const char *from,size_t length,CHARSET_INFO *cs) |
9012 | { |
9013 | ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; |
9014 | int err= 0; |
9015 | char buff[STRING_BUFFER_USUAL_SIZE]; |
9016 | String tmpstr(buff,sizeof(buff), &my_charset_bin); |
9017 | |
9018 | /* Convert character set if necessary */ |
9019 | if (String::needs_conversion_on_storage(length, cs, field_charset)) |
9020 | { |
9021 | uint dummy_errors; |
9022 | tmpstr.copy(from, length, cs, field_charset, &dummy_errors); |
9023 | from= tmpstr.ptr(); |
9024 | length= tmpstr.length(); |
9025 | } |
9026 | |
9027 | /* Remove end space */ |
9028 | length= (uint)field_charset->cset->lengthsp(field_charset, from, length); |
9029 | uint tmp=find_type2(typelib, from, length, field_charset); |
9030 | if (!tmp) |
9031 | { |
9032 | if (length < 6) // Can't be more than 99999 enums |
9033 | { |
9034 | /* This is for reading numbers with LOAD DATA INFILE */ |
9035 | char *end; |
9036 | tmp=(uint) my_strntoul(cs,from,length,10,&end,&err); |
9037 | if (err || end != from+length || tmp > typelib->count) |
9038 | { |
9039 | tmp=0; |
9040 | set_warning(WARN_DATA_TRUNCATED, 1); |
9041 | err= 1; |
9042 | } |
9043 | if ((get_thd()->count_cuted_fields <= CHECK_FIELD_EXPRESSION) && !length) |
9044 | err= 0; |
9045 | } |
9046 | else |
9047 | { |
9048 | set_warning(WARN_DATA_TRUNCATED, 1); |
9049 | err= 1; |
9050 | } |
9051 | } |
9052 | store_type((ulonglong) tmp); |
9053 | return err; |
9054 | } |
9055 | |
9056 | |
9057 | int Field_enum::store(double nr) |
9058 | { |
9059 | return Field_enum::store((longlong) nr, FALSE); |
9060 | } |
9061 | |
9062 | |
9063 | int Field_enum::store(longlong nr, bool unsigned_val) |
9064 | { |
9065 | ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; |
9066 | int error= 0; |
9067 | if ((ulonglong) nr > typelib->count || nr == 0) |
9068 | { |
9069 | set_warning(WARN_DATA_TRUNCATED, 1); |
9070 | if (nr != 0 || get_thd()->count_cuted_fields > CHECK_FIELD_EXPRESSION) |
9071 | { |
9072 | nr= 0; |
9073 | error= 1; |
9074 | } |
9075 | } |
9076 | store_type((ulonglong) (uint) nr); |
9077 | return error; |
9078 | } |
9079 | |
9080 | |
9081 | double Field_enum::val_real(void) |
9082 | { |
9083 | return (double) Field_enum::val_int(); |
9084 | } |
9085 | |
9086 | |
9087 | longlong Field_enum::val_int(void) |
9088 | { |
9089 | ASSERT_COLUMN_MARKED_FOR_READ; |
9090 | return read_lowendian(ptr, packlength); |
9091 | } |
9092 | |
9093 | |
9094 | /** |
9095 | Save the field metadata for enum fields. |
9096 | |
9097 | Saves the real type in the first byte and the pack length in the |
9098 | second byte of the field metadata array at index of *metadata_ptr and |
9099 | *(metadata_ptr + 1). |
9100 | |
9101 | @param metadata_ptr First byte of field metadata |
9102 | |
9103 | @returns number of bytes written to metadata_ptr |
9104 | */ |
9105 | int Field_enum::save_field_metadata(uchar *metadata_ptr) |
9106 | { |
9107 | *metadata_ptr= real_type(); |
9108 | *(metadata_ptr + 1)= pack_length(); |
9109 | return 2; |
9110 | } |
9111 | |
9112 | |
9113 | String *Field_enum::val_str(String *val_buffer __attribute__((unused)), |
9114 | String *val_ptr) |
9115 | { |
9116 | uint tmp=(uint) Field_enum::val_int(); |
9117 | if (!tmp || tmp > typelib->count) |
9118 | val_ptr->set("" , 0, field_charset); |
9119 | else |
9120 | val_ptr->set((const char*) typelib->type_names[tmp-1], |
9121 | typelib->type_lengths[tmp-1], |
9122 | field_charset); |
9123 | return val_ptr; |
9124 | } |
9125 | |
9126 | int Field_enum::cmp(const uchar *a_ptr, const uchar *b_ptr) |
9127 | { |
9128 | uchar *old= ptr; |
9129 | ptr= (uchar*) a_ptr; |
9130 | ulonglong a=Field_enum::val_int(); |
9131 | ptr= (uchar*) b_ptr; |
9132 | ulonglong b=Field_enum::val_int(); |
9133 | ptr= old; |
9134 | return (a < b) ? -1 : (a > b) ? 1 : 0; |
9135 | } |
9136 | |
9137 | void Field_enum::sort_string(uchar *to,uint length __attribute__((unused))) |
9138 | { |
9139 | ulonglong value=Field_enum::val_int(); |
9140 | to+=packlength-1; |
9141 | for (uint i=0 ; i < packlength ; i++) |
9142 | { |
9143 | *to-- = (uchar) (value & 255); |
9144 | value>>=8; |
9145 | } |
9146 | } |
9147 | |
9148 | |
9149 | void Field_enum::sql_type(String &res) const |
9150 | { |
9151 | char buffer[255]; |
9152 | String enum_item(buffer, sizeof(buffer), res.charset()); |
9153 | |
9154 | res.length(0); |
9155 | res.append(STRING_WITH_LEN("enum(" )); |
9156 | |
9157 | bool flag=0; |
9158 | uint *len= typelib->type_lengths; |
9159 | for (const char **pos= typelib->type_names; *pos; pos++, len++) |
9160 | { |
9161 | uint dummy_errors; |
9162 | if (flag) |
9163 | res.append(','); |
9164 | /* convert to res.charset() == utf8, then quote */ |
9165 | enum_item.copy(*pos, *len, charset(), res.charset(), &dummy_errors); |
9166 | append_unescaped(&res, enum_item.ptr(), enum_item.length()); |
9167 | flag= 1; |
9168 | } |
9169 | res.append(')'); |
9170 | } |
9171 | |
9172 | |
9173 | Field *Field_enum::make_new_field(MEM_ROOT *root, TABLE *new_table, |
9174 | bool keep_type) |
9175 | { |
9176 | Field_enum *res= (Field_enum*) Field::make_new_field(root, new_table, |
9177 | keep_type); |
9178 | if (res) |
9179 | res->typelib= copy_typelib(root, typelib); |
9180 | return res; |
9181 | } |
9182 | |
9183 | |
9184 | /* |
9185 | set type. |
9186 | This is a string which can have a collection of different values. |
9187 | Each string value is separated with a ','. |
9188 | For example "One,two,five" |
9189 | If one uses this string in a number context one gets the bits as a longlong |
9190 | number. |
9191 | */ |
9192 | |
9193 | |
9194 | int Field_set::store(const char *from,size_t length,CHARSET_INFO *cs) |
9195 | { |
9196 | ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; |
9197 | bool got_warning= 0; |
9198 | int err= 0; |
9199 | char *not_used; |
9200 | uint not_used2; |
9201 | char buff[STRING_BUFFER_USUAL_SIZE]; |
9202 | String tmpstr(buff,sizeof(buff), &my_charset_bin); |
9203 | |
9204 | /* Convert character set if necessary */ |
9205 | if (String::needs_conversion_on_storage(length, cs, field_charset)) |
9206 | { |
9207 | uint dummy_errors; |
9208 | tmpstr.copy(from, length, cs, field_charset, &dummy_errors); |
9209 | from= tmpstr.ptr(); |
9210 | length= tmpstr.length(); |
9211 | } |
9212 | ulonglong tmp= find_set(typelib, from, length, field_charset, |
9213 | ¬_used, ¬_used2, &got_warning); |
9214 | if (!tmp && length && length < 22) |
9215 | { |
9216 | /* This is for reading numbers with LOAD DATA INFILE */ |
9217 | char *end; |
9218 | tmp=my_strntoull(cs,from,length,10,&end,&err); |
9219 | if (err || end != from+length || |
9220 | tmp > (ulonglong) (((longlong) 1 << typelib->count) - (longlong) 1)) |
9221 | { |
9222 | tmp=0; |
9223 | set_warning(WARN_DATA_TRUNCATED, 1); |
9224 | err= 1; |
9225 | } |
9226 | } |
9227 | else if (got_warning) |
9228 | set_warning(WARN_DATA_TRUNCATED, 1); |
9229 | store_type(tmp); |
9230 | return err; |
9231 | } |
9232 | |
9233 | |
9234 | int Field_set::store(longlong nr, bool unsigned_val) |
9235 | { |
9236 | ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; |
9237 | int error= 0; |
9238 | ulonglong max_nr; |
9239 | |
9240 | if (sizeof(ulonglong)*8 <= typelib->count) |
9241 | max_nr= ULONGLONG_MAX; |
9242 | else |
9243 | max_nr= (1ULL << typelib->count) - 1; |
9244 | |
9245 | if ((ulonglong) nr > max_nr) |
9246 | { |
9247 | nr&= max_nr; |
9248 | set_warning(WARN_DATA_TRUNCATED, 1); |
9249 | error=1; |
9250 | } |
9251 | store_type((ulonglong) nr); |
9252 | return error; |
9253 | } |
9254 | |
9255 | |
9256 | String *Field_set::val_str(String *val_buffer, |
9257 | String *val_ptr __attribute__((unused))) |
9258 | { |
9259 | ulonglong tmp=(ulonglong) Field_enum::val_int(); |
9260 | uint bitnr=0; |
9261 | |
9262 | /* |
9263 | Some callers expect *val_buffer to contain the result, |
9264 | so we assign to it, rather than doing 'return &empty_set_string. |
9265 | */ |
9266 | *val_buffer= empty_set_string; |
9267 | if (tmp == 0) |
9268 | { |
9269 | return val_buffer; |
9270 | } |
9271 | |
9272 | val_buffer->set_charset(field_charset); |
9273 | val_buffer->length(0); |
9274 | |
9275 | while (tmp && bitnr < (uint) typelib->count) |
9276 | { |
9277 | if (tmp & 1) |
9278 | { |
9279 | if (val_buffer->length()) |
9280 | val_buffer->append(&field_separator, 1, &my_charset_latin1); |
9281 | String str(typelib->type_names[bitnr], |
9282 | typelib->type_lengths[bitnr], |
9283 | field_charset); |
9284 | val_buffer->append(str); |
9285 | } |
9286 | tmp>>=1; |
9287 | bitnr++; |
9288 | } |
9289 | return val_buffer; |
9290 | } |
9291 | |
9292 | |
9293 | void Field_set::sql_type(String &res) const |
9294 | { |
9295 | char buffer[255]; |
9296 | String set_item(buffer, sizeof(buffer), res.charset()); |
9297 | |
9298 | res.length(0); |
9299 | res.append(STRING_WITH_LEN("set(" )); |
9300 | |
9301 | bool flag=0; |
9302 | uint *len= typelib->type_lengths; |
9303 | for (const char **pos= typelib->type_names; *pos; pos++, len++) |
9304 | { |
9305 | uint dummy_errors; |
9306 | if (flag) |
9307 | res.append(','); |
9308 | /* convert to res.charset() == utf8, then quote */ |
9309 | set_item.copy(*pos, *len, charset(), res.charset(), &dummy_errors); |
9310 | append_unescaped(&res, set_item.ptr(), set_item.length()); |
9311 | flag= 1; |
9312 | } |
9313 | res.append(')'); |
9314 | } |
9315 | |
9316 | /** |
9317 | @retval |
9318 | 1 if the fields are equally defined |
9319 | @retval |
9320 | 0 if the fields are unequally defined |
9321 | */ |
9322 | |
9323 | bool Field::eq_def(const Field *field) const |
9324 | { |
9325 | if (real_type() != field->real_type() || charset() != field->charset() || |
9326 | pack_length() != field->pack_length()) |
9327 | return 0; |
9328 | return 1; |
9329 | } |
9330 | |
9331 | |
9332 | /** |
9333 | Compare the first t1::count type names. |
9334 | |
9335 | @return TRUE if the type names of t1 match those of t2. FALSE otherwise. |
9336 | */ |
9337 | |
9338 | static bool compare_type_names(CHARSET_INFO *charset, TYPELIB *t1, TYPELIB *t2) |
9339 | { |
9340 | for (uint i= 0; i < t1->count; i++) |
9341 | if (my_strnncoll(charset, |
9342 | (const uchar*) t1->type_names[i], |
9343 | t1->type_lengths[i], |
9344 | (const uchar*) t2->type_names[i], |
9345 | t2->type_lengths[i])) |
9346 | return FALSE; |
9347 | return TRUE; |
9348 | } |
9349 | |
9350 | /** |
9351 | @return |
9352 | returns 1 if the fields are equally defined |
9353 | */ |
9354 | |
9355 | bool Field_enum::eq_def(const Field *field) const |
9356 | { |
9357 | TYPELIB *values; |
9358 | |
9359 | if (!Field::eq_def(field)) |
9360 | return FALSE; |
9361 | |
9362 | values= ((Field_enum*) field)->typelib; |
9363 | |
9364 | /* Definition must be strictly equal. */ |
9365 | if (typelib->count != values->count) |
9366 | return FALSE; |
9367 | |
9368 | return compare_type_names(field_charset, typelib, values); |
9369 | } |
9370 | |
9371 | |
9372 | /** |
9373 | Check whether two fields can be considered 'equal' for table |
9374 | alteration purposes. Fields are equal if they retain the same |
9375 | pack length and if new members are added to the end of the list. |
9376 | |
9377 | @return IS_EQUAL_YES if fields are compatible. |
9378 | IS_EQUAL_NO otherwise. |
9379 | */ |
9380 | |
9381 | uint Field_enum::is_equal(Create_field *new_field) |
9382 | { |
9383 | TYPELIB *values= new_field->interval; |
9384 | |
9385 | /* |
9386 | The fields are compatible if they have the same flags, |
9387 | type, charset and have the same underlying length. |
9388 | */ |
9389 | if (new_field->type_handler() != type_handler() || |
9390 | new_field->charset != field_charset || |
9391 | new_field->pack_length != pack_length()) |
9392 | return IS_EQUAL_NO; |
9393 | |
9394 | /* |
9395 | Changing the definition of an ENUM or SET column by adding a new |
9396 | enumeration or set members to the end of the list of valid member |
9397 | values only alters table metadata and not table data. |
9398 | */ |
9399 | if (typelib->count > values->count) |
9400 | return IS_EQUAL_NO; |
9401 | |
9402 | /* Check whether there are modification before the end. */ |
9403 | if (! compare_type_names(field_charset, typelib, new_field->interval)) |
9404 | return IS_EQUAL_NO; |
9405 | |
9406 | return IS_EQUAL_YES; |
9407 | } |
9408 | |
9409 | |
9410 | uchar *Field_enum::pack(uchar *to, const uchar *from, uint max_length) |
9411 | { |
9412 | DBUG_ENTER("Field_enum::pack" ); |
9413 | DBUG_PRINT("debug" , ("packlength: %d" , packlength)); |
9414 | DBUG_DUMP("from" , from, packlength); |
9415 | DBUG_RETURN(pack_int(to, from, packlength)); |
9416 | } |
9417 | |
9418 | const uchar *Field_enum::unpack(uchar *to, const uchar *from, |
9419 | const uchar *from_end, uint param_data) |
9420 | { |
9421 | DBUG_ENTER("Field_enum::unpack" ); |
9422 | DBUG_PRINT("debug" , ("packlength: %d" , packlength)); |
9423 | DBUG_DUMP("from" , from, packlength); |
9424 | DBUG_RETURN(unpack_int(to, from, from_end, packlength)); |
9425 | } |
9426 | |
9427 | |
9428 | /** |
9429 | @return |
9430 | returns 1 if the fields are equally defined |
9431 | */ |
9432 | bool Field_num::eq_def(const Field *field) const |
9433 | { |
9434 | if (!Field::eq_def(field)) |
9435 | return 0; |
9436 | Field_num *from_num= (Field_num*) field; |
9437 | |
9438 | if (unsigned_flag != from_num->unsigned_flag || |
9439 | (zerofill && !from_num->zerofill && !zero_pack()) || |
9440 | dec != from_num->dec) |
9441 | return 0; |
9442 | return 1; |
9443 | } |
9444 | |
9445 | |
9446 | /** |
9447 | Check whether two numeric fields can be considered 'equal' for table |
9448 | alteration purposes. Fields are equal if they are of the same type |
9449 | and retain the same pack length. |
9450 | */ |
9451 | |
9452 | uint Field_num::is_equal(Create_field *new_field) |
9453 | { |
9454 | return ((new_field->type_handler() == type_handler()) && |
9455 | ((new_field->flags & UNSIGNED_FLAG) == |
9456 | (uint) (flags & UNSIGNED_FLAG)) && |
9457 | ((new_field->flags & AUTO_INCREMENT_FLAG) == |
9458 | (uint) (flags & AUTO_INCREMENT_FLAG)) && |
9459 | (new_field->pack_length == pack_length())); |
9460 | } |
9461 | |
9462 | |
9463 | bool Field_enum::can_optimize_range(const Item_bool_func *cond, |
9464 | const Item *item, |
9465 | bool is_eq_func) const |
9466 | { |
9467 | return item->cmp_type() != TIME_RESULT; |
9468 | } |
9469 | |
9470 | |
9471 | bool Field_enum::can_optimize_keypart_ref(const Item_bool_func *cond, |
9472 | const Item *item) const |
9473 | { |
9474 | switch (item->cmp_type()) |
9475 | { |
9476 | case TIME_RESULT: |
9477 | return false; |
9478 | case INT_RESULT: |
9479 | case DECIMAL_RESULT: |
9480 | case REAL_RESULT: |
9481 | return true; |
9482 | case STRING_RESULT: |
9483 | return charset() == cond->compare_collation(); |
9484 | case ROW_RESULT: |
9485 | DBUG_ASSERT(0); |
9486 | break; |
9487 | } |
9488 | return false; |
9489 | } |
9490 | |
9491 | |
9492 | /* |
9493 | Bit field. |
9494 | |
9495 | We store the first 0 - 6 uneven bits among the null bits |
9496 | at the start of the record. The rest bytes are stored in |
9497 | the record itself. |
9498 | |
9499 | For example: |
9500 | |
9501 | CREATE TABLE t1 (a int, b bit(17), c bit(21) not null, d bit(8)); |
9502 | We would store data as follows in the record: |
9503 | |
9504 | Byte Bit |
9505 | 1 7 - reserve for delete |
9506 | 6 - null bit for 'a' |
9507 | 5 - null bit for 'b' |
9508 | 4 - first (high) bit of 'b' |
9509 | 3 - first (high) bit of 'c' |
9510 | 2 - second bit of 'c' |
9511 | 1 - third bit of 'c' |
9512 | 0 - forth bit of 'c' |
9513 | 2 7 - firth bit of 'c' |
9514 | 6 - null bit for 'd' |
9515 | 3 - 6 four bytes for 'a' |
9516 | 7 - 8 two bytes for 'b' |
9517 | 9 - 10 two bytes for 'c' |
9518 | 11 one byte for 'd' |
9519 | */ |
9520 | |
9521 | Field_bit::Field_bit(uchar *ptr_arg, uint32 len_arg, uchar *null_ptr_arg, |
9522 | uchar null_bit_arg, uchar *bit_ptr_arg, uchar bit_ofs_arg, |
9523 | enum utype unireg_check_arg, |
9524 | const LEX_CSTRING *field_name_arg) |
9525 | : Field(ptr_arg, len_arg, null_ptr_arg, null_bit_arg, |
9526 | unireg_check_arg, field_name_arg), |
9527 | bit_ptr(bit_ptr_arg), bit_ofs(bit_ofs_arg), bit_len(len_arg & 7), |
9528 | bytes_in_rec(len_arg / 8) |
9529 | { |
9530 | DBUG_ENTER("Field_bit::Field_bit" ); |
9531 | DBUG_PRINT("enter" , ("ptr_arg: %p, null_ptr_arg: %p, len_arg: %u, bit_len: %u, bytes_in_rec: %u" , |
9532 | ptr_arg, null_ptr_arg, len_arg, bit_len, bytes_in_rec)); |
9533 | flags|= UNSIGNED_FLAG; |
9534 | /* |
9535 | Ensure that Field::eq() can distinguish between two different bit fields. |
9536 | (two bit fields that are not null, may have same ptr and null_ptr) |
9537 | */ |
9538 | if (!null_ptr_arg) |
9539 | null_bit= bit_ofs_arg; |
9540 | DBUG_VOID_RETURN; |
9541 | } |
9542 | |
9543 | |
9544 | void Field_bit::hash(ulong *nr, ulong *nr2) |
9545 | { |
9546 | if (is_null()) |
9547 | { |
9548 | *nr^= (*nr << 1) | 1; |
9549 | } |
9550 | else |
9551 | { |
9552 | CHARSET_INFO *cs= &my_charset_bin; |
9553 | longlong value= Field_bit::val_int(); |
9554 | uchar tmp[8]; |
9555 | mi_int8store(tmp,value); |
9556 | cs->coll->hash_sort(cs, tmp, 8, nr, nr2); |
9557 | } |
9558 | } |
9559 | |
9560 | |
9561 | size_t |
9562 | Field_bit::do_last_null_byte() const |
9563 | { |
9564 | /* |
9565 | Code elsewhere is assuming that bytes are 8 bits, so I'm using |
9566 | that value instead of the correct one: CHAR_BIT. |
9567 | |
9568 | REFACTOR SUGGESTION (Matz): Change to use the correct number of |
9569 | bits. On systems with CHAR_BIT > 8 (not very common), the storage |
9570 | will lose the extra bits. |
9571 | */ |
9572 | DBUG_PRINT("test" , ("bit_ofs: %d, bit_len: %d bit_ptr: %p" , |
9573 | bit_ofs, bit_len, bit_ptr)); |
9574 | uchar *result; |
9575 | if (bit_len == 0) |
9576 | result= null_ptr; |
9577 | else if (bit_ofs + bit_len > 8) |
9578 | result= bit_ptr + 1; |
9579 | else |
9580 | result= bit_ptr; |
9581 | |
9582 | if (result) |
9583 | return (size_t) (result - table->record[0]) + 1; |
9584 | return LAST_NULL_BYTE_UNDEF; |
9585 | } |
9586 | |
9587 | |
9588 | Field *Field_bit::new_key_field(MEM_ROOT *root, TABLE *new_table, |
9589 | uchar *new_ptr, uint32 length, |
9590 | uchar *new_null_ptr, uint new_null_bit) |
9591 | { |
9592 | Field_bit *res; |
9593 | if ((res= (Field_bit*) Field::new_key_field(root, new_table, new_ptr, length, |
9594 | new_null_ptr, new_null_bit))) |
9595 | { |
9596 | /* Move bits normally stored in null_pointer to new_ptr */ |
9597 | res->bit_ptr= new_ptr; |
9598 | res->bit_ofs= 0; |
9599 | if (bit_len) |
9600 | res->ptr++; // Store rest of data here |
9601 | } |
9602 | return res; |
9603 | } |
9604 | |
9605 | |
9606 | uint Field_bit::is_equal(Create_field *new_field) |
9607 | { |
9608 | return new_field->type_handler() == type_handler() && |
9609 | new_field->length == max_display_length(); |
9610 | } |
9611 | |
9612 | |
9613 | int Field_bit::store(const char *from, size_t length, CHARSET_INFO *cs) |
9614 | { |
9615 | ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; |
9616 | int delta; |
9617 | |
9618 | for (; length && !*from; from++, length--) // skip left 0's |
9619 | ; |
9620 | delta= (int)(bytes_in_rec - length); |
9621 | |
9622 | if (delta < -1 || |
9623 | (delta == -1 && (uchar) *from > ((1 << bit_len) - 1)) || |
9624 | (!bit_len && delta < 0)) |
9625 | { |
9626 | set_rec_bits((1 << bit_len) - 1, bit_ptr, bit_ofs, bit_len); |
9627 | memset(ptr, 0xff, bytes_in_rec); |
9628 | if (get_thd()->really_abort_on_warning()) |
9629 | set_warning(ER_DATA_TOO_LONG, 1); |
9630 | else |
9631 | set_warning(ER_WARN_DATA_OUT_OF_RANGE, 1); |
9632 | return 1; |
9633 | } |
9634 | /* delta is >= -1 here */ |
9635 | if (delta > 0) |
9636 | { |
9637 | if (bit_len) |
9638 | clr_rec_bits(bit_ptr, bit_ofs, bit_len); |
9639 | bzero(ptr, delta); |
9640 | memcpy(ptr + delta, from, length); |
9641 | } |
9642 | else if (delta == 0) |
9643 | { |
9644 | if (bit_len) |
9645 | clr_rec_bits(bit_ptr, bit_ofs, bit_len); |
9646 | memcpy(ptr, from, length); |
9647 | } |
9648 | else |
9649 | { |
9650 | if (bit_len) |
9651 | { |
9652 | set_rec_bits((uchar) *from, bit_ptr, bit_ofs, bit_len); |
9653 | from++; |
9654 | } |
9655 | memcpy(ptr, from, bytes_in_rec); |
9656 | } |
9657 | return 0; |
9658 | } |
9659 | |
9660 | |
9661 | int Field_bit::store(double nr) |
9662 | { |
9663 | return Field_bit::store((longlong) nr, FALSE); |
9664 | } |
9665 | |
9666 | |
9667 | int Field_bit::store(longlong nr, bool unsigned_val) |
9668 | { |
9669 | char buf[8]; |
9670 | |
9671 | mi_int8store(buf, nr); |
9672 | return store(buf, 8, NULL); |
9673 | } |
9674 | |
9675 | |
9676 | int Field_bit::store_decimal(const my_decimal *val) |
9677 | { |
9678 | int err= 0; |
9679 | longlong i= convert_decimal2longlong(val, 1, &err); |
9680 | return MY_TEST(err | store(i, TRUE)); |
9681 | } |
9682 | |
9683 | |
9684 | double Field_bit::val_real(void) |
9685 | { |
9686 | return (double) Field_bit::val_int(); |
9687 | } |
9688 | |
9689 | |
9690 | longlong Field_bit::val_int(void) |
9691 | { |
9692 | ASSERT_COLUMN_MARKED_FOR_READ; |
9693 | ulonglong bits= 0; |
9694 | if (bit_len) |
9695 | { |
9696 | bits= get_rec_bits(bit_ptr, bit_ofs, bit_len); |
9697 | bits<<= (bytes_in_rec * 8); |
9698 | } |
9699 | |
9700 | switch (bytes_in_rec) { |
9701 | case 0: return bits; |
9702 | case 1: return bits | (ulonglong) ptr[0]; |
9703 | case 2: return bits | mi_uint2korr(ptr); |
9704 | case 3: return bits | mi_uint3korr(ptr); |
9705 | case 4: return bits | mi_uint4korr(ptr); |
9706 | case 5: return bits | mi_uint5korr(ptr); |
9707 | case 6: return bits | mi_uint6korr(ptr); |
9708 | case 7: return bits | mi_uint7korr(ptr); |
9709 | default: return mi_uint8korr(ptr + bytes_in_rec - sizeof(longlong)); |
9710 | } |
9711 | } |
9712 | |
9713 | |
9714 | String *Field_bit::val_str(String *val_buffer, |
9715 | String *val_ptr __attribute__((unused))) |
9716 | { |
9717 | ASSERT_COLUMN_MARKED_FOR_READ; |
9718 | char buff[sizeof(longlong)]; |
9719 | uint length= MY_MIN(pack_length(), sizeof(longlong)); |
9720 | ulonglong bits= val_int(); |
9721 | mi_int8store(buff,bits); |
9722 | |
9723 | val_buffer->alloc(length); |
9724 | memcpy((char *) val_buffer->ptr(), buff+8-length, length); |
9725 | val_buffer->length(length); |
9726 | val_buffer->set_charset(&my_charset_bin); |
9727 | return val_buffer; |
9728 | } |
9729 | |
9730 | |
9731 | my_decimal *Field_bit::val_decimal(my_decimal *deciaml_value) |
9732 | { |
9733 | ASSERT_COLUMN_MARKED_FOR_READ; |
9734 | int2my_decimal(E_DEC_FATAL_ERROR, val_int(), 1, deciaml_value); |
9735 | return deciaml_value; |
9736 | } |
9737 | |
9738 | |
9739 | /* |
9740 | Compare two bit fields using pointers within the record. |
9741 | SYNOPSIS |
9742 | cmp_max() |
9743 | a Pointer to field->ptr in first record |
9744 | b Pointer to field->ptr in second record |
9745 | max_len Maximum length used in index |
9746 | DESCRIPTION |
9747 | This method is used from key_rec_cmp used by merge sorts used |
9748 | by partitioned index read and later other similar places. |
9749 | The a and b pointer must be pointers to the field in a record |
9750 | (not the table->record[0] necessarily) |
9751 | */ |
9752 | int Field_bit::cmp_max(const uchar *a, const uchar *b, uint max_len) |
9753 | { |
9754 | my_ptrdiff_t a_diff= a - ptr; |
9755 | my_ptrdiff_t b_diff= b - ptr; |
9756 | if (bit_len) |
9757 | { |
9758 | int flag; |
9759 | uchar bits_a= get_rec_bits(bit_ptr+a_diff, bit_ofs, bit_len); |
9760 | uchar bits_b= get_rec_bits(bit_ptr+b_diff, bit_ofs, bit_len); |
9761 | if ((flag= (int) (bits_a - bits_b))) |
9762 | return flag; |
9763 | } |
9764 | if (!bytes_in_rec) |
9765 | return 0; |
9766 | return memcmp(a, b, bytes_in_rec); |
9767 | } |
9768 | |
9769 | |
9770 | int Field_bit::key_cmp(const uchar *str, uint length) |
9771 | { |
9772 | if (bit_len) |
9773 | { |
9774 | int flag; |
9775 | uchar bits= get_rec_bits(bit_ptr, bit_ofs, bit_len); |
9776 | if ((flag= (int) (bits - *str))) |
9777 | return flag; |
9778 | str++; |
9779 | length--; |
9780 | } |
9781 | return memcmp(ptr, str, bytes_in_rec); |
9782 | } |
9783 | |
9784 | |
9785 | int Field_bit::cmp_offset(uint row_offset) |
9786 | { |
9787 | if (bit_len) |
9788 | { |
9789 | int flag; |
9790 | uchar bits_a= get_rec_bits(bit_ptr, bit_ofs, bit_len); |
9791 | uchar bits_b= get_rec_bits(bit_ptr + row_offset, bit_ofs, bit_len); |
9792 | if ((flag= (int) (bits_a - bits_b))) |
9793 | return flag; |
9794 | } |
9795 | return memcmp(ptr, ptr + row_offset, bytes_in_rec); |
9796 | } |
9797 | |
9798 | |
9799 | uint Field_bit::get_key_image(uchar *buff, uint length, imagetype type_arg) |
9800 | { |
9801 | if (bit_len) |
9802 | { |
9803 | uchar bits= get_rec_bits(bit_ptr, bit_ofs, bit_len); |
9804 | *buff++= bits; |
9805 | length--; |
9806 | } |
9807 | uint tmp_data_length = MY_MIN(length, bytes_in_rec); |
9808 | memcpy(buff, ptr, tmp_data_length); |
9809 | return tmp_data_length + 1; |
9810 | } |
9811 | |
9812 | |
9813 | /** |
9814 | Save the field metadata for bit fields. |
9815 | |
9816 | Saves the bit length in the first byte and bytes in record in the |
9817 | second byte of the field metadata array at index of *metadata_ptr and |
9818 | *(metadata_ptr + 1). |
9819 | |
9820 | @param metadata_ptr First byte of field metadata |
9821 | |
9822 | @returns number of bytes written to metadata_ptr |
9823 | */ |
9824 | int Field_bit::save_field_metadata(uchar *metadata_ptr) |
9825 | { |
9826 | DBUG_ENTER("Field_bit::save_field_metadata" ); |
9827 | DBUG_PRINT("debug" , ("bit_len: %d, bytes_in_rec: %d" , |
9828 | bit_len, bytes_in_rec)); |
9829 | /* |
9830 | Since this class and Field_bit_as_char have different ideas of |
9831 | what should be stored here, we compute the values of the metadata |
9832 | explicitly using the field_length. |
9833 | */ |
9834 | metadata_ptr[0]= field_length % 8; |
9835 | metadata_ptr[1]= field_length / 8; |
9836 | DBUG_RETURN(2); |
9837 | } |
9838 | |
9839 | |
9840 | /** |
9841 | Returns the number of bytes field uses in row-based replication |
9842 | row packed size. |
9843 | |
9844 | This method is used in row-based replication to determine the number |
9845 | of bytes that the field consumes in the row record format. This is |
9846 | used to skip fields in the master that do not exist on the slave. |
9847 | |
9848 | @param field_metadata Encoded size in field metadata |
9849 | |
9850 | @returns The size of the field based on the field metadata. |
9851 | */ |
9852 | uint Field_bit::pack_length_from_metadata(uint field_metadata) |
9853 | { |
9854 | uint const from_len= (field_metadata >> 8U) & 0x00ff; |
9855 | uint const from_bit_len= field_metadata & 0x00ff; |
9856 | uint const source_size= from_len + ((from_bit_len > 0) ? 1 : 0); |
9857 | return (source_size); |
9858 | } |
9859 | |
9860 | |
9861 | bool |
9862 | Field_bit::compatible_field_size(uint field_metadata, |
9863 | Relay_log_info * __attribute__((unused)), |
9864 | uint16 mflags, |
9865 | int *order_var) |
9866 | { |
9867 | DBUG_ENTER("Field_bit::compatible_field_size" ); |
9868 | DBUG_ASSERT((field_metadata >> 16) == 0); |
9869 | uint from_bit_len= |
9870 | 8 * (field_metadata >> 8) + (field_metadata & 0xff); |
9871 | uint to_bit_len= max_display_length(); |
9872 | DBUG_PRINT("debug" , ("from_bit_len: %u, to_bit_len: %u" , |
9873 | from_bit_len, to_bit_len)); |
9874 | /* |
9875 | If the bit length exact flag is clear, we are dealing with an old |
9876 | master, so we allow some less strict behaviour if replicating by |
9877 | moving both bit lengths to an even multiple of 8. |
9878 | |
9879 | We do this by computing the number of bytes to store the field |
9880 | instead, and then compare the result. |
9881 | */ |
9882 | if (!(mflags & Table_map_log_event::TM_BIT_LEN_EXACT_F)) { |
9883 | from_bit_len= (from_bit_len + 7) / 8; |
9884 | to_bit_len= (to_bit_len + 7) / 8; |
9885 | } |
9886 | |
9887 | *order_var= compare(from_bit_len, to_bit_len); |
9888 | DBUG_RETURN(TRUE); |
9889 | } |
9890 | |
9891 | |
9892 | |
9893 | void Field_bit::sql_type(String &res) const |
9894 | { |
9895 | CHARSET_INFO *cs= res.charset(); |
9896 | size_t length= cs->cset->snprintf(cs, (char*) res.ptr(), res.alloced_length(), |
9897 | "bit(%d)" , (int) field_length); |
9898 | res.length(length); |
9899 | } |
9900 | |
9901 | |
9902 | uchar * |
9903 | Field_bit::pack(uchar *to, const uchar *from, uint max_length) |
9904 | { |
9905 | DBUG_ASSERT(max_length > 0); |
9906 | uint length; |
9907 | if (bit_len > 0) |
9908 | { |
9909 | /* |
9910 | We have the following: |
9911 | |
9912 | ptr Points into a field in record R1 |
9913 | from Points to a field in a record R2 |
9914 | bit_ptr Points to the byte (in the null bytes) that holds the |
9915 | odd bits of R1 |
9916 | from_bitp Points to the byte that holds the odd bits of R2 |
9917 | |
9918 | We have the following: |
9919 | |
9920 | ptr - bit_ptr = from - from_bitp |
9921 | |
9922 | We want to isolate 'from_bitp', so this gives: |
9923 | |
9924 | ptr - bit_ptr - from = - from_bitp |
9925 | - ptr + bit_ptr + from = from_bitp |
9926 | bit_ptr + from - ptr = from_bitp |
9927 | */ |
9928 | uchar bits= get_rec_bits(bit_ptr + (from - ptr), bit_ofs, bit_len); |
9929 | *to++= bits; |
9930 | } |
9931 | length= MY_MIN(bytes_in_rec, max_length - (bit_len > 0)); |
9932 | memcpy(to, from, length); |
9933 | return to + length; |
9934 | } |
9935 | |
9936 | |
9937 | /** |
9938 | Unpack a bit field from row data. |
9939 | |
9940 | This method is used to unpack a bit field from a master whose size |
9941 | of the field is less than that of the slave. |
9942 | |
9943 | @param to Destination of the data |
9944 | @param from Source of the data |
9945 | @param param_data Bit length (upper) and length (lower) values |
9946 | |
9947 | @return New pointer into memory based on from + length of the data |
9948 | */ |
9949 | const uchar * |
9950 | Field_bit::unpack(uchar *to, const uchar *from, const uchar *from_end, |
9951 | uint param_data) |
9952 | { |
9953 | DBUG_ENTER("Field_bit::unpack" ); |
9954 | DBUG_PRINT("enter" , ("to: %p, from: %p, param_data: 0x%x" , |
9955 | to, from, param_data)); |
9956 | DBUG_PRINT("debug" , ("bit_ptr: %p, bit_len: %u, bit_ofs: %u" , |
9957 | bit_ptr, bit_len, bit_ofs)); |
9958 | uint const from_len= (param_data >> 8U) & 0x00ff; |
9959 | uint const from_bit_len= param_data & 0x00ff; |
9960 | DBUG_PRINT("debug" , ("from_len: %u, from_bit_len: %u" , |
9961 | from_len, from_bit_len)); |
9962 | /* |
9963 | If the parameter data is zero (i.e., undefined), or if the master |
9964 | and slave have the same sizes, then use the old unpack() method. |
9965 | */ |
9966 | if (param_data == 0 || |
9967 | ((from_bit_len == bit_len) && (from_len == bytes_in_rec))) |
9968 | { |
9969 | if (from + bytes_in_rec + MY_TEST(bit_len) > from_end) |
9970 | return 0; // Error in data |
9971 | |
9972 | if (bit_len > 0) |
9973 | { |
9974 | /* |
9975 | set_rec_bits is a macro, don't put the post-increment in the |
9976 | argument since that might cause strange side-effects. |
9977 | |
9978 | For the choice of the second argument, see the explanation for |
9979 | Field_bit::pack(). |
9980 | */ |
9981 | set_rec_bits(*from, bit_ptr + (to - ptr), bit_ofs, bit_len); |
9982 | from++; |
9983 | } |
9984 | memcpy(to, from, bytes_in_rec); |
9985 | DBUG_RETURN(from + bytes_in_rec); |
9986 | } |
9987 | |
9988 | /* |
9989 | We are converting a smaller bit field to a larger one here. |
9990 | To do that, we first need to construct a raw value for the original |
9991 | bit value stored in the from buffer. Then that needs to be converted |
9992 | to the larger field then sent to store() for writing to the field. |
9993 | Lastly the odd bits need to be masked out if the bytes_in_rec > 0. |
9994 | Otherwise stray bits can cause spurious values. |
9995 | */ |
9996 | |
9997 | uint len= from_len + ((from_bit_len > 0) ? 1 : 0); |
9998 | uint new_len= (field_length + 7) / 8; |
9999 | |
10000 | if (from + len > from_end || new_len < len) |
10001 | return 0; // Error in data |
10002 | |
10003 | char *value= (char *)my_alloca(new_len); |
10004 | bzero(value, new_len); |
10005 | |
10006 | memcpy(value + (new_len - len), from, len); |
10007 | /* |
10008 | Mask out the unused bits in the partial byte. |
10009 | TODO: Add code to the master to always mask these bits and remove |
10010 | the following. |
10011 | */ |
10012 | if ((from_bit_len > 0) && (from_len > 0)) |
10013 | value[new_len - len]= value[new_len - len] & ((1U << from_bit_len) - 1); |
10014 | bitmap_set_bit(table->write_set,field_index); |
10015 | store(value, new_len, system_charset_info); |
10016 | my_afree(value); |
10017 | DBUG_RETURN(from + len); |
10018 | } |
10019 | |
10020 | |
10021 | int Field_bit::set_default() |
10022 | { |
10023 | if (bit_len > 0) |
10024 | { |
10025 | my_ptrdiff_t const col_offset= table->s->default_values - table->record[0]; |
10026 | uchar bits= get_rec_bits(bit_ptr + col_offset, bit_ofs, bit_len); |
10027 | set_rec_bits(bits, bit_ptr, bit_ofs, bit_len); |
10028 | } |
10029 | return Field::set_default(); |
10030 | } |
10031 | |
10032 | /* |
10033 | Bit field support for non-MyISAM tables. |
10034 | */ |
10035 | |
10036 | Field_bit_as_char::Field_bit_as_char(uchar *ptr_arg, uint32 len_arg, |
10037 | uchar *null_ptr_arg, uchar null_bit_arg, |
10038 | enum utype unireg_check_arg, |
10039 | const LEX_CSTRING *field_name_arg) |
10040 | :Field_bit(ptr_arg, len_arg, null_ptr_arg, null_bit_arg, 0, 0, |
10041 | unireg_check_arg, field_name_arg) |
10042 | { |
10043 | flags|= UNSIGNED_FLAG; |
10044 | bit_len= 0; |
10045 | bytes_in_rec= (len_arg + 7) / 8; |
10046 | } |
10047 | |
10048 | |
10049 | int Field_bit_as_char::store(const char *from, size_t length, CHARSET_INFO *cs) |
10050 | { |
10051 | ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; |
10052 | int delta; |
10053 | uchar bits= (uchar) (field_length & 7); |
10054 | |
10055 | for (; length && !*from; from++, length--) // skip left 0's |
10056 | ; |
10057 | delta= (int)(bytes_in_rec - length); |
10058 | |
10059 | if (delta < 0 || |
10060 | (delta == 0 && bits && (uint) (uchar) *from >= (uint) (1 << bits))) |
10061 | { |
10062 | memset(ptr, 0xff, bytes_in_rec); |
10063 | if (bits) |
10064 | *ptr&= ((1 << bits) - 1); /* set first uchar */ |
10065 | if (get_thd()->really_abort_on_warning()) |
10066 | set_warning(ER_DATA_TOO_LONG, 1); |
10067 | else |
10068 | set_warning(ER_WARN_DATA_OUT_OF_RANGE, 1); |
10069 | return 1; |
10070 | } |
10071 | bzero(ptr, delta); |
10072 | memcpy(ptr + delta, from, length); |
10073 | return 0; |
10074 | } |
10075 | |
10076 | |
10077 | void Field_bit_as_char::sql_type(String &res) const |
10078 | { |
10079 | CHARSET_INFO *cs= res.charset(); |
10080 | size_t length= cs->cset->snprintf(cs, (char*) res.ptr(), res.alloced_length(), |
10081 | "bit(%d)" , (int) field_length); |
10082 | res.length(length); |
10083 | } |
10084 | |
10085 | |
10086 | /***************************************************************************** |
10087 | Handling of field and Create_field |
10088 | *****************************************************************************/ |
10089 | |
10090 | bool Column_definition::create_interval_from_interval_list(MEM_ROOT *mem_root, |
10091 | bool reuse_interval_list_values) |
10092 | { |
10093 | DBUG_ENTER("Column_definition::create_interval_from_interval_list" ); |
10094 | DBUG_ASSERT(!interval); |
10095 | if (!(interval= (TYPELIB*) alloc_root(mem_root, sizeof(TYPELIB)))) |
10096 | DBUG_RETURN(true); // EOM |
10097 | |
10098 | List_iterator<String> it(interval_list); |
10099 | StringBuffer<64> conv; |
10100 | char comma_buf[5]; /* 5 bytes for 'filename' charset */ |
10101 | DBUG_ASSERT(sizeof(comma_buf) >= charset->mbmaxlen); |
10102 | int comma_length= charset->cset->wc_mb(charset, ',', |
10103 | (uchar*) comma_buf, |
10104 | (uchar*) comma_buf + |
10105 | sizeof(comma_buf)); |
10106 | DBUG_ASSERT(comma_length >= 0 && comma_length <= (int) sizeof(comma_buf)); |
10107 | |
10108 | if (!multi_alloc_root(mem_root, |
10109 | &interval->type_names, |
10110 | sizeof(char*) * (interval_list.elements + 1), |
10111 | &interval->type_lengths, |
10112 | sizeof(uint) * (interval_list.elements + 1), |
10113 | NullS)) |
10114 | goto err; // EOM |
10115 | |
10116 | interval->name= "" ; |
10117 | interval->count= interval_list.elements; |
10118 | |
10119 | for (uint i= 0; i < interval->count; i++) |
10120 | { |
10121 | uint32 dummy; |
10122 | String *tmp= it++; |
10123 | LEX_CSTRING value; |
10124 | if (String::needs_conversion(tmp->length(), tmp->charset(), |
10125 | charset, &dummy)) |
10126 | { |
10127 | uint cnv_errs; |
10128 | conv.copy(tmp->ptr(), tmp->length(), tmp->charset(), charset, &cnv_errs); |
10129 | value.str= strmake_root(mem_root, conv.ptr(), conv.length()); |
10130 | value.length= conv.length(); |
10131 | } |
10132 | else |
10133 | { |
10134 | value.str= reuse_interval_list_values ? tmp->ptr() : |
10135 | strmake_root(mem_root, |
10136 | tmp->ptr(), |
10137 | tmp->length()); |
10138 | value.length= tmp->length(); |
10139 | } |
10140 | if (!value.str) |
10141 | goto err; // EOM |
10142 | |
10143 | // Strip trailing spaces. |
10144 | value.length= charset->cset->lengthsp(charset, value.str, value.length); |
10145 | ((char*) value.str)[value.length]= '\0'; |
10146 | |
10147 | if (real_field_type() == MYSQL_TYPE_SET) |
10148 | { |
10149 | if (charset->coll->instr(charset, value.str, value.length, |
10150 | comma_buf, comma_length, NULL, 0)) |
10151 | { |
10152 | ErrConvString err(tmp); |
10153 | my_error(ER_ILLEGAL_VALUE_FOR_TYPE, MYF(0), "set" , err.ptr()); |
10154 | goto err; |
10155 | } |
10156 | } |
10157 | interval->type_names[i]= value.str; |
10158 | interval->type_lengths[i]= (uint)value.length; |
10159 | } |
10160 | interval->type_names[interval->count]= 0; // End marker |
10161 | interval->type_lengths[interval->count]= 0; |
10162 | interval_list.empty(); // Don't need interval_list anymore |
10163 | DBUG_RETURN(false); |
10164 | err: |
10165 | interval= NULL; // Avoid having both non-empty interval_list and interval |
10166 | DBUG_RETURN(true); |
10167 | } |
10168 | |
10169 | |
10170 | bool Column_definition::prepare_interval_field(MEM_ROOT *mem_root, |
10171 | bool reuse_interval_list_values) |
10172 | { |
10173 | DBUG_ENTER("Column_definition::prepare_interval_field" ); |
10174 | DBUG_ASSERT(real_field_type() == MYSQL_TYPE_ENUM || |
10175 | real_field_type() == MYSQL_TYPE_SET); |
10176 | /* |
10177 | Interval values are either in "interval" or in "interval_list", |
10178 | but not in both at the same time, and are not empty at the same time. |
10179 | - Values are in "interval_list" when we're coming from the parser |
10180 | in CREATE TABLE or in CREATE {FUNCTION|PROCEDURE}. |
10181 | - Values are in "interval" when we're in ALTER TABLE. |
10182 | |
10183 | In a corner case with an empty set like SET(''): |
10184 | - after the parser we have interval_list.elements==1 |
10185 | - in ALTER TABLE we have a non-NULL interval with interval->count==1, |
10186 | with interval->type_names[0]=="" and interval->type_lengths[0]==0. |
10187 | So the assert is still valid for this corner case. |
10188 | |
10189 | ENUM and SET with no values at all (e.g. ENUM(), SET()) are not possible, |
10190 | as the parser requires at least one element, so for a ENUM or SET field it |
10191 | should never happen that both internal_list.elements and interval are 0. |
10192 | */ |
10193 | DBUG_ASSERT((interval == NULL) == (interval_list.elements > 0)); |
10194 | |
10195 | /* |
10196 | Create typelib from interval_list, and if necessary |
10197 | convert strings from client character set to the |
10198 | column character set. |
10199 | */ |
10200 | if (interval_list.elements && |
10201 | create_interval_from_interval_list(mem_root, |
10202 | reuse_interval_list_values)) |
10203 | DBUG_RETURN(true); |
10204 | |
10205 | if (!reuse_interval_list_values) |
10206 | { |
10207 | /* |
10208 | We're initializing from an existing table or view Field_enum |
10209 | (e.g. for a %TYPE variable) rather than from the parser. |
10210 | The constructor Column_definition(THD*,Field*,Field*) has already |
10211 | copied the TYPELIB pointer from the original Field_enum. |
10212 | Now we need to make a permanent copy of that TYPELIB, |
10213 | as the original field can be freed before the end of the life |
10214 | cycle of "this". |
10215 | */ |
10216 | DBUG_ASSERT(interval); |
10217 | if (!(interval= copy_typelib(mem_root, interval))) |
10218 | DBUG_RETURN(true); |
10219 | } |
10220 | prepare_interval_field_calc_length(); |
10221 | DBUG_RETURN(false); |
10222 | } |
10223 | |
10224 | |
10225 | void Column_definition::set_attributes(const Lex_field_type_st &type, |
10226 | CHARSET_INFO *cs) |
10227 | { |
10228 | DBUG_ASSERT(type_handler() == &type_handler_null); |
10229 | DBUG_ASSERT(charset == &my_charset_bin || charset == NULL); |
10230 | DBUG_ASSERT(length == 0); |
10231 | DBUG_ASSERT(decimals == 0); |
10232 | |
10233 | set_handler(type.type_handler()); |
10234 | charset= cs; |
10235 | |
10236 | if (type.length()) |
10237 | { |
10238 | int err; |
10239 | length= my_strtoll10(type.length(), NULL, &err); |
10240 | if (err) |
10241 | length= ~0ULL; // safety |
10242 | } |
10243 | |
10244 | if (type.dec()) |
10245 | decimals= (uint) atoi(type.dec()); |
10246 | } |
10247 | |
10248 | |
10249 | void Column_definition::create_length_to_internal_length_bit() |
10250 | { |
10251 | if (f_bit_as_char(pack_flag)) |
10252 | { |
10253 | key_length= pack_length= ((length + 7) & ~7) / 8; |
10254 | } |
10255 | else |
10256 | { |
10257 | pack_length= (uint) length / 8; |
10258 | /* We need one extra byte to store the bits we save among the null bits */ |
10259 | key_length= pack_length + MY_TEST(length & 7); |
10260 | } |
10261 | } |
10262 | |
10263 | |
10264 | void Column_definition::create_length_to_internal_length_newdecimal() |
10265 | { |
10266 | key_length= pack_length= |
10267 | my_decimal_get_binary_size(my_decimal_length_to_precision((uint) length, |
10268 | decimals, |
10269 | flags & |
10270 | UNSIGNED_FLAG), |
10271 | decimals); |
10272 | } |
10273 | |
10274 | |
10275 | bool check_expression(Virtual_column_info *vcol, LEX_CSTRING *name, |
10276 | enum_vcol_info_type type) |
10277 | |
10278 | { |
10279 | bool ret; |
10280 | Item::vcol_func_processor_result res; |
10281 | |
10282 | if (!vcol->name.length) |
10283 | vcol->name= *name; |
10284 | |
10285 | /* |
10286 | Walk through the Item tree checking if all items are valid |
10287 | to be part of the virtual column |
10288 | */ |
10289 | res.errors= 0; |
10290 | ret= vcol->expr->walk(&Item::check_vcol_func_processor, 0, &res); |
10291 | vcol->flags= res.errors; |
10292 | |
10293 | uint filter= VCOL_IMPOSSIBLE; |
10294 | if (type != VCOL_GENERATED_VIRTUAL && type != VCOL_DEFAULT) |
10295 | filter|= VCOL_NOT_STRICTLY_DETERMINISTIC; |
10296 | if (type == VCOL_GENERATED_VIRTUAL) |
10297 | filter|= VCOL_NOT_VIRTUAL; |
10298 | |
10299 | if (unlikely(ret || (res.errors & filter))) |
10300 | { |
10301 | my_error(ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED, MYF(0), res.name, |
10302 | vcol_type_name(type), name->str); |
10303 | return TRUE; |
10304 | } |
10305 | /* |
10306 | Safe to call before fix_fields as long as vcol's don't include sub |
10307 | queries (which is now checked in check_vcol_func_processor) |
10308 | */ |
10309 | if (vcol->expr->check_cols(1)) |
10310 | return TRUE; |
10311 | return FALSE; |
10312 | } |
10313 | |
10314 | |
10315 | bool Column_definition::check_length(uint mysql_errno, uint limit) const |
10316 | { |
10317 | if (length <= limit) |
10318 | return false; |
10319 | my_error(mysql_errno, MYF(0), field_name.str, static_cast<ulong>(limit)); |
10320 | return true; |
10321 | } |
10322 | |
10323 | |
10324 | bool Column_definition::fix_attributes_int(uint default_length) |
10325 | { |
10326 | if (length) |
10327 | return check_length(ER_TOO_BIG_DISPLAYWIDTH, MAX_FIELD_CHARLENGTH); |
10328 | length= default_length; |
10329 | return false; |
10330 | } |
10331 | |
10332 | |
10333 | bool Column_definition::fix_attributes_real(uint default_length) |
10334 | { |
10335 | /* change FLOAT(precision) to FLOAT or DOUBLE */ |
10336 | if (!length && !decimals) |
10337 | { |
10338 | length= default_length; |
10339 | decimals= NOT_FIXED_DEC; |
10340 | } |
10341 | if (length < decimals && decimals != NOT_FIXED_DEC) |
10342 | { |
10343 | my_error(ER_M_BIGGER_THAN_D, MYF(0), field_name.str); |
10344 | return true; |
10345 | } |
10346 | if (decimals != NOT_FIXED_DEC && decimals >= FLOATING_POINT_DECIMALS) |
10347 | { |
10348 | my_error(ER_TOO_BIG_SCALE, MYF(0), static_cast<ulonglong>(decimals), |
10349 | field_name.str, static_cast<uint>(FLOATING_POINT_DECIMALS-1)); |
10350 | return true; |
10351 | } |
10352 | return check_length(ER_TOO_BIG_DISPLAYWIDTH, MAX_FIELD_CHARLENGTH); |
10353 | } |
10354 | |
10355 | |
10356 | bool Column_definition::fix_attributes_decimal() |
10357 | { |
10358 | if (decimals >= NOT_FIXED_DEC) |
10359 | { |
10360 | my_error(ER_TOO_BIG_SCALE, MYF(0), static_cast<ulonglong>(decimals), |
10361 | field_name.str, static_cast<uint>(NOT_FIXED_DEC - 1)); |
10362 | return true; |
10363 | } |
10364 | my_decimal_trim(&length, &decimals); |
10365 | if (length > DECIMAL_MAX_PRECISION) |
10366 | { |
10367 | my_error(ER_TOO_BIG_PRECISION, MYF(0), length, field_name.str, |
10368 | DECIMAL_MAX_PRECISION); |
10369 | return true; |
10370 | } |
10371 | if (length < decimals) |
10372 | { |
10373 | my_error(ER_M_BIGGER_THAN_D, MYF(0), field_name.str); |
10374 | return true; |
10375 | } |
10376 | length= my_decimal_precision_to_length((uint) length, decimals, |
10377 | flags & UNSIGNED_FLAG); |
10378 | pack_length= my_decimal_get_binary_size((uint) length, decimals); |
10379 | return false; |
10380 | } |
10381 | |
10382 | |
10383 | bool Column_definition::fix_attributes_bit() |
10384 | { |
10385 | if (!length) |
10386 | length= 1; |
10387 | pack_length= ((uint) length + 7) / 8; |
10388 | return check_length(ER_TOO_BIG_DISPLAYWIDTH, MAX_BIT_FIELD_LENGTH); |
10389 | } |
10390 | |
10391 | |
10392 | bool Column_definition::fix_attributes_temporal_with_time(uint int_part_length) |
10393 | { |
10394 | if (length > MAX_DATETIME_PRECISION) |
10395 | { |
10396 | my_error(ER_TOO_BIG_PRECISION, MYF(0), length, field_name.str, |
10397 | MAX_DATETIME_PRECISION); |
10398 | return true; |
10399 | } |
10400 | length+= int_part_length + (length ? 1 : 0); |
10401 | return false; |
10402 | } |
10403 | |
10404 | |
10405 | bool Column_definition::check(THD *thd) |
10406 | { |
10407 | DBUG_ENTER("Column_definition::check" ); |
10408 | |
10409 | /* Initialize data for a computed field */ |
10410 | if (vcol_info) |
10411 | { |
10412 | DBUG_ASSERT(vcol_info->expr); |
10413 | vcol_info->set_field_type(real_field_type()); |
10414 | if (check_expression(vcol_info, &field_name, vcol_info->stored_in_db |
10415 | ? VCOL_GENERATED_STORED : VCOL_GENERATED_VIRTUAL)) |
10416 | DBUG_RETURN(TRUE); |
10417 | } |
10418 | |
10419 | if (check_constraint && |
10420 | check_expression(check_constraint, &field_name, VCOL_CHECK_FIELD)) |
10421 | DBUG_RETURN(1); |
10422 | |
10423 | if (default_value) |
10424 | { |
10425 | Item *def_expr= default_value->expr; |
10426 | if (check_expression(default_value, &field_name, VCOL_DEFAULT)) |
10427 | DBUG_RETURN(TRUE); |
10428 | |
10429 | /* Constant's are stored in the 'empty_record', except for blobs */ |
10430 | if (def_expr->basic_const_item()) |
10431 | { |
10432 | if (def_expr->type() == Item::NULL_ITEM) |
10433 | { |
10434 | default_value= 0; |
10435 | if ((flags & (NOT_NULL_FLAG | AUTO_INCREMENT_FLAG)) == NOT_NULL_FLAG) |
10436 | { |
10437 | my_error(ER_INVALID_DEFAULT, MYF(0), field_name.str); |
10438 | DBUG_RETURN(1); |
10439 | } |
10440 | } |
10441 | } |
10442 | } |
10443 | |
10444 | if (default_value && (flags & AUTO_INCREMENT_FLAG)) |
10445 | { |
10446 | my_error(ER_INVALID_DEFAULT, MYF(0), field_name.str); |
10447 | DBUG_RETURN(1); |
10448 | } |
10449 | |
10450 | if (default_value && !default_value->expr->basic_const_item() && |
10451 | mysql_timestamp_type() == MYSQL_TIMESTAMP_DATETIME && |
10452 | default_value->expr->type() == Item::FUNC_ITEM) |
10453 | { |
10454 | /* |
10455 | Special case: NOW() for TIMESTAMP and DATETIME fields are handled |
10456 | as in MariaDB 10.1 by marking them in unireg_check. |
10457 | */ |
10458 | Item_func *fn= static_cast<Item_func*>(default_value->expr); |
10459 | if (fn->functype() == Item_func::NOW_FUNC && |
10460 | (fn->decimals == 0 || fn->decimals >= length)) |
10461 | { |
10462 | default_value= 0; |
10463 | unireg_check= Field::TIMESTAMP_DN_FIELD; |
10464 | } |
10465 | } |
10466 | |
10467 | if (on_update) |
10468 | { |
10469 | if (mysql_timestamp_type() != MYSQL_TIMESTAMP_DATETIME || |
10470 | on_update->decimals < length) |
10471 | { |
10472 | my_error(ER_INVALID_ON_UPDATE, MYF(0), field_name.str); |
10473 | DBUG_RETURN(TRUE); |
10474 | } |
10475 | unireg_check= unireg_check == Field::NONE ? Field::TIMESTAMP_UN_FIELD |
10476 | : Field::TIMESTAMP_DNUN_FIELD; |
10477 | } |
10478 | else if (flags & AUTO_INCREMENT_FLAG) |
10479 | unireg_check= Field::NEXT_NUMBER; |
10480 | |
10481 | if (type_handler()->Column_definition_fix_attributes(this)) |
10482 | DBUG_RETURN(true); |
10483 | |
10484 | /* Remember the value of length */ |
10485 | char_length= (uint)length; |
10486 | |
10487 | /* |
10488 | Set NO_DEFAULT_VALUE_FLAG if this field doesn't have a default value and |
10489 | it is NOT NULL, not an AUTO_INCREMENT field. |
10490 | We need to do this check here and in mysql_create_prepare_table() as |
10491 | sp_head::fill_field_definition() calls this function. |
10492 | */ |
10493 | if (!default_value && unireg_check == Field::NONE && (flags & NOT_NULL_FLAG)) |
10494 | { |
10495 | /* |
10496 | TIMESTAMP columns get implicit DEFAULT value when |
10497 | explicit_defaults_for_timestamp is not set. |
10498 | */ |
10499 | if ((opt_explicit_defaults_for_timestamp || |
10500 | !is_timestamp_type()) && !vers_sys_field()) |
10501 | { |
10502 | flags|= NO_DEFAULT_VALUE_FLAG; |
10503 | } |
10504 | } |
10505 | |
10506 | |
10507 | if ((flags & AUTO_INCREMENT_FLAG) && |
10508 | !type_handler()->type_can_have_auto_increment_attribute()) |
10509 | { |
10510 | my_error(ER_WRONG_FIELD_SPEC, MYF(0), field_name.str); |
10511 | DBUG_RETURN(TRUE); |
10512 | } |
10513 | |
10514 | DBUG_RETURN(FALSE); /* success */ |
10515 | } |
10516 | |
10517 | enum_field_types get_blob_type_from_length(ulong length) |
10518 | { |
10519 | enum_field_types type; |
10520 | if (length < 256) |
10521 | type= MYSQL_TYPE_TINY_BLOB; |
10522 | else if (length < 65536) |
10523 | type= MYSQL_TYPE_BLOB; |
10524 | else if (length < 256L*256L*256L) |
10525 | type= MYSQL_TYPE_MEDIUM_BLOB; |
10526 | else |
10527 | type= MYSQL_TYPE_LONG_BLOB; |
10528 | return type; |
10529 | } |
10530 | |
10531 | |
10532 | uint pack_length_to_packflag(uint type) |
10533 | { |
10534 | switch (type) { |
10535 | case 1: return f_settype((uint) MYSQL_TYPE_TINY); |
10536 | case 2: return f_settype((uint) MYSQL_TYPE_SHORT); |
10537 | case 3: return f_settype((uint) MYSQL_TYPE_INT24); |
10538 | case 4: return f_settype((uint) MYSQL_TYPE_LONG); |
10539 | case 8: return f_settype((uint) MYSQL_TYPE_LONGLONG); |
10540 | } |
10541 | return 0; // This shouldn't happen |
10542 | } |
10543 | |
10544 | |
10545 | Field *make_field(TABLE_SHARE *share, |
10546 | MEM_ROOT *mem_root, |
10547 | uchar *ptr, uint32 field_length, |
10548 | uchar *null_pos, uchar null_bit, |
10549 | uint pack_flag, |
10550 | const Type_handler *handler, |
10551 | CHARSET_INFO *field_charset, |
10552 | Field::geometry_type geom_type, uint srid, |
10553 | Field::utype unireg_check, |
10554 | TYPELIB *interval, |
10555 | const LEX_CSTRING *field_name, |
10556 | uint32 flags) |
10557 | { |
10558 | uchar *UNINIT_VAR(bit_ptr); |
10559 | uchar UNINIT_VAR(bit_offset); |
10560 | |
10561 | DBUG_PRINT("debug" , ("field_type: %s, field_length: %u, interval: %p, pack_flag: %s%s%s%s%s" , |
10562 | handler->name().ptr(), field_length, interval, |
10563 | FLAGSTR(pack_flag, FIELDFLAG_BINARY), |
10564 | FLAGSTR(pack_flag, FIELDFLAG_INTERVAL), |
10565 | FLAGSTR(pack_flag, FIELDFLAG_NUMBER), |
10566 | FLAGSTR(pack_flag, FIELDFLAG_PACK), |
10567 | FLAGSTR(pack_flag, FIELDFLAG_BLOB))); |
10568 | |
10569 | if (handler == &type_handler_row) |
10570 | { |
10571 | DBUG_ASSERT(field_length == 0); |
10572 | DBUG_ASSERT(f_maybe_null(pack_flag)); |
10573 | return new (mem_root) Field_row(ptr, field_name); |
10574 | } |
10575 | |
10576 | if (handler->real_field_type() == MYSQL_TYPE_BIT && !f_bit_as_char(pack_flag)) |
10577 | { |
10578 | bit_ptr= null_pos; |
10579 | bit_offset= null_bit; |
10580 | if (f_maybe_null(pack_flag)) // if null field |
10581 | { |
10582 | bit_ptr+= (null_bit == 7); // shift bit_ptr and bit_offset |
10583 | bit_offset= (bit_offset + 1) & 7; |
10584 | } |
10585 | } |
10586 | |
10587 | if (!f_maybe_null(pack_flag)) |
10588 | { |
10589 | null_pos=0; |
10590 | null_bit=0; |
10591 | } |
10592 | else |
10593 | { |
10594 | null_bit= ((uchar) 1) << null_bit; |
10595 | } |
10596 | |
10597 | |
10598 | if (f_is_alpha(pack_flag)) |
10599 | { |
10600 | if (!f_is_packed(pack_flag)) |
10601 | { |
10602 | enum_field_types field_type= handler->real_field_type(); |
10603 | if (field_type == MYSQL_TYPE_STRING || |
10604 | field_type == MYSQL_TYPE_DECIMAL || // 3.23 or 4.0 string |
10605 | field_type == MYSQL_TYPE_VAR_STRING) |
10606 | return new (mem_root) |
10607 | Field_string(ptr,field_length,null_pos,null_bit, |
10608 | unireg_check, field_name, |
10609 | field_charset); |
10610 | if (field_type == MYSQL_TYPE_VARCHAR) |
10611 | { |
10612 | if (unireg_check == Field::TMYSQL_COMPRESSED) |
10613 | return new (mem_root) |
10614 | Field_varstring_compressed( |
10615 | ptr, field_length, |
10616 | HA_VARCHAR_PACKLENGTH(field_length), |
10617 | null_pos, null_bit, |
10618 | unireg_check, field_name, |
10619 | share, field_charset, zlib_compression_method); |
10620 | |
10621 | return new (mem_root) |
10622 | Field_varstring(ptr,field_length, |
10623 | HA_VARCHAR_PACKLENGTH(field_length), |
10624 | null_pos,null_bit, |
10625 | unireg_check, field_name, |
10626 | share, |
10627 | field_charset); |
10628 | } |
10629 | return 0; // Error |
10630 | } |
10631 | |
10632 | // MYSQL_TYPE_VAR_STRING is handled above |
10633 | DBUG_ASSERT(f_packtype(pack_flag) != MYSQL_TYPE_VAR_STRING); |
10634 | const Type_handler *tmp; |
10635 | tmp= Type_handler::get_handler_by_real_type((enum_field_types) |
10636 | f_packtype(pack_flag)); |
10637 | uint pack_length= tmp->calc_pack_length(field_length); |
10638 | |
10639 | #ifdef HAVE_SPATIAL |
10640 | if (f_is_geom(pack_flag)) |
10641 | { |
10642 | status_var_increment(current_thd->status_var.feature_gis); |
10643 | return new (mem_root) |
10644 | Field_geom(ptr,null_pos,null_bit, |
10645 | unireg_check, field_name, share, |
10646 | pack_length, geom_type, srid); |
10647 | } |
10648 | #endif |
10649 | if (f_is_blob(pack_flag)) |
10650 | { |
10651 | if (unireg_check == Field::TMYSQL_COMPRESSED) |
10652 | return new (mem_root) |
10653 | Field_blob_compressed(ptr, null_pos, null_bit, |
10654 | unireg_check, field_name, share, |
10655 | pack_length, field_charset, zlib_compression_method); |
10656 | |
10657 | return new (mem_root) |
10658 | Field_blob(ptr,null_pos,null_bit, |
10659 | unireg_check, field_name, share, |
10660 | pack_length, field_charset); |
10661 | } |
10662 | if (interval) |
10663 | { |
10664 | if (f_is_enum(pack_flag)) |
10665 | return new (mem_root) |
10666 | Field_enum(ptr,field_length,null_pos,null_bit, |
10667 | unireg_check, field_name, |
10668 | pack_length, interval, field_charset); |
10669 | else |
10670 | return new (mem_root) |
10671 | Field_set(ptr,field_length,null_pos,null_bit, |
10672 | unireg_check, field_name, |
10673 | pack_length, interval, field_charset); |
10674 | } |
10675 | } |
10676 | |
10677 | switch (handler->real_field_type()) { |
10678 | case MYSQL_TYPE_DECIMAL: |
10679 | return new (mem_root) |
10680 | Field_decimal(ptr,field_length,null_pos,null_bit, |
10681 | unireg_check, field_name, |
10682 | f_decimals(pack_flag), |
10683 | f_is_zerofill(pack_flag) != 0, |
10684 | f_is_dec(pack_flag) == 0); |
10685 | case MYSQL_TYPE_NEWDECIMAL: |
10686 | return new (mem_root) |
10687 | Field_new_decimal(ptr,field_length,null_pos,null_bit, |
10688 | unireg_check, field_name, |
10689 | f_decimals(pack_flag), |
10690 | f_is_zerofill(pack_flag) != 0, |
10691 | f_is_dec(pack_flag) == 0); |
10692 | case MYSQL_TYPE_FLOAT: |
10693 | { |
10694 | int decimals= f_decimals(pack_flag); |
10695 | if (decimals == FLOATING_POINT_DECIMALS) |
10696 | decimals= NOT_FIXED_DEC; |
10697 | return new (mem_root) |
10698 | Field_float(ptr,field_length,null_pos,null_bit, |
10699 | unireg_check, field_name, |
10700 | decimals, |
10701 | f_is_zerofill(pack_flag) != 0, |
10702 | f_is_dec(pack_flag)== 0); |
10703 | } |
10704 | case MYSQL_TYPE_DOUBLE: |
10705 | { |
10706 | int decimals= f_decimals(pack_flag); |
10707 | if (decimals == FLOATING_POINT_DECIMALS) |
10708 | decimals= NOT_FIXED_DEC; |
10709 | return new (mem_root) |
10710 | Field_double(ptr,field_length,null_pos,null_bit, |
10711 | unireg_check, field_name, |
10712 | decimals, |
10713 | f_is_zerofill(pack_flag) != 0, |
10714 | f_is_dec(pack_flag)== 0); |
10715 | } |
10716 | case MYSQL_TYPE_TINY: |
10717 | return new (mem_root) |
10718 | Field_tiny(ptr,field_length,null_pos,null_bit, |
10719 | unireg_check, field_name, |
10720 | f_is_zerofill(pack_flag) != 0, |
10721 | f_is_dec(pack_flag) == 0); |
10722 | case MYSQL_TYPE_SHORT: |
10723 | return new (mem_root) |
10724 | Field_short(ptr,field_length,null_pos,null_bit, |
10725 | unireg_check, field_name, |
10726 | f_is_zerofill(pack_flag) != 0, |
10727 | f_is_dec(pack_flag) == 0); |
10728 | case MYSQL_TYPE_INT24: |
10729 | return new (mem_root) |
10730 | Field_medium(ptr,field_length,null_pos,null_bit, |
10731 | unireg_check, field_name, |
10732 | f_is_zerofill(pack_flag) != 0, |
10733 | f_is_dec(pack_flag) == 0); |
10734 | case MYSQL_TYPE_LONG: |
10735 | return new (mem_root) |
10736 | Field_long(ptr,field_length,null_pos,null_bit, |
10737 | unireg_check, field_name, |
10738 | f_is_zerofill(pack_flag) != 0, |
10739 | f_is_dec(pack_flag) == 0); |
10740 | case MYSQL_TYPE_LONGLONG: |
10741 | if (flags & (VERS_SYS_START_FLAG|VERS_SYS_END_FLAG)) |
10742 | { |
10743 | return new (mem_root) |
10744 | Field_vers_trx_id(ptr, field_length, null_pos, null_bit, |
10745 | unireg_check, field_name, |
10746 | f_is_zerofill(pack_flag) != 0, |
10747 | f_is_dec(pack_flag) == 0); |
10748 | } |
10749 | else |
10750 | { |
10751 | return new (mem_root) |
10752 | Field_longlong(ptr,field_length,null_pos,null_bit, |
10753 | unireg_check, field_name, |
10754 | f_is_zerofill(pack_flag) != 0, |
10755 | f_is_dec(pack_flag) == 0); |
10756 | } |
10757 | case MYSQL_TYPE_TIMESTAMP: |
10758 | { |
10759 | uint dec= field_length > MAX_DATETIME_WIDTH ? |
10760 | field_length - MAX_DATETIME_WIDTH - 1: 0; |
10761 | return new_Field_timestamp(mem_root, ptr, null_pos, null_bit, unireg_check, |
10762 | field_name, share, dec); |
10763 | } |
10764 | case MYSQL_TYPE_TIMESTAMP2: |
10765 | { |
10766 | uint dec= field_length > MAX_DATETIME_WIDTH ? |
10767 | field_length - MAX_DATETIME_WIDTH - 1: 0; |
10768 | return new (mem_root) |
10769 | Field_timestampf(ptr, null_pos, null_bit, unireg_check, |
10770 | field_name, share, dec); |
10771 | } |
10772 | case MYSQL_TYPE_YEAR: |
10773 | return new (mem_root) |
10774 | Field_year(ptr,field_length,null_pos,null_bit, |
10775 | unireg_check, field_name); |
10776 | case MYSQL_TYPE_DATE: |
10777 | return new (mem_root) |
10778 | Field_date(ptr,null_pos,null_bit, |
10779 | unireg_check, field_name); |
10780 | case MYSQL_TYPE_NEWDATE: |
10781 | return new (mem_root) |
10782 | Field_newdate(ptr,null_pos,null_bit, |
10783 | unireg_check, field_name); |
10784 | case MYSQL_TYPE_TIME: |
10785 | { |
10786 | uint dec= field_length > MIN_TIME_WIDTH ? |
10787 | field_length - MIN_TIME_WIDTH - 1: 0; |
10788 | return new_Field_time(mem_root, ptr, null_pos, null_bit, unireg_check, |
10789 | field_name, dec); |
10790 | } |
10791 | case MYSQL_TYPE_TIME2: |
10792 | { |
10793 | uint dec= field_length > MIN_TIME_WIDTH ? |
10794 | field_length - MIN_TIME_WIDTH - 1: 0; |
10795 | return new (mem_root) |
10796 | Field_timef(ptr, null_pos, null_bit, unireg_check, |
10797 | field_name, dec); |
10798 | } |
10799 | case MYSQL_TYPE_DATETIME: |
10800 | { |
10801 | uint dec= field_length > MAX_DATETIME_WIDTH ? |
10802 | field_length - MAX_DATETIME_WIDTH - 1: 0; |
10803 | return new_Field_datetime(mem_root, ptr, null_pos, null_bit, unireg_check, |
10804 | field_name, dec); |
10805 | } |
10806 | case MYSQL_TYPE_DATETIME2: |
10807 | { |
10808 | uint dec= field_length > MAX_DATETIME_WIDTH ? |
10809 | field_length - MAX_DATETIME_WIDTH - 1: 0; |
10810 | return new (mem_root) |
10811 | Field_datetimef(ptr, null_pos, null_bit, unireg_check, |
10812 | field_name, dec); |
10813 | } |
10814 | case MYSQL_TYPE_NULL: |
10815 | return new (mem_root) |
10816 | Field_null(ptr, field_length, unireg_check, field_name, |
10817 | field_charset); |
10818 | case MYSQL_TYPE_BIT: |
10819 | return (f_bit_as_char(pack_flag) ? |
10820 | new (mem_root) |
10821 | Field_bit_as_char(ptr, field_length, null_pos, null_bit, |
10822 | unireg_check, field_name) : |
10823 | new (mem_root) |
10824 | Field_bit(ptr, field_length, null_pos, null_bit, bit_ptr, |
10825 | bit_offset, unireg_check, field_name)); |
10826 | |
10827 | default: // Impossible (Wrong version) |
10828 | break; |
10829 | } |
10830 | return 0; |
10831 | } |
10832 | |
10833 | bool Field_vers_trx_id::test_if_equality_guarantees_uniqueness(const Item* item) const |
10834 | { |
10835 | return item->type() == Item::DATE_ITEM; |
10836 | } |
10837 | |
10838 | |
10839 | /** Create a field suitable for create of table. */ |
10840 | |
10841 | Column_definition::Column_definition(THD *thd, Field *old_field, |
10842 | Field *orig_field) |
10843 | { |
10844 | on_update= NULL; |
10845 | field_name= old_field->field_name; |
10846 | length= old_field->field_length; |
10847 | flags= old_field->flags; |
10848 | unireg_check=old_field->unireg_check; |
10849 | pack_length=old_field->pack_length(); |
10850 | key_length= old_field->key_length(); |
10851 | set_handler(old_field->type_handler()); |
10852 | charset= old_field->charset(); // May be NULL ptr |
10853 | comment= old_field->comment; |
10854 | decimals= old_field->decimals(); |
10855 | vcol_info= old_field->vcol_info; |
10856 | option_list= old_field->option_list; |
10857 | pack_flag= 0; |
10858 | compression_method_ptr= 0; |
10859 | versioning= VERSIONING_NOT_SET; |
10860 | invisible= old_field->invisible; |
10861 | |
10862 | if (orig_field) |
10863 | { |
10864 | default_value= orig_field->default_value; |
10865 | check_constraint= orig_field->check_constraint; |
10866 | if (orig_field->unireg_check == Field::TMYSQL_COMPRESSED) |
10867 | { |
10868 | unireg_check= Field::TMYSQL_COMPRESSED; |
10869 | compression_method_ptr= zlib_compression_method; |
10870 | } |
10871 | } |
10872 | else |
10873 | { |
10874 | default_value= 0; |
10875 | check_constraint= 0; |
10876 | } |
10877 | |
10878 | switch (real_field_type()) { |
10879 | case MYSQL_TYPE_TINY_BLOB: |
10880 | case MYSQL_TYPE_BLOB: |
10881 | case MYSQL_TYPE_MEDIUM_BLOB: |
10882 | case MYSQL_TYPE_LONG_BLOB: |
10883 | length/= charset->mbmaxlen; |
10884 | key_length/= charset->mbmaxlen; |
10885 | break; |
10886 | case MYSQL_TYPE_STRING: |
10887 | /* Change CHAR -> VARCHAR if dynamic record length */ |
10888 | if (old_field->type() == MYSQL_TYPE_VAR_STRING) |
10889 | set_handler(&type_handler_varchar); |
10890 | /* fall through */ |
10891 | |
10892 | case MYSQL_TYPE_ENUM: |
10893 | case MYSQL_TYPE_SET: |
10894 | case MYSQL_TYPE_VARCHAR: |
10895 | case MYSQL_TYPE_VAR_STRING: |
10896 | /* This is corrected in create_length_to_internal_length */ |
10897 | length= (length+charset->mbmaxlen-1) / charset->mbmaxlen - |
10898 | MY_TEST(old_field->compression_method()); |
10899 | break; |
10900 | #ifdef HAVE_SPATIAL |
10901 | case MYSQL_TYPE_GEOMETRY: |
10902 | geom_type= ((Field_geom*)old_field)->geom_type; |
10903 | srid= ((Field_geom*)old_field)->srid; |
10904 | break; |
10905 | #endif |
10906 | case MYSQL_TYPE_YEAR: |
10907 | if (length != 4) |
10908 | { |
10909 | char buff[sizeof("YEAR()" ) + MY_INT64_NUM_DECIMAL_DIGITS + 1]; |
10910 | my_snprintf(buff, sizeof(buff), "YEAR(%llu)" , length); |
10911 | push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE, |
10912 | ER_WARN_DEPRECATED_SYNTAX, |
10913 | ER_THD(thd, ER_WARN_DEPRECATED_SYNTAX), |
10914 | buff, "YEAR(4)" ); |
10915 | } |
10916 | break; |
10917 | case MYSQL_TYPE_FLOAT: |
10918 | case MYSQL_TYPE_DOUBLE: |
10919 | /* |
10920 | Floating points are stored with FLOATING_POINT_DECIMALS but internally |
10921 | in MariaDB used with NOT_FIXED_DEC, which is >= FLOATING_POINT_DECIMALS. |
10922 | */ |
10923 | if (decimals >= FLOATING_POINT_DECIMALS) |
10924 | decimals= NOT_FIXED_DEC; |
10925 | break; |
10926 | default: |
10927 | break; |
10928 | } |
10929 | |
10930 | if (flags & (ENUM_FLAG | SET_FLAG)) |
10931 | interval= ((Field_enum*) old_field)->typelib; |
10932 | else |
10933 | interval=0; |
10934 | |
10935 | interval_list.empty(); // prepare_interval_field() needs this |
10936 | |
10937 | char_length= (uint)length; |
10938 | |
10939 | /* |
10940 | Copy the default (constant/function) from the column object orig_field, if |
10941 | supplied. We do this if all these conditions are met: |
10942 | |
10943 | - The column allows a default. |
10944 | |
10945 | - The column type is not a BLOB type (as BLOB's doesn't have constant |
10946 | defaults) |
10947 | |
10948 | - The original column (old_field) was properly initialized with a record |
10949 | buffer pointer. |
10950 | |
10951 | - The column didn't have a default expression |
10952 | */ |
10953 | if (!(flags & (NO_DEFAULT_VALUE_FLAG | BLOB_FLAG)) && |
10954 | old_field->ptr != NULL && orig_field != NULL) |
10955 | { |
10956 | if (orig_field->unireg_check != Field::NEXT_NUMBER) |
10957 | unireg_check= orig_field->unireg_check; |
10958 | |
10959 | /* Get the value from default_values */ |
10960 | const uchar *dv= orig_field->table->s->default_values; |
10961 | if (!default_value && !orig_field->is_null_in_record(dv)) |
10962 | { |
10963 | StringBuffer<MAX_FIELD_WIDTH> tmp(charset); |
10964 | String *res= orig_field->val_str(&tmp, orig_field->ptr_in_record(dv)); |
10965 | char *pos= (char*) thd->strmake(res->ptr(), res->length()); |
10966 | default_value= new (thd->mem_root) Virtual_column_info(); |
10967 | default_value->expr= |
10968 | new (thd->mem_root) Item_string(thd, pos, res->length(), charset); |
10969 | default_value->utf8= 0; |
10970 | } |
10971 | } |
10972 | } |
10973 | |
10974 | |
10975 | /** |
10976 | The common part for data type redefinition: |
10977 | CREATE TABLE t1 (a INT) AS SELECT a FROM t2; |
10978 | See Type_handler::Column_definition_redefine_stage1() |
10979 | for data type specific code. |
10980 | */ |
10981 | void |
10982 | Column_definition::redefine_stage1_common(const Column_definition *dup_field, |
10983 | const handler *file, |
10984 | const Schema_specification_st *schema) |
10985 | { |
10986 | set_handler(dup_field->type_handler()); |
10987 | default_value= dup_field->default_value; |
10988 | charset= dup_field->charset ? dup_field->charset : |
10989 | schema->default_table_charset; |
10990 | length= dup_field->char_length; |
10991 | pack_length= dup_field->pack_length; |
10992 | key_length= dup_field->key_length; |
10993 | decimals= dup_field->decimals; |
10994 | unireg_check= dup_field->unireg_check; |
10995 | flags= dup_field->flags; |
10996 | interval= dup_field->interval; |
10997 | vcol_info= dup_field->vcol_info; |
10998 | invisible= dup_field->invisible; |
10999 | } |
11000 | |
11001 | |
11002 | |
11003 | /** |
11004 | maximum possible character length for blob. |
11005 | |
11006 | This method is used in Item_field::set_field to calculate |
11007 | max_length for Item. |
11008 | |
11009 | For example: |
11010 | CREATE TABLE t2 SELECT CONCAT(tinyblob_utf8_column) FROM t1; |
11011 | must create a "VARCHAR(255) CHARACTER SET utf8" column. |
11012 | |
11013 | @return |
11014 | length |
11015 | */ |
11016 | |
11017 | uint32 Field_blob::char_length() const |
11018 | { |
11019 | return Field_blob::octet_length(); |
11020 | } |
11021 | |
11022 | |
11023 | uint32 Field_blob::octet_length() const |
11024 | { |
11025 | switch (packlength) |
11026 | { |
11027 | case 1: |
11028 | return 255; |
11029 | case 2: |
11030 | return 65535; |
11031 | case 3: |
11032 | return 16777215; |
11033 | case 4: |
11034 | return (uint32) UINT_MAX32; |
11035 | default: |
11036 | DBUG_ASSERT(0); // we should never go here |
11037 | return 0; |
11038 | } |
11039 | } |
11040 | |
11041 | |
11042 | /** |
11043 | Makes a clone of this object for ALTER/CREATE TABLE |
11044 | |
11045 | @param mem_root MEM_ROOT where to clone the field |
11046 | */ |
11047 | |
11048 | Create_field *Create_field::clone(MEM_ROOT *mem_root) const |
11049 | { |
11050 | Create_field *res= new (mem_root) Create_field(*this); |
11051 | return res; |
11052 | } |
11053 | |
11054 | /** |
11055 | Return true if default is an expression that must be saved explicitely |
11056 | |
11057 | This is: |
11058 | - Not basic constants |
11059 | - If field is a BLOB (Which doesn't support normal DEFAULT) |
11060 | */ |
11061 | |
11062 | bool Column_definition::has_default_expression() |
11063 | { |
11064 | return (default_value && |
11065 | (!default_value->expr->basic_const_item() || |
11066 | (flags & BLOB_FLAG))); |
11067 | } |
11068 | |
11069 | |
11070 | bool Column_definition::set_compressed(const char *method) |
11071 | { |
11072 | enum enum_field_types sql_type= real_field_type(); |
11073 | /* We can't use f_is_blob here as pack_flag is not yet set */ |
11074 | if (sql_type == MYSQL_TYPE_VARCHAR || sql_type == MYSQL_TYPE_TINY_BLOB || |
11075 | sql_type == MYSQL_TYPE_BLOB || sql_type == MYSQL_TYPE_MEDIUM_BLOB || |
11076 | sql_type == MYSQL_TYPE_LONG_BLOB) |
11077 | { |
11078 | if (!method || !strcmp(method, zlib_compression_method->name)) |
11079 | { |
11080 | unireg_check= Field::TMYSQL_COMPRESSED; |
11081 | compression_method_ptr= zlib_compression_method; |
11082 | return false; |
11083 | } |
11084 | my_error(ER_UNKNOWN_COMPRESSION_METHOD, MYF(0), method); |
11085 | } |
11086 | else |
11087 | my_error(ER_WRONG_FIELD_SPEC, MYF(0), field_name.str); |
11088 | return true; |
11089 | } |
11090 | |
11091 | |
11092 | /** |
11093 | maximum possible display length for blob. |
11094 | |
11095 | @return |
11096 | length |
11097 | */ |
11098 | |
11099 | uint32 Field_blob::max_display_length() const |
11100 | { |
11101 | switch (packlength) |
11102 | { |
11103 | case 1: |
11104 | return 255 * field_charset->mbmaxlen; |
11105 | case 2: |
11106 | return 65535 * field_charset->mbmaxlen; |
11107 | case 3: |
11108 | return 16777215 * field_charset->mbmaxlen; |
11109 | case 4: |
11110 | return (uint32) UINT_MAX32; |
11111 | default: |
11112 | DBUG_ASSERT(0); // we should never go here |
11113 | return 0; |
11114 | } |
11115 | } |
11116 | |
11117 | |
11118 | /***************************************************************************** |
11119 | Warning handling |
11120 | *****************************************************************************/ |
11121 | |
11122 | /** |
11123 | * Produce warning or note about data saved into field. |
11124 | |
11125 | @param level - level of message (Note/Warning/Error) |
11126 | @param code - error code of message to be produced |
11127 | @param cut_increment - whenever we should increase cut fields count |
11128 | |
11129 | @note |
11130 | This function won't produce warning or notes or increase cut fields counter |
11131 | if count_cuted_fields == CHECK_FIELD_IGNORE or CHECK_FIELD_EXPRESSION |
11132 | for the current thread. |
11133 | |
11134 | This allows us to avoid notes in optimisation, like |
11135 | convert_constant_item(). |
11136 | |
11137 | @retval |
11138 | 1 if count_cuted_fields == CHECK_FIELD_IGNORE and error level is not NOTE |
11139 | @retval |
11140 | 0 otherwise |
11141 | */ |
11142 | |
11143 | bool |
11144 | Field::set_warning(Sql_condition::enum_warning_level level, uint code, |
11145 | int cut_increment) const |
11146 | { |
11147 | /* |
11148 | If this field was created only for type conversion purposes it |
11149 | will have table == NULL. |
11150 | */ |
11151 | THD *thd= get_thd(); |
11152 | if (thd->count_cuted_fields > CHECK_FIELD_EXPRESSION) |
11153 | { |
11154 | thd->cuted_fields+= cut_increment; |
11155 | push_warning_printf(thd, level, code, ER_THD(thd, code), field_name.str, |
11156 | thd->get_stmt_da()->current_row_for_warning()); |
11157 | return 0; |
11158 | } |
11159 | return level >= Sql_condition::WARN_LEVEL_WARN; |
11160 | } |
11161 | |
11162 | |
11163 | /** |
11164 | Produce warning or note about datetime string data saved into field. |
11165 | |
11166 | @param level level of message (Note/Warning/Error) |
11167 | @param code error code of message to be produced |
11168 | @param str string value which we tried to save |
11169 | @param ts_type type of datetime value (datetime/date/time) |
11170 | @param cuted_increment whenever we should increase cut fields count or not |
11171 | |
11172 | @note |
11173 | This function will always produce some warning but won't increase cut |
11174 | fields counter if count_cuted_fields ==FIELD_CHECK_IGNORE for current |
11175 | thread. |
11176 | |
11177 | See also bug#2336 |
11178 | |
11179 | */ |
11180 | |
11181 | void Field::set_datetime_warning(Sql_condition::enum_warning_level level, |
11182 | uint code, const ErrConv *str, |
11183 | timestamp_type ts_type, int cuted_increment) |
11184 | const |
11185 | { |
11186 | THD *thd= get_thd(); |
11187 | if (thd->really_abort_on_warning() && level >= Sql_condition::WARN_LEVEL_WARN) |
11188 | make_truncated_value_warning(thd, level, str, ts_type, field_name.str); |
11189 | else |
11190 | set_warning(level, code, cuted_increment); |
11191 | } |
11192 | |
11193 | |
11194 | void Field::set_warning_truncated_wrong_value(const char *type_arg, |
11195 | const char *value) |
11196 | { |
11197 | THD *thd= get_thd(); |
11198 | push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, |
11199 | ER_TRUNCATED_WRONG_VALUE_FOR_FIELD, |
11200 | ER_THD(thd, ER_TRUNCATED_WRONG_VALUE_FOR_FIELD), |
11201 | type_arg, value, field_name.str, |
11202 | static_cast<ulong>(thd->get_stmt_da()-> |
11203 | current_row_for_warning())); |
11204 | } |
11205 | |
11206 | |
11207 | /* |
11208 | @brief |
11209 | Return possible keys for a field |
11210 | |
11211 | @details |
11212 | Return bit map of keys over this field which can be used by the range |
11213 | optimizer. For a field of a generic table such keys are all keys that starts |
11214 | from this field. For a field of a materialized derived table/view such keys |
11215 | are all keys in which this field takes a part. This is less restrictive as |
11216 | keys for a materialized derived table/view are generated on the fly from |
11217 | present fields, thus the case when a field for the beginning of a key is |
11218 | absent is impossible. |
11219 | |
11220 | @return map of possible keys |
11221 | */ |
11222 | |
11223 | key_map Field::get_possible_keys() |
11224 | { |
11225 | DBUG_ASSERT(table->pos_in_table_list); |
11226 | return (table->pos_in_table_list->is_materialized_derived() ? |
11227 | part_of_key : key_start); |
11228 | } |
11229 | |
11230 | |
11231 | /** |
11232 | Mark the field as having an explicit default value. |
11233 | |
11234 | @param value if available, the value that the field is being set to |
11235 | |
11236 | @note |
11237 | Fields that have an explicit default value should not be updated |
11238 | automatically via the DEFAULT or ON UPDATE functions. The functions |
11239 | that deal with data change functionality (INSERT/UPDATE/LOAD), |
11240 | determine if there is an explicit value for each field before performing |
11241 | the data change, and call this method to mark the field. |
11242 | |
11243 | If the 'value' parameter is NULL, then the field is marked unconditionally |
11244 | as having an explicit value. If 'value' is not NULL, then it can be further |
11245 | analyzed to check if it really should count as a value. |
11246 | */ |
11247 | |
11248 | bool Field::set_explicit_default(Item *value) |
11249 | { |
11250 | if (value->type() == Item::DEFAULT_VALUE_ITEM && |
11251 | !((Item_default_value*)value)->arg) |
11252 | return false; |
11253 | set_has_explicit_value(); |
11254 | return true; |
11255 | } |
11256 | |
11257 | |
11258 | bool Field::validate_value_in_record_with_warn(THD *thd, const uchar *record) |
11259 | { |
11260 | my_bitmap_map *old_map= dbug_tmp_use_all_columns(table, table->read_set); |
11261 | bool rc; |
11262 | if ((rc= validate_value_in_record(thd, record))) |
11263 | { |
11264 | // Get and report val_str() for the DEFAULT value |
11265 | StringBuffer<MAX_FIELD_WIDTH> tmp; |
11266 | val_str(&tmp, ptr_in_record(record)); |
11267 | push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, |
11268 | ER_INVALID_DEFAULT_VALUE_FOR_FIELD, |
11269 | ER_THD(thd, ER_INVALID_DEFAULT_VALUE_FOR_FIELD), |
11270 | ErrConvString(&tmp).ptr(), field_name.str); |
11271 | } |
11272 | dbug_tmp_restore_column_map(table->read_set, old_map); |
11273 | return rc; |
11274 | } |
11275 | |
11276 | |
11277 | bool Field::save_in_field_default_value(bool view_error_processing) |
11278 | { |
11279 | THD *thd= table->in_use; |
11280 | |
11281 | if (unlikely(flags & NO_DEFAULT_VALUE_FLAG && |
11282 | real_type() != MYSQL_TYPE_ENUM)) |
11283 | { |
11284 | if (reset()) |
11285 | { |
11286 | my_message(ER_CANT_CREATE_GEOMETRY_OBJECT, |
11287 | ER_THD(thd, ER_CANT_CREATE_GEOMETRY_OBJECT), MYF(0)); |
11288 | return true; |
11289 | } |
11290 | |
11291 | if (view_error_processing) |
11292 | { |
11293 | TABLE_LIST *view= table->pos_in_table_list->top_table(); |
11294 | push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, |
11295 | ER_NO_DEFAULT_FOR_VIEW_FIELD, |
11296 | ER_THD(thd, ER_NO_DEFAULT_FOR_VIEW_FIELD), |
11297 | view->view_db.str, |
11298 | view->view_name.str); |
11299 | } |
11300 | else |
11301 | { |
11302 | push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, |
11303 | ER_NO_DEFAULT_FOR_FIELD, |
11304 | ER_THD(thd, ER_NO_DEFAULT_FOR_FIELD), |
11305 | field_name.str); |
11306 | } |
11307 | return true; |
11308 | } |
11309 | set_default(); |
11310 | return |
11311 | !is_null() && |
11312 | validate_value_in_record_with_warn(thd, table->record[0]) && |
11313 | thd->is_error(); |
11314 | } |
11315 | |
11316 | |
11317 | bool Field::save_in_field_ignore_value(bool view_error_processing) |
11318 | { |
11319 | enum_sql_command com= table->in_use->lex->sql_command; |
11320 | // All insert-like commands |
11321 | if (com == SQLCOM_INSERT || com == SQLCOM_REPLACE || |
11322 | com == SQLCOM_INSERT_SELECT || com == SQLCOM_REPLACE_SELECT || |
11323 | com == SQLCOM_LOAD) |
11324 | return save_in_field_default_value(view_error_processing); |
11325 | return 0; // ignore |
11326 | } |
11327 | |
11328 | |
11329 | void Field::register_field_in_read_map() |
11330 | { |
11331 | if (vcol_info) |
11332 | { |
11333 | Item *vcol_item= vcol_info->expr; |
11334 | vcol_item->walk(&Item::register_field_in_read_map, 1, 0); |
11335 | } |
11336 | bitmap_set_bit(table->read_set, field_index); |
11337 | } |
11338 | |
11339 | |
11340 | bool Field::val_str_nopad(MEM_ROOT *mem_root, LEX_CSTRING *to) |
11341 | { |
11342 | StringBuffer<MAX_FIELD_WIDTH> str; |
11343 | bool rc= false; |
11344 | THD *thd= get_thd(); |
11345 | sql_mode_t sql_mode_backup= thd->variables.sql_mode; |
11346 | thd->variables.sql_mode&= ~MODE_PAD_CHAR_TO_FULL_LENGTH; |
11347 | |
11348 | val_str(&str); |
11349 | if (!(to->length= str.length())) |
11350 | *to= empty_clex_str; |
11351 | else if ((rc= !(to->str= strmake_root(mem_root, str.ptr(), str.length())))) |
11352 | to->length= 0; |
11353 | |
11354 | thd->variables.sql_mode= sql_mode_backup; |
11355 | return rc; |
11356 | } |
11357 | |