00001 /* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB 00002 00003 This program is free software; you can redistribute it and/or modify 00004 it under the terms of the GNU General Public License as published by 00005 the Free Software Foundation; either version 2 of the License, or 00006 (at your option) any later version. 00007 00008 This program is distributed in the hope that it will be useful, 00009 but WITHOUT ANY WARRANTY; without even the implied warranty of 00010 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00011 GNU General Public License for more details. 00012 00013 You should have received a copy of the GNU General Public License 00014 along with this program; if not, write to the Free Software 00015 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ 00016 00017 00018 /***************************************************************************** 00019 ** This file implements classes defined in field.h 00020 *****************************************************************************/ 00021 00022 #ifdef USE_PRAGMA_IMPLEMENTATION 00023 #pragma implementation // gcc: Class implementation 00024 #endif 00025 00026 #include "mysql_priv.h" 00027 #include "sql_select.h" 00028 #include <m_ctype.h> 00029 #include <errno.h> 00030 #ifdef HAVE_FCONVERT 00031 #include <floatingpoint.h> 00032 #endif 00033 00034 // Maximum allowed exponent value for converting string to decimal 00035 #define MAX_EXPONENT 1024 00036 00037 /***************************************************************************** 00038 Instansiate templates and static variables 00039 *****************************************************************************/ 00040 00041 #ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION 00042 template class List<create_field>; 00043 template class List_iterator<create_field>; 00044 #endif 00045 00046 uchar Field_null::null[1]={1}; 00047 const char field_separator=','; 00048 00049 #define DOUBLE_TO_STRING_CONVERSION_BUFFER_SIZE 320 00050 #define BLOB_PACK_LENGTH_TO_MAX_LENGH(arg) \ 00051 ((ulong) ((LL(1) << min(arg, 4) * 8) - LL(1))) 00052 00053 #define ASSERT_COLUMN_MARKED_FOR_READ DBUG_ASSERT(!table || (!table->read_set || bitmap_is_set(table->read_set, field_index))) 00054 #define ASSERT_COLUMN_MARKED_FOR_WRITE DBUG_ASSERT(!table || (!table->write_set || bitmap_is_set(table->write_set, field_index))) 00055 00056 /* 00057 Rules for merging different types of fields in UNION 00058 00059 NOTE: to avoid 256*256 table, gap in table types numeration is skiped 00060 following #defines describe that gap and how to canculate number of fields 00061 and index of field in thia array. 00062 */ 00063 #define FIELDTYPE_TEAR_FROM (MYSQL_TYPE_BIT + 1) 00064 #define FIELDTYPE_TEAR_TO (MYSQL_TYPE_NEWDECIMAL - 1) 00065 #define FIELDTYPE_NUM (FIELDTYPE_TEAR_FROM + (255 - FIELDTYPE_TEAR_TO)) 00066 inline int field_type2index (enum_field_types field_type) 00067 { 00068 return (field_type < FIELDTYPE_TEAR_FROM ? 00069 field_type : 00070 ((int)FIELDTYPE_TEAR_FROM) + (field_type - FIELDTYPE_TEAR_TO) - 1); 00071 } 00072 00073 00074 static enum_field_types field_types_merge_rules [FIELDTYPE_NUM][FIELDTYPE_NUM]= 00075 { 00076 /* MYSQL_TYPE_DECIMAL -> */ 00077 { 00078 //MYSQL_TYPE_DECIMAL MYSQL_TYPE_TINY 00079 MYSQL_TYPE_NEWDECIMAL, MYSQL_TYPE_NEWDECIMAL, 00080 //MYSQL_TYPE_SHORT MYSQL_TYPE_LONG 00081 MYSQL_TYPE_NEWDECIMAL, MYSQL_TYPE_NEWDECIMAL, 00082 //MYSQL_TYPE_FLOAT MYSQL_TYPE_DOUBLE 00083 MYSQL_TYPE_DOUBLE, MYSQL_TYPE_DOUBLE, 00084 //MYSQL_TYPE_NULL MYSQL_TYPE_TIMESTAMP 00085 MYSQL_TYPE_NEWDECIMAL, MYSQL_TYPE_VARCHAR, 00086 //MYSQL_TYPE_LONGLONG MYSQL_TYPE_INT24 00087 MYSQL_TYPE_DECIMAL, MYSQL_TYPE_DECIMAL, 00088 //MYSQL_TYPE_DATE MYSQL_TYPE_TIME 00089 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, 00090 //MYSQL_TYPE_DATETIME MYSQL_TYPE_YEAR 00091 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, 00092 //MYSQL_TYPE_NEWDATE MYSQL_TYPE_VARCHAR 00093 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, 00094 //MYSQL_TYPE_BIT <16>-<245> 00095 MYSQL_TYPE_VARCHAR, 00096 //MYSQL_TYPE_NEWDECIMAL MYSQL_TYPE_ENUM 00097 MYSQL_TYPE_NEWDECIMAL, MYSQL_TYPE_VARCHAR, 00098 //MYSQL_TYPE_SET MYSQL_TYPE_TINY_BLOB 00099 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_TINY_BLOB, 00100 //MYSQL_TYPE_MEDIUM_BLOB MYSQL_TYPE_LONG_BLOB 00101 MYSQL_TYPE_MEDIUM_BLOB, MYSQL_TYPE_LONG_BLOB, 00102 //MYSQL_TYPE_BLOB MYSQL_TYPE_VAR_STRING 00103 MYSQL_TYPE_BLOB, MYSQL_TYPE_VARCHAR, 00104 //MYSQL_TYPE_STRING MYSQL_TYPE_GEOMETRY 00105 MYSQL_TYPE_STRING, MYSQL_TYPE_VARCHAR 00106 }, 00107 /* MYSQL_TYPE_TINY -> */ 00108 { 00109 //MYSQL_TYPE_DECIMAL MYSQL_TYPE_TINY 00110 MYSQL_TYPE_NEWDECIMAL, MYSQL_TYPE_TINY, 00111 //MYSQL_TYPE_SHORT MYSQL_TYPE_LONG 00112 MYSQL_TYPE_SHORT, MYSQL_TYPE_LONG, 00113 //MYSQL_TYPE_FLOAT MYSQL_TYPE_DOUBLE 00114 MYSQL_TYPE_FLOAT, MYSQL_TYPE_DOUBLE, 00115 //MYSQL_TYPE_NULL MYSQL_TYPE_TIMESTAMP 00116 MYSQL_TYPE_TINY, MYSQL_TYPE_VARCHAR, 00117 //MYSQL_TYPE_LONGLONG MYSQL_TYPE_INT24 00118 MYSQL_TYPE_LONGLONG, MYSQL_TYPE_INT24, 00119 //MYSQL_TYPE_DATE MYSQL_TYPE_TIME 00120 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, 00121 //MYSQL_TYPE_DATETIME MYSQL_TYPE_YEAR 00122 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_TINY, 00123 //MYSQL_TYPE_NEWDATE MYSQL_TYPE_VARCHAR 00124 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, 00125 //MYSQL_TYPE_BIT <16>-<245> 00126 MYSQL_TYPE_VARCHAR, 00127 //MYSQL_TYPE_NEWDECIMAL MYSQL_TYPE_ENUM 00128 MYSQL_TYPE_NEWDECIMAL, MYSQL_TYPE_VARCHAR, 00129 //MYSQL_TYPE_SET MYSQL_TYPE_TINY_BLOB 00130 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_TINY_BLOB, 00131 //MYSQL_TYPE_MEDIUM_BLOB MYSQL_TYPE_LONG_BLOB 00132 MYSQL_TYPE_MEDIUM_BLOB, MYSQL_TYPE_LONG_BLOB, 00133 //MYSQL_TYPE_BLOB MYSQL_TYPE_VAR_STRING 00134 MYSQL_TYPE_BLOB, MYSQL_TYPE_VARCHAR, 00135 //MYSQL_TYPE_STRING MYSQL_TYPE_GEOMETRY 00136 MYSQL_TYPE_STRING, MYSQL_TYPE_VARCHAR 00137 }, 00138 /* MYSQL_TYPE_SHORT -> */ 00139 { 00140 //MYSQL_TYPE_DECIMAL MYSQL_TYPE_TINY 00141 MYSQL_TYPE_NEWDECIMAL, MYSQL_TYPE_SHORT, 00142 //MYSQL_TYPE_SHORT MYSQL_TYPE_LONG 00143 MYSQL_TYPE_SHORT, MYSQL_TYPE_LONG, 00144 //MYSQL_TYPE_FLOAT MYSQL_TYPE_DOUBLE 00145 MYSQL_TYPE_FLOAT, MYSQL_TYPE_DOUBLE, 00146 //MYSQL_TYPE_NULL MYSQL_TYPE_TIMESTAMP 00147 MYSQL_TYPE_SHORT, MYSQL_TYPE_VARCHAR, 00148 //MYSQL_TYPE_LONGLONG MYSQL_TYPE_INT24 00149 MYSQL_TYPE_LONGLONG, MYSQL_TYPE_INT24, 00150 //MYSQL_TYPE_DATE MYSQL_TYPE_TIME 00151 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, 00152 //MYSQL_TYPE_DATETIME MYSQL_TYPE_YEAR 00153 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_SHORT, 00154 //MYSQL_TYPE_NEWDATE MYSQL_TYPE_VARCHAR 00155 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, 00156 //MYSQL_TYPE_BIT <16>-<245> 00157 MYSQL_TYPE_VARCHAR, 00158 //MYSQL_TYPE_NEWDECIMAL MYSQL_TYPE_ENUM 00159 MYSQL_TYPE_NEWDECIMAL, MYSQL_TYPE_VARCHAR, 00160 //MYSQL_TYPE_SET MYSQL_TYPE_TINY_BLOB 00161 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_TINY_BLOB, 00162 //MYSQL_TYPE_MEDIUM_BLOB MYSQL_TYPE_LONG_BLOB 00163 MYSQL_TYPE_MEDIUM_BLOB, MYSQL_TYPE_LONG_BLOB, 00164 //MYSQL_TYPE_BLOB MYSQL_TYPE_VAR_STRING 00165 MYSQL_TYPE_BLOB, MYSQL_TYPE_VARCHAR, 00166 //MYSQL_TYPE_STRING MYSQL_TYPE_GEOMETRY 00167 MYSQL_TYPE_STRING, MYSQL_TYPE_VARCHAR 00168 }, 00169 /* MYSQL_TYPE_LONG -> */ 00170 { 00171 //MYSQL_TYPE_DECIMAL MYSQL_TYPE_TINY 00172 MYSQL_TYPE_NEWDECIMAL, MYSQL_TYPE_LONG, 00173 //MYSQL_TYPE_SHORT MYSQL_TYPE_LONG 00174 MYSQL_TYPE_LONG, MYSQL_TYPE_LONG, 00175 //MYSQL_TYPE_FLOAT MYSQL_TYPE_DOUBLE 00176 MYSQL_TYPE_DOUBLE, MYSQL_TYPE_DOUBLE, 00177 //MYSQL_TYPE_NULL MYSQL_TYPE_TIMESTAMP 00178 MYSQL_TYPE_LONG, MYSQL_TYPE_VARCHAR, 00179 //MYSQL_TYPE_LONGLONG MYSQL_TYPE_INT24 00180 MYSQL_TYPE_LONGLONG, MYSQL_TYPE_INT24, 00181 //MYSQL_TYPE_DATE MYSQL_TYPE_TIME 00182 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, 00183 //MYSQL_TYPE_DATETIME MYSQL_TYPE_YEAR 00184 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_LONG, 00185 //MYSQL_TYPE_NEWDATE MYSQL_TYPE_VARCHAR 00186 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, 00187 //MYSQL_TYPE_BIT <16>-<245> 00188 MYSQL_TYPE_VARCHAR, 00189 //MYSQL_TYPE_NEWDECIMAL MYSQL_TYPE_ENUM 00190 MYSQL_TYPE_NEWDECIMAL, MYSQL_TYPE_VARCHAR, 00191 //MYSQL_TYPE_SET MYSQL_TYPE_TINY_BLOB 00192 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_TINY_BLOB, 00193 //MYSQL_TYPE_MEDIUM_BLOB MYSQL_TYPE_LONG_BLOB 00194 MYSQL_TYPE_MEDIUM_BLOB, MYSQL_TYPE_LONG_BLOB, 00195 //MYSQL_TYPE_BLOB MYSQL_TYPE_VAR_STRING 00196 MYSQL_TYPE_BLOB, MYSQL_TYPE_VARCHAR, 00197 //MYSQL_TYPE_STRING MYSQL_TYPE_GEOMETRY 00198 MYSQL_TYPE_STRING, MYSQL_TYPE_VARCHAR 00199 }, 00200 /* MYSQL_TYPE_FLOAT -> */ 00201 { 00202 //MYSQL_TYPE_DECIMAL MYSQL_TYPE_TINY 00203 MYSQL_TYPE_DOUBLE, MYSQL_TYPE_FLOAT, 00204 //MYSQL_TYPE_SHORT MYSQL_TYPE_LONG 00205 MYSQL_TYPE_FLOAT, MYSQL_TYPE_DOUBLE, 00206 //MYSQL_TYPE_FLOAT MYSQL_TYPE_DOUBLE 00207 MYSQL_TYPE_FLOAT, MYSQL_TYPE_DOUBLE, 00208 //MYSQL_TYPE_NULL MYSQL_TYPE_TIMESTAMP 00209 MYSQL_TYPE_FLOAT, MYSQL_TYPE_VARCHAR, 00210 //MYSQL_TYPE_LONGLONG MYSQL_TYPE_INT24 00211 MYSQL_TYPE_FLOAT, MYSQL_TYPE_INT24, 00212 //MYSQL_TYPE_DATE MYSQL_TYPE_TIME 00213 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, 00214 //MYSQL_TYPE_DATETIME MYSQL_TYPE_YEAR 00215 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_FLOAT, 00216 //MYSQL_TYPE_NEWDATE MYSQL_TYPE_VARCHAR 00217 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, 00218 //MYSQL_TYPE_BIT <16>-<245> 00219 MYSQL_TYPE_VARCHAR, 00220 //MYSQL_TYPE_NEWDECIMAL MYSQL_TYPE_ENUM 00221 MYSQL_TYPE_DOUBLE, MYSQL_TYPE_VARCHAR, 00222 //MYSQL_TYPE_SET MYSQL_TYPE_TINY_BLOB 00223 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_TINY_BLOB, 00224 //MYSQL_TYPE_MEDIUM_BLOB MYSQL_TYPE_LONG_BLOB 00225 MYSQL_TYPE_MEDIUM_BLOB, MYSQL_TYPE_LONG_BLOB, 00226 //MYSQL_TYPE_BLOB MYSQL_TYPE_VAR_STRING 00227 MYSQL_TYPE_BLOB, MYSQL_TYPE_VARCHAR, 00228 //MYSQL_TYPE_STRING MYSQL_TYPE_GEOMETRY 00229 MYSQL_TYPE_STRING, MYSQL_TYPE_VARCHAR 00230 }, 00231 /* MYSQL_TYPE_DOUBLE -> */ 00232 { 00233 //MYSQL_TYPE_DECIMAL MYSQL_TYPE_TINY 00234 MYSQL_TYPE_DOUBLE, MYSQL_TYPE_DOUBLE, 00235 //MYSQL_TYPE_SHORT MYSQL_TYPE_LONG 00236 MYSQL_TYPE_DOUBLE, MYSQL_TYPE_DOUBLE, 00237 //MYSQL_TYPE_FLOAT MYSQL_TYPE_DOUBLE 00238 MYSQL_TYPE_DOUBLE, MYSQL_TYPE_DOUBLE, 00239 //MYSQL_TYPE_NULL MYSQL_TYPE_TIMESTAMP 00240 MYSQL_TYPE_DOUBLE, MYSQL_TYPE_VARCHAR, 00241 //MYSQL_TYPE_LONGLONG MYSQL_TYPE_INT24 00242 MYSQL_TYPE_DOUBLE, MYSQL_TYPE_INT24, 00243 //MYSQL_TYPE_DATE MYSQL_TYPE_TIME 00244 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, 00245 //MYSQL_TYPE_DATETIME MYSQL_TYPE_YEAR 00246 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_DOUBLE, 00247 //MYSQL_TYPE_NEWDATE MYSQL_TYPE_VARCHAR 00248 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, 00249 //MYSQL_TYPE_BIT <16>-<245> 00250 MYSQL_TYPE_VARCHAR, 00251 //MYSQL_TYPE_NEWDECIMAL MYSQL_TYPE_ENUM 00252 MYSQL_TYPE_DOUBLE, MYSQL_TYPE_VARCHAR, 00253 //MYSQL_TYPE_SET MYSQL_TYPE_TINY_BLOB 00254 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_TINY_BLOB, 00255 //MYSQL_TYPE_MEDIUM_BLOB MYSQL_TYPE_LONG_BLOB 00256 MYSQL_TYPE_MEDIUM_BLOB, MYSQL_TYPE_LONG_BLOB, 00257 //MYSQL_TYPE_BLOB MYSQL_TYPE_VAR_STRING 00258 MYSQL_TYPE_BLOB, MYSQL_TYPE_VARCHAR, 00259 //MYSQL_TYPE_STRING MYSQL_TYPE_GEOMETRY 00260 MYSQL_TYPE_STRING, MYSQL_TYPE_VARCHAR 00261 }, 00262 /* MYSQL_TYPE_NULL -> */ 00263 { 00264 //MYSQL_TYPE_DECIMAL MYSQL_TYPE_TINY 00265 MYSQL_TYPE_NEWDECIMAL, MYSQL_TYPE_TINY, 00266 //MYSQL_TYPE_SHORT MYSQL_TYPE_LONG 00267 MYSQL_TYPE_SHORT, MYSQL_TYPE_LONG, 00268 //MYSQL_TYPE_FLOAT MYSQL_TYPE_DOUBLE 00269 MYSQL_TYPE_FLOAT, MYSQL_TYPE_DOUBLE, 00270 //MYSQL_TYPE_NULL MYSQL_TYPE_TIMESTAMP 00271 MYSQL_TYPE_NULL, MYSQL_TYPE_TIMESTAMP, 00272 //MYSQL_TYPE_LONGLONG MYSQL_TYPE_INT24 00273 MYSQL_TYPE_LONGLONG, MYSQL_TYPE_INT24, 00274 //MYSQL_TYPE_DATE MYSQL_TYPE_TIME 00275 MYSQL_TYPE_NEWDATE, MYSQL_TYPE_TIME, 00276 //MYSQL_TYPE_DATETIME MYSQL_TYPE_YEAR 00277 MYSQL_TYPE_DATETIME, MYSQL_TYPE_YEAR, 00278 //MYSQL_TYPE_NEWDATE MYSQL_TYPE_VARCHAR 00279 MYSQL_TYPE_NEWDATE, MYSQL_TYPE_VARCHAR, 00280 //MYSQL_TYPE_BIT <16>-<245> 00281 MYSQL_TYPE_BIT, 00282 //MYSQL_TYPE_NEWDECIMAL MYSQL_TYPE_ENUM 00283 MYSQL_TYPE_NEWDECIMAL, MYSQL_TYPE_ENUM, 00284 //MYSQL_TYPE_SET MYSQL_TYPE_TINY_BLOB 00285 MYSQL_TYPE_SET, MYSQL_TYPE_TINY_BLOB, 00286 //MYSQL_TYPE_MEDIUM_BLOB MYSQL_TYPE_LONG_BLOB 00287 MYSQL_TYPE_MEDIUM_BLOB, MYSQL_TYPE_LONG_BLOB, 00288 //MYSQL_TYPE_BLOB MYSQL_TYPE_VAR_STRING 00289 MYSQL_TYPE_BLOB, MYSQL_TYPE_VARCHAR, 00290 //MYSQL_TYPE_STRING MYSQL_TYPE_GEOMETRY 00291 MYSQL_TYPE_STRING, MYSQL_TYPE_GEOMETRY 00292 }, 00293 /* MYSQL_TYPE_TIMESTAMP -> */ 00294 { 00295 //MYSQL_TYPE_DECIMAL MYSQL_TYPE_TINY 00296 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, 00297 //MYSQL_TYPE_SHORT MYSQL_TYPE_LONG 00298 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, 00299 //MYSQL_TYPE_FLOAT MYSQL_TYPE_DOUBLE 00300 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, 00301 //MYSQL_TYPE_NULL MYSQL_TYPE_TIMESTAMP 00302 MYSQL_TYPE_TIMESTAMP, MYSQL_TYPE_TIMESTAMP, 00303 //MYSQL_TYPE_LONGLONG MYSQL_TYPE_INT24 00304 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, 00305 //MYSQL_TYPE_DATE MYSQL_TYPE_TIME 00306 MYSQL_TYPE_DATETIME, MYSQL_TYPE_DATETIME, 00307 //MYSQL_TYPE_DATETIME MYSQL_TYPE_YEAR 00308 MYSQL_TYPE_DATETIME, MYSQL_TYPE_VARCHAR, 00309 //MYSQL_TYPE_NEWDATE MYSQL_TYPE_VARCHAR 00310 MYSQL_TYPE_NEWDATE, MYSQL_TYPE_VARCHAR, 00311 //MYSQL_TYPE_BIT <16>-<245> 00312 MYSQL_TYPE_VARCHAR, 00313 //MYSQL_TYPE_NEWDECIMAL MYSQL_TYPE_ENUM 00314 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, 00315 //MYSQL_TYPE_SET MYSQL_TYPE_TINY_BLOB 00316 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_TINY_BLOB, 00317 //MYSQL_TYPE_MEDIUM_BLOB MYSQL_TYPE_LONG_BLOB 00318 MYSQL_TYPE_MEDIUM_BLOB, MYSQL_TYPE_LONG_BLOB, 00319 //MYSQL_TYPE_BLOB MYSQL_TYPE_VAR_STRING 00320 MYSQL_TYPE_BLOB, MYSQL_TYPE_VARCHAR, 00321 //MYSQL_TYPE_STRING MYSQL_TYPE_GEOMETRY 00322 MYSQL_TYPE_STRING, MYSQL_TYPE_VARCHAR 00323 }, 00324 /* MYSQL_TYPE_LONGLONG -> */ 00325 { 00326 //MYSQL_TYPE_DECIMAL MYSQL_TYPE_TINY 00327 MYSQL_TYPE_NEWDECIMAL, MYSQL_TYPE_LONGLONG, 00328 //MYSQL_TYPE_SHORT MYSQL_TYPE_LONG 00329 MYSQL_TYPE_LONGLONG, MYSQL_TYPE_LONGLONG, 00330 //MYSQL_TYPE_FLOAT MYSQL_TYPE_DOUBLE 00331 MYSQL_TYPE_DOUBLE, MYSQL_TYPE_DOUBLE, 00332 //MYSQL_TYPE_NULL MYSQL_TYPE_TIMESTAMP 00333 MYSQL_TYPE_LONGLONG, MYSQL_TYPE_VARCHAR, 00334 //MYSQL_TYPE_LONGLONG MYSQL_TYPE_INT24 00335 MYSQL_TYPE_LONGLONG, MYSQL_TYPE_LONG, 00336 //MYSQL_TYPE_DATE MYSQL_TYPE_TIME 00337 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, 00338 //MYSQL_TYPE_DATETIME MYSQL_TYPE_YEAR 00339 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_LONGLONG, 00340 //MYSQL_TYPE_NEWDATE MYSQL_TYPE_VARCHAR 00341 MYSQL_TYPE_NEWDATE, MYSQL_TYPE_VARCHAR, 00342 //MYSQL_TYPE_BIT <16>-<245> 00343 MYSQL_TYPE_VARCHAR, 00344 //MYSQL_TYPE_NEWDECIMAL MYSQL_TYPE_ENUM 00345 MYSQL_TYPE_NEWDECIMAL, MYSQL_TYPE_VARCHAR, 00346 //MYSQL_TYPE_SET MYSQL_TYPE_TINY_BLOB 00347 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_TINY_BLOB, 00348 //MYSQL_TYPE_MEDIUM_BLOB MYSQL_TYPE_LONG_BLOB 00349 MYSQL_TYPE_MEDIUM_BLOB, MYSQL_TYPE_LONG_BLOB, 00350 //MYSQL_TYPE_BLOB MYSQL_TYPE_VAR_STRING 00351 MYSQL_TYPE_BLOB, MYSQL_TYPE_VARCHAR, 00352 //MYSQL_TYPE_STRING MYSQL_TYPE_GEOMETRY 00353 MYSQL_TYPE_STRING, MYSQL_TYPE_VARCHAR 00354 }, 00355 /* MYSQL_TYPE_INT24 -> */ 00356 { 00357 //MYSQL_TYPE_DECIMAL MYSQL_TYPE_TINY 00358 MYSQL_TYPE_NEWDECIMAL, MYSQL_TYPE_INT24, 00359 //MYSQL_TYPE_SHORT MYSQL_TYPE_LONG 00360 MYSQL_TYPE_INT24, MYSQL_TYPE_LONG, 00361 //MYSQL_TYPE_FLOAT MYSQL_TYPE_DOUBLE 00362 MYSQL_TYPE_FLOAT, MYSQL_TYPE_DOUBLE, 00363 //MYSQL_TYPE_NULL MYSQL_TYPE_TIMESTAMP 00364 MYSQL_TYPE_INT24, MYSQL_TYPE_VARCHAR, 00365 //MYSQL_TYPE_LONGLONG MYSQL_TYPE_INT24 00366 MYSQL_TYPE_LONGLONG, MYSQL_TYPE_INT24, 00367 //MYSQL_TYPE_DATE MYSQL_TYPE_TIME 00368 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, 00369 //MYSQL_TYPE_DATETIME MYSQL_TYPE_YEAR 00370 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_INT24, 00371 //MYSQL_TYPE_NEWDATE MYSQL_TYPE_VARCHAR 00372 MYSQL_TYPE_NEWDATE, MYSQL_TYPE_VARCHAR, 00373 //MYSQL_TYPE_BIT <16>-<245> 00374 MYSQL_TYPE_VARCHAR, 00375 //MYSQL_TYPE_NEWDECIMAL MYSQL_TYPE_ENUM 00376 MYSQL_TYPE_NEWDECIMAL, MYSQL_TYPE_VARCHAR, 00377 //MYSQL_TYPE_SET MYSQL_TYPE_TINY_BLOB 00378 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_TINY_BLOB, 00379 //MYSQL_TYPE_MEDIUM_BLOB MYSQL_TYPE_LONG_BLOB 00380 MYSQL_TYPE_MEDIUM_BLOB, MYSQL_TYPE_LONG_BLOB, 00381 //MYSQL_TYPE_BLOB MYSQL_TYPE_VAR_STRING 00382 MYSQL_TYPE_BLOB, MYSQL_TYPE_VARCHAR, 00383 //MYSQL_TYPE_STRING MYSQL_TYPE_GEOMETRY 00384 MYSQL_TYPE_STRING, MYSQL_TYPE_VARCHAR 00385 }, 00386 /* MYSQL_TYPE_DATE -> */ 00387 { 00388 //MYSQL_TYPE_DECIMAL MYSQL_TYPE_TINY 00389 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, 00390 //MYSQL_TYPE_SHORT MYSQL_TYPE_LONG 00391 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, 00392 //MYSQL_TYPE_FLOAT MYSQL_TYPE_DOUBLE 00393 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, 00394 //MYSQL_TYPE_NULL MYSQL_TYPE_TIMESTAMP 00395 MYSQL_TYPE_NEWDATE, MYSQL_TYPE_DATETIME, 00396 //MYSQL_TYPE_LONGLONG MYSQL_TYPE_INT24 00397 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, 00398 //MYSQL_TYPE_DATE MYSQL_TYPE_TIME 00399 MYSQL_TYPE_NEWDATE, MYSQL_TYPE_DATETIME, 00400 //MYSQL_TYPE_DATETIME MYSQL_TYPE_YEAR 00401 MYSQL_TYPE_DATETIME, MYSQL_TYPE_VARCHAR, 00402 //MYSQL_TYPE_NEWDATE MYSQL_TYPE_VARCHAR 00403 MYSQL_TYPE_NEWDATE, MYSQL_TYPE_VARCHAR, 00404 //MYSQL_TYPE_BIT <16>-<245> 00405 MYSQL_TYPE_VARCHAR, 00406 //MYSQL_TYPE_NEWDECIMAL MYSQL_TYPE_ENUM 00407 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, 00408 //MYSQL_TYPE_SET MYSQL_TYPE_TINY_BLOB 00409 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_TINY_BLOB, 00410 //MYSQL_TYPE_MEDIUM_BLOB MYSQL_TYPE_LONG_BLOB 00411 MYSQL_TYPE_MEDIUM_BLOB, MYSQL_TYPE_LONG_BLOB, 00412 //MYSQL_TYPE_BLOB MYSQL_TYPE_VAR_STRING 00413 MYSQL_TYPE_BLOB, MYSQL_TYPE_VARCHAR, 00414 //MYSQL_TYPE_STRING MYSQL_TYPE_GEOMETRY 00415 MYSQL_TYPE_STRING, MYSQL_TYPE_VARCHAR 00416 }, 00417 /* MYSQL_TYPE_TIME -> */ 00418 { 00419 //MYSQL_TYPE_DECIMAL MYSQL_TYPE_TINY 00420 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, 00421 //MYSQL_TYPE_SHORT MYSQL_TYPE_LONG 00422 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, 00423 //MYSQL_TYPE_FLOAT MYSQL_TYPE_DOUBLE 00424 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, 00425 //MYSQL_TYPE_NULL MYSQL_TYPE_TIMESTAMP 00426 MYSQL_TYPE_TIME, MYSQL_TYPE_DATETIME, 00427 //MYSQL_TYPE_LONGLONG MYSQL_TYPE_INT24 00428 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, 00429 //MYSQL_TYPE_DATE MYSQL_TYPE_TIME 00430 MYSQL_TYPE_DATETIME, MYSQL_TYPE_TIME, 00431 //MYSQL_TYPE_DATETIME MYSQL_TYPE_YEAR 00432 MYSQL_TYPE_DATETIME, MYSQL_TYPE_VARCHAR, 00433 //MYSQL_TYPE_NEWDATE MYSQL_TYPE_VARCHAR 00434 MYSQL_TYPE_NEWDATE, MYSQL_TYPE_VARCHAR, 00435 //MYSQL_TYPE_BIT <16>-<245> 00436 MYSQL_TYPE_VARCHAR, 00437 //MYSQL_TYPE_NEWDECIMAL MYSQL_TYPE_ENUM 00438 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, 00439 //MYSQL_TYPE_SET MYSQL_TYPE_TINY_BLOB 00440 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_TINY_BLOB, 00441 //MYSQL_TYPE_MEDIUM_BLOB MYSQL_TYPE_LONG_BLOB 00442 MYSQL_TYPE_MEDIUM_BLOB, MYSQL_TYPE_LONG_BLOB, 00443 //MYSQL_TYPE_BLOB MYSQL_TYPE_VAR_STRING 00444 MYSQL_TYPE_BLOB, MYSQL_TYPE_VARCHAR, 00445 //MYSQL_TYPE_STRING MYSQL_TYPE_GEOMETRY 00446 MYSQL_TYPE_STRING, MYSQL_TYPE_VARCHAR 00447 }, 00448 /* MYSQL_TYPE_DATETIME -> */ 00449 { 00450 //MYSQL_TYPE_DECIMAL MYSQL_TYPE_TINY 00451 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, 00452 //MYSQL_TYPE_SHORT MYSQL_TYPE_LONG 00453 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, 00454 //MYSQL_TYPE_FLOAT MYSQL_TYPE_DOUBLE 00455 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, 00456 //MYSQL_TYPE_NULL MYSQL_TYPE_TIMESTAMP 00457 MYSQL_TYPE_DATETIME, MYSQL_TYPE_DATETIME, 00458 //MYSQL_TYPE_LONGLONG MYSQL_TYPE_INT24 00459 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, 00460 //MYSQL_TYPE_DATE MYSQL_TYPE_TIME 00461 MYSQL_TYPE_DATETIME, MYSQL_TYPE_DATETIME, 00462 //MYSQL_TYPE_DATETIME MYSQL_TYPE_YEAR 00463 MYSQL_TYPE_DATETIME, MYSQL_TYPE_VARCHAR, 00464 //MYSQL_TYPE_NEWDATE MYSQL_TYPE_VARCHAR 00465 MYSQL_TYPE_NEWDATE, MYSQL_TYPE_VARCHAR, 00466 //MYSQL_TYPE_BIT <16>-<245> 00467 MYSQL_TYPE_VARCHAR, 00468 //MYSQL_TYPE_NEWDECIMAL MYSQL_TYPE_ENUM 00469 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, 00470 //MYSQL_TYPE_SET MYSQL_TYPE_TINY_BLOB 00471 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_TINY_BLOB, 00472 //MYSQL_TYPE_MEDIUM_BLOB MYSQL_TYPE_LONG_BLOB 00473 MYSQL_TYPE_MEDIUM_BLOB, MYSQL_TYPE_LONG_BLOB, 00474 //MYSQL_TYPE_BLOB MYSQL_TYPE_VAR_STRING 00475 MYSQL_TYPE_BLOB, MYSQL_TYPE_VARCHAR, 00476 //MYSQL_TYPE_STRING MYSQL_TYPE_GEOMETRY 00477 MYSQL_TYPE_STRING, MYSQL_TYPE_VARCHAR 00478 }, 00479 /* MYSQL_TYPE_YEAR -> */ 00480 { 00481 //MYSQL_TYPE_DECIMAL MYSQL_TYPE_TINY 00482 MYSQL_TYPE_DECIMAL, MYSQL_TYPE_TINY, 00483 //MYSQL_TYPE_SHORT MYSQL_TYPE_LONG 00484 MYSQL_TYPE_SHORT, MYSQL_TYPE_LONG, 00485 //MYSQL_TYPE_FLOAT MYSQL_TYPE_DOUBLE 00486 MYSQL_TYPE_FLOAT, MYSQL_TYPE_DOUBLE, 00487 //MYSQL_TYPE_NULL MYSQL_TYPE_TIMESTAMP 00488 MYSQL_TYPE_YEAR, MYSQL_TYPE_VARCHAR, 00489 //MYSQL_TYPE_LONGLONG MYSQL_TYPE_INT24 00490 MYSQL_TYPE_LONGLONG, MYSQL_TYPE_INT24, 00491 //MYSQL_TYPE_DATE MYSQL_TYPE_TIME 00492 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, 00493 //MYSQL_TYPE_DATETIME MYSQL_TYPE_YEAR 00494 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_YEAR, 00495 //MYSQL_TYPE_NEWDATE MYSQL_TYPE_VARCHAR 00496 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, 00497 //MYSQL_TYPE_BIT <16>-<245> 00498 MYSQL_TYPE_VARCHAR, 00499 //MYSQL_TYPE_NEWDECIMAL MYSQL_TYPE_ENUM 00500 MYSQL_TYPE_NEWDECIMAL, MYSQL_TYPE_VARCHAR, 00501 //MYSQL_TYPE_SET MYSQL_TYPE_TINY_BLOB 00502 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_TINY_BLOB, 00503 //MYSQL_TYPE_MEDIUM_BLOB MYSQL_TYPE_LONG_BLOB 00504 MYSQL_TYPE_MEDIUM_BLOB, MYSQL_TYPE_LONG_BLOB, 00505 //MYSQL_TYPE_BLOB MYSQL_TYPE_VAR_STRING 00506 MYSQL_TYPE_BLOB, MYSQL_TYPE_VARCHAR, 00507 //MYSQL_TYPE_STRING MYSQL_TYPE_GEOMETRY 00508 MYSQL_TYPE_STRING, MYSQL_TYPE_VARCHAR 00509 }, 00510 /* MYSQL_TYPE_NEWDATE -> */ 00511 { 00512 //MYSQL_TYPE_DECIMAL MYSQL_TYPE_TINY 00513 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, 00514 //MYSQL_TYPE_SHORT MYSQL_TYPE_LONG 00515 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, 00516 //MYSQL_TYPE_FLOAT MYSQL_TYPE_DOUBLE 00517 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, 00518 //MYSQL_TYPE_NULL MYSQL_TYPE_TIMESTAMP 00519 MYSQL_TYPE_NEWDATE, MYSQL_TYPE_DATETIME, 00520 //MYSQL_TYPE_LONGLONG MYSQL_TYPE_INT24 00521 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, 00522 //MYSQL_TYPE_DATE MYSQL_TYPE_TIME 00523 MYSQL_TYPE_NEWDATE, MYSQL_TYPE_DATETIME, 00524 //MYSQL_TYPE_DATETIME MYSQL_TYPE_YEAR 00525 MYSQL_TYPE_DATETIME, MYSQL_TYPE_VARCHAR, 00526 //MYSQL_TYPE_NEWDATE MYSQL_TYPE_VARCHAR 00527 MYSQL_TYPE_NEWDATE, MYSQL_TYPE_VARCHAR, 00528 //MYSQL_TYPE_BIT <16>-<245> 00529 MYSQL_TYPE_VARCHAR, 00530 //MYSQL_TYPE_NEWDECIMAL MYSQL_TYPE_ENUM 00531 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, 00532 //MYSQL_TYPE_SET MYSQL_TYPE_TINY_BLOB 00533 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_TINY_BLOB, 00534 //MYSQL_TYPE_MEDIUM_BLOB MYSQL_TYPE_LONG_BLOB 00535 MYSQL_TYPE_MEDIUM_BLOB, MYSQL_TYPE_LONG_BLOB, 00536 //MYSQL_TYPE_BLOB MYSQL_TYPE_VAR_STRING 00537 MYSQL_TYPE_BLOB, MYSQL_TYPE_VARCHAR, 00538 //MYSQL_TYPE_STRING MYSQL_TYPE_GEOMETRY 00539 MYSQL_TYPE_STRING, MYSQL_TYPE_VARCHAR 00540 }, 00541 /* MYSQL_TYPE_VARCHAR -> */ 00542 { 00543 //MYSQL_TYPE_DECIMAL MYSQL_TYPE_TINY 00544 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, 00545 //MYSQL_TYPE_SHORT MYSQL_TYPE_LONG 00546 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, 00547 //MYSQL_TYPE_FLOAT MYSQL_TYPE_DOUBLE 00548 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, 00549 //MYSQL_TYPE_NULL MYSQL_TYPE_TIMESTAMP 00550 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, 00551 //MYSQL_TYPE_LONGLONG MYSQL_TYPE_INT24 00552 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, 00553 //MYSQL_TYPE_DATE MYSQL_TYPE_TIME 00554 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, 00555 //MYSQL_TYPE_DATETIME MYSQL_TYPE_YEAR 00556 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, 00557 //MYSQL_TYPE_NEWDATE MYSQL_TYPE_VARCHAR 00558 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, 00559 //MYSQL_TYPE_BIT <16>-<245> 00560 MYSQL_TYPE_VARCHAR, 00561 //MYSQL_TYPE_NEWDECIMAL MYSQL_TYPE_ENUM 00562 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, 00563 //MYSQL_TYPE_SET MYSQL_TYPE_TINY_BLOB 00564 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_TINY_BLOB, 00565 //MYSQL_TYPE_MEDIUM_BLOB MYSQL_TYPE_LONG_BLOB 00566 MYSQL_TYPE_MEDIUM_BLOB, MYSQL_TYPE_LONG_BLOB, 00567 //MYSQL_TYPE_BLOB MYSQL_TYPE_VAR_STRING 00568 MYSQL_TYPE_BLOB, MYSQL_TYPE_VARCHAR, 00569 //MYSQL_TYPE_STRING MYSQL_TYPE_GEOMETRY 00570 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR 00571 }, 00572 /* MYSQL_TYPE_BIT -> */ 00573 { 00574 //MYSQL_TYPE_DECIMAL MYSQL_TYPE_TINY 00575 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, 00576 //MYSQL_TYPE_SHORT MYSQL_TYPE_LONG 00577 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, 00578 //MYSQL_TYPE_FLOAT MYSQL_TYPE_DOUBLE 00579 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, 00580 //MYSQL_TYPE_NULL MYSQL_TYPE_TIMESTAMP 00581 MYSQL_TYPE_BIT, MYSQL_TYPE_VARCHAR, 00582 //MYSQL_TYPE_LONGLONG MYSQL_TYPE_INT24 00583 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, 00584 //MYSQL_TYPE_DATE MYSQL_TYPE_TIME 00585 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, 00586 //MYSQL_TYPE_DATETIME MYSQL_TYPE_YEAR 00587 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, 00588 //MYSQL_TYPE_NEWDATE MYSQL_TYPE_VARCHAR 00589 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, 00590 //MYSQL_TYPE_BIT <16>-<245> 00591 MYSQL_TYPE_BIT, 00592 //MYSQL_TYPE_NEWDECIMAL MYSQL_TYPE_ENUM 00593 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, 00594 //MYSQL_TYPE_SET MYSQL_TYPE_TINY_BLOB 00595 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_TINY_BLOB, 00596 //MYSQL_TYPE_MEDIUM_BLOB MYSQL_TYPE_LONG_BLOB 00597 MYSQL_TYPE_MEDIUM_BLOB, MYSQL_TYPE_LONG_BLOB, 00598 //MYSQL_TYPE_BLOB MYSQL_TYPE_VAR_STRING 00599 MYSQL_TYPE_BLOB, MYSQL_TYPE_VARCHAR, 00600 //MYSQL_TYPE_STRING MYSQL_TYPE_GEOMETRY 00601 MYSQL_TYPE_STRING, MYSQL_TYPE_VARCHAR 00602 }, 00603 /* MYSQL_TYPE_NEWDECIMAL -> */ 00604 { 00605 //MYSQL_TYPE_DECIMAL MYSQL_TYPE_TINY 00606 MYSQL_TYPE_NEWDECIMAL, MYSQL_TYPE_NEWDECIMAL, 00607 //MYSQL_TYPE_SHORT MYSQL_TYPE_LONG 00608 MYSQL_TYPE_NEWDECIMAL, MYSQL_TYPE_NEWDECIMAL, 00609 //MYSQL_TYPE_FLOAT MYSQL_TYPE_DOUBLE 00610 MYSQL_TYPE_DOUBLE, MYSQL_TYPE_DOUBLE, 00611 //MYSQL_TYPE_NULL MYSQL_TYPE_TIMESTAMP 00612 MYSQL_TYPE_NEWDECIMAL, MYSQL_TYPE_VARCHAR, 00613 //MYSQL_TYPE_LONGLONG MYSQL_TYPE_INT24 00614 MYSQL_TYPE_NEWDECIMAL, MYSQL_TYPE_NEWDECIMAL, 00615 //MYSQL_TYPE_DATE MYSQL_TYPE_TIME 00616 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, 00617 //MYSQL_TYPE_DATETIME MYSQL_TYPE_YEAR 00618 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_NEWDECIMAL, 00619 //MYSQL_TYPE_NEWDATE MYSQL_TYPE_VARCHAR 00620 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, 00621 //MYSQL_TYPE_BIT <16>-<245> 00622 MYSQL_TYPE_VARCHAR, 00623 //MYSQL_TYPE_NEWDECIMAL MYSQL_TYPE_ENUM 00624 MYSQL_TYPE_NEWDECIMAL, MYSQL_TYPE_VARCHAR, 00625 //MYSQL_TYPE_SET MYSQL_TYPE_TINY_BLOB 00626 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_TINY_BLOB, 00627 //MYSQL_TYPE_MEDIUM_BLOB MYSQL_TYPE_LONG_BLOB 00628 MYSQL_TYPE_MEDIUM_BLOB, MYSQL_TYPE_LONG_BLOB, 00629 //MYSQL_TYPE_BLOB MYSQL_TYPE_VAR_STRING 00630 MYSQL_TYPE_BLOB, MYSQL_TYPE_VARCHAR, 00631 //MYSQL_TYPE_STRING MYSQL_TYPE_GEOMETRY 00632 MYSQL_TYPE_STRING, MYSQL_TYPE_VARCHAR 00633 }, 00634 /* MYSQL_TYPE_ENUM -> */ 00635 { 00636 //MYSQL_TYPE_DECIMAL MYSQL_TYPE_TINY 00637 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, 00638 //MYSQL_TYPE_SHORT MYSQL_TYPE_LONG 00639 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, 00640 //MYSQL_TYPE_FLOAT MYSQL_TYPE_DOUBLE 00641 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, 00642 //MYSQL_TYPE_NULL MYSQL_TYPE_TIMESTAMP 00643 MYSQL_TYPE_ENUM, MYSQL_TYPE_VARCHAR, 00644 //MYSQL_TYPE_LONGLONG MYSQL_TYPE_INT24 00645 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, 00646 //MYSQL_TYPE_DATE MYSQL_TYPE_TIME 00647 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, 00648 //MYSQL_TYPE_DATETIME MYSQL_TYPE_YEAR 00649 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, 00650 //MYSQL_TYPE_NEWDATE MYSQL_TYPE_VARCHAR 00651 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, 00652 //MYSQL_TYPE_BIT <16>-<245> 00653 MYSQL_TYPE_VARCHAR, 00654 //MYSQL_TYPE_NEWDECIMAL MYSQL_TYPE_ENUM 00655 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, 00656 //MYSQL_TYPE_SET MYSQL_TYPE_TINY_BLOB 00657 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_TINY_BLOB, 00658 //MYSQL_TYPE_MEDIUM_BLOB MYSQL_TYPE_LONG_BLOB 00659 MYSQL_TYPE_MEDIUM_BLOB, MYSQL_TYPE_LONG_BLOB, 00660 //MYSQL_TYPE_BLOB MYSQL_TYPE_VAR_STRING 00661 MYSQL_TYPE_BLOB, MYSQL_TYPE_VARCHAR, 00662 //MYSQL_TYPE_STRING MYSQL_TYPE_GEOMETRY 00663 MYSQL_TYPE_STRING, MYSQL_TYPE_VARCHAR 00664 }, 00665 /* MYSQL_TYPE_SET -> */ 00666 { 00667 //MYSQL_TYPE_DECIMAL MYSQL_TYPE_TINY 00668 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, 00669 //MYSQL_TYPE_SHORT MYSQL_TYPE_LONG 00670 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, 00671 //MYSQL_TYPE_FLOAT MYSQL_TYPE_DOUBLE 00672 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, 00673 //MYSQL_TYPE_NULL MYSQL_TYPE_TIMESTAMP 00674 MYSQL_TYPE_SET, MYSQL_TYPE_VARCHAR, 00675 //MYSQL_TYPE_LONGLONG MYSQL_TYPE_INT24 00676 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, 00677 //MYSQL_TYPE_DATE MYSQL_TYPE_TIME 00678 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, 00679 //MYSQL_TYPE_DATETIME MYSQL_TYPE_YEAR 00680 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, 00681 //MYSQL_TYPE_NEWDATE MYSQL_TYPE_VARCHAR 00682 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, 00683 //MYSQL_TYPE_BIT <16>-<245> 00684 MYSQL_TYPE_VARCHAR, 00685 //MYSQL_TYPE_NEWDECIMAL MYSQL_TYPE_ENUM 00686 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, 00687 //MYSQL_TYPE_SET MYSQL_TYPE_TINY_BLOB 00688 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_TINY_BLOB, 00689 //MYSQL_TYPE_MEDIUM_BLOB MYSQL_TYPE_LONG_BLOB 00690 MYSQL_TYPE_MEDIUM_BLOB, MYSQL_TYPE_LONG_BLOB, 00691 //MYSQL_TYPE_BLOB MYSQL_TYPE_VAR_STRING 00692 MYSQL_TYPE_BLOB, MYSQL_TYPE_VARCHAR, 00693 //MYSQL_TYPE_STRING MYSQL_TYPE_GEOMETRY 00694 MYSQL_TYPE_STRING, MYSQL_TYPE_VARCHAR 00695 }, 00696 /* MYSQL_TYPE_TINY_BLOB -> */ 00697 { 00698 //MYSQL_TYPE_DECIMAL MYSQL_TYPE_TINY 00699 MYSQL_TYPE_TINY_BLOB, MYSQL_TYPE_TINY_BLOB, 00700 //MYSQL_TYPE_SHORT MYSQL_TYPE_LONG 00701 MYSQL_TYPE_TINY_BLOB, MYSQL_TYPE_TINY_BLOB, 00702 //MYSQL_TYPE_FLOAT MYSQL_TYPE_DOUBLE 00703 MYSQL_TYPE_TINY_BLOB, MYSQL_TYPE_TINY_BLOB, 00704 //MYSQL_TYPE_NULL MYSQL_TYPE_TIMESTAMP 00705 MYSQL_TYPE_TINY_BLOB, MYSQL_TYPE_TINY_BLOB, 00706 //MYSQL_TYPE_LONGLONG MYSQL_TYPE_INT24 00707 MYSQL_TYPE_TINY_BLOB, MYSQL_TYPE_TINY_BLOB, 00708 //MYSQL_TYPE_DATE MYSQL_TYPE_TIME 00709 MYSQL_TYPE_TINY_BLOB, MYSQL_TYPE_TINY_BLOB, 00710 //MYSQL_TYPE_DATETIME MYSQL_TYPE_YEAR 00711 MYSQL_TYPE_TINY_BLOB, MYSQL_TYPE_TINY_BLOB, 00712 //MYSQL_TYPE_NEWDATE MYSQL_TYPE_VARCHAR 00713 MYSQL_TYPE_TINY_BLOB, MYSQL_TYPE_TINY_BLOB, 00714 //MYSQL_TYPE_BIT <16>-<245> 00715 MYSQL_TYPE_TINY_BLOB, 00716 //MYSQL_TYPE_NEWDECIMAL MYSQL_TYPE_ENUM 00717 MYSQL_TYPE_TINY_BLOB, MYSQL_TYPE_TINY_BLOB, 00718 //MYSQL_TYPE_SET MYSQL_TYPE_TINY_BLOB 00719 MYSQL_TYPE_TINY_BLOB, MYSQL_TYPE_TINY_BLOB, 00720 //MYSQL_TYPE_MEDIUM_BLOB MYSQL_TYPE_LONG_BLOB 00721 MYSQL_TYPE_MEDIUM_BLOB, MYSQL_TYPE_LONG_BLOB, 00722 //MYSQL_TYPE_BLOB MYSQL_TYPE_VAR_STRING 00723 MYSQL_TYPE_BLOB, MYSQL_TYPE_TINY_BLOB, 00724 //MYSQL_TYPE_STRING MYSQL_TYPE_GEOMETRY 00725 MYSQL_TYPE_TINY_BLOB, MYSQL_TYPE_TINY_BLOB 00726 }, 00727 /* MYSQL_TYPE_MEDIUM_BLOB -> */ 00728 { 00729 //MYSQL_TYPE_DECIMAL MYSQL_TYPE_TINY 00730 MYSQL_TYPE_MEDIUM_BLOB, MYSQL_TYPE_MEDIUM_BLOB, 00731 //MYSQL_TYPE_SHORT MYSQL_TYPE_LONG 00732 MYSQL_TYPE_MEDIUM_BLOB, MYSQL_TYPE_MEDIUM_BLOB, 00733 //MYSQL_TYPE_FLOAT MYSQL_TYPE_DOUBLE 00734 MYSQL_TYPE_MEDIUM_BLOB, MYSQL_TYPE_MEDIUM_BLOB, 00735 //MYSQL_TYPE_NULL MYSQL_TYPE_TIMESTAMP 00736 MYSQL_TYPE_MEDIUM_BLOB, MYSQL_TYPE_MEDIUM_BLOB, 00737 //MYSQL_TYPE_LONGLONG MYSQL_TYPE_INT24 00738 MYSQL_TYPE_MEDIUM_BLOB, MYSQL_TYPE_MEDIUM_BLOB, 00739 //MYSQL_TYPE_DATE MYSQL_TYPE_TIME 00740 MYSQL_TYPE_MEDIUM_BLOB, MYSQL_TYPE_MEDIUM_BLOB, 00741 //MYSQL_TYPE_DATETIME MYSQL_TYPE_YEAR 00742 MYSQL_TYPE_MEDIUM_BLOB, MYSQL_TYPE_MEDIUM_BLOB, 00743 //MYSQL_TYPE_NEWDATE MYSQL_TYPE_VARCHAR 00744 MYSQL_TYPE_MEDIUM_BLOB, MYSQL_TYPE_MEDIUM_BLOB, 00745 //MYSQL_TYPE_BIT <16>-<245> 00746 MYSQL_TYPE_MEDIUM_BLOB, 00747 //MYSQL_TYPE_NEWDECIMAL MYSQL_TYPE_ENUM 00748 MYSQL_TYPE_MEDIUM_BLOB, MYSQL_TYPE_MEDIUM_BLOB, 00749 //MYSQL_TYPE_SET MYSQL_TYPE_TINY_BLOB 00750 MYSQL_TYPE_MEDIUM_BLOB, MYSQL_TYPE_MEDIUM_BLOB, 00751 //MYSQL_TYPE_MEDIUM_BLOB MYSQL_TYPE_LONG_BLOB 00752 MYSQL_TYPE_MEDIUM_BLOB, MYSQL_TYPE_LONG_BLOB, 00753 //MYSQL_TYPE_BLOB MYSQL_TYPE_VAR_STRING 00754 MYSQL_TYPE_MEDIUM_BLOB, MYSQL_TYPE_MEDIUM_BLOB, 00755 //MYSQL_TYPE_STRING MYSQL_TYPE_GEOMETRY 00756 MYSQL_TYPE_MEDIUM_BLOB, MYSQL_TYPE_MEDIUM_BLOB 00757 }, 00758 /* MYSQL_TYPE_LONG_BLOB -> */ 00759 { 00760 //MYSQL_TYPE_DECIMAL MYSQL_TYPE_TINY 00761 MYSQL_TYPE_LONG_BLOB, MYSQL_TYPE_LONG_BLOB, 00762 //MYSQL_TYPE_SHORT MYSQL_TYPE_LONG 00763 MYSQL_TYPE_LONG_BLOB, MYSQL_TYPE_LONG_BLOB, 00764 //MYSQL_TYPE_FLOAT MYSQL_TYPE_DOUBLE 00765 MYSQL_TYPE_LONG_BLOB, MYSQL_TYPE_LONG_BLOB, 00766 //MYSQL_TYPE_NULL MYSQL_TYPE_TIMESTAMP 00767 MYSQL_TYPE_LONG_BLOB, MYSQL_TYPE_LONG_BLOB, 00768 //MYSQL_TYPE_LONGLONG MYSQL_TYPE_INT24 00769 MYSQL_TYPE_LONG_BLOB, MYSQL_TYPE_LONG_BLOB, 00770 //MYSQL_TYPE_DATE MYSQL_TYPE_TIME 00771 MYSQL_TYPE_LONG_BLOB, MYSQL_TYPE_LONG_BLOB, 00772 //MYSQL_TYPE_DATETIME MYSQL_TYPE_YEAR 00773 MYSQL_TYPE_LONG_BLOB, MYSQL_TYPE_LONG_BLOB, 00774 //MYSQL_TYPE_NEWDATE MYSQL_TYPE_VARCHAR 00775 MYSQL_TYPE_LONG_BLOB, MYSQL_TYPE_LONG_BLOB, 00776 //MYSQL_TYPE_BIT <16>-<245> 00777 MYSQL_TYPE_LONG_BLOB, 00778 //MYSQL_TYPE_NEWDECIMAL MYSQL_TYPE_ENUM 00779 MYSQL_TYPE_LONG_BLOB, MYSQL_TYPE_LONG_BLOB, 00780 //MYSQL_TYPE_SET MYSQL_TYPE_TINY_BLOB 00781 MYSQL_TYPE_LONG_BLOB, MYSQL_TYPE_LONG_BLOB, 00782 //MYSQL_TYPE_MEDIUM_BLOB MYSQL_TYPE_LONG_BLOB 00783 MYSQL_TYPE_LONG_BLOB, MYSQL_TYPE_LONG_BLOB, 00784 //MYSQL_TYPE_BLOB MYSQL_TYPE_VAR_STRING 00785 MYSQL_TYPE_LONG_BLOB, MYSQL_TYPE_LONG_BLOB, 00786 //MYSQL_TYPE_STRING MYSQL_TYPE_GEOMETRY 00787 MYSQL_TYPE_LONG_BLOB, MYSQL_TYPE_LONG_BLOB 00788 }, 00789 /* MYSQL_TYPE_BLOB -> */ 00790 { 00791 //MYSQL_TYPE_DECIMAL MYSQL_TYPE_TINY 00792 MYSQL_TYPE_BLOB, MYSQL_TYPE_BLOB, 00793 //MYSQL_TYPE_SHORT MYSQL_TYPE_LONG 00794 MYSQL_TYPE_BLOB, MYSQL_TYPE_BLOB, 00795 //MYSQL_TYPE_FLOAT MYSQL_TYPE_DOUBLE 00796 MYSQL_TYPE_BLOB, MYSQL_TYPE_BLOB, 00797 //MYSQL_TYPE_NULL MYSQL_TYPE_TIMESTAMP 00798 MYSQL_TYPE_BLOB, MYSQL_TYPE_BLOB, 00799 //MYSQL_TYPE_LONGLONG MYSQL_TYPE_INT24 00800 MYSQL_TYPE_BLOB, MYSQL_TYPE_BLOB, 00801 //MYSQL_TYPE_DATE MYSQL_TYPE_TIME 00802 MYSQL_TYPE_BLOB, MYSQL_TYPE_BLOB, 00803 //MYSQL_TYPE_DATETIME MYSQL_TYPE_YEAR 00804 MYSQL_TYPE_BLOB, MYSQL_TYPE_BLOB, 00805 //MYSQL_TYPE_NEWDATE MYSQL_TYPE_VARCHAR 00806 MYSQL_TYPE_BLOB, MYSQL_TYPE_BLOB, 00807 //MYSQL_TYPE_BIT <16>-<245> 00808 MYSQL_TYPE_BLOB, 00809 //MYSQL_TYPE_NEWDECIMAL MYSQL_TYPE_ENUM 00810 MYSQL_TYPE_BLOB, MYSQL_TYPE_BLOB, 00811 //MYSQL_TYPE_SET MYSQL_TYPE_TINY_BLOB 00812 MYSQL_TYPE_BLOB, MYSQL_TYPE_BLOB, 00813 //MYSQL_TYPE_MEDIUM_BLOB MYSQL_TYPE_LONG_BLOB 00814 MYSQL_TYPE_MEDIUM_BLOB, MYSQL_TYPE_LONG_BLOB, 00815 //MYSQL_TYPE_BLOB MYSQL_TYPE_VAR_STRING 00816 MYSQL_TYPE_BLOB, MYSQL_TYPE_BLOB, 00817 //MYSQL_TYPE_STRING MYSQL_TYPE_GEOMETRY 00818 MYSQL_TYPE_BLOB, MYSQL_TYPE_BLOB 00819 }, 00820 /* MYSQL_TYPE_VAR_STRING -> */ 00821 { 00822 //MYSQL_TYPE_DECIMAL MYSQL_TYPE_TINY 00823 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, 00824 //MYSQL_TYPE_SHORT MYSQL_TYPE_LONG 00825 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, 00826 //MYSQL_TYPE_FLOAT MYSQL_TYPE_DOUBLE 00827 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, 00828 //MYSQL_TYPE_NULL MYSQL_TYPE_TIMESTAMP 00829 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, 00830 //MYSQL_TYPE_LONGLONG MYSQL_TYPE_INT24 00831 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, 00832 //MYSQL_TYPE_DATE MYSQL_TYPE_TIME 00833 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, 00834 //MYSQL_TYPE_DATETIME MYSQL_TYPE_YEAR 00835 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, 00836 //MYSQL_TYPE_NEWDATE MYSQL_TYPE_VARCHAR 00837 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, 00838 //MYSQL_TYPE_BIT <16>-<245> 00839 MYSQL_TYPE_VARCHAR, 00840 //MYSQL_TYPE_NEWDECIMAL MYSQL_TYPE_ENUM 00841 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, 00842 //MYSQL_TYPE_SET MYSQL_TYPE_TINY_BLOB 00843 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_TINY_BLOB, 00844 //MYSQL_TYPE_MEDIUM_BLOB MYSQL_TYPE_LONG_BLOB 00845 MYSQL_TYPE_MEDIUM_BLOB, MYSQL_TYPE_LONG_BLOB, 00846 //MYSQL_TYPE_BLOB MYSQL_TYPE_VAR_STRING 00847 MYSQL_TYPE_BLOB, MYSQL_TYPE_VARCHAR, 00848 //MYSQL_TYPE_STRING MYSQL_TYPE_GEOMETRY 00849 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR 00850 }, 00851 /* MYSQL_TYPE_STRING -> */ 00852 { 00853 //MYSQL_TYPE_DECIMAL MYSQL_TYPE_TINY 00854 MYSQL_TYPE_STRING, MYSQL_TYPE_STRING, 00855 //MYSQL_TYPE_SHORT MYSQL_TYPE_LONG 00856 MYSQL_TYPE_STRING, MYSQL_TYPE_STRING, 00857 //MYSQL_TYPE_FLOAT MYSQL_TYPE_DOUBLE 00858 MYSQL_TYPE_STRING, MYSQL_TYPE_STRING, 00859 //MYSQL_TYPE_NULL MYSQL_TYPE_TIMESTAMP 00860 MYSQL_TYPE_STRING, MYSQL_TYPE_STRING, 00861 //MYSQL_TYPE_LONGLONG MYSQL_TYPE_INT24 00862 MYSQL_TYPE_STRING, MYSQL_TYPE_STRING, 00863 //MYSQL_TYPE_DATE MYSQL_TYPE_TIME 00864 MYSQL_TYPE_STRING, MYSQL_TYPE_STRING, 00865 //MYSQL_TYPE_DATETIME MYSQL_TYPE_YEAR 00866 MYSQL_TYPE_STRING, MYSQL_TYPE_STRING, 00867 //MYSQL_TYPE_NEWDATE MYSQL_TYPE_VARCHAR 00868 MYSQL_TYPE_STRING, MYSQL_TYPE_VARCHAR, 00869 //MYSQL_TYPE_BIT <16>-<245> 00870 MYSQL_TYPE_STRING, 00871 //MYSQL_TYPE_NEWDECIMAL MYSQL_TYPE_ENUM 00872 MYSQL_TYPE_STRING, MYSQL_TYPE_STRING, 00873 //MYSQL_TYPE_SET MYSQL_TYPE_TINY_BLOB 00874 MYSQL_TYPE_STRING, MYSQL_TYPE_TINY_BLOB, 00875 //MYSQL_TYPE_MEDIUM_BLOB MYSQL_TYPE_LONG_BLOB 00876 MYSQL_TYPE_MEDIUM_BLOB, MYSQL_TYPE_LONG_BLOB, 00877 //MYSQL_TYPE_BLOB MYSQL_TYPE_VAR_STRING 00878 MYSQL_TYPE_BLOB, MYSQL_TYPE_VARCHAR, 00879 //MYSQL_TYPE_STRING MYSQL_TYPE_GEOMETRY 00880 MYSQL_TYPE_STRING, MYSQL_TYPE_STRING 00881 }, 00882 /* MYSQL_TYPE_GEOMETRY -> */ 00883 { 00884 //MYSQL_TYPE_DECIMAL MYSQL_TYPE_TINY 00885 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, 00886 //MYSQL_TYPE_SHORT MYSQL_TYPE_LONG 00887 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, 00888 //MYSQL_TYPE_FLOAT MYSQL_TYPE_DOUBLE 00889 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, 00890 //MYSQL_TYPE_NULL MYSQL_TYPE_TIMESTAMP 00891 MYSQL_TYPE_GEOMETRY, MYSQL_TYPE_VARCHAR, 00892 //MYSQL_TYPE_LONGLONG MYSQL_TYPE_INT24 00893 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, 00894 //MYSQL_TYPE_DATE MYSQL_TYPE_TIME 00895 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, 00896 //MYSQL_TYPE_DATETIME MYSQL_TYPE_YEAR 00897 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, 00898 //MYSQL_TYPE_NEWDATE MYSQL_TYPE_VARCHAR 00899 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, 00900 //MYSQL_TYPE_BIT <16>-<245> 00901 MYSQL_TYPE_VARCHAR, 00902 //MYSQL_TYPE_NEWDECIMAL MYSQL_TYPE_ENUM 00903 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, 00904 //MYSQL_TYPE_SET MYSQL_TYPE_TINY_BLOB 00905 MYSQL_TYPE_VARCHAR, MYSQL_TYPE_TINY_BLOB, 00906 //MYSQL_TYPE_MEDIUM_BLOB MYSQL_TYPE_LONG_BLOB 00907 MYSQL_TYPE_MEDIUM_BLOB, MYSQL_TYPE_LONG_BLOB, 00908 //MYSQL_TYPE_BLOB MYSQL_TYPE_VAR_STRING 00909 MYSQL_TYPE_BLOB, MYSQL_TYPE_VARCHAR, 00910 //MYSQL_TYPE_STRING MYSQL_TYPE_GEOMETRY 00911 MYSQL_TYPE_STRING, MYSQL_TYPE_GEOMETRY 00912 } 00913 }; 00914 00915 /* 00916 Return type of which can carry value of both given types in UNION result 00917 00918 SYNOPSIS 00919 Field::field_type_merge() 00920 a, b types for merging 00921 00922 RETURN 00923 type of field 00924 */ 00925 00926 enum_field_types Field::field_type_merge(enum_field_types a, 00927 enum_field_types b) 00928 { 00929 DBUG_ASSERT(a < FIELDTYPE_TEAR_FROM || a > FIELDTYPE_TEAR_TO); 00930 DBUG_ASSERT(b < FIELDTYPE_TEAR_FROM || b > FIELDTYPE_TEAR_TO); 00931 return field_types_merge_rules[field_type2index(a)] 00932 [field_type2index(b)]; 00933 } 00934 00935 00936 static Item_result field_types_result_type [FIELDTYPE_NUM]= 00937 { 00938 //MYSQL_TYPE_DECIMAL MYSQL_TYPE_TINY 00939 DECIMAL_RESULT, INT_RESULT, 00940 //MYSQL_TYPE_SHORT MYSQL_TYPE_LONG 00941 INT_RESULT, INT_RESULT, 00942 //MYSQL_TYPE_FLOAT MYSQL_TYPE_DOUBLE 00943 REAL_RESULT, REAL_RESULT, 00944 //MYSQL_TYPE_NULL MYSQL_TYPE_TIMESTAMP 00945 STRING_RESULT, STRING_RESULT, 00946 //MYSQL_TYPE_LONGLONG MYSQL_TYPE_INT24 00947 INT_RESULT, INT_RESULT, 00948 //MYSQL_TYPE_DATE MYSQL_TYPE_TIME 00949 STRING_RESULT, STRING_RESULT, 00950 //MYSQL_TYPE_DATETIME MYSQL_TYPE_YEAR 00951 STRING_RESULT, INT_RESULT, 00952 //MYSQL_TYPE_NEWDATE MYSQL_TYPE_VARCHAR 00953 STRING_RESULT, STRING_RESULT, 00954 //MYSQL_TYPE_BIT <16>-<245> 00955 STRING_RESULT, 00956 //MYSQL_TYPE_NEWDECIMAL MYSQL_TYPE_ENUM 00957 DECIMAL_RESULT, STRING_RESULT, 00958 //MYSQL_TYPE_SET MYSQL_TYPE_TINY_BLOB 00959 STRING_RESULT, STRING_RESULT, 00960 //MYSQL_TYPE_MEDIUM_BLOB MYSQL_TYPE_LONG_BLOB 00961 STRING_RESULT, STRING_RESULT, 00962 //MYSQL_TYPE_BLOB MYSQL_TYPE_VAR_STRING 00963 STRING_RESULT, STRING_RESULT, 00964 //MYSQL_TYPE_STRING MYSQL_TYPE_GEOMETRY 00965 STRING_RESULT, STRING_RESULT 00966 }; 00967 00968 00969 /* 00970 Detect Item_result by given field type of UNION merge result 00971 00972 SYNOPSIS 00973 Field::result_merge_type() 00974 field_type given field type 00975 00976 RETURN 00977 Item_result (type of internal MySQL expression result) 00978 */ 00979 00980 Item_result Field::result_merge_type(enum_field_types field_type) 00981 { 00982 DBUG_ASSERT(field_type < FIELDTYPE_TEAR_FROM || field_type 00983 > FIELDTYPE_TEAR_TO); 00984 return field_types_result_type[field_type2index(field_type)]; 00985 } 00986 00987 /***************************************************************************** 00988 Static help functions 00989 *****************************************************************************/ 00990 00991 00992 /* 00993 Check whether a field type can be partially indexed by a key 00994 00995 This is a static method, rather than a virtual function, because we need 00996 to check the type of a non-Field in mysql_alter_table(). 00997 00998 SYNOPSIS 00999 type_can_have_key_part() 01000 type field type 01001 01002 RETURN 01003 TRUE Type can have a prefixed key 01004 FALSE Type can not have a prefixed key 01005 */ 01006 01007 bool Field::type_can_have_key_part(enum enum_field_types type) 01008 { 01009 switch (type) { 01010 case MYSQL_TYPE_VARCHAR: 01011 case MYSQL_TYPE_TINY_BLOB: 01012 case MYSQL_TYPE_MEDIUM_BLOB: 01013 case MYSQL_TYPE_LONG_BLOB: 01014 case MYSQL_TYPE_BLOB: 01015 case MYSQL_TYPE_VAR_STRING: 01016 case MYSQL_TYPE_STRING: 01017 return TRUE; 01018 default: 01019 return FALSE; 01020 } 01021 } 01022 01023 01024 /* 01025 Numeric fields base class constructor 01026 */ 01027 Field_num::Field_num(char *ptr_arg,uint32 len_arg, uchar *null_ptr_arg, 01028 uchar null_bit_arg, utype unireg_check_arg, 01029 const char *field_name_arg, 01030 uint8 dec_arg, bool zero_arg, bool unsigned_arg) 01031 :Field(ptr_arg, len_arg, null_ptr_arg, null_bit_arg, 01032 unireg_check_arg, field_name_arg), 01033 dec(dec_arg),zerofill(zero_arg),unsigned_flag(unsigned_arg) 01034 { 01035 if (zerofill) 01036 flags|=ZEROFILL_FLAG; 01037 if (unsigned_flag) 01038 flags|=UNSIGNED_FLAG; 01039 } 01040 01041 01042 void Field_num::prepend_zeros(String *value) 01043 { 01044 int diff; 01045 if ((diff= (int) (field_length - value->length())) > 0) 01046 { 01047 bmove_upp((char*) value->ptr()+field_length,value->ptr()+value->length(), 01048 value->length()); 01049 bfill((char*) value->ptr(),diff,'0'); 01050 value->length(field_length); 01051 (void) value->c_ptr_quick(); // Avoid warnings in purify 01052 } 01053 } 01054 01055 /* 01056 Test if given number is a int (or a fixed format float with .000) 01057 01058 SYNOPSIS 01059 test_if_int() 01060 str String to test 01061 end Pointer to char after last used digit 01062 cs Character set 01063 01064 NOTES 01065 This is called after one has called my_strntol() or similar function. 01066 This is only used to give warnings in ALTER TABLE or LOAD DATA... 01067 01068 TODO 01069 Make this multi-byte-character safe 01070 01071 RETURN 01072 0 OK 01073 1 error. A warning is pushed if field_name != 0 01074 */ 01075 01076 bool Field::check_int(const char *str, int length, const char *int_end, 01077 CHARSET_INFO *cs) 01078 { 01079 const char *end; 01080 if (str == int_end) 01081 { 01082 char buff[128]; 01083 String tmp(buff,(uint32) sizeof(buff), system_charset_info); 01084 tmp.copy(str, length, system_charset_info); 01085 push_warning_printf(table->in_use, MYSQL_ERROR::WARN_LEVEL_WARN, 01086 ER_TRUNCATED_WRONG_VALUE_FOR_FIELD, 01087 ER(ER_TRUNCATED_WRONG_VALUE_FOR_FIELD), 01088 "integer", tmp.c_ptr(), field_name, 01089 (ulong) table->in_use->row_count); 01090 return 1; // Empty string 01091 } 01092 end= str+length; 01093 if ((str= int_end) == end) 01094 return 0; // OK; All digits was used 01095 01096 /* Allow end .0000 */ 01097 if (*str == '.') 01098 { 01099 for (str++ ; str != end && *str == '0'; str++) 01100 ; 01101 } 01102 /* Allow end space */ 01103 for ( ; str != end ; str++) 01104 { 01105 if (!my_isspace(cs,*str)) 01106 { 01107 set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, 1); 01108 return 1; 01109 } 01110 } 01111 return 0; 01112 } 01113 01114 01115 /* 01116 Process decimal library return codes and issue warnings for overflow and 01117 truncation. 01118 01119 SYNOPSIS 01120 Field::warn_if_overflow() 01121 op_result decimal library return code (E_DEC_* see include/decimal.h) 01122 01123 RETURN 01124 1 there was overflow 01125 0 no error or some other errors except overflow 01126 */ 01127 01128 int Field::warn_if_overflow(int op_result) 01129 { 01130 if (op_result == E_DEC_OVERFLOW) 01131 { 01132 set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1); 01133 return 1; 01134 } 01135 if (op_result == E_DEC_TRUNCATED) 01136 { 01137 set_warning(MYSQL_ERROR::WARN_LEVEL_NOTE, WARN_DATA_TRUNCATED, 1); 01138 /* We return 0 here as this is not a critical issue */ 01139 } 01140 return 0; 01141 } 01142 01143 01144 #ifdef NOT_USED 01145 static bool test_if_real(const char *str,int length, CHARSET_INFO *cs) 01146 { 01147 cs= system_charset_info; // QQ move test_if_real into CHARSET_INFO struct 01148 01149 while (length && my_isspace(cs,*str)) 01150 { // Allow start space 01151 length--; str++; 01152 } 01153 if (!length) 01154 return 0; 01155 if (*str == '+' || *str == '-') 01156 { 01157 length--; str++; 01158 if (!length || !(my_isdigit(cs,*str) || *str == '.')) 01159 return 0; 01160 } 01161 while (length && my_isdigit(cs,*str)) 01162 { 01163 length--; str++; 01164 } 01165 if (!length) 01166 return 1; 01167 if (*str == '.') 01168 { 01169 length--; str++; 01170 while (length && my_isdigit(cs,*str)) 01171 { 01172 length--; str++; 01173 } 01174 } 01175 if (!length) 01176 return 1; 01177 if (*str == 'E' || *str == 'e') 01178 { 01179 if (length < 3 || (str[1] != '+' && str[1] != '-') || 01180 !my_isdigit(cs,str[2])) 01181 return 0; 01182 length-=3; 01183 str+=3; 01184 while (length && my_isdigit(cs,*str)) 01185 { 01186 length--; str++; 01187 } 01188 } 01189 for (; length ; length--, str++) 01190 { // Allow end space 01191 if (!my_isspace(cs,*str)) 01192 return 0; 01193 } 01194 return 1; 01195 } 01196 #endif 01197 01198 01199 /* 01200 Interpret field value as an integer but return the result as a string. 01201 01202 This is used for printing bit_fields as numbers while debugging 01203 */ 01204 01205 String *Field::val_int_as_str(String *val_buffer, my_bool unsigned_val) 01206 { 01207 ASSERT_COLUMN_MARKED_FOR_READ; 01208 CHARSET_INFO *cs= &my_charset_bin; 01209 uint length= 21; 01210 longlong value= val_int(); 01211 01212 if (val_buffer->alloc(length)) 01213 return 0; 01214 length= (uint) (*cs->cset->longlong10_to_str)(cs, (char*) val_buffer->ptr(), 01215 length, 01216 unsigned_val ? 10 : -10, 01217 value); 01218 val_buffer->length(length); 01219 return val_buffer; 01220 } 01221 01222 01223 Field::Field(char *ptr_arg,uint32 length_arg,uchar *null_ptr_arg, 01224 uchar null_bit_arg, 01225 utype unireg_check_arg, const char *field_name_arg) 01226 :ptr(ptr_arg), null_ptr(null_ptr_arg), 01227 table(0), orig_table(0), table_name(0), 01228 field_name(field_name_arg), 01229 key_start(0), part_of_key(0), part_of_key_not_clustered(0), 01230 part_of_sortkey(0), unireg_check(unireg_check_arg), 01231 field_length(length_arg), null_bit(null_bit_arg) 01232 { 01233 flags=null_ptr ? 0: NOT_NULL_FLAG; 01234 comment.str= (char*) ""; 01235 comment.length=0; 01236 field_index= 0; 01237 } 01238 01239 01240 uint Field::offset() 01241 { 01242 return (uint) (ptr - (char*) table->record[0]); 01243 } 01244 01245 01246 void Field::hash(ulong *nr, ulong *nr2) 01247 { 01248 if (is_null()) 01249 { 01250 *nr^= (*nr << 1) | 1; 01251 } 01252 else 01253 { 01254 uint len= pack_length(); 01255 CHARSET_INFO *cs= charset(); 01256 cs->coll->hash_sort(cs, (uchar*) ptr, len, nr, nr2); 01257 } 01258 } 01259 01260 01261 void Field::copy_from_tmp(int row_offset) 01262 { 01263 memcpy(ptr,ptr+row_offset,pack_length()); 01264 if (null_ptr) 01265 { 01266 *null_ptr= (uchar) ((null_ptr[0] & (uchar) ~(uint) null_bit) | 01267 null_ptr[row_offset] & (uchar) null_bit); 01268 } 01269 } 01270 01271 01272 bool Field::send_binary(Protocol *protocol) 01273 { 01274 char buff[MAX_FIELD_WIDTH]; 01275 String tmp(buff,sizeof(buff),charset()); 01276 val_str(&tmp); 01277 return protocol->store(tmp.ptr(), tmp.length(), tmp.charset()); 01278 } 01279 01280 01281 my_decimal *Field::val_decimal(my_decimal *decimal) 01282 { 01283 /* This never have to be called */ 01284 DBUG_ASSERT(0); 01285 return 0; 01286 } 01287 01288 01289 void Field_num::add_zerofill_and_unsigned(String &res) const 01290 { 01291 if (unsigned_flag) 01292 res.append(STRING_WITH_LEN(" unsigned")); 01293 if (zerofill) 01294 res.append(STRING_WITH_LEN(" zerofill")); 01295 } 01296 01297 01298 void Field::make_field(Send_field *field) 01299 { 01300 if (orig_table->s->db.str && *orig_table->s->db.str) 01301 { 01302 field->db_name= orig_table->s->db.str; 01303 field->org_table_name= orig_table->s->table_name.str; 01304 } 01305 else 01306 field->org_table_name= field->db_name= ""; 01307 field->table_name= orig_table->alias; 01308 field->col_name= field->org_col_name= field_name; 01309 field->charsetnr= charset()->number; 01310 field->length=field_length; 01311 field->type=type(); 01312 field->flags=table->maybe_null ? (flags & ~NOT_NULL_FLAG) : flags; 01313 field->decimals= 0; 01314 } 01315 01316 01317 /* 01318 Conversion from decimal to longlong with checking overflow and 01319 setting correct value (min/max) in case of overflow 01320 01321 SYNOPSIS 01322 Field::convert_decimal2longlong() 01323 val value which have to be converted 01324 unsigned_flag type of integer in which we convert val 01325 err variable to pass error code 01326 01327 RETURN 01328 value converted from val 01329 */ 01330 longlong Field::convert_decimal2longlong(const my_decimal *val, 01331 bool unsigned_flag, int *err) 01332 { 01333 longlong i; 01334 if (unsigned_flag) 01335 { 01336 if (val->sign()) 01337 { 01338 set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1); 01339 i= 0; 01340 *err= 1; 01341 } 01342 else if (warn_if_overflow(my_decimal2int(E_DEC_ERROR & 01343 ~E_DEC_OVERFLOW & ~E_DEC_TRUNCATED, 01344 val, TRUE, &i))) 01345 { 01346 i= ~(longlong) 0; 01347 *err= 1; 01348 } 01349 } 01350 else if (warn_if_overflow(my_decimal2int(E_DEC_ERROR & 01351 ~E_DEC_OVERFLOW & ~E_DEC_TRUNCATED, 01352 val, FALSE, &i))) 01353 { 01354 i= (val->sign() ? LONGLONG_MIN : LONGLONG_MAX); 01355 *err= 1; 01356 } 01357 return i; 01358 } 01359 01360 01361 /* 01362 Storing decimal in integer fields. 01363 01364 SYNOPSIS 01365 Field_num::store_decimal() 01366 val value for storing 01367 01368 NOTE 01369 This method is used by all integer fields, real/decimal redefine it 01370 01371 RETURN 01372 0 OK 01373 != 0 error 01374 */ 01375 01376 int Field_num::store_decimal(const my_decimal *val) 01377 { 01378 ASSERT_COLUMN_MARKED_FOR_WRITE; 01379 int err= 0; 01380 longlong i= convert_decimal2longlong(val, unsigned_flag, &err); 01381 return test(err | store(i, unsigned_flag)); 01382 } 01383 01384 01385 /* 01386 Return decimal value of integer field 01387 01388 SYNOPSIS 01389 Field_num::val_decimal() 01390 decimal_value buffer for storing decimal value 01391 01392 NOTE 01393 This method is used by all integer fields, real/decimal redefine it 01394 All longlong values fit in our decimal buffer which cal store 8*9=72 01395 digits of integer number 01396 01397 RETURN 01398 pointer to decimal buffer with value of field 01399 */ 01400 01401 my_decimal* Field_num::val_decimal(my_decimal *decimal_value) 01402 { 01403 ASSERT_COLUMN_MARKED_FOR_READ; 01404 DBUG_ASSERT(result_type() == INT_RESULT); 01405 longlong nr= val_int(); 01406 int2my_decimal(E_DEC_FATAL_ERROR, nr, unsigned_flag, decimal_value); 01407 return decimal_value; 01408 } 01409 01410 01411 Field_str::Field_str(char *ptr_arg,uint32 len_arg, uchar *null_ptr_arg, 01412 uchar null_bit_arg, utype unireg_check_arg, 01413 const char *field_name_arg, CHARSET_INFO *charset) 01414 :Field(ptr_arg, len_arg, null_ptr_arg, null_bit_arg, 01415 unireg_check_arg, field_name_arg) 01416 { 01417 field_charset=charset; 01418 if (charset->state & MY_CS_BINSORT) 01419 flags|=BINARY_FLAG; 01420 } 01421 01422 01423 void Field_num::make_field(Send_field *field) 01424 { 01425 Field::make_field(field); 01426 field->decimals= dec; 01427 } 01428 01429 /* 01430 Decimal representation of Field_str 01431 01432 SYNOPSIS 01433 Field_str::store_decimal() 01434 d value for storing 01435 01436 NOTE 01437 Field_str is the base class for fields like Field_enum, Field_date and some 01438 similar. Some dates use fraction and also string value should be 01439 converted to floating point value according our rules, so we use double 01440 to store value of decimal in string 01441 01442 RETURN 01443 0 OK 01444 != 0 error 01445 */ 01446 01447 int Field_str::store_decimal(const my_decimal *d) 01448 { 01449 ASSERT_COLUMN_MARKED_FOR_WRITE; 01450 double val; 01451 /* TODO: use decimal2string? */ 01452 int err= warn_if_overflow(my_decimal2double(E_DEC_FATAL_ERROR & 01453 ~E_DEC_OVERFLOW, d, &val)); 01454 return err | store(val); 01455 } 01456 01457 01458 my_decimal *Field_str::val_decimal(my_decimal *decimal_value) 01459 { 01460 ASSERT_COLUMN_MARKED_FOR_READ; 01461 longlong nr= val_int(); 01462 int2my_decimal(E_DEC_FATAL_ERROR, nr, 0, decimal_value); 01463 return decimal_value; 01464 } 01465 01466 01467 uint Field::fill_cache_field(CACHE_FIELD *copy) 01468 { 01469 uint store_length; 01470 copy->str=ptr; 01471 copy->length=pack_length(); 01472 copy->blob_field=0; 01473 if (flags & BLOB_FLAG) 01474 { 01475 copy->blob_field=(Field_blob*) this; 01476 copy->strip=0; 01477 copy->length-= table->s->blob_ptr_size; 01478 return copy->length; 01479 } 01480 else if (!zero_pack() && 01481 (type() == MYSQL_TYPE_STRING && copy->length >= 4 && 01482 copy->length < 256)) 01483 { 01484 copy->strip=1; /* Remove end space */ 01485 store_length= 2; 01486 } 01487 else 01488 { 01489 copy->strip=0; 01490 store_length= 0; 01491 } 01492 return copy->length+ store_length; 01493 } 01494 01495 01496 bool Field::get_date(TIME *ltime,uint fuzzydate) 01497 { 01498 char buff[40]; 01499 String tmp(buff,sizeof(buff),&my_charset_bin),*res; 01500 if (!(res=val_str(&tmp)) || 01501 str_to_datetime_with_warn(res->ptr(), res->length(), 01502 ltime, fuzzydate) <= MYSQL_TIMESTAMP_ERROR) 01503 return 1; 01504 return 0; 01505 } 01506 01507 bool Field::get_time(TIME *ltime) 01508 { 01509 char buff[40]; 01510 String tmp(buff,sizeof(buff),&my_charset_bin),*res; 01511 if (!(res=val_str(&tmp)) || 01512 str_to_time_with_warn(res->ptr(), res->length(), ltime)) 01513 return 1; 01514 return 0; 01515 } 01516 01517 /* 01518 This is called when storing a date in a string 01519 01520 NOTES 01521 Needs to be changed if/when we want to support different time formats 01522 */ 01523 01524 int Field::store_time(TIME *ltime, timestamp_type type) 01525 { 01526 ASSERT_COLUMN_MARKED_FOR_WRITE; 01527 char buff[MAX_DATE_STRING_REP_LENGTH]; 01528 uint length= (uint) my_TIME_to_str(ltime, buff); 01529 return store(buff, length, &my_charset_bin); 01530 } 01531 01532 01533 bool Field::optimize_range(uint idx, uint part) 01534 { 01535 return test(table->file->index_flags(idx, part, 1) & HA_READ_RANGE); 01536 } 01537 01538 01539 Field *Field::new_field(MEM_ROOT *root, struct st_table *new_table, 01540 bool keep_type __attribute__((unused))) 01541 { 01542 Field *tmp; 01543 if (!(tmp= (Field*) memdup_root(root,(char*) this,size_of()))) 01544 return 0; 01545 01546 if (tmp->table->maybe_null) 01547 tmp->flags&= ~NOT_NULL_FLAG; 01548 tmp->table= new_table; 01549 tmp->key_start.init(0); 01550 tmp->part_of_key.init(0); 01551 tmp->part_of_sortkey.init(0); 01552 tmp->unireg_check= Field::NONE; 01553 tmp->flags&= (NOT_NULL_FLAG | BLOB_FLAG | UNSIGNED_FLAG | 01554 ZEROFILL_FLAG | BINARY_FLAG | ENUM_FLAG | SET_FLAG); 01555 tmp->reset_fields(); 01556 return tmp; 01557 } 01558 01559 01560 Field *Field::new_key_field(MEM_ROOT *root, struct st_table *new_table, 01561 char *new_ptr, uchar *new_null_ptr, 01562 uint new_null_bit) 01563 { 01564 Field *tmp; 01565 if ((tmp= new_field(root, new_table, table == new_table))) 01566 { 01567 tmp->ptr= new_ptr; 01568 tmp->null_ptr= new_null_ptr; 01569 tmp->null_bit= new_null_bit; 01570 } 01571 return tmp; 01572 } 01573 01574 01575 /* This is used to generate a field in TABLE from TABLE_SHARE */ 01576 01577 Field *Field::clone(MEM_ROOT *root, struct st_table *new_table) 01578 { 01579 Field *tmp; 01580 if ((tmp= (Field*) memdup_root(root,(char*) this,size_of()))) 01581 { 01582 tmp->init(new_table); 01583 tmp->move_field_offset((my_ptrdiff_t) (new_table->record[0] - 01584 new_table->s->default_values)); 01585 } 01586 return tmp; 01587 } 01588 01589 01590 /**************************************************************************** 01591 Field_null, a field that always return NULL 01592 ****************************************************************************/ 01593 01594 void Field_null::sql_type(String &res) const 01595 { 01596 res.set_ascii(STRING_WITH_LEN("null")); 01597 } 01598 01599 01600 /**************************************************************************** 01601 Functions for the Field_decimal class 01602 This is an number stored as a pre-space (or pre-zero) string 01603 ****************************************************************************/ 01604 01605 void 01606 Field_decimal::reset(void) 01607 { 01608 Field_decimal::store(STRING_WITH_LEN("0"),&my_charset_bin); 01609 } 01610 01611 void Field_decimal::overflow(bool negative) 01612 { 01613 uint len=field_length; 01614 char *to=ptr, filler= '9'; 01615 01616 set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1); 01617 if (negative) 01618 { 01619 if (!unsigned_flag) 01620 { 01621 /* Put - sign as a first digit so we'll have -999..999 or 999..999 */ 01622 *to++ = '-'; 01623 len--; 01624 } 01625 else 01626 { 01627 filler= '0'; // Fill up with 0 01628 if (!zerofill) 01629 { 01630 /* 01631 Handle unsigned integer without zerofill, in which case 01632 the number should be of format ' 0' or ' 0.000' 01633 */ 01634 uint whole_part=field_length- (dec ? dec+2 : 1); 01635 // Fill with spaces up to the first digit 01636 bfill(to, whole_part, ' '); 01637 to+= whole_part; 01638 len-= whole_part; 01639 // The main code will also handle the 0 before the decimal point 01640 } 01641 } 01642 } 01643 bfill(to, len, filler); 01644 if (dec) 01645 ptr[field_length-dec-1]='.'; 01646 return; 01647 } 01648 01649 01650 int Field_decimal::store(const char *from, uint len, CHARSET_INFO *cs) 01651 { 01652 ASSERT_COLUMN_MARKED_FOR_WRITE; 01653 char buff[STRING_BUFFER_USUAL_SIZE]; 01654 String tmp(buff,sizeof(buff), &my_charset_bin); 01655 01656 /* Convert character set if the old one is multi byte */ 01657 if (cs->mbmaxlen > 1) 01658 { 01659 uint dummy_errors; 01660 tmp.copy(from, len, cs, &my_charset_bin, &dummy_errors); 01661 from= tmp.ptr(); 01662 len= tmp.length(); 01663 } 01664 01665 const char *end= from+len; 01666 /* The pointer where the field value starts (i.e., "where to write") */ 01667 char *to=ptr; 01668 uint tmp_dec, tmp_uint; 01669 /* 01670 The sign of the number : will be 0 (means positive but sign not 01671 specified), '+' or '-' 01672 */ 01673 char sign_char=0; 01674 /* The pointers where prezeros start and stop */ 01675 const char *pre_zeros_from, *pre_zeros_end; 01676 /* The pointers where digits at the left of '.' start and stop */ 01677 const char *int_digits_from, *int_digits_end; 01678 /* The pointers where digits at the right of '.' start and stop */ 01679 const char *frac_digits_from, *frac_digits_end; 01680 /* The sign of the exponent : will be 0 (means no exponent), '+' or '-' */ 01681 char expo_sign_char=0; 01682 uint exponent=0; // value of the exponent 01683 /* 01684 Pointers used when digits move from the left of the '.' to the 01685 right of the '.' (explained below) 01686 */ 01687 const char *int_digits_tail_from; 01688 /* Number of 0 that need to be added at the left of the '.' (1E3: 3 zeros) */ 01689 uint int_digits_added_zeros; 01690 /* 01691 Pointer used when digits move from the right of the '.' to the left 01692 of the '.' 01693 */ 01694 const char *frac_digits_head_end; 01695 /* Number of 0 that need to be added at the right of the '.' (for 1E-3) */ 01696 uint frac_digits_added_zeros; 01697 char *pos,*tmp_left_pos,*tmp_right_pos; 01698 /* Pointers that are used as limits (begin and end of the field buffer) */ 01699 char *left_wall,*right_wall; 01700 char tmp_char; 01701 /* 01702 To remember if table->in_use->cuted_fields has already been incremented, 01703 to do that only once 01704 */ 01705 bool is_cuted_fields_incr=0; 01706 01707 LINT_INIT(int_digits_tail_from); 01708 LINT_INIT(int_digits_added_zeros); 01709 LINT_INIT(frac_digits_head_end); 01710 LINT_INIT(frac_digits_added_zeros); 01711 01712 /* 01713 There are three steps in this function : 01714 - parse the input string 01715 - modify the position of digits around the decimal dot '.' 01716 according to the exponent value (if specified) 01717 - write the formatted number 01718 */ 01719 01720 if ((tmp_dec=dec)) 01721 tmp_dec++; 01722 01723 /* skip pre-space */ 01724 while (from != end && my_isspace(&my_charset_bin,*from)) 01725 from++; 01726 if (from == end) 01727 { 01728 set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, 1); 01729 is_cuted_fields_incr=1; 01730 } 01731 else if (*from == '+' || *from == '-') // Found some sign ? 01732 { 01733 sign_char= *from++; 01734 /* 01735 We allow "+" for unsigned decimal unless defined different 01736 Both options allowed as one may wish not to have "+" for unsigned numbers 01737 because of data processing issues 01738 */ 01739 if (unsigned_flag) 01740 { 01741 if (sign_char=='-') 01742 { 01743 Field_decimal::overflow(1); 01744 return 1; 01745 } 01746 /* 01747 Defining this will not store "+" for unsigned decimal type even if 01748 it is passed in numeric string. This will make some tests to fail 01749 */ 01750 #ifdef DONT_ALLOW_UNSIGNED_PLUS 01751 else 01752 sign_char=0; 01753 #endif 01754 } 01755 } 01756 01757 pre_zeros_from= from; 01758 for (; from!=end && *from == '0'; from++) ; // Read prezeros 01759 pre_zeros_end=int_digits_from=from; 01760 /* Read non zero digits at the left of '.'*/ 01761 for (; from != end && my_isdigit(&my_charset_bin, *from) ; from++) ; 01762 int_digits_end=from; 01763 if (from!=end && *from == '.') // Some '.' ? 01764 from++; 01765 frac_digits_from= from; 01766 /* Read digits at the right of '.' */ 01767 for (;from!=end && my_isdigit(&my_charset_bin, *from); from++) ; 01768 frac_digits_end=from; 01769 // Some exponentiation symbol ? 01770 if (from != end && (*from == 'e' || *from == 'E')) 01771 { 01772 from++; 01773 if (from != end && (*from == '+' || *from == '-')) // Some exponent sign ? 01774 expo_sign_char= *from++; 01775 else 01776 expo_sign_char= '+'; 01777 /* 01778 Read digits of the exponent and compute its value. We must care about 01779 'exponent' overflow, because as unsigned arithmetic is "modulo", big 01780 exponents will become small (e.g. 1e4294967296 will become 1e0, and the 01781 field will finally contain 1 instead of its max possible value). 01782 */ 01783 for (;from!=end && my_isdigit(&my_charset_bin, *from); from++) 01784 { 01785 exponent=10*exponent+(*from-'0'); 01786 if (exponent>MAX_EXPONENT) 01787 break; 01788 } 01789 } 01790 01791 /* 01792 We only have to generate warnings if count_cuted_fields is set. 01793 This is to avoid extra checks of the number when they are not needed. 01794 Even if this flag is not set, it's OK to increment warnings, if 01795 it makes the code easer to read. 01796 */ 01797 01798 if (table->in_use->count_cuted_fields) 01799 { 01800 // Skip end spaces 01801 for (;from != end && my_isspace(&my_charset_bin, *from); from++) ; 01802 if (from != end) // If still something left, warn 01803 { 01804 set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, 1); 01805 is_cuted_fields_incr=1; 01806 } 01807 } 01808 01809 /* 01810 Now "move" digits around the decimal dot according to the exponent value, 01811 and add necessary zeros. 01812 Examples : 01813 - 1E+3 : needs 3 more zeros at the left of '.' (int_digits_added_zeros=3) 01814 - 1E-3 : '1' moves at the right of '.', and 2 more zeros are needed 01815 between '.' and '1' 01816 - 1234.5E-3 : '234' moves at the right of '.' 01817 These moves are implemented with pointers which point at the begin 01818 and end of each moved segment. Examples : 01819 - 1234.5E-3 : before the code below is executed, the int_digits part is 01820 from '1' to '4' and the frac_digits part from '5' to '5'. After the code 01821 below, the int_digits part is from '1' to '1', the frac_digits_head 01822 part is from '2' to '4', and the frac_digits part from '5' to '5'. 01823 - 1234.5E3 : before the code below is executed, the int_digits part is 01824 from '1' to '4' and the frac_digits part from '5' to '5'. After the code 01825 below, the int_digits part is from '1' to '4', the int_digits_tail 01826 part is from '5' to '5', the frac_digits part is empty, and 01827 int_digits_added_zeros=2 (to make 1234500). 01828 */ 01829 01830 /* 01831 Below tmp_uint cannot overflow with small enough MAX_EXPONENT setting, 01832 as int_digits_added_zeros<=exponent<4G and 01833 (int_digits_end-int_digits_from)<=max_allowed_packet<=2G and 01834 (frac_digits_from-int_digits_tail_from)<=max_allowed_packet<=2G 01835 */ 01836 01837 if (!expo_sign_char) 01838 tmp_uint=tmp_dec+(uint)(int_digits_end-int_digits_from); 01839 else if (expo_sign_char == '-') 01840 { 01841 tmp_uint=min(exponent,(uint)(int_digits_end-int_digits_from)); 01842 frac_digits_added_zeros=exponent-tmp_uint; 01843 int_digits_end -= tmp_uint; 01844 frac_digits_head_end=int_digits_end+tmp_uint; 01845 tmp_uint=tmp_dec+(uint)(int_digits_end-int_digits_from); 01846 } 01847 else // (expo_sign_char=='+') 01848 { 01849 tmp_uint=min(exponent,(uint)(frac_digits_end-frac_digits_from)); 01850 int_digits_added_zeros=exponent-tmp_uint; 01851 int_digits_tail_from=frac_digits_from; 01852 frac_digits_from=frac_digits_from+tmp_uint; 01853 /* 01854 We "eat" the heading zeros of the 01855 int_digits.int_digits_tail.int_digits_added_zeros concatenation 01856 (for example 0.003e3 must become 3 and not 0003) 01857 */ 01858 if (int_digits_from == int_digits_end) 01859 { 01860 /* 01861 There was nothing in the int_digits part, so continue 01862 eating int_digits_tail zeros 01863 */ 01864 for (; int_digits_tail_from != frac_digits_from && 01865 *int_digits_tail_from == '0'; int_digits_tail_from++) ; 01866 if (int_digits_tail_from == frac_digits_from) 01867 { 01868 // there were only zeros in int_digits_tail too 01869 int_digits_added_zeros=0; 01870 } 01871 } 01872 tmp_uint= (uint) (tmp_dec+(int_digits_end-int_digits_from)+ 01873 (uint)(frac_digits_from-int_digits_tail_from)+ 01874 int_digits_added_zeros); 01875 } 01876 01877 /* 01878 Now write the formated number 01879 01880 First the digits of the int_% parts. 01881 Do we have enough room to write these digits ? 01882 If the sign is defined and '-', we need one position for it 01883 */ 01884 01885 if (field_length < tmp_uint + (int) (sign_char == '-')) 01886 { 01887 // too big number, change to max or min number 01888 Field_decimal::overflow(sign_char == '-'); 01889 return 1; 01890 } 01891 01892 /* 01893 Tmp_left_pos is the position where the leftmost digit of 01894 the int_% parts will be written 01895 */ 01896 tmp_left_pos=pos=to+(uint)(field_length-tmp_uint); 01897 01898 // Write all digits of the int_% parts 01899 while (int_digits_from != int_digits_end) 01900 *pos++ = *int_digits_from++ ; 01901 01902 if (expo_sign_char == '+') 01903 { 01904 while (int_digits_tail_from != frac_digits_from) 01905 *pos++= *int_digits_tail_from++; 01906 while (int_digits_added_zeros-- >0) 01907 *pos++= '0'; 01908 } 01909 /* 01910 Note the position where the rightmost digit of the int_% parts has been 01911 written (this is to later check if the int_% parts contained nothing, 01912 meaning an extra 0 is needed). 01913 */ 01914 tmp_right_pos=pos; 01915 01916 /* 01917 Step back to the position of the leftmost digit of the int_% parts, 01918 to write sign and fill with zeros or blanks or prezeros. 01919 */ 01920 pos=tmp_left_pos-1; 01921 if (zerofill) 01922 { 01923 left_wall=to-1; 01924 while (pos > left_wall) // Fill with zeros 01925 *pos--='0'; 01926 } 01927 else 01928 { 01929 left_wall=to+(sign_char != 0)-1; 01930 if (!expo_sign_char) // If exponent was specified, ignore prezeros 01931 { 01932 for (;pos > left_wall && pre_zeros_from !=pre_zeros_end; 01933 pre_zeros_from++) 01934 *pos--= '0'; 01935 } 01936 if (pos == tmp_right_pos-1) 01937 *pos--= '0'; // no 0 has ever been written, so write one 01938 left_wall= to-1; 01939 if (sign_char && pos != left_wall) 01940 { 01941 /* Write sign if possible (it is if sign is '-') */ 01942 *pos--= sign_char; 01943 } 01944 while (pos != left_wall) 01945 *pos--=' '; //fill with blanks 01946 } 01947 01948 /* 01949 Write digits of the frac_% parts ; 01950 Depending on table->in_use->count_cutted_fields, we may also want 01951 to know if some non-zero tail of these parts will 01952 be truncated (for example, 0.002->0.00 will generate a warning, 01953 while 0.000->0.00 will not) 01954 (and 0E1000000000 will not, while 1E-1000000000 will) 01955 */ 01956 01957 pos=to+(uint)(field_length-tmp_dec); // Calculate post to '.' 01958 right_wall=to+field_length; 01959 if (pos != right_wall) 01960 *pos++='.'; 01961 01962 if (expo_sign_char == '-') 01963 { 01964 while (frac_digits_added_zeros-- > 0) 01965 { 01966 if (pos == right_wall) 01967 { 01968 if (table->in_use->count_cuted_fields && !is_cuted_fields_incr) 01969 break; // Go on below to see if we lose non zero digits 01970 return 0; 01971 } 01972 *pos++='0'; 01973 } 01974 while (int_digits_end != frac_digits_head_end) 01975 { 01976 tmp_char= *int_digits_end++; 01977 if (pos == right_wall) 01978 { 01979 if (tmp_char != '0') // Losing a non zero digit ? 01980 { 01981 if (!is_cuted_fields_incr) 01982 set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, 01983 WARN_DATA_TRUNCATED, 1); 01984 return 0; 01985 } 01986 continue; 01987 } 01988 *pos++= tmp_char; 01989 } 01990 } 01991 01992 for (;frac_digits_from!=frac_digits_end;) 01993 { 01994 tmp_char= *frac_digits_from++; 01995 if (pos == right_wall) 01996 { 01997 if (tmp_char != '0') // Losing a non zero digit ? 01998 { 01999 if (!is_cuted_fields_incr) 02000 { 02001 /* 02002 This is a note, not a warning, as we don't want to abort 02003 when we cut decimals in strict mode 02004 */ 02005 set_warning(MYSQL_ERROR::WARN_LEVEL_NOTE, WARN_DATA_TRUNCATED, 1); 02006 } 02007 return 0; 02008 } 02009 continue; 02010 } 02011 *pos++= tmp_char; 02012 } 02013 02014 while (pos != right_wall) 02015 *pos++='0'; // Fill with zeros at right of '.' 02016 return 0; 02017 } 02018 02019 02020 int Field_decimal::store(double nr) 02021 { 02022 ASSERT_COLUMN_MARKED_FOR_WRITE; 02023 if (unsigned_flag && nr < 0) 02024 { 02025 overflow(1); 02026 return 1; 02027 } 02028 02029 #ifdef HAVE_FINITE 02030 if (!finite(nr)) // Handle infinity as special case 02031 { 02032 overflow(nr < 0.0); 02033 return 1; 02034 } 02035 #endif 02036 02037 reg4 uint i,length; 02038 char fyllchar,*to; 02039 char buff[DOUBLE_TO_STRING_CONVERSION_BUFFER_SIZE]; 02040 02041 fyllchar = zerofill ? (char) '0' : (char) ' '; 02042 #ifdef HAVE_SNPRINTF 02043 buff[sizeof(buff)-1]=0; // Safety 02044 snprintf(buff,sizeof(buff)-1, "%.*f",(int) dec,nr); 02045 length=(uint) strlen(buff); 02046 #else 02047 length=(uint) my_sprintf(buff,(buff,"%.*f",dec,nr)); 02048 #endif 02049 02050 if (length > field_length) 02051 { 02052 overflow(nr < 0.0); 02053 return 1; 02054 } 02055 else 02056 { 02057 to=ptr; 02058 for (i=field_length-length ; i-- > 0 ;) 02059 *to++ = fyllchar; 02060 memcpy(to,buff,length); 02061 return 0; 02062 } 02063 } 02064 02065 02066 int Field_decimal::store(longlong nr, bool unsigned_val) 02067 { 02068 ASSERT_COLUMN_MARKED_FOR_WRITE; 02069 char buff[22]; 02070 uint length, int_part; 02071 char fyllchar, *to; 02072 02073 if (nr < 0 && unsigned_flag && !unsigned_val) 02074 { 02075 overflow(1); 02076 return 1; 02077 } 02078 length= (uint) (longlong10_to_str(nr,buff,unsigned_val ? 10 : -10) - buff); 02079 int_part= field_length- (dec ? dec+1 : 0); 02080 02081 if (length > int_part) 02082 { 02083 overflow(!unsigned_val && nr < 0L); /* purecov: inspected */ 02084 return 1; 02085 } 02086 02087 fyllchar = zerofill ? (char) '0' : (char) ' '; 02088 to= ptr; 02089 for (uint i=int_part-length ; i-- > 0 ;) 02090 *to++ = fyllchar; 02091 memcpy(to,buff,length); 02092 if (dec) 02093 { 02094 to[length]='.'; 02095 bfill(to+length+1,dec,'0'); 02096 } 02097 return 0; 02098 } 02099 02100 02101 double Field_decimal::val_real(void) 02102 { 02103 ASSERT_COLUMN_MARKED_FOR_READ; 02104 int not_used; 02105 char *end_not_used; 02106 return my_strntod(&my_charset_bin, ptr, field_length, &end_not_used, 02107 ¬_used); 02108 } 02109 02110 longlong Field_decimal::val_int(void) 02111 { 02112 ASSERT_COLUMN_MARKED_FOR_READ; 02113 int not_used; 02114 if (unsigned_flag) 02115 return my_strntoull(&my_charset_bin, ptr, field_length, 10, NULL, 02116 ¬_used); 02117 else 02118 return my_strntoll(&my_charset_bin, ptr, field_length, 10, NULL, 02119 ¬_used); 02120 } 02121 02122 02123 String *Field_decimal::val_str(String *val_buffer __attribute__((unused)), 02124 String *val_ptr) 02125 { 02126 ASSERT_COLUMN_MARKED_FOR_READ; 02127 char *str; 02128 for (str=ptr ; *str == ' ' ; str++) ; 02129 uint tmp_length=(uint) (str-ptr); 02130 val_ptr->set_charset(&my_charset_bin); 02131 if (field_length < tmp_length) // Error in data 02132 val_ptr->length(0); 02133 else 02134 val_ptr->set_ascii((const char*) str, field_length-tmp_length); 02135 return val_ptr; 02136 } 02137 02138 /* 02139 ** Should be able to handle at least the following fixed decimal formats: 02140 ** 5.00 , -1.0, 05, -05, +5 with optional pre/end space 02141 */ 02142 02143 int Field_decimal::cmp(const char *a_ptr,const char *b_ptr) 02144 { 02145 const char *end; 02146 int swap=0; 02147 /* First remove prefixes '0', ' ', and '-' */ 02148 for (end=a_ptr+field_length; 02149 a_ptr != end && 02150 (*a_ptr == *b_ptr || 02151 ((my_isspace(&my_charset_bin,*a_ptr) || *a_ptr == '+' || 02152 *a_ptr == '0') && 02153 (my_isspace(&my_charset_bin,*b_ptr) || *b_ptr == '+' || 02154 *b_ptr == '0'))); 02155 a_ptr++,b_ptr++) 02156 { 02157 if (*a_ptr == '-') // If both numbers are negative 02158 swap= -1 ^ 1; // Swap result 02159 } 02160 if (a_ptr == end) 02161 return 0; 02162 if (*a_ptr == '-') 02163 return -1; 02164 if (*b_ptr == '-') 02165 return 1; 02166 02167 while (a_ptr != end) 02168 { 02169 if (*a_ptr++ != *b_ptr++) 02170 return swap ^ (a_ptr[-1] < b_ptr[-1] ? -1 : 1); // compare digits 02171 } 02172 return 0; 02173 } 02174 02175 02176 void Field_decimal::sort_string(char *to,uint length) 02177 { 02178 char *str,*end; 02179 for (str=ptr,end=ptr+length; 02180 str != end && 02181 ((my_isspace(&my_charset_bin,*str) || *str == '+' || 02182 *str == '0')) ; 02183 str++) 02184 *to++=' '; 02185 if (str == end) 02186 return; /* purecov: inspected */ 02187 02188 if (*str == '-') 02189 { 02190 *to++=1; // Smaller than any number 02191 str++; 02192 while (str != end) 02193 if (my_isdigit(&my_charset_bin,*str)) 02194 *to++= (char) ('9' - *str++); 02195 else 02196 *to++= *str++; 02197 } 02198 else memcpy(to,str,(uint) (end-str)); 02199 } 02200 02201 02202 void Field_decimal::sql_type(String &res) const 02203 { 02204 CHARSET_INFO *cs=res.charset(); 02205 uint tmp=field_length; 02206 if (!unsigned_flag) 02207 tmp--; 02208 if (dec) 02209 tmp--; 02210 res.length(cs->cset->snprintf(cs,(char*) res.ptr(),res.alloced_length(), 02211 "decimal(%d,%d)",tmp,dec)); 02212 add_zerofill_and_unsigned(res); 02213 } 02214 02215 02216 /**************************************************************************** 02217 ** Field_new_decimal 02218 ****************************************************************************/ 02219 02220 Field_new_decimal::Field_new_decimal(char *ptr_arg, 02221 uint32 len_arg, uchar *null_ptr_arg, 02222 uchar null_bit_arg, 02223 enum utype unireg_check_arg, 02224 const char *field_name_arg, 02225 uint8 dec_arg,bool zero_arg, 02226 bool unsigned_arg) 02227 :Field_num(ptr_arg, len_arg, null_ptr_arg, null_bit_arg, 02228 unireg_check_arg, field_name_arg, dec_arg, zero_arg, unsigned_arg) 02229 { 02230 precision= my_decimal_length_to_precision(len_arg, dec_arg, unsigned_arg); 02231 DBUG_ASSERT((precision <= DECIMAL_MAX_PRECISION) && 02232 (dec <= DECIMAL_MAX_SCALE)); 02233 bin_size= my_decimal_get_binary_size(precision, dec); 02234 } 02235 02236 02237 Field_new_decimal::Field_new_decimal(uint32 len_arg, 02238 bool maybe_null, 02239 const char *name, 02240 uint8 dec_arg, 02241 bool unsigned_arg) 02242 :Field_num((char*) 0, len_arg, 02243 maybe_null ? (uchar*) "": 0, 0, 02244 NONE, name, dec_arg, 0, unsigned_arg) 02245 { 02246 precision= my_decimal_length_to_precision(len_arg, dec_arg, unsigned_arg); 02247 DBUG_ASSERT((precision <= DECIMAL_MAX_PRECISION) && 02248 (dec <= DECIMAL_MAX_SCALE)); 02249 bin_size= my_decimal_get_binary_size(precision, dec); 02250 } 02251 02252 02253 void Field_new_decimal::reset(void) 02254 { 02255 store_value(&decimal_zero); 02256 } 02257 02258 02259 /* 02260 Generate max/min decimal value in case of overflow. 02261 02262 SYNOPSIS 02263 Field_new_decimal::set_value_on_overflow(); 02264 decimal_value buffer for value 02265 sign sign of value which caused overflow 02266 */ 02267 02268 void Field_new_decimal::set_value_on_overflow(my_decimal *decimal_value, 02269 bool sign) 02270 { 02271 DBUG_ENTER("Field_new_decimal::set_value_on_overflow"); 02272 max_my_decimal(decimal_value, precision, decimals()); 02273 if (sign) 02274 { 02275 if (unsigned_flag) 02276 my_decimal_set_zero(decimal_value); 02277 else 02278 decimal_value->sign(TRUE); 02279 } 02280 DBUG_VOID_RETURN; 02281 } 02282 02283 02284 /* 02285 Store decimal value in the binary buffer 02286 02287 SYNOPSIS 02288 store_value(const my_decimal *decimal_value) 02289 decimal_value my_decimal 02290 02291 DESCRIPTION 02292 checks if decimal_value fits into field size. 02293 if it does, stores the decimal in the buffer using binary format. 02294 Otherwise sets maximal number that can be stored in the field. 02295 02296 RETURN 02297 0 ok 02298 1 error 02299 */ 02300 02301 bool Field_new_decimal::store_value(const my_decimal *decimal_value) 02302 { 02303 ASSERT_COLUMN_MARKED_FOR_WRITE; 02304 int error= 0; 02305 DBUG_ENTER("Field_new_decimal::store_value"); 02306 #ifndef DBUG_OFF 02307 { 02308 char dbug_buff[DECIMAL_MAX_STR_LENGTH+1]; 02309 DBUG_PRINT("enter", ("value: %s", dbug_decimal_as_string(dbug_buff, decimal_value))); 02310 } 02311 #endif 02312 02313 /* check that we do not try to write negative value in unsigned field */ 02314 if (unsigned_flag && decimal_value->sign()) 02315 { 02316 DBUG_PRINT("info", ("unsigned overflow")); 02317 set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1); 02318 error= 1; 02319 decimal_value= &decimal_zero; 02320 } 02321 #ifndef DBUG_OFF 02322 { 02323 char dbug_buff[DECIMAL_MAX_STR_LENGTH+1]; 02324 DBUG_PRINT("info", ("saving with precision %d scale: %d value %s", 02325 (int)precision, (int)dec, 02326 dbug_decimal_as_string(dbug_buff, decimal_value))); 02327 } 02328 #endif 02329 02330 if (warn_if_overflow(my_decimal2binary(E_DEC_FATAL_ERROR & ~E_DEC_OVERFLOW, 02331 decimal_value, ptr, precision, dec))) 02332 { 02333 my_decimal buff; 02334 DBUG_PRINT("info", ("overflow")); 02335 set_value_on_overflow(&buff, decimal_value->sign()); 02336 my_decimal2binary(E_DEC_FATAL_ERROR, &buff, ptr, precision, dec); 02337 error= 1; 02338 } 02339 DBUG_EXECUTE("info", print_decimal_buff(decimal_value, (byte *) ptr, 02340 bin_size);); 02341 DBUG_RETURN(error); 02342 } 02343 02344 02345 int Field_new_decimal::store(const char *from, uint length, 02346 CHARSET_INFO *charset) 02347 { 02348 ASSERT_COLUMN_MARKED_FOR_WRITE; 02349 int err; 02350 my_decimal decimal_value; 02351 DBUG_ENTER("Field_new_decimal::store(char*)"); 02352 02353 if ((err= str2my_decimal(E_DEC_FATAL_ERROR & 02354 ~(E_DEC_OVERFLOW | E_DEC_BAD_NUM), 02355 from, length, charset, &decimal_value)) && 02356 table->in_use->abort_on_warning) 02357 { 02358 push_warning_printf(table->in_use, MYSQL_ERROR::WARN_LEVEL_ERROR, 02359 ER_TRUNCATED_WRONG_VALUE_FOR_FIELD, 02360 ER(ER_TRUNCATED_WRONG_VALUE_FOR_FIELD), 02361 "decimal", from, field_name, 02362 (ulong) table->in_use->row_count); 02363 DBUG_RETURN(err); 02364 } 02365 02366 switch (err) { 02367 case E_DEC_TRUNCATED: 02368 set_warning(MYSQL_ERROR::WARN_LEVEL_NOTE, WARN_DATA_TRUNCATED, 1); 02369 break; 02370 case E_DEC_OVERFLOW: 02371 set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1); 02372 set_value_on_overflow(&decimal_value, decimal_value.sign()); 02373 break; 02374 case E_DEC_BAD_NUM: 02375 push_warning_printf(table->in_use, MYSQL_ERROR::WARN_LEVEL_WARN, 02376 ER_TRUNCATED_WRONG_VALUE_FOR_FIELD, 02377 ER(ER_TRUNCATED_WRONG_VALUE_FOR_FIELD), 02378 "decimal", from, field_name, 02379 (ulong) table->in_use->row_count); 02380 my_decimal_set_zero(&decimal_value); 02381 break; 02382 } 02383 02384 #ifndef DBUG_OFF 02385 char dbug_buff[DECIMAL_MAX_STR_LENGTH+1]; 02386 DBUG_PRINT("enter", ("value: %s", 02387 dbug_decimal_as_string(dbug_buff, &decimal_value))); 02388 #endif 02389 store_value(&decimal_value); 02390 DBUG_RETURN(err); 02391 } 02392 02393 02394 int Field_new_decimal::store(double nr) 02395 { 02396 ASSERT_COLUMN_MARKED_FOR_WRITE; 02397 my_decimal decimal_value; 02398 int err; 02399 DBUG_ENTER("Field_new_decimal::store(double)"); 02400 02401 err= double2my_decimal(E_DEC_FATAL_ERROR & ~E_DEC_OVERFLOW, nr, 02402 &decimal_value); 02403 /* 02404 TODO: fix following when double2my_decimal when double2decimal 02405 will return E_DEC_TRUNCATED always correctly 02406 */ 02407 if (!err) 02408 { 02409 double nr2; 02410 my_decimal2double(E_DEC_FATAL_ERROR, &decimal_value, &nr2); 02411 if (nr2 != nr) 02412 err= E_DEC_TRUNCATED; 02413 } 02414 if (err) 02415 { 02416 if (check_overflow(err)) 02417 set_value_on_overflow(&decimal_value, decimal_value.sign()); 02418 /* Only issue a warning if store_value doesn't issue an warning */ 02419 table->in_use->got_warning= 0; 02420 } 02421 if (store_value(&decimal_value)) 02422 err= 1; 02423 else if (err && !table->in_use->got_warning) 02424 err= warn_if_overflow(err); 02425 DBUG_RETURN(err); 02426 } 02427 02428 02429 int Field_new_decimal::store(longlong nr, bool unsigned_val) 02430 { 02431 ASSERT_COLUMN_MARKED_FOR_WRITE; 02432 my_decimal decimal_value; 02433 int err; 02434 02435 if ((err= int2my_decimal(E_DEC_FATAL_ERROR & ~E_DEC_OVERFLOW, 02436 nr, unsigned_val, &decimal_value))) 02437 { 02438 if (check_overflow(err)) 02439 set_value_on_overflow(&decimal_value, decimal_value.sign()); 02440 /* Only issue a warning if store_value doesn't issue an warning */ 02441 table->in_use->got_warning= 0; 02442 } 02443 if (store_value(&decimal_value)) 02444 err= 1; 02445 else if (err && !table->in_use->got_warning) 02446 err= warn_if_overflow(err); 02447 return err; 02448 } 02449 02450 02451 int Field_new_decimal::store_decimal(const my_decimal *decimal_value) 02452 { 02453 ASSERT_COLUMN_MARKED_FOR_WRITE; 02454 return store_value(decimal_value); 02455 } 02456 02457 02458 double Field_new_decimal::val_real(void) 02459 { 02460 ASSERT_COLUMN_MARKED_FOR_READ; 02461 double dbl; 02462 my_decimal decimal_value; 02463 my_decimal2double(E_DEC_FATAL_ERROR, val_decimal(&decimal_value), &dbl); 02464 return dbl; 02465 } 02466 02467 02468 longlong Field_new_decimal::val_int(void) 02469 { 02470 ASSERT_COLUMN_MARKED_FOR_READ; 02471 longlong i; 02472 my_decimal decimal_value; 02473 my_decimal2int(E_DEC_FATAL_ERROR, val_decimal(&decimal_value), 02474 unsigned_flag, &i); 02475 return i; 02476 } 02477 02478 02479 my_decimal* Field_new_decimal::val_decimal(my_decimal *decimal_value) 02480 { 02481 ASSERT_COLUMN_MARKED_FOR_READ; 02482 DBUG_ENTER("Field_new_decimal::val_decimal"); 02483 binary2my_decimal(E_DEC_FATAL_ERROR, ptr, decimal_value, 02484 precision, dec); 02485 DBUG_EXECUTE("info", print_decimal_buff(decimal_value, (byte *) ptr, 02486 bin_size);); 02487 DBUG_RETURN(decimal_value); 02488 } 02489 02490 02491 String *Field_new_decimal::val_str(String *val_buffer, 02492 String *val_ptr __attribute__((unused))) 02493 { 02494 ASSERT_COLUMN_MARKED_FOR_READ; 02495 my_decimal decimal_value; 02496 uint fixed_precision= zerofill ? precision : 0; 02497 my_decimal2string(E_DEC_FATAL_ERROR, val_decimal(&decimal_value), 02498 fixed_precision, dec, '0', val_buffer); 02499 return val_buffer; 02500 } 02501 02502 02503 int Field_new_decimal::cmp(const char *a,const char*b) 02504 { 02505 return memcmp(a, b, bin_size); 02506 } 02507 02508 02509 void Field_new_decimal::sort_string(char *buff, 02510 uint length __attribute__((unused))) 02511 { 02512 memcpy(buff, ptr, bin_size); 02513 } 02514 02515 02516 void Field_new_decimal::sql_type(String &str) const 02517 { 02518 CHARSET_INFO *cs= str.charset(); 02519 str.length(cs->cset->snprintf(cs, (char*) str.ptr(), str.alloced_length(), 02520 "decimal(%d,%d)", precision, (int)dec)); 02521 add_zerofill_and_unsigned(str); 02522 } 02523 02524 02525 uint Field_new_decimal::is_equal(create_field *new_field) 02526 { 02527 return ((new_field->sql_type == real_type()) && 02528 ((new_field->flags & UNSIGNED_FLAG) == 02529 (uint) (flags & UNSIGNED_FLAG)) && 02530 ((new_field->flags & AUTO_INCREMENT_FLAG) == 02531 (uint) (flags & AUTO_INCREMENT_FLAG)) && 02532 (new_field->length == max_length()) && 02533 (new_field->decimals == dec)); 02534 } 02535 02536 02537 /**************************************************************************** 02538 ** tiny int 02539 ****************************************************************************/ 02540 02541 int Field_tiny::store(const char *from,uint len,CHARSET_INFO *cs) 02542 { 02543 ASSERT_COLUMN_MARKED_FOR_WRITE; 02544 int not_used; // We can ignore result from str2int 02545 char *end; 02546 long tmp= my_strntol(cs, from, len, 10, &end, ¬_used); 02547 int error= 0; 02548 02549 if (unsigned_flag) 02550 { 02551 if (tmp < 0) 02552 { 02553 tmp=0; /* purecov: inspected */ 02554 set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1); 02555 error= 1; 02556 } 02557 else if (tmp > 255) 02558 { 02559 tmp= 255; 02560 set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1); 02561 error= 1; 02562 } 02563 else if (table->in_use->count_cuted_fields && check_int(from,len,end,cs)) 02564 error= 1; 02565 } 02566 else 02567 { 02568 if (tmp < -128) 02569 { 02570 tmp= -128; 02571 set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1); 02572 error= 1; 02573 } 02574 else if (tmp >= 128) 02575 { 02576 tmp= 127; 02577 set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1); 02578 error= 1; 02579 } 02580 else if (table->in_use->count_cuted_fields && check_int(from,len,end,cs)) 02581 error= 1; 02582 } 02583 ptr[0]= (char) tmp; 02584 return error; 02585 } 02586 02587 02588 int Field_tiny::store(double nr) 02589 { 02590 ASSERT_COLUMN_MARKED_FOR_WRITE; 02591 int error= 0; 02592 nr=rint(nr); 02593 if (unsigned_flag) 02594 { 02595 if (nr < 0.0) 02596 { 02597 *ptr=0; 02598 set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1); 02599 error= 1; 02600 } 02601 else if (nr > 255.0) 02602 { 02603 *ptr=(char) 255; 02604 set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1); 02605 error= 1; 02606 } 02607 else 02608 *ptr=(char) nr; 02609 } 02610 else 02611 { 02612 if (nr < -128.0) 02613 { 02614 *ptr= (char) -128; 02615 set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1); 02616 error= 1; 02617 } 02618 else if (nr > 127.0) 02619 { 02620 *ptr=127; 02621 set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1); 02622 error= 1; 02623 } 02624 else 02625 *ptr=(char) (int) nr; 02626 } 02627 return error; 02628 } 02629 02630 02631 int Field_tiny::store(longlong nr, bool unsigned_val) 02632 { 02633 ASSERT_COLUMN_MARKED_FOR_WRITE; 02634 int error= 0; 02635 02636 if (unsigned_flag) 02637 { 02638 if (nr < 0 && !unsigned_val) 02639 { 02640 *ptr= 0; 02641 set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1); 02642 error= 1; 02643 } 02644 else if ((ulonglong) nr > (ulonglong) 255) 02645 { 02646 *ptr= (char) 255; 02647 set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1); 02648 error= 1; 02649 } 02650 else 02651 *ptr=(char) nr; 02652 } 02653 else 02654 { 02655 if (nr < 0 && unsigned_val) 02656 nr= 256; // Generate overflow 02657 if (nr < -128) 02658 { 02659 *ptr= (char) -128; 02660 set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1); 02661 error= 1; 02662 } 02663 else if (nr > 127) 02664 { 02665 *ptr=127; 02666 set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1); 02667 error= 1; 02668 } 02669 else 02670 *ptr=(char) nr; 02671 } 02672 return error; 02673 } 02674 02675 02676 double Field_tiny::val_real(void) 02677 { 02678 ASSERT_COLUMN_MARKED_FOR_READ; 02679 int tmp= unsigned_flag ? (int) ((uchar*) ptr)[0] : 02680 (int) ((signed char*) ptr)[0]; 02681 return (double) tmp; 02682 } 02683 02684 02685 longlong Field_tiny::val_int(void) 02686 { 02687 ASSERT_COLUMN_MARKED_FOR_READ; 02688 int tmp= unsigned_flag ? (int) ((uchar*) ptr)[0] : 02689 (int) ((signed char*) ptr)[0]; 02690 return (longlong) tmp; 02691 } 02692 02693 02694 String *Field_tiny::val_str(String *val_buffer, 02695 String *val_ptr __attribute__((unused))) 02696 { 02697 ASSERT_COLUMN_MARKED_FOR_READ; 02698 CHARSET_INFO *cs= &my_charset_bin; 02699 uint length; 02700 uint mlength=max(field_length+1,5*cs->mbmaxlen); 02701 val_buffer->alloc(mlength); 02702 char *to=(char*) val_buffer->ptr(); 02703 02704 if (unsigned_flag) 02705 length= (uint) cs->cset->long10_to_str(cs,to,mlength, 10, 02706 (long) *((uchar*) ptr)); 02707 else 02708 length= (uint) cs->cset->long10_to_str(cs,to,mlength,-10, 02709 (long) *((signed char*) ptr)); 02710 02711 val_buffer->length(length); 02712 if (zerofill) 02713 prepend_zeros(val_buffer); 02714 return val_buffer; 02715 } 02716 02717 bool Field_tiny::send_binary(Protocol *protocol) 02718 { 02719 return protocol->store_tiny((longlong) (int8) ptr[0]); 02720 } 02721 02722 int Field_tiny::cmp(const char *a_ptr, const char *b_ptr) 02723 { 02724 signed char a,b; 02725 a=(signed char) a_ptr[0]; b= (signed char) b_ptr[0]; 02726 if (unsigned_flag) 02727 return ((uchar) a < (uchar) b) ? -1 : ((uchar) a > (uchar) b) ? 1 : 0; 02728 return (a < b) ? -1 : (a > b) ? 1 : 0; 02729 } 02730 02731 void Field_tiny::sort_string(char *to,uint length __attribute__((unused))) 02732 { 02733 if (unsigned_flag) 02734 *to= *ptr; 02735 else 02736 to[0] = (char) ((uchar) ptr[0] ^ (uchar) 128); /* Revers signbit */ 02737 } 02738 02739 void Field_tiny::sql_type(String &res) const 02740 { 02741 CHARSET_INFO *cs=res.charset(); 02742 res.length(cs->cset->snprintf(cs,(char*) res.ptr(),res.alloced_length(), 02743 "tinyint(%d)",(int) field_length)); 02744 add_zerofill_and_unsigned(res); 02745 } 02746 02747 /**************************************************************************** 02748 Field type short int (2 byte) 02749 ****************************************************************************/ 02750 02751 int Field_short::store(const char *from,uint len,CHARSET_INFO *cs) 02752 { 02753 ASSERT_COLUMN_MARKED_FOR_WRITE; 02754 int not_used; // We can ignore result from str2int 02755 char *end; 02756 long tmp= my_strntol(cs, from, len, 10, &end, ¬_used); 02757 int error= 0; 02758 02759 if (unsigned_flag) 02760 { 02761 if (tmp < 0) 02762 { 02763 tmp=0; 02764 set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1); 02765 error= 1; 02766 } 02767 else if (tmp > UINT_MAX16) 02768 { 02769 tmp=UINT_MAX16; 02770 set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1); 02771 error= 1; 02772 } 02773 else if (table->in_use->count_cuted_fields && check_int(from,len,end,cs)) 02774 error= 1; 02775 } 02776 else 02777 { 02778 if (tmp < INT_MIN16) 02779 { 02780 tmp= INT_MIN16; 02781 set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1); 02782 error= 1; 02783 } 02784 else if (tmp > INT_MAX16) 02785 { 02786 tmp=INT_MAX16; 02787 set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1); 02788 error= 1; 02789 } 02790 else if (table->in_use->count_cuted_fields && check_int(from,len,end,cs)) 02791 error= 1; 02792 } 02793 #ifdef WORDS_BIGENDIAN 02794 if (table->s->db_low_byte_first) 02795 { 02796 int2store(ptr,tmp); 02797 } 02798 else 02799 #endif 02800 shortstore(ptr,(short) tmp); 02801 return error; 02802 } 02803 02804 02805 int Field_short::store(double nr) 02806 { 02807 ASSERT_COLUMN_MARKED_FOR_WRITE; 02808 int error= 0; 02809 int16 res; 02810 nr=rint(nr); 02811 if (unsigned_flag) 02812 { 02813 if (nr < 0) 02814 { 02815 res=0; 02816 set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1); 02817 error= 1; 02818 } 02819 else if (nr > (double) UINT_MAX16) 02820 { 02821 res=(int16) UINT_MAX16; 02822 set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1); 02823 error= 1; 02824 } 02825 else 02826 res=(int16) (uint16) nr; 02827 } 02828 else 02829 { 02830 if (nr < (double) INT_MIN16) 02831 { 02832 res=INT_MIN16; 02833 set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1); 02834 error= 1; 02835 } 02836 else if (nr > (double) INT_MAX16) 02837 { 02838 res=INT_MAX16; 02839 set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1); 02840 error= 1; 02841 } 02842 else 02843 res=(int16) (int) nr; 02844 } 02845 #ifdef WORDS_BIGENDIAN 02846 if (table->s->db_low_byte_first) 02847 { 02848 int2store(ptr,res); 02849 } 02850 else 02851 #endif 02852 shortstore(ptr,res); 02853 return error; 02854 } 02855 02856 02857 int Field_short::store(longlong nr, bool unsigned_val) 02858 { 02859 ASSERT_COLUMN_MARKED_FOR_WRITE; 02860 int error= 0; 02861 int16 res; 02862 02863 if (unsigned_flag) 02864 { 02865 if (nr < 0L && !unsigned_val) 02866 { 02867 res=0; 02868 set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1); 02869 error= 1; 02870 } 02871 else if ((ulonglong) nr > (ulonglong) UINT_MAX16) 02872 { 02873 res=(int16) UINT_MAX16; 02874 set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1); 02875 error= 1; 02876 } 02877 else 02878 res=(int16) (uint16) nr; 02879 } 02880 else 02881 { 02882 if (nr < 0 && unsigned_val) 02883 nr= UINT_MAX16+1; // Generate overflow 02884 02885 if (nr < INT_MIN16) 02886 { 02887 res=INT_MIN16; 02888 set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1); 02889 error= 1; 02890 } 02891 else if (nr > (longlong) INT_MAX16) 02892 { 02893 res=INT_MAX16; 02894 set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1); 02895 error= 1; 02896 } 02897 else 02898 res=(int16) nr; 02899 } 02900 #ifdef WORDS_BIGENDIAN 02901 if (table->s->db_low_byte_first) 02902 { 02903 int2store(ptr,res); 02904 } 02905 else 02906 #endif 02907 shortstore(ptr,res); 02908 return error; 02909 } 02910 02911 02912 double Field_short::val_real(void) 02913 { 02914 ASSERT_COLUMN_MARKED_FOR_READ; 02915 short j; 02916 #ifdef WORDS_BIGENDIAN 02917 if (table->s->db_low_byte_first) 02918 j=sint2korr(ptr); 02919 else 02920 #endif 02921 shortget(j,ptr); 02922 return unsigned_flag ? (double) (unsigned short) j : (double) j; 02923 } 02924 02925 longlong Field_short::val_int(void) 02926 { 02927 ASSERT_COLUMN_MARKED_FOR_READ; 02928 short j; 02929 #ifdef WORDS_BIGENDIAN 02930 if (table->s->db_low_byte_first) 02931 j=sint2korr(ptr); 02932 else 02933 #endif 02934 shortget(j,ptr); 02935 return unsigned_flag ? (longlong) (unsigned short) j : (longlong) j; 02936 } 02937 02938 02939 String *Field_short::val_str(String *val_buffer, 02940 String *val_ptr __attribute__((unused))) 02941 { 02942 ASSERT_COLUMN_MARKED_FOR_READ; 02943 CHARSET_INFO *cs= &my_charset_bin; 02944 uint length; 02945 uint mlength=max(field_length+1,7*cs->mbmaxlen); 02946 val_buffer->alloc(mlength); 02947 char *to=(char*) val_buffer->ptr(); 02948 short j; 02949 #ifdef WORDS_BIGENDIAN 02950 if (table->s->db_low_byte_first) 02951 j=sint2korr(ptr); 02952 else 02953 #endif 02954 shortget(j,ptr); 02955 02956 if (unsigned_flag) 02957 length=(uint) cs->cset->long10_to_str(cs, to, mlength, 10, 02958 (long) (uint16) j); 02959 else 02960 length=(uint) cs->cset->long10_to_str(cs, to, mlength,-10, (long) j); 02961 val_buffer->length(length); 02962 if (zerofill) 02963 prepend_zeros(val_buffer); 02964 return val_buffer; 02965 } 02966 02967 02968 bool Field_short::send_binary(Protocol *protocol) 02969 { 02970 return protocol->store_short(Field_short::val_int()); 02971 } 02972 02973 02974 int Field_short::cmp(const char *a_ptr, const char *b_ptr) 02975 { 02976 short a,b; 02977 #ifdef WORDS_BIGENDIAN 02978 if (table->s->db_low_byte_first) 02979 { 02980 a=sint2korr(a_ptr); 02981 b=sint2korr(b_ptr); 02982 } 02983 else 02984 #endif 02985 { 02986 shortget(a,a_ptr); 02987 shortget(b,b_ptr); 02988 } 02989 02990 if (unsigned_flag) 02991 return ((unsigned short) a < (unsigned short) b) ? -1 : 02992 ((unsigned short) a > (unsigned short) b) ? 1 : 0; 02993 return (a < b) ? -1 : (a > b) ? 1 : 0; 02994 } 02995 02996 void Field_short::sort_string(char *to,uint length __attribute__((unused))) 02997 { 02998 #ifdef WORDS_BIGENDIAN 02999 if (!table->s->db_low_byte_first) 03000 { 03001 if (unsigned_flag) 03002 to[0] = ptr[0]; 03003 else 03004 to[0] = (char) (ptr[0] ^ 128); /* Revers signbit */ 03005 to[1] = ptr[1]; 03006 } 03007 else 03008 #endif 03009 { 03010 if (unsigned_flag) 03011 to[0] = ptr[1]; 03012 else 03013 to[0] = (char) (ptr[1] ^ 128); /* Revers signbit */ 03014 to[1] = ptr[0]; 03015 } 03016 } 03017 03018 void Field_short::sql_type(String &res) const 03019 { 03020 CHARSET_INFO *cs=res.charset(); 03021 res.length(cs->cset->snprintf(cs,(char*) res.ptr(),res.alloced_length(), 03022 "smallint(%d)",(int) field_length)); 03023 add_zerofill_and_unsigned(res); 03024 } 03025 03026 03027 /**************************************************************************** 03028 Field type medium int (3 byte) 03029 ****************************************************************************/ 03030 03031 int Field_medium::store(const char *from,uint len,CHARSET_INFO *cs) 03032 { 03033 ASSERT_COLUMN_MARKED_FOR_WRITE; 03034 int not_used; // We can ignore result from str2int 03035 char *end; 03036 long tmp= my_strntol(cs, from, len, 10, &end, ¬_used); 03037 int error= 0; 03038 03039 if (unsigned_flag) 03040 { 03041 if (tmp < 0) 03042 { 03043 tmp=0; 03044 set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1); 03045 error= 1; 03046 } 03047 else if (tmp >= (long) (1L << 24)) 03048 { 03049 tmp=(long) (1L << 24)-1L; 03050 set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1); 03051 error= 1; 03052 } 03053 else if (table->in_use->count_cuted_fields && check_int(from,len,end,cs)) 03054 error= 1; 03055 } 03056 else 03057 { 03058 if (tmp < INT_MIN24) 03059 { 03060 tmp= INT_MIN24; 03061 set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1); 03062 error= 1; 03063 } 03064 else if (tmp > INT_MAX24) 03065 { 03066 tmp=INT_MAX24; 03067 set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1); 03068 error= 1; 03069 } 03070 else if (table->in_use->count_cuted_fields && check_int(from,len,end,cs)) 03071 error= 1; 03072 } 03073 03074 int3store(ptr,tmp); 03075 return error; 03076 } 03077 03078 03079 int Field_medium::store(double nr) 03080 { 03081 ASSERT_COLUMN_MARKED_FOR_WRITE; 03082 int error= 0; 03083 nr=rint(nr); 03084 if (unsigned_flag) 03085 { 03086 if (nr < 0) 03087 { 03088 int3store(ptr,0); 03089 set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1); 03090 error= 1; 03091 } 03092 else if (nr >= (double) (long) (1L << 24)) 03093 { 03094 uint32 tmp=(uint32) (1L << 24)-1L; 03095 int3store(ptr,tmp); 03096 set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1); 03097 error= 1; 03098 } 03099 else 03100 int3store(ptr,(uint32) nr); 03101 } 03102 else 03103 { 03104 if (nr < (double) INT_MIN24) 03105 { 03106 long tmp=(long) INT_MIN24; 03107 int3store(ptr,tmp); 03108 set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1); 03109 error= 1; 03110 } 03111 else if (nr > (double) INT_MAX24) 03112 { 03113 long tmp=(long) INT_MAX24; 03114 int3store(ptr,tmp); 03115 set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1); 03116 error= 1; 03117 } 03118 else 03119 int3store(ptr,(long) nr); 03120 } 03121 return error; 03122 } 03123 03124 03125 int Field_medium::store(longlong nr, bool unsigned_val) 03126 { 03127 ASSERT_COLUMN_MARKED_FOR_WRITE; 03128 int error= 0; 03129 03130 if (unsigned_flag) 03131 { 03132 if (nr < 0 && !unsigned_val) 03133 { 03134 int3store(ptr,0); 03135 set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1); 03136 error= 1; 03137 } 03138 else if ((ulonglong) nr >= (ulonglong) (long) (1L << 24)) 03139 { 03140 long tmp= (long) (1L << 24)-1L; 03141 int3store(ptr,tmp); 03142 set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1); 03143 error= 1; 03144 } 03145 else 03146 int3store(ptr,(uint32) nr); 03147 } 03148 else 03149 { 03150 if (nr < 0 && unsigned_val) 03151 nr= (ulonglong) (long) (1L << 24); // Generate overflow 03152 03153 if (nr < (longlong) INT_MIN24) 03154 { 03155 long tmp= (long) INT_MIN24; 03156 int3store(ptr,tmp); 03157 set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1); 03158 error= 1; 03159 } 03160 else if (nr > (longlong) INT_MAX24) 03161 { 03162 long tmp=(long) INT_MAX24; 03163 int3store(ptr,tmp); 03164 set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1); 03165 error= 1; 03166 } 03167 else 03168 int3store(ptr,(long) nr); 03169 } 03170 return error; 03171 } 03172 03173 03174 double Field_medium::val_real(void) 03175 { 03176 ASSERT_COLUMN_MARKED_FOR_READ; 03177 long j= unsigned_flag ? (long) uint3korr(ptr) : sint3korr(ptr); 03178 return (double) j; 03179 } 03180 03181 03182 longlong Field_medium::val_int(void) 03183 { 03184 ASSERT_COLUMN_MARKED_FOR_READ; 03185 long j= unsigned_flag ? (long) uint3korr(ptr) : sint3korr(ptr); 03186 return (longlong) j; 03187 } 03188 03189 03190 String *Field_medium::val_str(String *val_buffer, 03191 String *val_ptr __attribute__((unused))) 03192 { 03193 ASSERT_COLUMN_MARKED_FOR_READ; 03194 CHARSET_INFO *cs= &my_charset_bin; 03195 uint length; 03196 uint mlength=max(field_length+1,10*cs->mbmaxlen); 03197 val_buffer->alloc(mlength); 03198 char *to=(char*) val_buffer->ptr(); 03199 long j= unsigned_flag ? (long) uint3korr(ptr) : sint3korr(ptr); 03200 03201 length=(uint) cs->cset->long10_to_str(cs,to,mlength,-10,j); 03202 val_buffer->length(length); 03203 if (zerofill) 03204 prepend_zeros(val_buffer); /* purecov: inspected */ 03205 return val_buffer; 03206 } 03207 03208 03209 bool Field_medium::send_binary(Protocol *protocol) 03210 { 03211 ASSERT_COLUMN_MARKED_FOR_READ; 03212 return protocol->store_long(Field_medium::val_int()); 03213 } 03214 03215 03216 int Field_medium::cmp(const char *a_ptr, const char *b_ptr) 03217 { 03218 long a,b; 03219 if (unsigned_flag) 03220 { 03221 a=uint3korr(a_ptr); 03222 b=uint3korr(b_ptr); 03223 } 03224 else 03225 { 03226 a=sint3korr(a_ptr); 03227 b=sint3korr(b_ptr); 03228 } 03229 return (a < b) ? -1 : (a > b) ? 1 : 0; 03230 } 03231 03232 void Field_medium::sort_string(char *to,uint length __attribute__((unused))) 03233 { 03234 if (unsigned_flag) 03235 to[0] = ptr[2]; 03236 else 03237 to[0] = (uchar) (ptr[2] ^ 128); /* Revers signbit */ 03238 to[1] = ptr[1]; 03239 to[2] = ptr[0]; 03240 } 03241 03242 03243 void Field_medium::sql_type(String &res) const 03244 { 03245 CHARSET_INFO *cs=res.charset(); 03246 res.length(cs->cset->snprintf(cs,(char*) res.ptr(),res.alloced_length(), 03247 "mediumint(%d)",(int) field_length)); 03248 add_zerofill_and_unsigned(res); 03249 } 03250 03251 /**************************************************************************** 03252 ** long int 03253 ****************************************************************************/ 03254 03255 /* 03256 A helper function to check whether the next character 03257 in the string "s" is MINUS SIGN. 03258 */ 03259 #ifdef HAVE_CHARSET_ucs2 03260 static bool test_if_minus(CHARSET_INFO *cs, 03261 const char *s, const char *e) 03262 { 03263 my_wc_t wc; 03264 return cs->cset->mb_wc(cs, &wc, (uchar*) s, (uchar*) e) > 0 && wc == '-'; 03265 } 03266 #else 03267 /* 03268 If not UCS2 support is compiled then it is easier 03269 */ 03270 #define test_if_minus(cs, s, e) (*s == '-') 03271 #endif 03272 03273 03274 int Field_long::store(const char *from,uint len,CHARSET_INFO *cs) 03275 { 03276 ASSERT_COLUMN_MARKED_FOR_WRITE; 03277 ulong tmp_scan; 03278 longlong tmp; 03279 long store_tmp; 03280 int error; 03281 char *end; 03282 03283 tmp_scan= cs->cset->scan(cs, from, from+len, MY_SEQ_SPACES); 03284 len-= tmp_scan; 03285 from+= tmp_scan; 03286 03287 end= (char*) from+len; 03288 tmp= cs->cset->strtoll10(cs, from, &end, &error); 03289 03290 if (error != MY_ERRNO_EDOM) 03291 { 03292 if (unsigned_flag) 03293 { 03294 if (error < 0) 03295 { 03296 error= 1; 03297 tmp= 0; 03298 } 03299 else if ((ulonglong) tmp > (ulonglong) UINT_MAX32) 03300 { 03301 tmp= UINT_MAX32; 03302 error= 1; 03303 } 03304 else 03305 error= 0; 03306 } 03307 else 03308 { 03309 if (error < 0) 03310 { 03311 error= 0; 03312 if (tmp < INT_MIN32) 03313 { 03314 tmp= INT_MIN32; 03315 error= 1; 03316 } 03317 } 03318 else if (tmp > INT_MAX32) 03319 { 03320 tmp= INT_MAX32; 03321 error= 1; 03322 } 03323 } 03324 } 03325 if (error) 03326 { 03327 error= error != MY_ERRNO_EDOM ? 1 : 2; 03328 set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1); 03329 } 03330 else if (from+len != end && table->in_use->count_cuted_fields && 03331 check_int(from,len,end,cs)) 03332 error= 2; 03333 03334 store_tmp= (long) tmp; 03335 #ifdef WORDS_BIGENDIAN 03336 if (table->s->db_low_byte_first) 03337 { 03338 int4store(ptr, store_tmp); 03339 } 03340 else 03341 #endif 03342 longstore(ptr, store_tmp); 03343 return error; 03344 } 03345 03346 03347 int Field_long::store(double nr) 03348 { 03349 ASSERT_COLUMN_MARKED_FOR_WRITE; 03350 int error= 0; 03351 int32 res; 03352 nr=rint(nr); 03353 if (unsigned_flag) 03354 { 03355 if (nr < 0) 03356 { 03357 res=0; 03358 error= 1; 03359 } 03360 else if (nr > (double) UINT_MAX32) 03361 { 03362 res= UINT_MAX32; 03363 set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1); 03364 error= 1; 03365 } 03366 else 03367 res=(int32) (ulong) nr; 03368 } 03369 else 03370 { 03371 if (nr < (double) INT_MIN32) 03372 { 03373 res=(int32) INT_MIN32; 03374 error= 1; 03375 } 03376 else if (nr > (double) INT_MAX32) 03377 { 03378 res=(int32) INT_MAX32; 03379 error= 1; 03380 } 03381 else 03382 res=(int32) (longlong) nr; 03383 } 03384 if (error) 03385 set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1); 03386 03387 #ifdef WORDS_BIGENDIAN 03388 if (table->s->db_low_byte_first) 03389 { 03390 int4store(ptr,res); 03391 } 03392 else 03393 #endif 03394 longstore(ptr,res); 03395 return error; 03396 } 03397 03398 03399 int Field_long::store(longlong nr, bool unsigned_val) 03400 { 03401 ASSERT_COLUMN_MARKED_FOR_WRITE; 03402 int error= 0; 03403 int32 res; 03404 03405 if (unsigned_flag) 03406 { 03407 if (nr < 0 && !unsigned_val) 03408 { 03409 res=0; 03410 error= 1; 03411 } 03412 else if ((ulonglong) nr >= (LL(1) << 32)) 03413 { 03414 res=(int32) (uint32) ~0L; 03415 error= 1; 03416 } 03417 else 03418 res=(int32) (uint32) nr; 03419 } 03420 else 03421 { 03422 if (nr < 0 && unsigned_val) 03423 nr= ((longlong) INT_MAX32) + 1; // Generate overflow 03424 if (nr < (longlong) INT_MIN32) 03425 { 03426 res=(int32) INT_MIN32; 03427 error= 1; 03428 } 03429 else if (nr > (longlong) INT_MAX32) 03430 { 03431 res=(int32) INT_MAX32; 03432 error= 1; 03433 } 03434 else 03435 res=(int32) nr; 03436 } 03437 if (error) 03438 set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1); 03439 03440 #ifdef WORDS_BIGENDIAN 03441 if (table->s->db_low_byte_first) 03442 { 03443 int4store(ptr,res); 03444 } 03445 else 03446 #endif 03447 longstore(ptr,res); 03448 return error; 03449 } 03450 03451 03452 double Field_long::val_real(void) 03453 { 03454 ASSERT_COLUMN_MARKED_FOR_READ; 03455 int32 j; 03456 #ifdef WORDS_BIGENDIAN 03457 if (table->s->db_low_byte_first) 03458 j=sint4korr(ptr); 03459 else 03460 #endif 03461 longget(j,ptr); 03462 return unsigned_flag ? (double) (uint32) j : (double) j; 03463 } 03464 03465 longlong Field_long::val_int(void) 03466 { 03467 ASSERT_COLUMN_MARKED_FOR_READ; 03468 int32 j; 03469 /* See the comment in Field_long::store(long long) */ 03470 DBUG_ASSERT(table->in_use == current_thd); 03471 #ifdef WORDS_BIGENDIAN 03472 if (table->s->db_low_byte_first) 03473 j=sint4korr(ptr); 03474 else 03475 #endif 03476 longget(j,ptr); 03477 return unsigned_flag ? (longlong) (uint32) j : (longlong) j; 03478 } 03479 03480 String *Field_long::val_str(String *val_buffer, 03481 String *val_ptr __attribute__((unused))) 03482 { 03483 ASSERT_COLUMN_MARKED_FOR_READ; 03484 CHARSET_INFO *cs= &my_charset_bin; 03485 uint length; 03486 uint mlength=max(field_length+1,12*cs->mbmaxlen); 03487 val_buffer->alloc(mlength); 03488 char *to=(char*) val_buffer->ptr(); 03489 int32 j; 03490 #ifdef WORDS_BIGENDIAN 03491 if (table->s->db_low_byte_first) 03492 j=sint4korr(ptr); 03493 else 03494 #endif 03495 longget(j,ptr); 03496 03497 if (unsigned_flag) 03498 length=cs->cset->long10_to_str(cs,to,mlength, 10,(long) (uint32)j); 03499 else 03500 length=cs->cset->long10_to_str(cs,to,mlength,-10,(long) j); 03501 val_buffer->length(length); 03502 if (zerofill) 03503 prepend_zeros(val_buffer); 03504 return val_buffer; 03505 } 03506 03507 03508 bool Field_long::send_binary(Protocol *protocol) 03509 { 03510 ASSERT_COLUMN_MARKED_FOR_READ; 03511 return protocol->store_long(Field_long::val_int()); 03512 } 03513 03514 int Field_long::cmp(const char *a_ptr, const char *b_ptr) 03515 { 03516 int32 a,b; 03517 #ifdef WORDS_BIGENDIAN 03518 if (table->s->db_low_byte_first) 03519 { 03520 a=sint4korr(a_ptr); 03521 b=sint4korr(b_ptr); 03522 } 03523 else 03524 #endif 03525 { 03526 longget(a,a_ptr); 03527 longget(b,b_ptr); 03528 } 03529 if (unsigned_flag) 03530 return ((uint32) a < (uint32) b) ? -1 : ((uint32) a > (uint32) b) ? 1 : 0; 03531 return (a < b) ? -1 : (a > b) ? 1 : 0; 03532 } 03533 03534 void Field_long::sort_string(char *to,uint length __attribute__((unused))) 03535 { 03536 #ifdef WORDS_BIGENDIAN 03537 if (!table->s->db_low_byte_first) 03538 { 03539 if (unsigned_flag) 03540 to[0] = ptr[0]; 03541 else 03542 to[0] = (char) (ptr[0] ^ 128); /* Revers signbit */ 03543 to[1] = ptr[1]; 03544 to[2] = ptr[2]; 03545 to[3] = ptr[3]; 03546 } 03547 else 03548 #endif 03549 { 03550 if (unsigned_flag) 03551 to[0] = ptr[3]; 03552 else 03553 to[0] = (char) (ptr[3] ^ 128); /* Revers signbit */ 03554 to[1] = ptr[2]; 03555 to[2] = ptr[1]; 03556 to[3] = ptr[0]; 03557 } 03558 } 03559 03560 03561 void Field_long::sql_type(String &res) const 03562 { 03563 CHARSET_INFO *cs=res.charset(); 03564 res.length(cs->cset->snprintf(cs,(char*) res.ptr(),res.alloced_length(), 03565 "int(%d)",(int) field_length)); 03566 add_zerofill_and_unsigned(res); 03567 } 03568 03569 /**************************************************************************** 03570 Field type longlong int (8 bytes) 03571 ****************************************************************************/ 03572 03573 int Field_longlong::store(const char *from,uint len,CHARSET_INFO *cs) 03574 { 03575 ASSERT_COLUMN_MARKED_FOR_WRITE; 03576 longlong tmp; 03577 int error= 0; 03578 char *end; 03579 03580 tmp= cs->cset->scan(cs, from, from+len, MY_SEQ_SPACES); 03581 len-= (uint)tmp; 03582 from+= tmp; 03583 if (unsigned_flag) 03584 { 03585 if (!len || test_if_minus(cs, from, from + len)) 03586 { 03587 tmp=0; // Set negative to 0 03588 error= 1; 03589 } 03590 else 03591 tmp=(longlong) my_strntoull(cs,from,len,10,&end,&error); 03592 } 03593 else 03594 tmp=my_strntoll(cs,from,len,10,&end,&error); 03595 if (error) 03596 { 03597 set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1); 03598 error= 1; 03599 } 03600 else if (from+len != end && table->in_use->count_cuted_fields && 03601 check_int(from,len,end,cs)) 03602 error= 2; 03603 #ifdef WORDS_BIGENDIAN 03604 if (table->s->db_low_byte_first) 03605 { 03606 int8store(ptr,tmp); 03607 } 03608 else 03609 #endif 03610 longlongstore(ptr,tmp); 03611 return error; 03612 } 03613 03614 03615 int Field_longlong::store(double nr) 03616 { 03617 ASSERT_COLUMN_MARKED_FOR_WRITE; 03618 int error= 0; 03619 longlong res; 03620 03621 nr= rint(nr); 03622 if (unsigned_flag) 03623 { 03624 if (nr < 0) 03625 { 03626 res=0; 03627 error= 1; 03628 } 03629 else if (nr >= (double) ULONGLONG_MAX) 03630 { 03631 res= ~(longlong) 0; 03632 error= 1; 03633 } 03634 else 03635 res=(longlong) (ulonglong) nr; 03636 } 03637 else 03638 { 03639 if (nr <= (double) LONGLONG_MIN) 03640 { 03641 res= LONGLONG_MIN; 03642 error= (nr < (double) LONGLONG_MIN); 03643 } 03644 else if (nr >= (double) (ulonglong) LONGLONG_MAX) 03645 { 03646 res= LONGLONG_MAX; 03647 error= (nr > (double) LONGLONG_MAX); 03648 } 03649 else 03650 res=(longlong) nr; 03651 } 03652 if (error) 03653 set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1); 03654 03655 #ifdef WORDS_BIGENDIAN 03656 if (table->s->db_low_byte_first) 03657 { 03658 int8store(ptr,res); 03659 } 03660 else 03661 #endif 03662 longlongstore(ptr,res); 03663 return error; 03664 } 03665 03666 03667 int Field_longlong::store(longlong nr, bool unsigned_val) 03668 { 03669 ASSERT_COLUMN_MARKED_FOR_WRITE; 03670 int error= 0; 03671 03672 if (nr < 0) // Only possible error 03673 { 03674 /* 03675 if field is unsigned and value is signed (< 0) or 03676 if field is signed and value is unsigned we have an overflow 03677 */ 03678 if (unsigned_flag != unsigned_val) 03679 { 03680 nr= unsigned_flag ? (ulonglong) 0 : (ulonglong) LONGLONG_MAX; 03681 set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1); 03682 error= 1; 03683 } 03684 } 03685 03686 #ifdef WORDS_BIGENDIAN 03687 if (table->s->db_low_byte_first) 03688 { 03689 int8store(ptr,nr); 03690 } 03691 else 03692 #endif 03693 longlongstore(ptr,nr); 03694 return error; 03695 } 03696 03697 03698 double Field_longlong::val_real(void) 03699 { 03700 ASSERT_COLUMN_MARKED_FOR_READ; 03701 longlong j; 03702 #ifdef WORDS_BIGENDIAN 03703 if (table->s->db_low_byte_first) 03704 { 03705 j=sint8korr(ptr); 03706 } 03707 else 03708 #endif 03709 longlongget(j,ptr); 03710 /* The following is open coded to avoid a bug in gcc 3.3 */ 03711 if (unsigned_flag) 03712 { 03713 ulonglong tmp= (ulonglong) j; 03714 return ulonglong2double(tmp); 03715 } 03716 return (double) j; 03717 } 03718 03719 03720 longlong Field_longlong::val_int(void) 03721 { 03722 ASSERT_COLUMN_MARKED_FOR_READ; 03723 longlong j; 03724 #ifdef WORDS_BIGENDIAN 03725 if (table->s->db_low_byte_first) 03726 j=sint8korr(ptr); 03727 else 03728 #endif 03729 longlongget(j,ptr); 03730 return j; 03731 } 03732 03733 03734 String *Field_longlong::val_str(String *val_buffer, 03735 String *val_ptr __attribute__((unused))) 03736 { 03737 CHARSET_INFO *cs= &my_charset_bin; 03738 uint length; 03739 uint mlength=max(field_length+1,22*cs->mbmaxlen); 03740 val_buffer->alloc(mlength); 03741 char *to=(char*) val_buffer->ptr(); 03742 longlong j; 03743 #ifdef WORDS_BIGENDIAN 03744 if (table->s->db_low_byte_first) 03745 j=sint8korr(ptr); 03746 else 03747 #endif 03748 longlongget(j,ptr); 03749 03750 length=(uint) (cs->cset->longlong10_to_str)(cs,to,mlength, 03751 unsigned_flag ? 10 : -10, j); 03752 val_buffer->length(length); 03753 if (zerofill) 03754 prepend_zeros(val_buffer); 03755 return val_buffer; 03756 } 03757 03758 03759 bool Field_longlong::send_binary(Protocol *protocol) 03760 { 03761 ASSERT_COLUMN_MARKED_FOR_READ; 03762 return protocol->store_longlong(Field_longlong::val_int(), unsigned_flag); 03763 } 03764 03765 03766 int Field_longlong::cmp(const char *a_ptr, const char *b_ptr) 03767 { 03768 longlong a,b; 03769 #ifdef WORDS_BIGENDIAN 03770 if (table->s->db_low_byte_first) 03771 { 03772 a=sint8korr(a_ptr); 03773 b=sint8korr(b_ptr); 03774 } 03775 else 03776 #endif 03777 { 03778 longlongget(a,a_ptr); 03779 longlongget(b,b_ptr); 03780 } 03781 if (unsigned_flag) 03782 return ((ulonglong) a < (ulonglong) b) ? -1 : 03783 ((ulonglong) a > (ulonglong) b) ? 1 : 0; 03784 return (a < b) ? -1 : (a > b) ? 1 : 0; 03785 } 03786 03787 void Field_longlong::sort_string(char *to,uint length __attribute__((unused))) 03788 { 03789 #ifdef WORDS_BIGENDIAN 03790 if (!table->s->db_low_byte_first) 03791 { 03792 if (unsigned_flag) 03793 to[0] = ptr[0]; 03794 else 03795 to[0] = (char) (ptr[0] ^ 128); /* Revers signbit */ 03796 to[1] = ptr[1]; 03797 to[2] = ptr[2]; 03798 to[3] = ptr[3]; 03799 to[4] = ptr[4]; 03800 to[5] = ptr[5]; 03801 to[6] = ptr[6]; 03802 to[7] = ptr[7]; 03803 } 03804 else 03805 #endif 03806 { 03807 if (unsigned_flag) 03808 to[0] = ptr[7]; 03809 else 03810 to[0] = (char) (ptr[7] ^ 128); /* Revers signbit */ 03811 to[1] = ptr[6]; 03812 to[2] = ptr[5]; 03813 to[3] = ptr[4]; 03814 to[4] = ptr[3]; 03815 to[5] = ptr[2]; 03816 to[6] = ptr[1]; 03817 to[7] = ptr[0]; 03818 } 03819 } 03820 03821 03822 void Field_longlong::sql_type(String &res) const 03823 { 03824 CHARSET_INFO *cs=res.charset(); 03825 res.length(cs->cset->snprintf(cs,(char*) res.ptr(),res.alloced_length(), 03826 "bigint(%d)",(int) field_length)); 03827 add_zerofill_and_unsigned(res); 03828 } 03829 03830 03831 /**************************************************************************** 03832 single precision float 03833 ****************************************************************************/ 03834 03835 int Field_float::store(const char *from,uint len,CHARSET_INFO *cs) 03836 { 03837 int error; 03838 char *end; 03839 double nr= my_strntod(cs,(char*) from,len,&end,&error); 03840 if (error || (!len || (uint) (end-from) != len && 03841 table->in_use->count_cuted_fields)) 03842 { 03843 set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, 03844 (error ? ER_WARN_DATA_OUT_OF_RANGE : WARN_DATA_TRUNCATED), 1); 03845 error= error ? 1 : 2; 03846 } 03847 Field_float::store(nr); 03848 return error; 03849 } 03850 03851 03852 int Field_float::store(double nr) 03853 { 03854 ASSERT_COLUMN_MARKED_FOR_WRITE; 03855 float j; 03856 int error= 0; 03857 03858 if (isnan(nr)) 03859 { 03860 j= 0; 03861 set_null(); 03862 set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1); 03863 error= 1; 03864 } 03865 else if (unsigned_flag && nr < 0) 03866 { 03867 j= 0; 03868 set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1); 03869 error= 1; 03870 } 03871 else 03872 { 03873 double max_value; 03874 if (dec >= NOT_FIXED_DEC) 03875 { 03876 max_value= FLT_MAX; 03877 } 03878 else 03879 { 03880 uint tmp=min(field_length,array_elements(log_10)-1); 03881 max_value= (log_10[tmp]-1)/log_10[dec]; 03882 /* 03883 The following comparison is needed to not get an overflow if nr 03884 is close to FLT_MAX 03885 */ 03886 if (fabs(nr) < FLT_MAX/10.0e+32) 03887 nr= floor(nr*log_10[dec]+0.5)/log_10[dec]; 03888 } 03889 if (nr < -max_value) 03890 { 03891 j= (float)-max_value; 03892 set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1); 03893 error= 1; 03894 } 03895 else if (nr > max_value) 03896 { 03897 j= (float)max_value; 03898 set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1); 03899 error= 1; 03900 } 03901 else 03902 j= (float) nr; 03903 } 03904 03905 #ifdef WORDS_BIGENDIAN 03906 if (table->s->db_low_byte_first) 03907 { 03908 float4store(ptr,j); 03909 } 03910 else 03911 #endif 03912 memcpy_fixed(ptr,(byte*) &j,sizeof(j)); 03913 return error; 03914 } 03915 03916 03917 int Field_float::store(longlong nr, bool unsigned_val) 03918 { 03919 return Field_float::store(unsigned_val ? ulonglong2double((ulonglong) nr) : 03920 (double) nr); 03921 } 03922 03923 03924 double Field_float::val_real(void) 03925 { 03926 ASSERT_COLUMN_MARKED_FOR_READ; 03927 float j; 03928 #ifdef WORDS_BIGENDIAN 03929 if (table->s->db_low_byte_first) 03930 { 03931 float4get(j,ptr); 03932 } 03933 else 03934 #endif 03935 memcpy_fixed((byte*) &j,ptr,sizeof(j)); 03936 return ((double) j); 03937 } 03938 03939 longlong Field_float::val_int(void) 03940 { 03941 float j; 03942 #ifdef WORDS_BIGENDIAN 03943 if (table->s->db_low_byte_first) 03944 { 03945 float4get(j,ptr); 03946 } 03947 else 03948 #endif 03949 memcpy_fixed((byte*) &j,ptr,sizeof(j)); 03950 return (longlong) rint(j); 03951 } 03952 03953 03954 String *Field_float::val_str(String *val_buffer, 03955 String *val_ptr __attribute__((unused))) 03956 { 03957 ASSERT_COLUMN_MARKED_FOR_READ; 03958 float nr; 03959 #ifdef WORDS_BIGENDIAN 03960 if (table->s->db_low_byte_first) 03961 { 03962 float4get(nr,ptr); 03963 } 03964 else 03965 #endif 03966 memcpy_fixed((byte*) &nr,ptr,sizeof(nr)); 03967 03968 uint to_length=max(field_length,70); 03969 val_buffer->alloc(to_length); 03970 char *to=(char*) val_buffer->ptr(); 03971 03972 if (dec >= NOT_FIXED_DEC) 03973 { 03974 sprintf(to,"%-*.*g",(int) field_length,FLT_DIG,nr); 03975 to=strcend(to,' '); 03976 *to=0; 03977 } 03978 else 03979 { 03980 #ifdef HAVE_FCONVERT 03981 char buff[70],*pos=buff; 03982 int decpt,sign,tmp_dec=dec; 03983 03984 VOID(sfconvert(&nr,tmp_dec,&decpt,&sign,buff)); 03985 if (sign) 03986 { 03987 *to++='-'; 03988 } 03989 if (decpt < 0) 03990 { /* val_buffer is < 0 */ 03991 *to++='0'; 03992 if (!tmp_dec) 03993 goto end; 03994 *to++='.'; 03995 if (-decpt > tmp_dec) 03996 decpt= - (int) tmp_dec; 03997 tmp_dec=(uint) ((int) tmp_dec+decpt); 03998 while (decpt++ < 0) 03999 *to++='0'; 04000 } 04001 else if (decpt == 0) 04002 { 04003 *to++= '0'; 04004 if (!tmp_dec) 04005 goto end; 04006 *to++='.'; 04007 } 04008 else 04009 { 04010 while (decpt-- > 0) 04011 *to++= *pos++; 04012 if (!tmp_dec) 04013 goto end; 04014 *to++='.'; 04015 } 04016 while (tmp_dec--) 04017 *to++= *pos++; 04018 #else 04019 #ifdef HAVE_SNPRINTF 04020 to[to_length-1]=0; // Safety 04021 snprintf(to,to_length-1,"%.*f",dec,nr); 04022 to=strend(to); 04023 #else 04024 to+= my_sprintf(to,(to,"%.*f",dec,nr)); 04025 #endif 04026 #endif 04027 } 04028 #ifdef HAVE_FCONVERT 04029 end: 04030 #endif 04031 val_buffer->length((uint) (to-val_buffer->ptr())); 04032 if (zerofill) 04033 prepend_zeros(val_buffer); 04034 return val_buffer; 04035 } 04036 04037 04038 int Field_float::cmp(const char *a_ptr, const char *b_ptr) 04039 { 04040 float a,b; 04041 #ifdef WORDS_BIGENDIAN 04042 if (table->s->db_low_byte_first) 04043 { 04044 float4get(a,a_ptr); 04045 float4get(b,b_ptr); 04046 } 04047 else 04048 #endif 04049 { 04050 memcpy_fixed(&a,a_ptr,sizeof(float)); 04051 memcpy_fixed(&b,b_ptr,sizeof(float)); 04052 } 04053 return (a < b) ? -1 : (a > b) ? 1 : 0; 04054 } 04055 04056 #define FLT_EXP_DIG (sizeof(float)*8-FLT_MANT_DIG) 04057 04058 void Field_float::sort_string(char *to,uint length __attribute__((unused))) 04059 { 04060 float nr; 04061 #ifdef WORDS_BIGENDIAN 04062 if (table->s->db_low_byte_first) 04063 { 04064 float4get(nr,ptr); 04065 } 04066 else 04067 #endif 04068 memcpy_fixed(&nr,ptr,sizeof(float)); 04069 04070 uchar *tmp= (uchar*) to; 04071 if (nr == (float) 0.0) 04072 { /* Change to zero string */ 04073 tmp[0]=(uchar) 128; 04074 bzero((char*) tmp+1,sizeof(nr)-1); 04075 } 04076 else 04077 { 04078 #ifdef WORDS_BIGENDIAN 04079 memcpy_fixed(tmp,&nr,sizeof(nr)); 04080 #else 04081 tmp[0]= ptr[3]; tmp[1]=ptr[2]; tmp[2]= ptr[1]; tmp[3]=ptr[0]; 04082 #endif 04083 if (tmp[0] & 128) /* Negative */ 04084 { /* make complement */ 04085 uint i; 04086 for (i=0 ; i < sizeof(nr); i++) 04087 tmp[i]= (uchar) (tmp[i] ^ (uchar) 255); 04088 } 04089 else 04090 { 04091 ushort exp_part=(((ushort) tmp[0] << 8) | (ushort) tmp[1] | 04092 (ushort) 32768); 04093 exp_part+= (ushort) 1 << (16-1-FLT_EXP_DIG); 04094 tmp[0]= (uchar) (exp_part >> 8); 04095 tmp[1]= (uchar) exp_part; 04096 } 04097 } 04098 } 04099 04100 04101 bool Field_float::send_binary(Protocol *protocol) 04102 { 04103 ASSERT_COLUMN_MARKED_FOR_READ; 04104 return protocol->store((float) Field_float::val_real(), dec, (String*) 0); 04105 } 04106 04107 04108 void Field_float::sql_type(String &res) const 04109 { 04110 if (dec == NOT_FIXED_DEC) 04111 { 04112 res.set_ascii(STRING_WITH_LEN("float")); 04113 } 04114 else 04115 { 04116 CHARSET_INFO *cs= res.charset(); 04117 res.length(cs->cset->snprintf(cs,(char*) res.ptr(),res.alloced_length(), 04118 "float(%d,%d)",(int) field_length,dec)); 04119 } 04120 add_zerofill_and_unsigned(res); 04121 } 04122 04123 04124 /**************************************************************************** 04125 double precision floating point numbers 04126 ****************************************************************************/ 04127 04128 int Field_double::store(const char *from,uint len,CHARSET_INFO *cs) 04129 { 04130 int error; 04131 char *end; 04132 double nr= my_strntod(cs,(char*) from, len, &end, &error); 04133 if (error || (!len || (uint) (end-from) != len && 04134 table->in_use->count_cuted_fields)) 04135 { 04136 set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, 04137 (error ? ER_WARN_DATA_OUT_OF_RANGE : WARN_DATA_TRUNCATED), 1); 04138 error= error ? 1 : 2; 04139 } 04140 Field_double::store(nr); 04141 return error; 04142 } 04143 04144 04145 int Field_double::store(double nr) 04146 { 04147 ASSERT_COLUMN_MARKED_FOR_WRITE; 04148 int error= 0; 04149 04150 if (isnan(nr)) 04151 { 04152 nr= 0; 04153 set_null(); 04154 set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1); 04155 error= 1; 04156 } 04157 else if (unsigned_flag && nr < 0) 04158 { 04159 nr= 0; 04160 set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1); 04161 error= 1; 04162 } 04163 else 04164 { 04165 double max_value; 04166 if (dec >= NOT_FIXED_DEC) 04167 { 04168 max_value= DBL_MAX; 04169 } 04170 else 04171 { 04172 uint tmp=min(field_length,array_elements(log_10)-1); 04173 max_value= (log_10[tmp]-1)/log_10[dec]; 04174 if (fabs(nr) < DBL_MAX/10.0e+32) 04175 nr= floor(nr*log_10[dec]+0.5)/log_10[dec]; 04176 } 04177 if (nr < -max_value) 04178 { 04179 nr= -max_value; 04180 set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1); 04181 error= 1; 04182 } 04183 else if (nr > max_value) 04184 { 04185 nr= max_value; 04186 set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1); 04187 error= 1; 04188 } 04189 } 04190 04191 #ifdef WORDS_BIGENDIAN 04192 if (table->s->db_low_byte_first) 04193 { 04194 float8store(ptr,nr); 04195 } 04196 else 04197 #endif 04198 doublestore(ptr,nr); 04199 return error; 04200 } 04201 04202 04203 int Field_double::store(longlong nr, bool unsigned_val) 04204 { 04205 return Field_double::store(unsigned_val ? ulonglong2double((ulonglong) nr) : 04206 (double) nr); 04207 } 04208 04209 04210 int Field_real::store_decimal(const my_decimal *dm) 04211 { 04212 double dbl; 04213 my_decimal2double(E_DEC_FATAL_ERROR, dm, &dbl); 04214 return store(dbl); 04215 } 04216 04217 double Field_double::val_real(void) 04218 { 04219 ASSERT_COLUMN_MARKED_FOR_READ; 04220 double j; 04221 #ifdef WORDS_BIGENDIAN 04222 if (table->s->db_low_byte_first) 04223 { 04224 float8get(j,ptr); 04225 } 04226 else 04227 #endif 04228 doubleget(j,ptr); 04229 return j; 04230 } 04231 04232 longlong Field_double::val_int(void) 04233 { 04234 ASSERT_COLUMN_MARKED_FOR_READ; 04235 double j; 04236 longlong res; 04237 #ifdef WORDS_BIGENDIAN 04238 if (table->s->db_low_byte_first) 04239 { 04240 float8get(j,ptr); 04241 } 04242 else 04243 #endif 04244 doubleget(j,ptr); 04245 /* Check whether we fit into longlong range */ 04246 if (j <= (double) LONGLONG_MIN) 04247 { 04248 res= (longlong) LONGLONG_MIN; 04249 goto warn; 04250 } 04251 if (j >= (double) (ulonglong) LONGLONG_MAX) 04252 { 04253 res= (longlong) LONGLONG_MAX; 04254 goto warn; 04255 } 04256 return (longlong) rint(j); 04257 04258 warn: 04259 { 04260 char buf[DOUBLE_TO_STRING_CONVERSION_BUFFER_SIZE]; 04261 String tmp(buf, sizeof(buf), &my_charset_latin1), *str; 04262 str= val_str(&tmp, 0); 04263 push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, 04264 ER_TRUNCATED_WRONG_VALUE, 04265 ER(ER_TRUNCATED_WRONG_VALUE), "INTEGER", 04266 str->c_ptr()); 04267 } 04268 return res; 04269 } 04270 04271 04272 my_decimal *Field_real::val_decimal(my_decimal *decimal_value) 04273 { 04274 ASSERT_COLUMN_MARKED_FOR_READ; 04275 double2my_decimal(E_DEC_FATAL_ERROR, val_real(), decimal_value); 04276 return decimal_value; 04277 } 04278 04279 04280 String *Field_double::val_str(String *val_buffer, 04281 String *val_ptr __attribute__((unused))) 04282 { 04283 ASSERT_COLUMN_MARKED_FOR_READ; 04284 double nr; 04285 #ifdef WORDS_BIGENDIAN 04286 if (table->s->db_low_byte_first) 04287 { 04288 float8get(nr,ptr); 04289 } 04290 else 04291 #endif 04292 doubleget(nr,ptr); 04293 04294 uint to_length=max(field_length, DOUBLE_TO_STRING_CONVERSION_BUFFER_SIZE); 04295 val_buffer->alloc(to_length); 04296 char *to=(char*) val_buffer->ptr(); 04297 04298 if (dec >= NOT_FIXED_DEC) 04299 { 04300 sprintf(to,"%-*.*g",(int) field_length,DBL_DIG,nr); 04301 to=strcend(to,' '); 04302 } 04303 else 04304 { 04305 #ifdef HAVE_FCONVERT 04306 char buff[DOUBLE_TO_STRING_CONVERSION_BUFFER_SIZE]; 04307 char *pos= buff; 04308 int decpt,sign,tmp_dec=dec; 04309 04310 VOID(fconvert(nr,tmp_dec,&decpt,&sign,buff)); 04311 if (sign) 04312 { 04313 *to++='-'; 04314 } 04315 if (decpt < 0) 04316 { /* val_buffer is < 0 */ 04317 *to++='0'; 04318 if (!tmp_dec) 04319 goto end; 04320 *to++='.'; 04321 if (-decpt > tmp_dec) 04322 decpt= - (int) tmp_dec; 04323 tmp_dec=(uint) ((int) tmp_dec+decpt); 04324 while (decpt++ < 0) 04325 *to++='0'; 04326 } 04327 else if (decpt == 0) 04328 { 04329 *to++= '0'; 04330 if (!tmp_dec) 04331 goto end; 04332 *to++='.'; 04333 } 04334 else 04335 { 04336 while (decpt-- > 0) 04337 *to++= *pos++; 04338 if (!tmp_dec) 04339 goto end; 04340 *to++='.'; 04341 } 04342 while (tmp_dec--) 04343 *to++= *pos++; 04344 #else 04345 #ifdef HAVE_SNPRINTF 04346 to[to_length-1]=0; // Safety 04347 snprintf(to,to_length-1,"%.*f",dec,nr); 04348 to=strend(to); 04349 #else 04350 to+= my_sprintf(to,(to,"%.*f",dec,nr)); 04351 #endif 04352 #endif 04353 } 04354 #ifdef HAVE_FCONVERT 04355 end: 04356 #endif 04357 04358 val_buffer->length((uint) (to-val_buffer->ptr())); 04359 if (zerofill) 04360 prepend_zeros(val_buffer); 04361 return val_buffer; 04362 } 04363 04364 bool Field_double::send_binary(Protocol *protocol) 04365 { 04366 return protocol->store((double) Field_double::val_real(), dec, (String*) 0); 04367 } 04368 04369 04370 int Field_double::cmp(const char *a_ptr, const char *b_ptr) 04371 { 04372 ASSERT_COLUMN_MARKED_FOR_READ; 04373 double a,b; 04374 #ifdef WORDS_BIGENDIAN 04375 if (table->s->db_low_byte_first) 04376 { 04377 float8get(a,a_ptr); 04378 float8get(b,b_ptr); 04379 } 04380 else 04381 #endif 04382 { 04383 doubleget(a, a_ptr); 04384 doubleget(b, b_ptr); 04385 } 04386 return (a < b) ? -1 : (a > b) ? 1 : 0; 04387 } 04388 04389 04390 #define DBL_EXP_DIG (sizeof(double)*8-DBL_MANT_DIG) 04391 04392 /* The following should work for IEEE */ 04393 04394 void Field_double::sort_string(char *to,uint length __attribute__((unused))) 04395 { 04396 double nr; 04397 #ifdef WORDS_BIGENDIAN 04398 if (table->s->db_low_byte_first) 04399 { 04400 float8get(nr,ptr); 04401 } 04402 else 04403 #endif 04404 doubleget(nr,ptr); 04405 change_double_for_sort(nr, (byte*) to); 04406 } 04407 04408 04409 void Field_double::sql_type(String &res) const 04410 { 04411 CHARSET_INFO *cs=res.charset(); 04412 if (dec == NOT_FIXED_DEC) 04413 { 04414 res.set_ascii(STRING_WITH_LEN("double")); 04415 } 04416 else 04417 { 04418 res.length(cs->cset->snprintf(cs,(char*) res.ptr(),res.alloced_length(), 04419 "double(%d,%d)",(int) field_length,dec)); 04420 } 04421 add_zerofill_and_unsigned(res); 04422 } 04423 04424 04425 /* 04426 TIMESTAMP type. 04427 Holds datetime values in range from 1970-01-01 00:00:01 UTC to 04428 2038-01-01 00:00:00 UTC stored as number of seconds since Unix 04429 Epoch in UTC. 04430 04431 Up to one of timestamps columns in the table can be automatically 04432 set on row update and/or have NOW() as default value. 04433 TABLE::timestamp_field points to Field object for such timestamp with 04434 auto-set-on-update. TABLE::time_stamp holds offset in record + 1 for this 04435 field, and is used by handler code which performs updates required. 04436 04437 Actually SQL-99 says that we should allow niladic functions (like NOW()) 04438 as defaults for any field. Current limitations (only NOW() and only 04439 for one TIMESTAMP field) are because of restricted binary .frm format 04440 and should go away in the future. 04441 04442 Also because of this limitation of binary .frm format we use 5 different 04443 unireg_check values with TIMESTAMP field to distinguish various cases of 04444 DEFAULT or ON UPDATE values. These values are: 04445 04446 TIMESTAMP_OLD_FIELD - old timestamp, if there was not any fields with 04447 auto-set-on-update (or now() as default) in this table before, then this 04448 field has NOW() as default and is updated when row changes, else it is 04449 field which has 0 as default value and is not automatically updated. 04450 TIMESTAMP_DN_FIELD - field with NOW() as default but not set on update 04451 automatically (TIMESTAMP DEFAULT NOW()) 04452 TIMESTAMP_UN_FIELD - field which is set on update automatically but has not 04453 NOW() as default (but it may has 0 or some other const timestamp as 04454 default) (TIMESTAMP ON UPDATE NOW()). 04455 TIMESTAMP_DNUN_FIELD - field which has now() as default and is auto-set on 04456 update. (TIMESTAMP DEFAULT NOW() ON UPDATE NOW()) 04457 NONE - field which is not auto-set on update with some other than NOW() 04458 default value (TIMESTAMP DEFAULT 0). 04459 04460 Note that TIMESTAMP_OLD_FIELD's are never created explicitly now, they are 04461 left only for preserving ability to read old tables. Such fields replaced 04462 with their newer analogs in CREATE TABLE and in SHOW CREATE TABLE. This is 04463 because we want to prefer NONE unireg_check before TIMESTAMP_OLD_FIELD for 04464 "TIMESTAMP DEFAULT 'Const'" field. (Old timestamps allowed such 04465 specification too but ignored default value for first timestamp, which of 04466 course is non-standard.) In most cases user won't notice any change, only 04467 exception is different behavior of old/new timestamps during ALTER TABLE. 04468 */ 04469 04470 Field_timestamp::Field_timestamp(char *ptr_arg, uint32 len_arg, 04471 uchar *null_ptr_arg, uchar null_bit_arg, 04472 enum utype unireg_check_arg, 04473 const char *field_name_arg, 04474 TABLE_SHARE *share, 04475 CHARSET_INFO *cs) 04476 :Field_str(ptr_arg, 19, null_ptr_arg, null_bit_arg, 04477 unireg_check_arg, field_name_arg, cs) 04478 { 04479 /* For 4.0 MYD and 4.0 InnoDB compatibility */ 04480 flags|= ZEROFILL_FLAG | UNSIGNED_FLAG; 04481 if (!share->timestamp_field && unireg_check != NONE) 04482 { 04483 /* This timestamp has auto-update */ 04484 share->timestamp_field= this; 04485 flags|= TIMESTAMP_FLAG; 04486 } 04487 } 04488 04489 04490 Field_timestamp::Field_timestamp(bool maybe_null_arg, 04491 const char *field_name_arg, 04492 CHARSET_INFO *cs) 04493 :Field_str((char*) 0, 19, maybe_null_arg ? (uchar*) "": 0, 0, 04494 NONE, field_name_arg, cs) 04495 { 04496 /* For 4.0 MYD and 4.0 InnoDB compatibility */ 04497 flags|= ZEROFILL_FLAG | UNSIGNED_FLAG; 04498 } 04499 04500 04501 /* 04502 Get auto-set type for TIMESTAMP field. 04503 04504 SYNOPSIS 04505 get_auto_set_type() 04506 04507 DESCRIPTION 04508 Returns value indicating during which operations this TIMESTAMP field 04509 should be auto-set to current timestamp. 04510 */ 04511 timestamp_auto_set_type Field_timestamp::get_auto_set_type() const 04512 { 04513 switch (unireg_check) 04514 { 04515 case TIMESTAMP_DN_FIELD: 04516 return TIMESTAMP_AUTO_SET_ON_INSERT; 04517 case TIMESTAMP_UN_FIELD: 04518 return TIMESTAMP_AUTO_SET_ON_UPDATE; 04519 case TIMESTAMP_OLD_FIELD: 04520 /* 04521 Although we can have several such columns in legacy tables this 04522 function should be called only for first of them (i.e. the one 04523 having auto-set property). 04524 */ 04525 DBUG_ASSERT(table->timestamp_field == this); 04526 /* Fall-through */ 04527 case TIMESTAMP_DNUN_FIELD: 04528 return TIMESTAMP_AUTO_SET_ON_BOTH; 04529 default: 04530 /* 04531 Normally this function should not be called for TIMESTAMPs without 04532 auto-set property. 04533 */ 04534 DBUG_ASSERT(0); 04535 return TIMESTAMP_NO_AUTO_SET; 04536 } 04537 } 04538 04539 04540 int Field_timestamp::store(const char *from,uint len,CHARSET_INFO *cs) 04541 { 04542 ASSERT_COLUMN_MARKED_FOR_WRITE; 04543 TIME l_time; 04544 my_time_t tmp= 0; 04545 int error; 04546 bool have_smth_to_conv; 04547 my_bool in_dst_time_gap; 04548 THD *thd= table ? table->in_use : current_thd; 04549 04550 /* We don't want to store invalid or fuzzy datetime values in TIMESTAMP */ 04551 have_smth_to_conv= (str_to_datetime(from, len, &l_time, 04552 (thd->variables.sql_mode & 04553 MODE_NO_ZERO_DATE) | 04554 MODE_NO_ZERO_IN_DATE, &error) > 04555 MYSQL_TIMESTAMP_ERROR); 04556 04557 if (error || !have_smth_to_conv) 04558 { 04559 error= 1; 04560 set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, 04561 from, len, MYSQL_TIMESTAMP_DATETIME, 1); 04562 } 04563 04564 /* Only convert a correct date (not a zero date) */ 04565 if (have_smth_to_conv && l_time.month) 04566 { 04567 if (!(tmp= TIME_to_timestamp(thd, &l_time, &in_dst_time_gap))) 04568 { 04569 set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, 04570 ER_WARN_DATA_OUT_OF_RANGE, 04571 from, len, MYSQL_TIMESTAMP_DATETIME, !error); 04572 error= 1; 04573 } 04574 else if (in_dst_time_gap) 04575 { 04576 set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, 04577 ER_WARN_INVALID_TIMESTAMP, 04578 from, len, MYSQL_TIMESTAMP_DATETIME, !error); 04579 error= 1; 04580 } 04581 } 04582 04583 #ifdef WORDS_BIGENDIAN 04584 if (table && table->s->db_low_byte_first) 04585 { 04586 int4store(ptr,tmp); 04587 } 04588 else 04589 #endif 04590 longstore(ptr,tmp); 04591 return error; 04592 } 04593 04594 04595 int Field_timestamp::store(double nr) 04596 { 04597 int error= 0; 04598 if (nr < 0 || nr > 99991231235959.0) 04599 { 04600 set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, 04601 ER_WARN_DATA_OUT_OF_RANGE, 04602 nr, MYSQL_TIMESTAMP_DATETIME); 04603 nr= 0; // Avoid overflow on buff 04604 error= 1; 04605 } 04606 error|= Field_timestamp::store((longlong) rint(nr), FALSE); 04607 return error; 04608 } 04609 04610 04611 int Field_timestamp::store(longlong nr, bool unsigned_val) 04612 { 04613 ASSERT_COLUMN_MARKED_FOR_WRITE; 04614 TIME l_time; 04615 my_time_t timestamp= 0; 04616 int error; 04617 my_bool in_dst_time_gap; 04618 THD *thd= table ? table->in_use : current_thd; 04619 04620 /* We don't want to store invalid or fuzzy datetime values in TIMESTAMP */ 04621 longlong tmp= number_to_datetime(nr, &l_time, (thd->variables.sql_mode & 04622 MODE_NO_ZERO_DATE) | 04623 MODE_NO_ZERO_IN_DATE, &error); 04624 if (tmp == LL(-1)) 04625 { 04626 error= 2; 04627 } 04628 04629 if (!error && tmp) 04630 { 04631 if (!(timestamp= TIME_to_timestamp(thd, &l_time, &in_dst_time_gap))) 04632 { 04633 set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, 04634 ER_WARN_DATA_OUT_OF_RANGE, 04635 nr, MYSQL_TIMESTAMP_DATETIME, 1); 04636 error= 1; 04637 } 04638 if (in_dst_time_gap) 04639 { 04640 set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, 04641 ER_WARN_INVALID_TIMESTAMP, 04642 nr, MYSQL_TIMESTAMP_DATETIME, 1); 04643 error= 1; 04644 } 04645 } else if (error) 04646 set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, 04647 WARN_DATA_TRUNCATED, 04648 nr, MYSQL_TIMESTAMP_DATETIME, 1); 04649 04650 #ifdef WORDS_BIGENDIAN 04651 if (table && table->s->db_low_byte_first) 04652 { 04653 int4store(ptr,timestamp); 04654 } 04655 else 04656 #endif 04657 longstore(ptr,(uint32) timestamp); 04658 04659 return error; 04660 } 04661 04662 04663 double Field_timestamp::val_real(void) 04664 { 04665 ASSERT_COLUMN_MARKED_FOR_READ; 04666 return (double) Field_timestamp::val_int(); 04667 } 04668 04669 longlong Field_timestamp::val_int(void) 04670 { 04671 ASSERT_COLUMN_MARKED_FOR_READ; 04672 uint32 temp; 04673 TIME time_tmp; 04674 THD *thd= table ? table->in_use : current_thd; 04675 04676 #ifdef WORDS_BIGENDIAN 04677 if (table && table->s->db_low_byte_first) 04678 temp=uint4korr(ptr); 04679 else 04680 #endif 04681 longget(temp,ptr); 04682 04683 if (temp == 0L) // No time 04684 return(0); /* purecov: inspected */ 04685 04686 thd->variables.time_zone->gmt_sec_to_TIME(&time_tmp, (my_time_t)temp); 04687 thd->time_zone_used= 1; 04688 04689 return time_tmp.year * LL(10000000000) + time_tmp.month * LL(100000000) + 04690 time_tmp.day * 1000000L + time_tmp.hour * 10000L + 04691 time_tmp.minute * 100 + time_tmp.second; 04692 } 04693 04694 04695 String *Field_timestamp::val_str(String *val_buffer, String *val_ptr) 04696 { 04697 ASSERT_COLUMN_MARKED_FOR_READ; 04698 uint32 temp, temp2; 04699 TIME time_tmp; 04700 THD *thd= table ? table->in_use : current_thd; 04701 char *to; 04702 04703 val_buffer->alloc(field_length+1); 04704 to= (char*) val_buffer->ptr(); 04705 val_buffer->length(field_length); 04706 04707 #ifdef WORDS_BIGENDIAN 04708 if (table && table->s->db_low_byte_first) 04709 temp=uint4korr(ptr); 04710 else 04711 #endif 04712 longget(temp,ptr); 04713 04714 if (temp == 0L) 04715 { /* Zero time is "000000" */ 04716 val_ptr->set(STRING_WITH_LEN("0000-00-00 00:00:00"), &my_charset_bin); 04717 return val_ptr; 04718 } 04719 val_buffer->set_charset(&my_charset_bin); // Safety 04720 04721 thd->variables.time_zone->gmt_sec_to_TIME(&time_tmp,(my_time_t)temp); 04722 thd->time_zone_used= 1; 04723 04724 temp= time_tmp.year % 100; 04725 if (temp < YY_PART_YEAR - 1) 04726 { 04727 *to++= '2'; 04728 *to++= '0'; 04729 } 04730 else 04731 { 04732 *to++= '1'; 04733 *to++= '9'; 04734 } 04735 temp2=temp/10; temp=temp-temp2*10; 04736 *to++= (char) ('0'+(char) (temp2)); 04737 *to++= (char) ('0'+(char) (temp)); 04738 *to++= '-'; 04739 temp=time_tmp.month; 04740 temp2=temp/10; temp=temp-temp2*10; 04741 *to++= (char) ('0'+(char) (temp2)); 04742 *to++= (char) ('0'+(char) (temp)); 04743 *to++= '-'; 04744 temp=time_tmp.day; 04745 temp2=temp/10; temp=temp-temp2*10; 04746 *to++= (char) ('0'+(char) (temp2)); 04747 *to++= (char) ('0'+(char) (temp)); 04748 *to++= ' '; 04749 temp=time_tmp.hour; 04750 temp2=temp/10; temp=temp-temp2*10; 04751 *to++= (char) ('0'+(char) (temp2)); 04752 *to++= (char) ('0'+(char) (temp)); 04753 *to++= ':'; 04754 temp=time_tmp.minute; 04755 temp2=temp/10; temp=temp-temp2*10; 04756 *to++= (char) ('0'+(char) (temp2)); 04757 *to++= (char) ('0'+(char) (temp)); 04758 *to++= ':'; 04759 temp=time_tmp.second; 04760 temp2=temp/10; temp=temp-temp2*10; 04761 *to++= (char) ('0'+(char) (temp2)); 04762 *to++= (char) ('0'+(char) (temp)); 04763 *to= 0; 04764 return val_buffer; 04765 } 04766 04767 04768 bool Field_timestamp::get_date(TIME *ltime, uint fuzzydate) 04769 { 04770 long temp; 04771 THD *thd= table ? table->in_use : current_thd; 04772 #ifdef WORDS_BIGENDIAN 04773 if (table && table->s->db_low_byte_first) 04774 temp=uint4korr(ptr); 04775 else 04776 #endif 04777 longget(temp,ptr); 04778 if (temp == 0L) 04779 { /* Zero time is "000000" */ 04780 if (fuzzydate & TIME_NO_ZERO_DATE) 04781 return 1; 04782 bzero((char*) ltime,sizeof(*ltime)); 04783 } 04784 else 04785 { 04786 thd->variables.time_zone->gmt_sec_to_TIME(ltime, (my_time_t)temp); 04787 thd->time_zone_used= 1; 04788 } 04789 return 0; 04790 } 04791 04792 bool Field_timestamp::get_time(TIME *ltime) 04793 { 04794 return Field_timestamp::get_date(ltime,0); 04795 } 04796 04797 04798 bool Field_timestamp::send_binary(Protocol *protocol) 04799 { 04800 TIME tm; 04801 Field_timestamp::get_date(&tm, 0); 04802 return protocol->store(&tm); 04803 } 04804 04805 04806 int Field_timestamp::cmp(const char *a_ptr, const char *b_ptr) 04807 { 04808 int32 a,b; 04809 #ifdef WORDS_BIGENDIAN 04810 if (table && table->s->db_low_byte_first) 04811 { 04812 a=sint4korr(a_ptr); 04813 b=sint4korr(b_ptr); 04814 } 04815 else 04816 #endif 04817 { 04818 longget(a,a_ptr); 04819 longget(b,b_ptr); 04820 } 04821 return ((uint32) a < (uint32) b) ? -1 : ((uint32) a > (uint32) b) ? 1 : 0; 04822 } 04823 04824 04825 void Field_timestamp::sort_string(char *to,uint length __attribute__((unused))) 04826 { 04827 #ifdef WORDS_BIGENDIAN 04828 if (!table || !table->s->db_low_byte_first) 04829 { 04830 to[0] = ptr[0]; 04831 to[1] = ptr[1]; 04832 to[2] = ptr[2]; 04833 to[3] = ptr[3]; 04834 } 04835 else 04836 #endif 04837 { 04838 to[0] = ptr[3]; 04839 to[1] = ptr[2]; 04840 to[2] = ptr[1]; 04841 to[3] = ptr[0]; 04842 } 04843 } 04844 04845 04846 void Field_timestamp::sql_type(String &res) const 04847 { 04848 res.set_ascii(STRING_WITH_LEN("timestamp")); 04849 } 04850 04851 04852 void Field_timestamp::set_time() 04853 { 04854 THD *thd= table ? table->in_use : current_thd; 04855 long tmp= (long) thd->query_start(); 04856 set_notnull(); 04857 #ifdef WORDS_BIGENDIAN 04858 if (table && table->s->db_low_byte_first) 04859 { 04860 int4store(ptr,tmp); 04861 } 04862 else 04863 #endif 04864 longstore(ptr,tmp); 04865 } 04866 04867 /**************************************************************************** 04868 ** time type 04869 ** In string context: HH:MM:SS 04870 ** In number context: HHMMSS 04871 ** Stored as a 3 byte unsigned int 04872 ****************************************************************************/ 04873 04874 int Field_time::store(const char *from,uint len,CHARSET_INFO *cs) 04875 { 04876 TIME ltime; 04877 long tmp; 04878 int error; 04879 04880 if (str_to_time(from, len, <ime, &error)) 04881 { 04882 tmp=0L; 04883 error= 2; 04884 set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, 04885 from, len, MYSQL_TIMESTAMP_TIME, 1); 04886 } 04887 else 04888 { 04889 if (error) 04890 set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, 04891 WARN_DATA_TRUNCATED, 04892 from, len, MYSQL_TIMESTAMP_TIME, 1); 04893 04894 if (ltime.month) 04895 ltime.day=0; 04896 tmp=(ltime.day*24L+ltime.hour)*10000L+(ltime.minute*100+ltime.second); 04897 if (tmp > 8385959) 04898 { 04899 tmp=8385959; 04900 set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, 04901 ER_WARN_DATA_OUT_OF_RANGE, 04902 from, len, MYSQL_TIMESTAMP_TIME, !error); 04903 error= 1; 04904 } 04905 if (error > 1) 04906 error= 2; 04907 } 04908 04909 if (ltime.neg) 04910 tmp= -tmp; 04911 error |= Field_time::store((longlong) tmp, FALSE); 04912 return error; 04913 } 04914 04915 04916 int Field_time::store_time(TIME *ltime, timestamp_type type) 04917 { 04918 long tmp= ((ltime->month ? 0 : ltime->day * 24L) + ltime->hour) * 10000L + 04919 (ltime->minute * 100 + ltime->second); 04920 if (ltime->neg) 04921 tmp= -tmp; 04922 return Field_time::store((longlong) tmp, TRUE); 04923 } 04924 04925 04926 int Field_time::store(double nr) 04927 { 04928 ASSERT_COLUMN_MARKED_FOR_WRITE; 04929 long tmp; 04930 int error= 0; 04931 if (nr > 8385959.0) 04932 { 04933 tmp=8385959L; 04934 set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, 04935 ER_WARN_DATA_OUT_OF_RANGE, nr, MYSQL_TIMESTAMP_TIME); 04936 error= 1; 04937 } 04938 else if (nr < -8385959.0) 04939 { 04940 tmp= -8385959L; 04941 set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, 04942 ER_WARN_DATA_OUT_OF_RANGE, nr, MYSQL_TIMESTAMP_TIME); 04943 error= 1; 04944 } 04945 else 04946 { 04947 tmp=(long) floor(fabs(nr)); // Remove fractions 04948 if (nr < 0) 04949 tmp= -tmp; 04950 if (tmp % 100 > 59 || tmp/100 % 100 > 59) 04951 { 04952 tmp=0; 04953 set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, 04954 ER_WARN_DATA_OUT_OF_RANGE, nr, 04955 MYSQL_TIMESTAMP_TIME); 04956 error= 1; 04957 } 04958 } 04959 int3store(ptr,tmp); 04960 return error; 04961 } 04962 04963 04964 int Field_time::store(longlong nr, bool unsigned_val) 04965 { 04966 ASSERT_COLUMN_MARKED_FOR_WRITE; 04967 long tmp; 04968 int error= 0; 04969 if (nr < (longlong) -8385959L && !unsigned_val) 04970 { 04971 tmp= -8385959L; 04972 set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, 04973 ER_WARN_DATA_OUT_OF_RANGE, nr, 04974 MYSQL_TIMESTAMP_TIME, 1); 04975 error= 1; 04976 } 04977 else if (nr > (longlong) 8385959 || nr < 0 && unsigned_val) 04978 { 04979 tmp=8385959L; 04980 set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, 04981 ER_WARN_DATA_OUT_OF_RANGE, nr, 04982 MYSQL_TIMESTAMP_TIME, 1); 04983 error= 1; 04984 } 04985 else 04986 { 04987 tmp=(long) nr; 04988 if (tmp % 100 > 59 || tmp/100 % 100 > 59) 04989 { 04990 tmp=0; 04991 set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, 04992 ER_WARN_DATA_OUT_OF_RANGE, nr, 04993 MYSQL_TIMESTAMP_TIME, 1); 04994 error= 1; 04995 } 04996 } 04997 int3store(ptr,tmp); 04998 return error; 04999 } 05000 05001 05002 double Field_time::val_real(void) 05003 { 05004 ASSERT_COLUMN_MARKED_FOR_READ; 05005 uint32 j= (uint32) uint3korr(ptr); 05006 return (double) j; 05007 } 05008 05009 longlong Field_time::val_int(void) 05010 { 05011 ASSERT_COLUMN_MARKED_FOR_READ; 05012 return (longlong) sint3korr(ptr); 05013 } 05014 05015 05016 /* 05017 This function is multi-byte safe as the result string is always of type 05018 my_charset_bin 05019 */ 05020 05021 String *Field_time::val_str(String *val_buffer, 05022 String *val_ptr __attribute__((unused))) 05023 { 05024 ASSERT_COLUMN_MARKED_FOR_READ; 05025 TIME ltime; 05026 val_buffer->alloc(19); 05027 long tmp=(long) sint3korr(ptr); 05028 ltime.neg= 0; 05029 if (tmp < 0) 05030 { 05031 tmp= -tmp; 05032 ltime.neg= 1; 05033 } 05034 ltime.day= (uint) 0; 05035 ltime.hour= (uint) (tmp/10000); 05036 ltime.minute= (uint) (tmp/100 % 100); 05037 ltime.second= (uint) (tmp % 100); 05038 make_time((DATE_TIME_FORMAT*) 0, <ime, val_buffer); 05039 return val_buffer; 05040 } 05041 05042 05043 /* 05044 Normally we would not consider 'time' as a valid date, but we allow 05045 get_date() here to be able to do things like 05046 DATE_FORMAT(time, "%l.%i %p") 05047 */ 05048 05049 bool Field_time::get_date(TIME *ltime, uint fuzzydate) 05050 { 05051 long tmp; 05052 THD *thd= table ? table->in_use : current_thd; 05053 if (!(fuzzydate & TIME_FUZZY_DATE)) 05054 { 05055 push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, 05056 ER_WARN_DATA_OUT_OF_RANGE, 05057 ER(ER_WARN_DATA_OUT_OF_RANGE), field_name, 05058 thd->row_count); 05059 return 1; 05060 } 05061 tmp=(long) sint3korr(ptr); 05062 ltime->neg=0; 05063 if (tmp < 0) 05064 { 05065 ltime->neg= 1; 05066 tmp=-tmp; 05067 } 05068 ltime->hour=tmp/10000; 05069 tmp-=ltime->hour*10000; 05070 ltime->minute= tmp/100; 05071 ltime->second= tmp % 100; 05072 ltime->year= ltime->month= ltime->day= ltime->second_part= 0; 05073 return 0; 05074 } 05075 05076 05077 bool Field_time::get_time(TIME *ltime) 05078 { 05079 long tmp=(long) sint3korr(ptr); 05080 ltime->neg=0; 05081 if (tmp < 0) 05082 { 05083 ltime->neg= 1; 05084 tmp=-tmp; 05085 } 05086 ltime->day= 0; 05087 ltime->hour= (int) (tmp/10000); 05088 tmp-=ltime->hour*10000; 05089 ltime->minute= (int) tmp/100; 05090 ltime->second= (int) tmp % 100; 05091 ltime->second_part=0; 05092 ltime->time_type= MYSQL_TIMESTAMP_TIME; 05093 return 0; 05094 } 05095 05096 05097 bool Field_time::send_binary(Protocol *protocol) 05098 { 05099 TIME tm; 05100 Field_time::get_time(&tm); 05101 tm.day= tm.hour/24; // Move hours to days 05102 tm.hour-= tm.day*24; 05103 return protocol->store_time(&tm); 05104 } 05105 05106 05107 int Field_time::cmp(const char *a_ptr, const char *b_ptr) 05108 { 05109 int32 a,b; 05110 a=(int32) sint3korr(a_ptr); 05111 b=(int32) sint3korr(b_ptr); 05112 return (a < b) ? -1 : (a > b) ? 1 : 0; 05113 } 05114 05115 void Field_time::sort_string(char *to,uint length __attribute__((unused))) 05116 { 05117 to[0] = (uchar) (ptr[2] ^ 128); 05118 to[1] = ptr[1]; 05119 to[2] = ptr[0]; 05120 } 05121 05122 void Field_time::sql_type(String &res) const 05123 { 05124 res.set_ascii(STRING_WITH_LEN("time")); 05125 } 05126 05127 /**************************************************************************** 05128 ** year type 05129 ** Save in a byte the year 0, 1901->2155 05130 ** Can handle 2 byte or 4 byte years! 05131 ****************************************************************************/ 05132 05133 int Field_year::store(const char *from, uint len,CHARSET_INFO *cs) 05134 { 05135 ASSERT_COLUMN_MARKED_FOR_WRITE; 05136 char *end; 05137 int error; 05138 long nr= my_strntol(cs, from, len, 10, &end, &error); 05139 05140 if (nr < 0 || nr >= 100 && nr <= 1900 || nr > 2155 || error) 05141 { 05142 *ptr=0; 05143 set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1); 05144 return 1; 05145 } 05146 if (table->in_use->count_cuted_fields && check_int(from,len,end,cs)) 05147 error= 1; 05148 05149 if (nr != 0 || len != 4) 05150 { 05151 if (nr < YY_PART_YEAR) 05152 nr+=100; // 2000 - 2069 05153 else if (nr > 1900) 05154 nr-= 1900; 05155 } 05156 *ptr= (char) (uchar) nr; 05157 return error; 05158 } 05159 05160 05161 int Field_year::store(double nr) 05162 { 05163 if (nr < 0.0 || nr >= 2155.0) 05164 { 05165 (void) Field_year::store((longlong) -1, FALSE); 05166 return 1; 05167 } 05168 return Field_year::store((longlong) nr, FALSE); 05169 } 05170 05171 05172 int Field_year::store(longlong nr, bool unsigned_val) 05173 { 05174 ASSERT_COLUMN_MARKED_FOR_WRITE; 05175 if (nr < 0 || nr >= 100 && nr <= 1900 || nr > 2155) 05176 { 05177 *ptr= 0; 05178 set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1); 05179 return 1; 05180 } 05181 if (nr != 0 || field_length != 4) // 0000 -> 0; 00 -> 2000 05182 { 05183 if (nr < YY_PART_YEAR) 05184 nr+=100; // 2000 - 2069 05185 else if (nr > 1900) 05186 nr-= 1900; 05187 } 05188 *ptr= (char) (uchar) nr; 05189 return 0; 05190 } 05191 05192 05193 bool Field_year::send_binary(Protocol *protocol) 05194 { 05195 ASSERT_COLUMN_MARKED_FOR_READ; 05196 ulonglong tmp= Field_year::val_int(); 05197 return protocol->store_short(tmp); 05198 } 05199 05200 05201 double Field_year::val_real(void) 05202 { 05203 return (double) Field_year::val_int(); 05204 } 05205 05206 05207 longlong Field_year::val_int(void) 05208 { 05209 ASSERT_COLUMN_MARKED_FOR_READ; 05210 int tmp= (int) ((uchar*) ptr)[0]; 05211 if (field_length != 4) 05212 tmp%=100; // Return last 2 char 05213 else if (tmp) 05214 tmp+=1900; 05215 return (longlong) tmp; 05216 } 05217 05218 05219 String *Field_year::val_str(String *val_buffer, 05220 String *val_ptr __attribute__((unused))) 05221 { 05222 val_buffer->alloc(5); 05223 val_buffer->length(field_length); 05224 char *to=(char*) val_buffer->ptr(); 05225 sprintf(to,field_length == 2 ? "%02d" : "%04d",(int) Field_year::val_int()); 05226 return val_buffer; 05227 } 05228 05229 05230 void Field_year::sql_type(String &res) const 05231 { 05232 CHARSET_INFO *cs=res.charset(); 05233 res.length(cs->cset->snprintf(cs,(char*)res.ptr(),res.alloced_length(), 05234 "year(%d)",(int) field_length)); 05235 } 05236 05237 05238 /**************************************************************************** 05239 ** date type 05240 ** In string context: YYYY-MM-DD 05241 ** In number context: YYYYMMDD 05242 ** Stored as a 4 byte unsigned int 05243 ****************************************************************************/ 05244 05245 int Field_date::store(const char *from, uint len,CHARSET_INFO *cs) 05246 { 05247 ASSERT_COLUMN_MARKED_FOR_WRITE; 05248 TIME l_time; 05249 uint32 tmp; 05250 int error; 05251 THD *thd= table ? table->in_use : current_thd; 05252 05253 if (str_to_datetime(from, len, &l_time, TIME_FUZZY_DATE | 05254 (thd->variables.sql_mode & 05255 (MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE | 05256 MODE_INVALID_DATES)), 05257 &error) <= MYSQL_TIMESTAMP_ERROR) 05258 { 05259 tmp= 0; 05260 error= 2; 05261 } 05262 else 05263 tmp=(uint32) l_time.year*10000L + (uint32) (l_time.month*100+l_time.day); 05264 05265 if (error) 05266 set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, 05267 from, len, MYSQL_TIMESTAMP_DATE, 1); 05268 05269 #ifdef WORDS_BIGENDIAN 05270 if (table && table->s->db_low_byte_first) 05271 { 05272 int4store(ptr,tmp); 05273 } 05274 else 05275 #endif 05276 longstore(ptr,tmp); 05277 return error; 05278 } 05279 05280 05281 int Field_date::store(double nr) 05282 { 05283 longlong tmp; 05284 int error= 0; 05285 if (nr >= 19000000000000.0 && nr <= 99991231235959.0) 05286 nr=floor(nr/1000000.0); // Timestamp to date 05287 if (nr < 0.0 || nr > 99991231.0) 05288 { 05289 tmp= LL(0); 05290 set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, 05291 ER_WARN_DATA_OUT_OF_RANGE, 05292 nr, MYSQL_TIMESTAMP_DATE); 05293 error= 1; 05294 } 05295 else 05296 tmp= (longlong) rint(nr); 05297 05298 return Field_date::store(tmp, TRUE); 05299 } 05300 05301 05302 int Field_date::store(longlong nr, bool unsigned_val) 05303 { 05304 ASSERT_COLUMN_MARKED_FOR_WRITE; 05305 TIME not_used; 05306 int error; 05307 longlong initial_nr= nr; 05308 THD *thd= table ? table->in_use : current_thd; 05309 05310 nr= number_to_datetime(nr, ¬_used, (TIME_FUZZY_DATE | 05311 (thd->variables.sql_mode & 05312 (MODE_NO_ZERO_IN_DATE | 05313 MODE_NO_ZERO_DATE | 05314 MODE_INVALID_DATES))), &error); 05315 05316 if (nr == LL(-1)) 05317 { 05318 nr= 0; 05319 error= 2; 05320 } 05321 05322 if (nr >= 19000000000000.0 && nr <= 99991231235959.0) 05323 nr= (longlong) floor(nr/1000000.0); // Timestamp to date 05324 05325 if (error) 05326 set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, 05327 error == 2 ? ER_WARN_DATA_OUT_OF_RANGE : 05328 WARN_DATA_TRUNCATED, initial_nr, 05329 MYSQL_TIMESTAMP_DATETIME, 1); 05330 05331 #ifdef WORDS_BIGENDIAN 05332 if (table && table->s->db_low_byte_first) 05333 { 05334 int4store(ptr, nr); 05335 } 05336 else 05337 #endif 05338 longstore(ptr, nr); 05339 return error; 05340 } 05341 05342 05343 bool Field_date::send_binary(Protocol *protocol) 05344 { 05345 longlong tmp= Field_date::val_int(); 05346 TIME tm; 05347 tm.year= (uint32) tmp/10000L % 10000; 05348 tm.month= (uint32) tmp/100 % 100; 05349 tm.day= (uint32) tmp % 100; 05350 return protocol->store_date(&tm); 05351 } 05352 05353 05354 double Field_date::val_real(void) 05355 { 05356 ASSERT_COLUMN_MARKED_FOR_READ; 05357 int32 j; 05358 #ifdef WORDS_BIGENDIAN 05359 if (table && table->s->db_low_byte_first) 05360 j=sint4korr(ptr); 05361 else 05362 #endif 05363 longget(j,ptr); 05364 return (double) (uint32) j; 05365 } 05366 05367 05368 longlong Field_date::val_int(void) 05369 { 05370 ASSERT_COLUMN_MARKED_FOR_READ; 05371 int32 j; 05372 #ifdef WORDS_BIGENDIAN 05373 if (table && table->s->db_low_byte_first) 05374 j=sint4korr(ptr); 05375 else 05376 #endif 05377 longget(j,ptr); 05378 return (longlong) (uint32) j; 05379 } 05380 05381 05382 String *Field_date::val_str(String *val_buffer, 05383 String *val_ptr __attribute__((unused))) 05384 { 05385 ASSERT_COLUMN_MARKED_FOR_READ; 05386 TIME ltime; 05387 val_buffer->alloc(field_length); 05388 int32 tmp; 05389 #ifdef WORDS_BIGENDIAN 05390 if (table && table->s->db_low_byte_first) 05391 tmp=sint4korr(ptr); 05392 else 05393 #endif 05394 longget(tmp,ptr); 05395 ltime.neg= 0; 05396 ltime.year= (int) ((uint32) tmp/10000L % 10000); 05397 ltime.month= (int) ((uint32) tmp/100 % 100); 05398 ltime.day= (int) ((uint32) tmp % 100); 05399 make_date((DATE_TIME_FORMAT *) 0, <ime, val_buffer); 05400 return val_buffer; 05401 } 05402 05403 05404 int Field_date::cmp(const char *a_ptr, const char *b_ptr) 05405 { 05406 int32 a,b; 05407 #ifdef WORDS_BIGENDIAN 05408 if (table && table->s->db_low_byte_first) 05409 { 05410 a=sint4korr(a_ptr); 05411 b=sint4korr(b_ptr); 05412 } 05413 else 05414 #endif 05415 { 05416 longget(a,a_ptr); 05417 longget(b,b_ptr); 05418 } 05419 return ((uint32) a < (uint32) b) ? -1 : ((uint32) a > (uint32) b) ? 1 : 0; 05420 } 05421 05422 05423 void Field_date::sort_string(char *to,uint length __attribute__((unused))) 05424 { 05425 #ifdef WORDS_BIGENDIAN 05426 if (!table || !table->s->db_low_byte_first) 05427 { 05428 to[0] = ptr[0]; 05429 to[1] = ptr[1]; 05430 to[2] = ptr[2]; 05431 to[3] = ptr[3]; 05432 } 05433 else 05434 #endif 05435 { 05436 to[0] = ptr[3]; 05437 to[1] = ptr[2]; 05438 to[2] = ptr[1]; 05439 to[3] = ptr[0]; 05440 } 05441 } 05442 05443 void Field_date::sql_type(String &res) const 05444 { 05445 res.set_ascii(STRING_WITH_LEN("date")); 05446 } 05447 05448 05449 /**************************************************************************** 05450 ** The new date type 05451 ** This is identical to the old date type, but stored on 3 bytes instead of 4 05452 ** In number context: YYYYMMDD 05453 ****************************************************************************/ 05454 05455 int Field_newdate::store(const char *from,uint len,CHARSET_INFO *cs) 05456 { 05457 ASSERT_COLUMN_MARKED_FOR_WRITE; 05458 TIME l_time; 05459 long tmp; 05460 int error; 05461 THD *thd= table ? table->in_use : current_thd; 05462 if (str_to_datetime(from, len, &l_time, 05463 (TIME_FUZZY_DATE | 05464 (thd->variables.sql_mode & 05465 (MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE | 05466 MODE_INVALID_DATES))), 05467 &error) <= MYSQL_TIMESTAMP_ERROR) 05468 { 05469 tmp= 0L; 05470 error= 2; 05471 } 05472 else 05473 tmp= l_time.day + l_time.month*32 + l_time.year*16*32; 05474 05475 if (error) 05476 set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, 05477 from, len, MYSQL_TIMESTAMP_DATE, 1); 05478 05479 int3store(ptr,tmp); 05480 return error; 05481 } 05482 05483 05484 int Field_newdate::store(double nr) 05485 { 05486 if (nr < 0.0 || nr > 99991231235959.0) 05487 { 05488 int3store(ptr,(int32) 0); 05489 set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, 05490 WARN_DATA_TRUNCATED, nr, MYSQL_TIMESTAMP_DATE); 05491 return 1; 05492 } 05493 return Field_newdate::store((longlong) rint(nr), FALSE); 05494 } 05495 05496 05497 int Field_newdate::store(longlong nr, bool unsigned_val) 05498 { 05499 ASSERT_COLUMN_MARKED_FOR_WRITE; 05500 TIME l_time; 05501 longlong tmp; 05502 int error; 05503 THD *thd= table ? table->in_use : current_thd; 05504 if (number_to_datetime(nr, &l_time, 05505 (TIME_FUZZY_DATE | 05506 (thd->variables.sql_mode & 05507 (MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE | 05508 MODE_INVALID_DATES))), 05509 &error) == LL(-1)) 05510 { 05511 tmp= 0L; 05512 error= 2; 05513 } 05514 else 05515 tmp= l_time.day + l_time.month*32 + l_time.year*16*32; 05516 05517 if (error) 05518 set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, 05519 error == 2 ? ER_WARN_DATA_OUT_OF_RANGE : 05520 WARN_DATA_TRUNCATED,nr,MYSQL_TIMESTAMP_DATE, 1); 05521 05522 int3store(ptr,tmp); 05523 return error; 05524 } 05525 05526 05527 int Field_newdate::store_time(TIME *ltime,timestamp_type type) 05528 { 05529 ASSERT_COLUMN_MARKED_FOR_WRITE; 05530 long tmp; 05531 int error= 0; 05532 if (type == MYSQL_TIMESTAMP_DATE || type == MYSQL_TIMESTAMP_DATETIME) 05533 tmp=ltime->year*16*32+ltime->month*32+ltime->day; 05534 else 05535 { 05536 tmp=0; 05537 error= 1; 05538 set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, 1); 05539 } 05540 int3store(ptr,tmp); 05541 return error; 05542 } 05543 05544 05545 bool Field_newdate::send_binary(Protocol *protocol) 05546 { 05547 TIME tm; 05548 Field_newdate::get_date(&tm,0); 05549 return protocol->store_date(&tm); 05550 } 05551 05552 05553 double Field_newdate::val_real(void) 05554 { 05555 ASSERT_COLUMN_MARKED_FOR_READ; 05556 return (double) Field_newdate::val_int(); 05557 } 05558 05559 05560 longlong Field_newdate::val_int(void) 05561 { 05562 ASSERT_COLUMN_MARKED_FOR_READ; 05563 ulong j= uint3korr(ptr); 05564 j= (j % 32L)+(j / 32L % 16L)*100L + (j/(16L*32L))*10000L; 05565 return (longlong) j; 05566 } 05567 05568 05569 String *Field_newdate::val_str(String *val_buffer, 05570 String *val_ptr __attribute__((unused))) 05571 { 05572 ASSERT_COLUMN_MARKED_FOR_READ; 05573 val_buffer->alloc(field_length); 05574 val_buffer->length(field_length); 05575 uint32 tmp=(uint32) uint3korr(ptr); 05576 int part; 05577 char *pos=(char*) val_buffer->ptr()+10; 05578 05579 /* Open coded to get more speed */ 05580 *pos--=0; // End NULL 05581 part=(int) (tmp & 31); 05582 *pos--= (char) ('0'+part%10); 05583 *pos--= (char) ('0'+part/10); 05584 *pos--= '-'; 05585 part=(int) (tmp >> 5 & 15); 05586 *pos--= (char) ('0'+part%10); 05587 *pos--= (char) ('0'+part/10); 05588 *pos--= '-'; 05589 part=(int) (tmp >> 9); 05590 *pos--= (char) ('0'+part%10); part/=10; 05591 *pos--= (char) ('0'+part%10); part/=10; 05592 *pos--= (char) ('0'+part%10); part/=10; 05593 *pos= (char) ('0'+part); 05594 return val_buffer; 05595 } 05596 05597 05598 bool Field_newdate::get_date(TIME *ltime,uint fuzzydate) 05599 { 05600 uint32 tmp=(uint32) uint3korr(ptr); 05601 ltime->day= tmp & 31; 05602 ltime->month= (tmp >> 5) & 15; 05603 ltime->year= (tmp >> 9); 05604 ltime->time_type= MYSQL_TIMESTAMP_DATE; 05605 ltime->hour= ltime->minute= ltime->second= ltime->second_part= ltime->neg= 0; 05606 return ((!(fuzzydate & TIME_FUZZY_DATE) && (!ltime->month || !ltime->day)) ? 05607 1 : 0); 05608 } 05609 05610 05611 bool Field_newdate::get_time(TIME *ltime) 05612 { 05613 return Field_newdate::get_date(ltime,0); 05614 } 05615 05616 05617 int Field_newdate::cmp(const char *a_ptr, const char *b_ptr) 05618 { 05619 uint32 a,b; 05620 a=(uint32) uint3korr(a_ptr); 05621 b=(uint32) uint3korr(b_ptr); 05622 return (a < b) ? -1 : (a > b) ? 1 : 0; 05623 } 05624 05625 05626 void Field_newdate::sort_string(char *to,uint length __attribute__((unused))) 05627 { 05628 to[0] = ptr[2]; 05629 to[1] = ptr[1]; 05630 to[2] = ptr[0]; 05631 } 05632 05633 05634 void Field_newdate::sql_type(String &res) const 05635 { 05636 res.set_ascii(STRING_WITH_LEN("date")); 05637 } 05638 05639 05640 /**************************************************************************** 05641 ** datetime type 05642 ** In string context: YYYY-MM-DD HH:MM:DD 05643 ** In number context: YYYYMMDDHHMMDD 05644 ** Stored as a 8 byte unsigned int. Should sometimes be change to a 6 byte int. 05645 ****************************************************************************/ 05646 05647 int Field_datetime::store(const char *from,uint len,CHARSET_INFO *cs) 05648 { 05649 ASSERT_COLUMN_MARKED_FOR_WRITE; 05650 TIME time_tmp; 05651 int error; 05652 ulonglong tmp= 0; 05653 enum enum_mysql_timestamp_type func_res; 05654 THD *thd= table ? table->in_use : current_thd; 05655 05656 func_res= str_to_datetime(from, len, &time_tmp, 05657 (TIME_FUZZY_DATE | 05658 (thd->variables.sql_mode & 05659 (MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE | 05660 MODE_INVALID_DATES))), 05661 &error); 05662 if ((int) func_res > (int) MYSQL_TIMESTAMP_ERROR) 05663 tmp= TIME_to_ulonglong_datetime(&time_tmp); 05664 else 05665 error= 1; // Fix if invalid zero date 05666 05667 if (error) 05668 set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, 05669 ER_WARN_DATA_OUT_OF_RANGE, 05670 from, len, MYSQL_TIMESTAMP_DATETIME, 1); 05671 05672 #ifdef WORDS_BIGENDIAN 05673 if (table && table->s->db_low_byte_first) 05674 { 05675 int8store(ptr,tmp); 05676 } 05677 else 05678 #endif 05679 longlongstore(ptr,tmp); 05680 return error; 05681 } 05682 05683 05684 int Field_datetime::store(double nr) 05685 { 05686 int error= 0; 05687 if (nr < 0.0 || nr > 99991231235959.0) 05688 { 05689 set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, 05690 ER_WARN_DATA_OUT_OF_RANGE, 05691 nr, MYSQL_TIMESTAMP_DATETIME); 05692 nr= 0.0; 05693 error= 1; 05694 } 05695 error|= Field_datetime::store((longlong) rint(nr), FALSE); 05696 return error; 05697 } 05698 05699 05700 int Field_datetime::store(longlong nr, bool unsigned_val) 05701 { 05702 ASSERT_COLUMN_MARKED_FOR_WRITE; 05703 TIME not_used; 05704 int error; 05705 longlong initial_nr= nr; 05706 THD *thd= table ? table->in_use : current_thd; 05707 05708 nr= number_to_datetime(nr, ¬_used, (TIME_FUZZY_DATE | 05709 (thd->variables.sql_mode & 05710 (MODE_NO_ZERO_IN_DATE | 05711 MODE_NO_ZERO_DATE | 05712 MODE_INVALID_DATES))), &error); 05713 05714 if (nr == LL(-1)) 05715 { 05716 nr= 0; 05717 error= 2; 05718 } 05719 05720 if (error) 05721 set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, 05722 error == 2 ? ER_WARN_DATA_OUT_OF_RANGE : 05723 WARN_DATA_TRUNCATED, initial_nr, 05724 MYSQL_TIMESTAMP_DATETIME, 1); 05725 05726 #ifdef WORDS_BIGENDIAN 05727 if (table && table->s->db_low_byte_first) 05728 { 05729 int8store(ptr,nr); 05730 } 05731 else 05732 #endif 05733 longlongstore(ptr,nr); 05734 return error; 05735 } 05736 05737 05738 int Field_datetime::store_time(TIME *ltime,timestamp_type type) 05739 { 05740 ASSERT_COLUMN_MARKED_FOR_WRITE; 05741 longlong tmp; 05742 int error= 0; 05743 /* 05744 We don't perform range checking here since values stored in TIME 05745 structure always fit into DATETIME range. 05746 */ 05747 if (type == MYSQL_TIMESTAMP_DATE || type == MYSQL_TIMESTAMP_DATETIME) 05748 tmp=((ltime->year*10000L+ltime->month*100+ltime->day)*LL(1000000)+ 05749 (ltime->hour*10000L+ltime->minute*100+ltime->second)); 05750 else 05751 { 05752 tmp=0; 05753 error= 1; 05754 set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, 1); 05755 } 05756 #ifdef WORDS_BIGENDIAN 05757 if (table && table->s->db_low_byte_first) 05758 { 05759 int8store(ptr,tmp); 05760 } 05761 else 05762 #endif 05763 longlongstore(ptr,tmp); 05764 return error; 05765 } 05766 05767 bool Field_datetime::send_binary(Protocol *protocol) 05768 { 05769 TIME tm; 05770 Field_datetime::get_date(&tm, TIME_FUZZY_DATE); 05771 return protocol->store(&tm); 05772 } 05773 05774 05775 double Field_datetime::val_real(void) 05776 { 05777 return (double) Field_datetime::val_int(); 05778 } 05779 05780 longlong Field_datetime::val_int(void) 05781 { 05782 ASSERT_COLUMN_MARKED_FOR_READ; 05783 longlong j; 05784 #ifdef WORDS_BIGENDIAN 05785 if (table && table->s->db_low_byte_first) 05786 j=sint8korr(ptr); 05787 else 05788 #endif 05789 longlongget(j,ptr); 05790 return j; 05791 } 05792 05793 05794 String *Field_datetime::val_str(String *val_buffer, 05795 String *val_ptr __attribute__((unused))) 05796 { 05797 ASSERT_COLUMN_MARKED_FOR_READ; 05798 val_buffer->alloc(field_length); 05799 val_buffer->length(field_length); 05800 ulonglong tmp; 05801 long part1,part2; 05802 char *pos; 05803 int part3; 05804 05805 #ifdef WORDS_BIGENDIAN 05806 if (table && table->s->db_low_byte_first) 05807 tmp=sint8korr(ptr); 05808 else 05809 #endif 05810 longlongget(tmp,ptr); 05811 05812 /* 05813 Avoid problem with slow longlong arithmetic and sprintf 05814 */ 05815 05816 part1=(long) (tmp/LL(1000000)); 05817 part2=(long) (tmp - (ulonglong) part1*LL(1000000)); 05818 05819 pos=(char*) val_buffer->ptr()+19; 05820 *pos--=0; 05821 *pos--= (char) ('0'+(char) (part2%10)); part2/=10; 05822 *pos--= (char) ('0'+(char) (part2%10)); part3= (int) (part2 / 10); 05823 *pos--= ':'; 05824 *pos--= (char) ('0'+(char) (part3%10)); part3/=10; 05825 *pos--= (char) ('0'+(char) (part3%10)); part3/=10; 05826 *pos--= ':'; 05827 *pos--= (char) ('0'+(char) (part3%10)); part3/=10; 05828 *pos--= (char) ('0'+(char) part3); 05829 *pos--= ' '; 05830 *pos--= (char) ('0'+(char) (part1%10)); part1/=10; 05831 *pos--= (char) ('0'+(char) (part1%10)); part1/=10; 05832 *pos--= '-'; 05833 *pos--= (char) ('0'+(char) (part1%10)); part1/=10; 05834 *pos--= (char) ('0'+(char) (part1%10)); part3= (int) (part1/10); 05835 *pos--= '-'; 05836 *pos--= (char) ('0'+(char) (part3%10)); part3/=10; 05837 *pos--= (char) ('0'+(char) (part3%10)); part3/=10; 05838 *pos--= (char) ('0'+(char) (part3%10)); part3/=10; 05839 *pos=(char) ('0'+(char) part3); 05840 return val_buffer; 05841 } 05842 05843 bool Field_datetime::get_date(TIME *ltime, uint fuzzydate) 05844 { 05845 longlong tmp=Field_datetime::val_int(); 05846 uint32 part1,part2; 05847 part1=(uint32) (tmp/LL(1000000)); 05848 part2=(uint32) (tmp - (ulonglong) part1*LL(1000000)); 05849 05850 ltime->time_type= MYSQL_TIMESTAMP_DATETIME; 05851 ltime->neg= 0; 05852 ltime->second_part= 0; 05853 ltime->second= (int) (part2%100); 05854 ltime->minute= (int) (part2/100%100); 05855 ltime->hour= (int) (part2/10000); 05856 ltime->day= (int) (part1%100); 05857 ltime->month= (int) (part1/100%100); 05858 ltime->year= (int) (part1/10000); 05859 return (!(fuzzydate & TIME_FUZZY_DATE) && (!ltime->month || !ltime->day)) ? 1 : 0; 05860 } 05861 05862 bool Field_datetime::get_time(TIME *ltime) 05863 { 05864 return Field_datetime::get_date(ltime,0); 05865 } 05866 05867 int Field_datetime::cmp(const char *a_ptr, const char *b_ptr) 05868 { 05869 longlong a,b; 05870 #ifdef WORDS_BIGENDIAN 05871 if (table && table->s->db_low_byte_first) 05872 { 05873 a=sint8korr(a_ptr); 05874 b=sint8korr(b_ptr); 05875 } 05876 else 05877 #endif 05878 { 05879 longlongget(a,a_ptr); 05880 longlongget(b,b_ptr); 05881 } 05882 return ((ulonglong) a < (ulonglong) b) ? -1 : 05883 ((ulonglong) a > (ulonglong) b) ? 1 : 0; 05884 } 05885 05886 void Field_datetime::sort_string(char *to,uint length __attribute__((unused))) 05887 { 05888 #ifdef WORDS_BIGENDIAN 05889 if (!table || !table->s->db_low_byte_first) 05890 { 05891 to[0] = ptr[0]; 05892 to[1] = ptr[1]; 05893 to[2] = ptr[2]; 05894 to[3] = ptr[3]; 05895 to[4] = ptr[4]; 05896 to[5] = ptr[5]; 05897 to[6] = ptr[6]; 05898 to[7] = ptr[7]; 05899 } 05900 else 05901 #endif 05902 { 05903 to[0] = ptr[7]; 05904 to[1] = ptr[6]; 05905 to[2] = ptr[5]; 05906 to[3] = ptr[4]; 05907 to[4] = ptr[3]; 05908 to[5] = ptr[2]; 05909 to[6] = ptr[1]; 05910 to[7] = ptr[0]; 05911 } 05912 } 05913 05914 05915 void Field_datetime::sql_type(String &res) const 05916 { 05917 res.set_ascii(STRING_WITH_LEN("datetime")); 05918 } 05919 05920 /**************************************************************************** 05921 ** string type 05922 ** A string may be varchar or binary 05923 ****************************************************************************/ 05924 05925 /* Copy a string and fill with space */ 05926 05927 int Field_string::store(const char *from,uint length,CHARSET_INFO *cs) 05928 { 05929 ASSERT_COLUMN_MARKED_FOR_WRITE; 05930 int error= 0, well_formed_error; 05931 uint32 not_used; 05932 char buff[STRING_BUFFER_USUAL_SIZE]; 05933 String tmpstr(buff,sizeof(buff), &my_charset_bin); 05934 uint copy_length; 05935 05936 /* See the comment for Field_long::store(long long) */ 05937 DBUG_ASSERT(table->in_use == current_thd); 05938 05939 /* Convert character set if necessary */ 05940 if (String::needs_conversion(length, cs, field_charset, ¬_used)) 05941 { 05942 uint conv_errors; 05943 tmpstr.copy(from, length, cs, field_charset, &conv_errors); 05944 from= tmpstr.ptr(); 05945 length= tmpstr.length(); 05946 if (conv_errors) 05947 error= 2; 05948 } 05949 05950 /* Make sure we don't break a multibyte sequence or copy malformed data. */ 05951 copy_length= field_charset->cset->well_formed_len(field_charset, 05952 from,from+length, 05953 field_length/ 05954 field_charset->mbmaxlen, 05955 &well_formed_error); 05956 memmove(ptr, from, copy_length); 05957 05958 /* Append spaces if the string was shorter than the field. */ 05959 if (copy_length < field_length) 05960 field_charset->cset->fill(field_charset,ptr+copy_length, 05961 field_length-copy_length, 05962 field_charset->pad_char); 05963 05964 /* 05965 Check if we lost any important data (anything in a binary string, 05966 or any non-space in others). 05967 */ 05968 if ((copy_length < length) && table->in_use->count_cuted_fields) 05969 { 05970 if (binary()) 05971 error= 2; 05972 else 05973 { 05974 const char *end=from+length; 05975 from+= copy_length; 05976 from+= field_charset->cset->scan(field_charset, from, end, 05977 MY_SEQ_SPACES); 05978 if (from != end) 05979 error= 2; 05980 } 05981 } 05982 if (error) 05983 { 05984 if (table->in_use->abort_on_warning) 05985 set_warning(MYSQL_ERROR::WARN_LEVEL_ERROR, ER_DATA_TOO_LONG, 1); 05986 else 05987 set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, 1); 05988 } 05989 return error; 05990 } 05991 05992 05993 /* 05994 Store double value in Field_string or Field_varstring. 05995 05996 SYNOPSIS 05997 store(double nr) 05998 nr number 05999 06000 DESCRIPTION 06001 Pretty prints double number into field_length characters buffer. 06002 */ 06003 06004 int Field_str::store(double nr) 06005 { 06006 ASSERT_COLUMN_MARKED_FOR_WRITE; 06007 char buff[DOUBLE_TO_STRING_CONVERSION_BUFFER_SIZE]; 06008 uint length; 06009 bool use_scientific_notation= TRUE; 06010 uint char_length= field_length / charset()->mbmaxlen; 06011 /* 06012 Check fabs(nr) against longest value that can be stored in field, 06013 which depends on whether the value is < 1 or not, and negative or not 06014 */ 06015 double anr= fabs(nr); 06016 int neg= (nr < 0.0) ? 1 : 0; 06017 if (char_length > 4 && char_length < 32 && 06018 (anr < 1.0 ? anr > 1/(log_10[max(0,(int) char_length-neg-2)]) /* -2 for "0." */ 06019 : anr < log_10[char_length-neg]-1)) 06020 use_scientific_notation= FALSE; 06021 06022 length= (uint) my_sprintf(buff, (buff, "%-.*g", 06023 (use_scientific_notation ? 06024 max(0, (int)char_length-neg-5) : 06025 char_length), 06026 nr)); 06027 /* 06028 +1 below is because "precision" in %g above means the 06029 max. number of significant digits, not the output width. 06030 Thus the width can be larger than number of significant digits by 1 06031 (for decimal point) 06032 the test for char_length < 5 is for extreme cases, 06033 like inserting 500.0 in char(1) 06034 */ 06035 DBUG_ASSERT(char_length < 5 || length <= char_length+1); 06036 return store((const char *) buff, length, charset()); 06037 } 06038 06039 06040 uint Field::is_equal(create_field *new_field) 06041 { 06042 return (new_field->sql_type == real_type()); 06043 } 06044 06045 06046 uint Field_str::is_equal(create_field *new_field) 06047 { 06048 if (((new_field->flags & (BINCMP_FLAG | BINARY_FLAG)) && 06049 !(flags & (BINCMP_FLAG | BINARY_FLAG))) || 06050 (!(new_field->flags & (BINCMP_FLAG | BINARY_FLAG)) && 06051 (flags & (BINCMP_FLAG | BINARY_FLAG)))) 06052 return 0; /* One of the fields is binary and the other one isn't */ 06053 06054 return ((new_field->sql_type == real_type()) && 06055 new_field->charset == field_charset && 06056 new_field->length == max_length()); 06057 } 06058 06059 06060 int Field_string::store(longlong nr, bool unsigned_val) 06061 { 06062 char buff[64]; 06063 int l; 06064 CHARSET_INFO *cs=charset(); 06065 l= (cs->cset->longlong10_to_str)(cs,buff,sizeof(buff), 06066 unsigned_val ? 10 : -10, nr); 06067 return Field_string::store(buff,(uint)l,cs); 06068 } 06069 06070 06071 int Field_longstr::store_decimal(const my_decimal *d) 06072 { 06073 char buff[DECIMAL_MAX_STR_LENGTH+1]; 06074 String str(buff, sizeof(buff), &my_charset_bin); 06075 my_decimal2string(E_DEC_FATAL_ERROR, d, 0, 0, 0, &str); 06076 return store(str.ptr(), str.length(), str.charset()); 06077 } 06078 06079 06080 double Field_string::val_real(void) 06081 { 06082 ASSERT_COLUMN_MARKED_FOR_READ; 06083 int not_used; 06084 char *end_not_used; 06085 CHARSET_INFO *cs= charset(); 06086 return my_strntod(cs,ptr,field_length,&end_not_used,¬_used); 06087 } 06088 06089 06090 longlong Field_string::val_int(void) 06091 { 06092 ASSERT_COLUMN_MARKED_FOR_READ; 06093 int not_used; 06094 char *end_not_used; 06095 CHARSET_INFO *cs=charset(); 06096 return my_strntoll(cs,ptr,field_length,10,&end_not_used,¬_used); 06097 } 06098 06099 06100 String *Field_string::val_str(String *val_buffer __attribute__((unused)), 06101 String *val_ptr) 06102 { 06103 ASSERT_COLUMN_MARKED_FOR_READ; 06104 uint length= field_charset->cset->lengthsp(field_charset, ptr, field_length); 06105 /* See the comment for Field_long::store(long long) */ 06106 DBUG_ASSERT(table->in_use == current_thd); 06107 val_ptr->set((const char*) ptr, length, field_charset); 06108 return val_ptr; 06109 } 06110 06111 06112 my_decimal *Field_string::val_decimal(my_decimal *decimal_value) 06113 { 06114 ASSERT_COLUMN_MARKED_FOR_READ; 06115 str2my_decimal(E_DEC_FATAL_ERROR, ptr, field_length, charset(), 06116 decimal_value); 06117 return decimal_value; 06118 } 06119 06120 06121 int Field_string::cmp(const char *a_ptr, const char *b_ptr) 06122 { 06123 uint a_len, b_len; 06124 06125 if (field_charset->mbmaxlen != 1) 06126 { 06127 uint char_len= field_length/field_charset->mbmaxlen; 06128 a_len= my_charpos(field_charset, a_ptr, a_ptr + field_length, char_len); 06129 b_len= my_charpos(field_charset, b_ptr, b_ptr + field_length, char_len); 06130 } 06131 else 06132 a_len= b_len= field_length; 06133 /* 06134 We have to remove end space to be able to compare multi-byte-characters 06135 like in latin_de 'ae' and 0xe4 06136 */ 06137 return field_charset->coll->strnncollsp(field_charset, 06138 (const uchar*) a_ptr, a_len, 06139 (const uchar*) b_ptr, b_len, 06140 0); 06141 } 06142 06143 06144 void Field_string::sort_string(char *to,uint length) 06145 { 06146 uint tmp= my_strnxfrm(field_charset, 06147 (uchar*) to, length, 06148 (uchar*) ptr, field_length); 06149 DBUG_ASSERT(tmp == length); 06150 } 06151 06152 06153 void Field_string::sql_type(String &res) const 06154 { 06155 THD *thd= table->in_use; 06156 CHARSET_INFO *cs=res.charset(); 06157 ulong length; 06158 06159 length= cs->cset->snprintf(cs,(char*) res.ptr(), 06160 res.alloced_length(), "%s(%d)", 06161 ((type() == MYSQL_TYPE_VAR_STRING && 06162 !thd->variables.new_mode) ? 06163 (has_charset() ? "varchar" : "varbinary") : 06164 (has_charset() ? "char" : "binary")), 06165 (int) field_length / charset()->mbmaxlen); 06166 res.length(length); 06167 if ((thd->variables.sql_mode & (MODE_MYSQL323 | MODE_MYSQL40)) && 06168 has_charset() && (charset()->state & MY_CS_BINSORT)) 06169 res.append(STRING_WITH_LEN(" binary")); 06170 } 06171 06172 06173 char *Field_string::pack(char *to, const char *from, uint max_length) 06174 { 06175 uint length= min(field_length,max_length); 06176 uint char_length= max_length/field_charset->mbmaxlen; 06177 if (length > char_length) 06178 char_length= my_charpos(field_charset, from, from+length, char_length); 06179 set_if_smaller(length, char_length); 06180 while (length && from[length-1] == ' ') 06181 length--; 06182 *to++= (char) (uchar) length; 06183 if (field_length > 255) 06184 *to++= (char) (uchar) (length >> 8); 06185 memcpy(to, from, length); 06186 return to+length; 06187 } 06188 06189 06190 const char *Field_string::unpack(char *to, const char *from) 06191 { 06192 uint length; 06193 if (field_length > 255) 06194 { 06195 length= uint2korr(from); 06196 from+= 2; 06197 } 06198 else 06199 length= (uint) (uchar) *from++; 06200 memcpy(to, from, (int) length); 06201 bfill(to+length, field_length - length, ' '); 06202 return from+length; 06203 } 06204 06205 06206 /* 06207 Compare two packed keys 06208 06209 SYNOPSIS 06210 pack_cmp() 06211 a New key 06212 b Original key 06213 length Key length 06214 insert_or_update 1 if this is an insert or update 06215 06216 RETURN 06217 < 0 a < b 06218 0 a = b 06219 > 0 a > b 06220 */ 06221 06222 int Field_string::pack_cmp(const char *a, const char *b, uint length, 06223 my_bool insert_or_update) 06224 { 06225 uint a_length, b_length; 06226 if (length > 255) 06227 { 06228 a_length= uint2korr(a); 06229 b_length= uint2korr(b); 06230 a+= 2; 06231 b+= 2; 06232 } 06233 else 06234 { 06235 a_length= (uint) (uchar) *a++; 06236 b_length= (uint) (uchar) *b++; 06237 } 06238 return field_charset->coll->strnncollsp(field_charset, 06239 (const uchar*) a, a_length, 06240 (const uchar*) b, b_length, 06241 insert_or_update); 06242 } 06243 06244 06245 /* 06246 Compare a packed key against row 06247 06248 SYNOPSIS 06249 pack_cmp() 06250 key Original key 06251 length Key length. (May be less than field length) 06252 insert_or_update 1 if this is an insert or update 06253 06254 RETURN 06255 < 0 row < key 06256 0 row = key 06257 > 0 row > key 06258 */ 06259 06260 int Field_string::pack_cmp(const char *key, uint length, 06261 my_bool insert_or_update) 06262 { 06263 uint row_length, key_length; 06264 char *end; 06265 if (length > 255) 06266 { 06267 key_length= uint2korr(key); 06268 key+= 2; 06269 } 06270 else 06271 key_length= (uint) (uchar) *key++; 06272 06273 /* Only use 'length' of key, not field_length */ 06274 end= ptr + length; 06275 while (end > ptr && end[-1] == ' ') 06276 end--; 06277 row_length= (uint) (end - ptr); 06278 06279 return field_charset->coll->strnncollsp(field_charset, 06280 (const uchar*) ptr, row_length, 06281 (const uchar*) key, key_length, 06282 insert_or_update); 06283 } 06284 06285 06286 uint Field_string::packed_col_length(const char *data_ptr, uint length) 06287 { 06288 if (length > 255) 06289 return uint2korr(data_ptr)+2; 06290 return (uint) ((uchar) *data_ptr)+1; 06291 } 06292 06293 06294 uint Field_string::max_packed_col_length(uint max_length) 06295 { 06296 return (max_length > 255 ? 2 : 1)+max_length; 06297 } 06298 06299 06300 Field *Field_string::new_field(MEM_ROOT *root, struct st_table *new_table, 06301 bool keep_type) 06302 { 06303 Field *field; 06304 if (type() != MYSQL_TYPE_VAR_STRING || keep_type) 06305 return Field::new_field(root, new_table, keep_type); 06306 06307 /* 06308 Old VARCHAR field which should be modified to a VARCHAR on copy 06309 This is done to ensure that ALTER TABLE will convert old VARCHAR fields 06310 to now VARCHAR fields. 06311 */ 06312 if ((field= new Field_varstring(field_length, maybe_null(), field_name, 06313 new_table->s, charset()))) 06314 field->init(new_table); 06315 return field; 06316 } 06317 06318 06319 /**************************************************************************** 06320 VARCHAR type 06321 Data in field->ptr is stored as: 06322 1 or 2 bytes length-prefix-header (from Field_varstring::length_bytes) 06323 data 06324 06325 NOTE: 06326 When VARCHAR is stored in a key (for handler::index_read() etc) it's always 06327 stored with a 2 byte prefix. (Just like blob keys). 06328 06329 Normally length_bytes is calculated as (field_length < 256 : 1 ? 2) 06330 The exception is if there is a prefix key field that is part of a long 06331 VARCHAR, in which case field_length for this may be 1 but the length_bytes 06332 is 2. 06333 ****************************************************************************/ 06334 06335 06336 int Field_varstring::store(const char *from,uint length,CHARSET_INFO *cs) 06337 { 06338 ASSERT_COLUMN_MARKED_FOR_WRITE; 06339 uint32 not_used, copy_length; 06340 char buff[STRING_BUFFER_USUAL_SIZE]; 06341 String tmpstr(buff,sizeof(buff), &my_charset_bin); 06342 int error_code= 0, well_formed_error; 06343 enum MYSQL_ERROR::enum_warning_level level= MYSQL_ERROR::WARN_LEVEL_WARN; 06344 06345 /* Convert character set if necessary */ 06346 if (String::needs_conversion(length, cs, field_charset, ¬_used)) 06347 { 06348 uint conv_errors; 06349 tmpstr.copy(from, length, cs, field_charset, &conv_errors); 06350 from= tmpstr.ptr(); 06351 length= tmpstr.length(); 06352 if (conv_errors) 06353 error_code= WARN_DATA_TRUNCATED; 06354 } 06355 /* 06356 Make sure we don't break a multibyte sequence 06357 as well as don't copy a malformed data. 06358 */ 06359 copy_length= field_charset->cset->well_formed_len(field_charset, 06360 from,from+length, 06361 field_length/ 06362 field_charset->mbmaxlen, 06363 &well_formed_error); 06364 memmove(ptr + length_bytes, from, copy_length); 06365 if (length_bytes == 1) 06366 *ptr= (uchar) copy_length; 06367 else 06368 int2store(ptr, copy_length); 06369 06370 // Check if we lost something other than just trailing spaces 06371 if ((copy_length < length) && table->in_use->count_cuted_fields && 06372 !error_code) 06373 { 06374 if (!binary()) 06375 { 06376 const char *end= from + length; 06377 from+= copy_length; 06378 from+= field_charset->cset->scan(field_charset, from, end, MY_SEQ_SPACES); 06379 /* If we lost only spaces then produce a NOTE, not a WARNING */ 06380 if (from == end) 06381 level= MYSQL_ERROR::WARN_LEVEL_NOTE; 06382 } 06383 error_code= WARN_DATA_TRUNCATED; 06384 } 06385 if (error_code) 06386 { 06387 if (level == MYSQL_ERROR::WARN_LEVEL_WARN && 06388 table->in_use->abort_on_warning) 06389 error_code= ER_DATA_TOO_LONG; 06390 set_warning(level, error_code, 1); 06391 return 2; 06392 } 06393 return 0; 06394 } 06395 06396 06397 int Field_varstring::store(longlong nr, bool unsigned_val) 06398 { 06399 char buff[64]; 06400 uint length; 06401 length= (uint) (field_charset->cset->longlong10_to_str)(field_charset, 06402 buff, 06403 sizeof(buff), 06404 (unsigned_val ? 10: 06405 -10), 06406 nr); 06407 return Field_varstring::store(buff, length, field_charset); 06408 } 06409 06410 06411 double Field_varstring::val_real(void) 06412 { 06413 ASSERT_COLUMN_MARKED_FOR_READ; 06414 int not_used; 06415 char *end_not_used; 06416 uint length= length_bytes == 1 ? (uint) (uchar) *ptr : uint2korr(ptr); 06417 return my_strntod(field_charset, ptr+length_bytes, length, &end_not_used, 06418 ¬_used); 06419 } 06420 06421 06422 longlong Field_varstring::val_int(void) 06423 { 06424 ASSERT_COLUMN_MARKED_FOR_READ; 06425 int not_used; 06426 char *end_not_used; 06427 uint length= length_bytes == 1 ? (uint) (uchar) *ptr : uint2korr(ptr); 06428 return my_strntoll(field_charset, ptr+length_bytes, length, 10, 06429 &end_not_used, ¬_used); 06430 } 06431 06432 String *Field_varstring::val_str(String *val_buffer __attribute__((unused)), 06433 String *val_ptr) 06434 { 06435 ASSERT_COLUMN_MARKED_FOR_READ; 06436 uint length= length_bytes == 1 ? (uint) (uchar) *ptr : uint2korr(ptr); 06437 val_ptr->set((const char*) ptr+length_bytes, length, field_charset); 06438 return val_ptr; 06439 } 06440 06441 06442 my_decimal *Field_varstring::val_decimal(my_decimal *decimal_value) 06443 { 06444 ASSERT_COLUMN_MARKED_FOR_READ; 06445 uint length= length_bytes == 1 ? (uint) (uchar) *ptr : uint2korr(ptr); 06446 str2my_decimal(E_DEC_FATAL_ERROR, ptr+length_bytes, length, charset(), 06447 decimal_value); 06448 return decimal_value; 06449 } 06450 06451 06452 int Field_varstring::cmp_max(const char *a_ptr, const char *b_ptr, 06453 uint max_len) 06454 { 06455 uint a_length, b_length; 06456 int diff; 06457 06458 if (length_bytes == 1) 06459 { 06460 a_length= (uint) (uchar) *a_ptr; 06461 b_length= (uint) (uchar) *b_ptr; 06462 } 06463 else 06464 { 06465 a_length= uint2korr(a_ptr); 06466 b_length= uint2korr(b_ptr); 06467 } 06468 set_if_smaller(a_length, max_len); 06469 set_if_smaller(b_length, max_len); 06470 diff= field_charset->coll->strnncollsp(field_charset, 06471 (const uchar*) a_ptr+ 06472 length_bytes, 06473 a_length, 06474 (const uchar*) b_ptr+ 06475 length_bytes, 06476 b_length,0); 06477 return diff; 06478 } 06479 06480 06481 /* 06482 NOTE: varstring and blob keys are ALWAYS stored with a 2 byte length prefix 06483 */ 06484 06485 int Field_varstring::key_cmp(const byte *key_ptr, uint max_key_length) 06486 { 06487 uint length= length_bytes == 1 ? (uint) (uchar) *ptr : uint2korr(ptr); 06488 uint char_length= max_key_length / field_charset->mbmaxlen; 06489 06490 char_length= my_charpos(field_charset, ptr + length_bytes, 06491 ptr + length_bytes + length, char_length); 06492 set_if_smaller(length, char_length); 06493 return field_charset->coll->strnncollsp(field_charset, 06494 (const uchar*) ptr + length_bytes, 06495 length, 06496 (const uchar*) key_ptr+ 06497 HA_KEY_BLOB_LENGTH, 06498 uint2korr(key_ptr), 0); 06499 } 06500 06501 06502 /* 06503 Compare to key segments (always 2 byte length prefix) 06504 06505 NOTE 06506 This is used only to compare key segments created for index_read(). 06507 (keys are created and compared in key.cc) 06508 */ 06509 06510 int Field_varstring::key_cmp(const byte *a,const byte *b) 06511 { 06512 return field_charset->coll->strnncollsp(field_charset, 06513 (const uchar*) a + 06514 HA_KEY_BLOB_LENGTH, 06515 uint2korr(a), 06516 (const uchar*) b + 06517 HA_KEY_BLOB_LENGTH, 06518 uint2korr(b), 06519 0); 06520 } 06521 06522 06523 void Field_varstring::sort_string(char *to,uint length) 06524 { 06525 uint tot_length= length_bytes == 1 ? (uint) (uchar) *ptr : uint2korr(ptr); 06526 06527 if (field_charset == &my_charset_bin) 06528 { 06529 /* Store length last in high-byte order to sort longer strings first */ 06530 if (length_bytes == 1) 06531 to[length-1]= tot_length; 06532 else 06533 mi_int2store(to+length-2, tot_length); 06534 length-= length_bytes; 06535 } 06536 06537 tot_length= my_strnxfrm(field_charset, 06538 (uchar*) to, length, 06539 (uchar*) ptr + length_bytes, 06540 tot_length); 06541 DBUG_ASSERT(tot_length == length); 06542 } 06543 06544 06545 enum ha_base_keytype Field_varstring::key_type() const 06546 { 06547 enum ha_base_keytype res; 06548 06549 if (binary()) 06550 res= length_bytes == 1 ? HA_KEYTYPE_VARBINARY1 : HA_KEYTYPE_VARBINARY2; 06551 else 06552 res= length_bytes == 1 ? HA_KEYTYPE_VARTEXT1 : HA_KEYTYPE_VARTEXT2; 06553 return res; 06554 } 06555 06556 06557 void Field_varstring::sql_type(String &res) const 06558 { 06559 THD *thd= table->in_use; 06560 CHARSET_INFO *cs=res.charset(); 06561 ulong length; 06562 06563 length= cs->cset->snprintf(cs,(char*) res.ptr(), 06564 res.alloced_length(), "%s(%d)", 06565 (has_charset() ? "varchar" : "varbinary"), 06566 (int) field_length / charset()->mbmaxlen); 06567 res.length(length); 06568 if ((thd->variables.sql_mode & (MODE_MYSQL323 | MODE_MYSQL40)) && 06569 has_charset() && (charset()->state & MY_CS_BINSORT)) 06570 res.append(STRING_WITH_LEN(" binary")); 06571 } 06572 06573 06574 uint32 Field_varstring::data_length(const char *from) 06575 { 06576 return length_bytes == 1 ? (uint) (uchar) *ptr : uint2korr(ptr); 06577 } 06578 06579 /* 06580 Functions to create a packed row. 06581 Here the number of length bytes are depending on the given max_length 06582 */ 06583 06584 char *Field_varstring::pack(char *to, const char *from, uint max_length) 06585 { 06586 uint length= length_bytes == 1 ? (uint) (uchar) *from : uint2korr(from); 06587 set_if_smaller(max_length, field_length); 06588 if (length > max_length) 06589 length=max_length; 06590 *to++= (char) (length & 255); 06591 if (max_length > 255) 06592 *to++= (char) (length >> 8); 06593 if (length) 06594 memcpy(to, from+length_bytes, length); 06595 return to+length; 06596 } 06597 06598 06599 char *Field_varstring::pack_key(char *to, const char *key, uint max_length) 06600 { 06601 uint length= length_bytes == 1 ? (uint) (uchar) *key : uint2korr(key); 06602 uint char_length= ((field_charset->mbmaxlen > 1) ? 06603 max_length/field_charset->mbmaxlen : max_length); 06604 key+= length_bytes; 06605 if (length > char_length) 06606 { 06607 char_length= my_charpos(field_charset, key, key+length, char_length); 06608 set_if_smaller(length, char_length); 06609 } 06610 *to++= (char) (length & 255); 06611 if (max_length > 255) 06612 *to++= (char) (length >> 8); 06613 if (length) 06614 memcpy(to, key, length); 06615 return to+length; 06616 } 06617 06618 06619 /* 06620 Unpack a key into a record buffer. 06621 06622 SYNOPSIS 06623 unpack_key() 06624 to Pointer into the record buffer. 06625 key Pointer to the packed key. 06626 max_length Key length limit from key description. 06627 06628 DESCRIPTION 06629 A VARCHAR key has a maximum size of 64K-1. 06630 In its packed form, the length field is one or two bytes long, 06631 depending on 'max_length'. 06632 06633 RETURN 06634 Pointer to end of 'key' (To the next key part if multi-segment key) 06635 */ 06636 06637 const char *Field_varstring::unpack_key(char *to, const char *key, 06638 uint max_length) 06639 { 06640 /* get length of the blob key */ 06641 uint32 length= *((uchar*) key++); 06642 if (max_length > 255) 06643 length+= (*((uchar*) key++)) << 8; 06644 06645 /* put the length into the record buffer */ 06646 if (length_bytes == 1) 06647 *ptr= (uchar) length; 06648 else 06649 int2store(ptr, length); 06650 memcpy(ptr + length_bytes, key, length); 06651 return key + length; 06652 } 06653 06654 /* 06655 Create a packed key that will be used for storage in the index tree 06656 06657 SYNOPSIS 06658 pack_key_from_key_image() 06659 to Store packed key segment here 06660 from Key segment (as given to index_read()) 06661 max_length Max length of key 06662 06663 RETURN 06664 end of key storage 06665 */ 06666 06667 char *Field_varstring::pack_key_from_key_image(char *to, const char *from, 06668 uint max_length) 06669 { 06670 /* Key length is always stored as 2 bytes */ 06671 uint length= uint2korr(from); 06672 if (length > max_length) 06673 length= max_length; 06674 *to++= (char) (length & 255); 06675 if (max_length > 255) 06676 *to++= (char) (length >> 8); 06677 if (length) 06678 memcpy(to, from+HA_KEY_BLOB_LENGTH, length); 06679 return to+length; 06680 } 06681 06682 06683 /* 06684 unpack field packed with Field_varstring::pack() 06685 */ 06686 06687 const char *Field_varstring::unpack(char *to, const char *from) 06688 { 06689 uint length; 06690 if (length_bytes == 1) 06691 length= (uint) (uchar) (*to= *from++); 06692 else 06693 { 06694 length= uint2korr(from); 06695 to[0]= *from++; 06696 to[1]= *from++; 06697 } 06698 if (length) 06699 memcpy(to+ length_bytes, from, length); 06700 return from+length; 06701 } 06702 06703 06704 int Field_varstring::pack_cmp(const char *a, const char *b, uint key_length, 06705 my_bool insert_or_update) 06706 { 06707 uint a_length, b_length; 06708 if (key_length > 255) 06709 { 06710 a_length=uint2korr(a); a+= 2; 06711 b_length=uint2korr(b); b+= 2; 06712 } 06713 else 06714 { 06715 a_length= (uint) (uchar) *a++; 06716 b_length= (uint) (uchar) *b++; 06717 } 06718 return field_charset->coll->strnncollsp(field_charset, 06719 (const uchar*) a, a_length, 06720 (const uchar*) b, b_length, 06721 insert_or_update); 06722 } 06723 06724 06725 int Field_varstring::pack_cmp(const char *b, uint key_length, 06726 my_bool insert_or_update) 06727 { 06728 char *a= ptr+ length_bytes; 06729 uint a_length= length_bytes == 1 ? (uint) (uchar) *ptr : uint2korr(ptr); 06730 uint b_length; 06731 uint char_length= ((field_charset->mbmaxlen > 1) ? 06732 key_length / field_charset->mbmaxlen : key_length); 06733 06734 if (key_length > 255) 06735 { 06736 b_length=uint2korr(b); b+= HA_KEY_BLOB_LENGTH; 06737 } 06738 else 06739 b_length= (uint) (uchar) *b++; 06740 06741 if (a_length > char_length) 06742 { 06743 char_length= my_charpos(field_charset, a, a+a_length, char_length); 06744 set_if_smaller(a_length, char_length); 06745 } 06746 06747 return field_charset->coll->strnncollsp(field_charset, 06748 (const uchar*) a, 06749 a_length, 06750 (const uchar*) b, b_length, 06751 insert_or_update); 06752 } 06753 06754 06755 uint Field_varstring::packed_col_length(const char *data_ptr, uint length) 06756 { 06757 if (length > 255) 06758 return uint2korr(data_ptr)+2; 06759 return (uint) ((uchar) *data_ptr)+1; 06760 } 06761 06762 06763 uint Field_varstring::max_packed_col_length(uint max_length) 06764 { 06765 return (max_length > 255 ? 2 : 1)+max_length; 06766 } 06767 06768 06769 void Field_varstring::get_key_image(char *buff, uint length, imagetype type) 06770 { 06771 uint f_length= length_bytes == 1 ? (uint) (uchar) *ptr : uint2korr(ptr); 06772 uint char_length= length / field_charset->mbmaxlen; 06773 char *pos= ptr+length_bytes; 06774 char_length= my_charpos(field_charset, pos, pos + f_length, char_length); 06775 set_if_smaller(f_length, char_length); 06776 /* Key is always stored with 2 bytes */ 06777 int2store(buff,f_length); 06778 memcpy(buff+HA_KEY_BLOB_LENGTH, pos, f_length); 06779 if (f_length < length) 06780 { 06781 /* 06782 Must clear this as we do a memcmp in opt_range.cc to detect 06783 identical keys 06784 */ 06785 bzero(buff+HA_KEY_BLOB_LENGTH+f_length, (length-f_length)); 06786 } 06787 } 06788 06789 06790 void Field_varstring::set_key_image(char *buff,uint length) 06791 { 06792 length= uint2korr(buff); // Real length is here 06793 (void) Field_varstring::store(buff+HA_KEY_BLOB_LENGTH, length, 06794 field_charset); 06795 } 06796 06797 06798 int Field_varstring::cmp_binary(const char *a_ptr, const char *b_ptr, 06799 uint32 max_length) 06800 { 06801 uint32 a_length,b_length; 06802 06803 if (length_bytes == 1) 06804 { 06805 a_length= (uint) (uchar) *a_ptr; 06806 b_length= (uint) (uchar) *b_ptr; 06807 } 06808 else 06809 { 06810 a_length= uint2korr(a_ptr); 06811 b_length= uint2korr(b_ptr); 06812 } 06813 set_if_smaller(a_length, max_length); 06814 set_if_smaller(b_length, max_length); 06815 if (a_length != b_length) 06816 return 1; 06817 return memcmp(a_ptr+length_bytes, b_ptr+length_bytes, a_length); 06818 } 06819 06820 06821 Field *Field_varstring::new_field(MEM_ROOT *root, struct st_table *new_table, 06822 bool keep_type) 06823 { 06824 Field_varstring *res= (Field_varstring*) Field::new_field(root, new_table, 06825 keep_type); 06826 if (res) 06827 res->length_bytes= length_bytes; 06828 return res; 06829 } 06830 06831 06832 Field *Field_varstring::new_key_field(MEM_ROOT *root, 06833 struct st_table *new_table, 06834 char *new_ptr, uchar *new_null_ptr, 06835 uint new_null_bit) 06836 { 06837 Field_varstring *res; 06838 if ((res= (Field_varstring*) Field::new_key_field(root, 06839 new_table, 06840 new_ptr, 06841 new_null_ptr, 06842 new_null_bit))) 06843 { 06844 /* Keys length prefixes are always packed with 2 bytes */ 06845 res->length_bytes= 2; 06846 } 06847 return res; 06848 } 06849 06850 06851 uint Field_varstring::is_equal(create_field *new_field) 06852 { 06853 if (new_field->sql_type == real_type() && 06854 new_field->charset == field_charset) 06855 { 06856 if (new_field->length == max_length()) 06857 return IS_EQUAL_YES; 06858 if (new_field->length > max_length() && 06859 ((new_field->length <= 255 && max_length() <= 255) || 06860 (new_field->length > 255 && max_length() > 255))) 06861 return IS_EQUAL_PACK_LENGTH; // VARCHAR, longer variable length 06862 } 06863 return IS_EQUAL_NO; 06864 } 06865 06866 06867 void Field_varstring::hash(ulong *nr, ulong *nr2) 06868 { 06869 if (is_null()) 06870 { 06871 *nr^= (*nr << 1) | 1; 06872 } 06873 else 06874 { 06875 uint len= length_bytes == 1 ? (uint) (uchar) *ptr : uint2korr(ptr); 06876 CHARSET_INFO *cs= charset(); 06877 cs->coll->hash_sort(cs, (uchar*) ptr + length_bytes, len, nr, nr2); 06878 } 06879 } 06880 06881 06882 /**************************************************************************** 06883 ** blob type 06884 ** A blob is saved as a length and a pointer. The length is stored in the 06885 ** packlength slot and may be from 1-4. 06886 ****************************************************************************/ 06887 06888 Field_blob::Field_blob(char *ptr_arg, uchar *null_ptr_arg, uchar null_bit_arg, 06889 enum utype unireg_check_arg, const char *field_name_arg, 06890 TABLE_SHARE *share, uint blob_pack_length, 06891 CHARSET_INFO *cs) 06892 :Field_longstr(ptr_arg, BLOB_PACK_LENGTH_TO_MAX_LENGH(blob_pack_length), 06893 null_ptr_arg, null_bit_arg, unireg_check_arg, field_name_arg, 06894 cs), 06895 packlength(blob_pack_length) 06896 { 06897 flags|= BLOB_FLAG; 06898 share->blob_fields++; 06899 /* TODO: why do not fill table->s->blob_field array here? */ 06900 } 06901 06902 06903 void Field_blob::store_length(uint32 number) 06904 { 06905 switch (packlength) { 06906 case 1: 06907 ptr[0]= (uchar) number; 06908 break; 06909 case 2: 06910 #ifdef WORDS_BIGENDIAN 06911 if (table->s->db_low_byte_first) 06912 { 06913 int2store(ptr,(unsigned short) number); 06914 } 06915 else 06916 #endif 06917 shortstore(ptr,(unsigned short) number); 06918 break; 06919 case 3: 06920 int3store(ptr,number); 06921 break; 06922 case 4: 06923 #ifdef WORDS_BIGENDIAN 06924 if (table->s->db_low_byte_first) 06925 { 06926 int4store(ptr,number); 06927 } 06928 else 06929 #endif 06930 longstore(ptr,number); 06931 } 06932 } 06933 06934 06935 uint32 Field_blob::get_length(const char *pos) 06936 { 06937 switch (packlength) { 06938 case 1: 06939 return (uint32) (uchar) pos[0]; 06940 case 2: 06941 { 06942 uint16 tmp; 06943 #ifdef WORDS_BIGENDIAN 06944 if (table->s->db_low_byte_first) 06945 tmp=sint2korr(pos); 06946 else 06947 #endif 06948 shortget(tmp,pos); 06949 return (uint32) tmp; 06950 } 06951 case 3: 06952 return (uint32) uint3korr(pos); 06953 case 4: 06954 { 06955 uint32 tmp; 06956 #ifdef WORDS_BIGENDIAN 06957 if (table->s->db_low_byte_first) 06958 tmp=uint4korr(pos); 06959 else 06960 #endif 06961 longget(tmp,pos); 06962 return (uint32) tmp; 06963 } 06964 } 06965 return 0; // Impossible 06966 } 06967 06968 06969 /* 06970 Put a blob length field into a record buffer. 06971 06972 SYNOPSIS 06973 Field_blob::put_length() 06974 pos Pointer into the record buffer. 06975 length The length value to put. 06976 06977 DESCRIPTION 06978 Depending on the maximum length of a blob, its length field is 06979 put into 1 to 4 bytes. This is a property of the blob object, 06980 described by 'packlength'. 06981 06982 RETURN 06983 nothing 06984 */ 06985 06986 void Field_blob::put_length(char *pos, uint32 length) 06987 { 06988 switch (packlength) { 06989 case 1: 06990 *pos= (char) length; 06991 break; 06992 case 2: 06993 int2store(pos, length); 06994 break; 06995 case 3: 06996 int3store(pos, length); 06997 break; 06998 case 4: 06999 int4store(pos, length); 07000 break; 07001 } 07002 } 07003 07004 07005 int Field_blob::store(const char *from,uint length,CHARSET_INFO *cs) 07006 { 07007 ASSERT_COLUMN_MARKED_FOR_WRITE; 07008 int error= 0, well_formed_error; 07009 if (!length) 07010 { 07011 bzero(ptr,Field_blob::pack_length()); 07012 } 07013 else 07014 { 07015 bool was_conversion; 07016 char buff[STRING_BUFFER_USUAL_SIZE]; 07017 String tmpstr(buff,sizeof(buff), &my_charset_bin); 07018 uint copy_length; 07019 uint32 not_used; 07020 07021 /* Convert character set if necessary */ 07022 if ((was_conversion= String::needs_conversion(length, cs, field_charset, 07023 ¬_used))) 07024 { 07025 uint conv_errors; 07026 if (tmpstr.copy(from, length, cs, field_charset, &conv_errors)) 07027 { 07028 /* Fatal OOM error */ 07029 bzero(ptr,Field_blob::pack_length()); 07030 return -1; 07031 } 07032 from= tmpstr.ptr(); 07033 length= tmpstr.length(); 07034 if (conv_errors) 07035 error= 2; 07036 } 07037 07038 copy_length= max_data_length(); 07039 /* 07040 copy_length is OK as last argument to well_formed_len as this is never 07041 used to limit the length of the data. The cut of long data is done with 07042 the 'min()' call below. 07043 */ 07044 copy_length= field_charset->cset->well_formed_len(field_charset, 07045 from,from + 07046 min(length, copy_length), 07047 copy_length, 07048 &well_formed_error); 07049 if (copy_length < length) 07050 error= 2; 07051 Field_blob::store_length(copy_length); 07052 if (was_conversion || table->copy_blobs || copy_length <= MAX_FIELD_WIDTH) 07053 { // Must make a copy 07054 if (from != value.ptr()) // For valgrind 07055 { 07056 value.copy(from,copy_length,charset()); 07057 from=value.ptr(); 07058 } 07059 } 07060 bmove(ptr+packlength,(char*) &from,sizeof(char*)); 07061 } 07062 if (error) 07063 { 07064 if (table->in_use->abort_on_warning) 07065 set_warning(MYSQL_ERROR::WARN_LEVEL_ERROR, ER_DATA_TOO_LONG, 1); 07066 else 07067 set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, 1); 07068 } 07069 return 0; 07070 } 07071 07072 07073 int Field_blob::store(double nr) 07074 { 07075 CHARSET_INFO *cs=charset(); 07076 value.set_real(nr, 2, cs); 07077 return Field_blob::store(value.ptr(),(uint) value.length(), cs); 07078 } 07079 07080 07081 int Field_blob::store(longlong nr, bool unsigned_val) 07082 { 07083 CHARSET_INFO *cs=charset(); 07084 value.set_int(nr, unsigned_val, cs); 07085 return Field_blob::store(value.ptr(), (uint) value.length(), cs); 07086 } 07087 07088 07089 double Field_blob::val_real(void) 07090 { 07091 ASSERT_COLUMN_MARKED_FOR_READ; 07092 int not_used; 07093 char *end_not_used, *blob; 07094 uint32 length; 07095 CHARSET_INFO *cs; 07096 07097 memcpy_fixed(&blob,ptr+packlength,sizeof(char*)); 07098 if (!blob) 07099 return 0.0; 07100 length= get_length(ptr); 07101 cs= charset(); 07102 return my_strntod(cs, blob, length, &end_not_used, ¬_used); 07103 } 07104 07105 07106 longlong Field_blob::val_int(void) 07107 { 07108 ASSERT_COLUMN_MARKED_FOR_READ; 07109 int not_used; 07110 char *blob; 07111 memcpy_fixed(&blob,ptr+packlength,sizeof(char*)); 07112 if (!blob) 07113 return 0; 07114 uint32 length=get_length(ptr); 07115 return my_strntoll(charset(),blob,length,10,NULL,¬_used); 07116 } 07117 07118 String *Field_blob::val_str(String *val_buffer __attribute__((unused)), 07119 String *val_ptr) 07120 { 07121 ASSERT_COLUMN_MARKED_FOR_READ; 07122 char *blob; 07123 memcpy_fixed(&blob,ptr+packlength,sizeof(char*)); 07124 if (!blob) 07125 val_ptr->set("",0,charset()); // A bit safer than ->length(0) 07126 else 07127 val_ptr->set((const char*) blob,get_length(ptr),charset()); 07128 return val_ptr; 07129 } 07130 07131 07132 my_decimal *Field_blob::val_decimal(my_decimal *decimal_value) 07133 { 07134 ASSERT_COLUMN_MARKED_FOR_READ; 07135 const char *blob; 07136 memcpy_fixed(&blob, ptr+packlength, sizeof(const char*)); 07137 if (!blob) 07138 blob= ""; 07139 str2my_decimal(E_DEC_FATAL_ERROR, blob, get_length(ptr), charset(), 07140 decimal_value); 07141 return decimal_value; 07142 } 07143 07144 07145 int Field_blob::cmp(const char *a,uint32 a_length, const char *b, 07146 uint32 b_length) 07147 { 07148 return field_charset->coll->strnncollsp(field_charset, 07149 (const uchar*)a, a_length, 07150 (const uchar*)b, b_length, 07151 0); 07152 } 07153 07154 07155 int Field_blob::cmp_max(const char *a_ptr, const char *b_ptr, 07156 uint max_length) 07157 { 07158 char *blob1,*blob2; 07159 memcpy_fixed(&blob1,a_ptr+packlength,sizeof(char*)); 07160 memcpy_fixed(&blob2,b_ptr+packlength,sizeof(char*)); 07161 uint a_len= get_length(a_ptr), b_len= get_length(b_ptr); 07162 set_if_smaller(a_len, max_length); 07163 set_if_smaller(b_len, max_length); 07164 return Field_blob::cmp(blob1,a_len,blob2,b_len); 07165 } 07166 07167 07168 int Field_blob::cmp_binary(const char *a_ptr, const char *b_ptr, 07169 uint32 max_length) 07170 { 07171 char *a,*b; 07172 uint diff; 07173 uint32 a_length,b_length; 07174 memcpy_fixed(&a,a_ptr+packlength,sizeof(char*)); 07175 memcpy_fixed(&b,b_ptr+packlength,sizeof(char*)); 07176 a_length=get_length(a_ptr); 07177 if (a_length > max_length) 07178 a_length=max_length; 07179 b_length=get_length(b_ptr); 07180 if (b_length > max_length) 07181 b_length=max_length; 07182 diff=memcmp(a,b,min(a_length,b_length)); 07183 return diff ? diff : (int) (a_length - b_length); 07184 } 07185 07186 07187 /* The following is used only when comparing a key */ 07188 07189 void Field_blob::get_key_image(char *buff, uint length, imagetype type) 07190 { 07191 uint32 blob_length= get_length(ptr); 07192 char *blob; 07193 07194 #ifdef HAVE_SPATIAL 07195 if (type == itMBR) 07196 { 07197 const char *dummy; 07198 MBR mbr; 07199 Geometry_buffer buffer; 07200 Geometry *gobj; 07201 07202 if (blob_length < SRID_SIZE) 07203 { 07204 bzero(buff, SIZEOF_STORED_DOUBLE*4); 07205 return; 07206 } 07207 get_ptr(&blob); 07208 gobj= Geometry::construct(&buffer, blob, blob_length); 07209 if (!gobj || gobj->get_mbr(&mbr, &dummy)) 07210 bzero(buff, SIZEOF_STORED_DOUBLE*4); 07211 else 07212 { 07213 float8store(buff, mbr.xmin); 07214 float8store(buff+8, mbr.xmax); 07215 float8store(buff+16, mbr.ymin); 07216 float8store(buff+24, mbr.ymax); 07217 } 07218 return; 07219 } 07220 #endif /*HAVE_SPATIAL*/ 07221 07222 get_ptr(&blob); 07223 uint char_length= length / field_charset->mbmaxlen; 07224 char_length= my_charpos(field_charset, blob, blob + blob_length, 07225 char_length); 07226 set_if_smaller(blob_length, char_length); 07227 07228 if ((uint32) length > blob_length) 07229 { 07230 /* 07231 Must clear this as we do a memcmp in opt_range.cc to detect 07232 identical keys 07233 */ 07234 bzero(buff+HA_KEY_BLOB_LENGTH+blob_length, (length-blob_length)); 07235 length=(uint) blob_length; 07236 } 07237 int2store(buff,length); 07238 memcpy(buff+HA_KEY_BLOB_LENGTH, blob, length); 07239 } 07240 07241 07242 void Field_blob::set_key_image(char *buff,uint length) 07243 { 07244 length= uint2korr(buff); 07245 (void) Field_blob::store(buff+HA_KEY_BLOB_LENGTH, length, field_charset); 07246 } 07247 07248 07249 int Field_blob::key_cmp(const byte *key_ptr, uint max_key_length) 07250 { 07251 char *blob1; 07252 uint blob_length=get_length(ptr); 07253 memcpy_fixed(&blob1,ptr+packlength,sizeof(char*)); 07254 CHARSET_INFO *cs= charset(); 07255 uint char_length= max_key_length / cs->mbmaxlen; 07256 char_length= my_charpos(cs, blob1, blob1+blob_length, char_length); 07257 set_if_smaller(blob_length, char_length); 07258 return Field_blob::cmp(blob1, blob_length, 07259 (char*) key_ptr+HA_KEY_BLOB_LENGTH, 07260 uint2korr(key_ptr)); 07261 } 07262 07263 int Field_blob::key_cmp(const byte *a,const byte *b) 07264 { 07265 return Field_blob::cmp((char*) a+HA_KEY_BLOB_LENGTH, uint2korr(a), 07266 (char*) b+HA_KEY_BLOB_LENGTH, uint2korr(b)); 07267 } 07268 07269 07270 uint32 Field_blob::sort_length() const 07271 { 07272 return (uint32) (current_thd->variables.max_sort_length + 07273 (field_charset == &my_charset_bin ? 0 : packlength)); 07274 } 07275 07276 07277 void Field_blob::sort_string(char *to,uint length) 07278 { 07279 char *blob; 07280 uint blob_length=get_length(); 07281 07282 if (!blob_length) 07283 bzero(to,length); 07284 else 07285 { 07286 if (field_charset == &my_charset_bin) 07287 { 07288 char *pos; 07289 07290 /* 07291 Store length of blob last in blob to shorter blobs before longer blobs 07292 */ 07293 length-= packlength; 07294 pos= to+length; 07295 07296 switch (packlength) { 07297 case 1: 07298 *pos= (char) blob_length; 07299 break; 07300 case 2: 07301 mi_int2store(pos, blob_length); 07302 break; 07303 case 3: 07304 mi_int3store(pos, blob_length); 07305 break; 07306 case 4: 07307 mi_int4store(pos, blob_length); 07308 break; 07309 } 07310 } 07311 memcpy_fixed(&blob,ptr+packlength,sizeof(char*)); 07312 07313 blob_length=my_strnxfrm(field_charset, 07314 (uchar*) to, length, 07315 (uchar*) blob, blob_length); 07316 DBUG_ASSERT(blob_length == length); 07317 } 07318 } 07319 07320 07321 void Field_blob::sql_type(String &res) const 07322 { 07323 const char *str; 07324 uint length; 07325 switch (packlength) { 07326 default: str="tiny"; length=4; break; 07327 case 2: str=""; length=0; break; 07328 case 3: str="medium"; length= 6; break; 07329 case 4: str="long"; length=4; break; 07330 } 07331 res.set_ascii(str,length); 07332 if (charset() == &my_charset_bin) 07333 res.append(STRING_WITH_LEN("blob")); 07334 else 07335 { 07336 res.append(STRING_WITH_LEN("text")); 07337 } 07338 } 07339 07340 07341 char *Field_blob::pack(char *to, const char *from, uint max_length) 07342 { 07343 char *save=ptr; 07344 ptr=(char*) from; 07345 uint32 length=get_length(); // Length of from string 07346 if (length > max_length) 07347 { 07348 ptr=to; 07349 length=max_length; 07350 store_length(length); // Store max length 07351 ptr=(char*) from; 07352 } 07353 else 07354 memcpy(to,from,packlength); // Copy length 07355 if (length) 07356 { 07357 get_ptr((char**) &from); 07358 memcpy(to+packlength, from,length); 07359 } 07360 ptr=save; // Restore org row pointer 07361 return to+packlength+length; 07362 } 07363 07364 07365 const char *Field_blob::unpack(char *to, const char *from) 07366 { 07367 memcpy(to,from,packlength); 07368 uint32 length=get_length(from); 07369 from+=packlength; 07370 if (length) 07371 memcpy_fixed(to+packlength, &from, sizeof(from)); 07372 else 07373 bzero(to+packlength,sizeof(from)); 07374 return from+length; 07375 } 07376 07377 /* Keys for blobs are like keys on varchars */ 07378 07379 int Field_blob::pack_cmp(const char *a, const char *b, uint key_length, 07380 my_bool insert_or_update) 07381 { 07382 uint a_length, b_length; 07383 if (key_length > 255) 07384 { 07385 a_length=uint2korr(a); a+=2; 07386 b_length=uint2korr(b); b+=2; 07387 } 07388 else 07389 { 07390 a_length= (uint) (uchar) *a++; 07391 b_length= (uint) (uchar) *b++; 07392 } 07393 return field_charset->coll->strnncollsp(field_charset, 07394 (const uchar*) a, a_length, 07395 (const uchar*) b, b_length, 07396 insert_or_update); 07397 } 07398 07399 07400 int Field_blob::pack_cmp(const char *b, uint key_length, 07401 my_bool insert_or_update) 07402 { 07403 char *a; 07404 memcpy_fixed(&a,ptr+packlength,sizeof(char*)); 07405 if (!a) 07406 return key_length > 0 ? -1 : 0; 07407 uint a_length=get_length(ptr); 07408 uint b_length; 07409 07410 if (key_length > 255) 07411 { 07412 b_length=uint2korr(b); b+=2; 07413 } 07414 else 07415 b_length= (uint) (uchar) *b++; 07416 return field_charset->coll->strnncollsp(field_charset, 07417 (const uchar*) a, a_length, 07418 (const uchar*) b, b_length, 07419 insert_or_update); 07420 } 07421 07422 /* Create a packed key that will be used for storage from a MySQL row */ 07423 07424 char *Field_blob::pack_key(char *to, const char *from, uint max_length) 07425 { 07426 char *save=ptr; 07427 ptr=(char*) from; 07428 uint32 length=get_length(); // Length of from string 07429 uint char_length= ((field_charset->mbmaxlen > 1) ? 07430 max_length/field_charset->mbmaxlen : max_length); 07431 if (length) 07432 get_ptr((char**) &from); 07433 if (length > char_length) 07434 char_length= my_charpos(field_charset, from, from+length, char_length); 07435 set_if_smaller(length, char_length); 07436 *to++= (uchar) length; 07437 if (max_length > 255) // 2 byte length 07438 *to++= (uchar) (length >> 8); 07439 memcpy(to, from, length); 07440 ptr=save; // Restore org row pointer 07441 return to+length; 07442 } 07443 07444 07445 /* 07446 Unpack a blob key into a record buffer. 07447 07448 SYNOPSIS 07449 Field_blob::unpack_key() 07450 to Pointer into the record buffer. 07451 from Pointer to the packed key. 07452 max_length Key length limit from key description. 07453 07454 DESCRIPTION 07455 A blob key has a maximum size of 64K-1. 07456 In its packed form, the length field is one or two bytes long, 07457 depending on 'max_length'. 07458 Depending on the maximum length of a blob, its length field is 07459 put into 1 to 4 bytes. This is a property of the blob object, 07460 described by 'packlength'. 07461 Blobs are internally stored apart from the record buffer, which 07462 contains a pointer to the blob buffer. 07463 07464 RETURN 07465 Pointer into 'from' past the last byte copied from packed key. 07466 */ 07467 07468 const char *Field_blob::unpack_key(char *to, const char *from, uint max_length) 07469 { 07470 /* get length of the blob key */ 07471 uint32 length= *((uchar*) from++); 07472 if (max_length > 255) 07473 length+= (*((uchar*) from++)) << 8; 07474 07475 /* put the length into the record buffer */ 07476 put_length(to, length); 07477 07478 /* put the address of the blob buffer or NULL */ 07479 if (length) 07480 memcpy_fixed(to + packlength, &from, sizeof(from)); 07481 else 07482 bzero(to + packlength, sizeof(from)); 07483 07484 /* point to first byte of next field in 'from' */ 07485 return from + length; 07486 } 07487 07488 07489 /* Create a packed key that will be used for storage from a MySQL key */ 07490 07491 char *Field_blob::pack_key_from_key_image(char *to, const char *from, 07492 uint max_length) 07493 { 07494 uint length=uint2korr(from); 07495 if (length > max_length) 07496 length=max_length; 07497 *to++= (char) (length & 255); 07498 if (max_length > 255) 07499 *to++= (char) (length >> 8); 07500 if (length) 07501 memcpy(to, from+HA_KEY_BLOB_LENGTH, length); 07502 return to+length; 07503 } 07504 07505 07506 uint Field_blob::packed_col_length(const char *data_ptr, uint length) 07507 { 07508 if (length > 255) 07509 return uint2korr(data_ptr)+2; 07510 return (uint) ((uchar) *data_ptr)+1; 07511 } 07512 07513 07514 uint Field_blob::max_packed_col_length(uint max_length) 07515 { 07516 return (max_length > 255 ? 2 : 1)+max_length; 07517 } 07518 07519 07520 #ifdef HAVE_SPATIAL 07521 07522 void Field_geom::get_key_image(char *buff, uint length, imagetype type) 07523 { 07524 char *blob; 07525 const char *dummy; 07526 MBR mbr; 07527 ulong blob_length= get_length(ptr); 07528 Geometry_buffer buffer; 07529 Geometry *gobj; 07530 07531 if (blob_length < SRID_SIZE) 07532 { 07533 bzero(buff, SIZEOF_STORED_DOUBLE*4); 07534 return; 07535 } 07536 get_ptr(&blob); 07537 gobj= Geometry::construct(&buffer, blob, blob_length); 07538 if (!gobj || gobj->get_mbr(&mbr, &dummy)) 07539 bzero(buff, SIZEOF_STORED_DOUBLE*4); 07540 else 07541 { 07542 float8store(buff, mbr.xmin); 07543 float8store(buff + 8, mbr.xmax); 07544 float8store(buff + 16, mbr.ymin); 07545 float8store(buff + 24, mbr.ymax); 07546 } 07547 } 07548 07549 07550 void Field_geom::sql_type(String &res) const 07551 { 07552 CHARSET_INFO *cs= &my_charset_latin1; 07553 switch (geom_type) 07554 { 07555 case GEOM_POINT: 07556 res.set(STRING_WITH_LEN("point"), cs); 07557 break; 07558 case GEOM_LINESTRING: 07559 res.set(STRING_WITH_LEN("linestring"), cs); 07560 break; 07561 case GEOM_POLYGON: 07562 res.set(STRING_WITH_LEN("polygon"), cs); 07563 break; 07564 case GEOM_MULTIPOINT: 07565 res.set(STRING_WITH_LEN("multipoint"), cs); 07566 break; 07567 case GEOM_MULTILINESTRING: 07568 res.set(STRING_WITH_LEN("multilinestring"), cs); 07569 break; 07570 case GEOM_MULTIPOLYGON: 07571 res.set(STRING_WITH_LEN("multipolygon"), cs); 07572 break; 07573 case GEOM_GEOMETRYCOLLECTION: 07574 res.set(STRING_WITH_LEN("geometrycollection"), cs); 07575 break; 07576 default: 07577 res.set(STRING_WITH_LEN("geometry"), cs); 07578 } 07579 } 07580 07581 07582 int Field_geom::store(double nr) 07583 { 07584 my_message(ER_CANT_CREATE_GEOMETRY_OBJECT, 07585 ER(ER_CANT_CREATE_GEOMETRY_OBJECT), MYF(0)); 07586 return -1; 07587 } 07588 07589 07590 int Field_geom::store(longlong nr, bool unsigned_val) 07591 { 07592 my_message(ER_CANT_CREATE_GEOMETRY_OBJECT, 07593 ER(ER_CANT_CREATE_GEOMETRY_OBJECT), MYF(0)); 07594 return -1; 07595 } 07596 07597 07598 int Field_geom::store_decimal(const my_decimal *) 07599 { 07600 my_message(ER_CANT_CREATE_GEOMETRY_OBJECT, 07601 ER(ER_CANT_CREATE_GEOMETRY_OBJECT), MYF(0)); 07602 return -1; 07603 } 07604 07605 07606 int Field_geom::store(const char *from, uint length, CHARSET_INFO *cs) 07607 { 07608 if (!length) 07609 bzero(ptr, Field_blob::pack_length()); 07610 else 07611 { 07612 if (from == Geometry::bad_geometry_data.ptr()) 07613 goto err; 07614 // Check given WKB 07615 uint32 wkb_type; 07616 if (length < SRID_SIZE + WKB_HEADER_SIZE + SIZEOF_STORED_DOUBLE*2) 07617 goto err; 07618 wkb_type= uint4korr(from + SRID_SIZE + 1); 07619 if (wkb_type < (uint32) Geometry::wkb_point || 07620 wkb_type > (uint32) Geometry::wkb_end) 07621 goto err; 07622 Field_blob::store_length(length); 07623 if (table->copy_blobs || length <= MAX_FIELD_WIDTH) 07624 { // Must make a copy 07625 value.copy(from, length, cs); 07626 from= value.ptr(); 07627 } 07628 bmove(ptr + packlength, (char*) &from, sizeof(char*)); 07629 } 07630 return 0; 07631 07632 err: 07633 bzero(ptr, Field_blob::pack_length()); 07634 my_message(ER_CANT_CREATE_GEOMETRY_OBJECT, 07635 ER(ER_CANT_CREATE_GEOMETRY_OBJECT), MYF(0)); 07636 return -1; 07637 } 07638 07639 #endif /*HAVE_SPATIAL*/ 07640 07641 /**************************************************************************** 07642 ** enum type. 07643 ** This is a string which only can have a selection of different values. 07644 ** If one uses this string in a number context one gets the type number. 07645 ****************************************************************************/ 07646 07647 enum ha_base_keytype Field_enum::key_type() const 07648 { 07649 switch (packlength) { 07650 default: return HA_KEYTYPE_BINARY; 07651 case 2: return HA_KEYTYPE_USHORT_INT; 07652 case 3: return HA_KEYTYPE_UINT24; 07653 case 4: return HA_KEYTYPE_ULONG_INT; 07654 case 8: return HA_KEYTYPE_ULONGLONG; 07655 } 07656 } 07657 07658 void Field_enum::store_type(ulonglong value) 07659 { 07660 switch (packlength) { 07661 case 1: ptr[0]= (uchar) value; break; 07662 case 2: 07663 #ifdef WORDS_BIGENDIAN 07664 if (table->s->db_low_byte_first) 07665 { 07666 int2store(ptr,(unsigned short) value); 07667 } 07668 else 07669 #endif 07670 shortstore(ptr,(unsigned short) value); 07671 break; 07672 case 3: int3store(ptr,(long) value); break; 07673 case 4: 07674 #ifdef WORDS_BIGENDIAN 07675 if (table->s->db_low_byte_first) 07676 { 07677 int4store(ptr,value); 07678 } 07679 else 07680 #endif 07681 longstore(ptr,(long) value); 07682 break; 07683 case 8: 07684 #ifdef WORDS_BIGENDIAN 07685 if (table->s->db_low_byte_first) 07686 { 07687 int8store(ptr,value); 07688 } 07689 else 07690 #endif 07691 longlongstore(ptr,value); break; 07692 } 07693 } 07694 07695 07696 /* 07697 ** Note. Storing a empty string in a enum field gives a warning 07698 ** (if there isn't a empty value in the enum) 07699 */ 07700 07701 int Field_enum::store(const char *from,uint length,CHARSET_INFO *cs) 07702 { 07703 ASSERT_COLUMN_MARKED_FOR_WRITE; 07704 int err= 0; 07705 uint32 not_used; 07706 char buff[STRING_BUFFER_USUAL_SIZE]; 07707 String tmpstr(buff,sizeof(buff), &my_charset_bin); 07708 07709 /* Convert character set if necessary */ 07710 if (String::needs_conversion(length, cs, field_charset, ¬_used)) 07711 { 07712 uint dummy_errors; 07713 tmpstr.copy(from, length, cs, field_charset, &dummy_errors); 07714 from= tmpstr.ptr(); 07715 length= tmpstr.length(); 07716 } 07717 07718 /* Remove end space */ 07719 length= field_charset->cset->lengthsp(field_charset, from, length); 07720 uint tmp=find_type2(typelib, from, length, field_charset); 07721 if (!tmp) 07722 { 07723 if (length < 6) // Can't be more than 99999 enums 07724 { 07725 /* This is for reading numbers with LOAD DATA INFILE */ 07726 char *end; 07727 tmp=(uint) my_strntoul(cs,from,length,10,&end,&err); 07728 if (err || end != from+length || tmp > typelib->count) 07729 { 07730 tmp=0; 07731 set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, 1); 07732 } 07733 } 07734 else 07735 set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, 1); 07736 } 07737 store_type((ulonglong) tmp); 07738 return err; 07739 } 07740 07741 07742 int Field_enum::store(double nr) 07743 { 07744 return Field_enum::store((longlong) nr, FALSE); 07745 } 07746 07747 07748 int Field_enum::store(longlong nr, bool unsigned_val) 07749 { 07750 ASSERT_COLUMN_MARKED_FOR_WRITE; 07751 int error= 0; 07752 if ((ulonglong) nr > typelib->count || nr == 0) 07753 { 07754 set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, 1); 07755 nr=0; 07756 error=1; 07757 } 07758 store_type((ulonglong) (uint) nr); 07759 return error; 07760 } 07761 07762 07763 double Field_enum::val_real(void) 07764 { 07765 return (double) Field_enum::val_int(); 07766 } 07767 07768 07769 longlong Field_enum::val_int(void) 07770 { 07771 ASSERT_COLUMN_MARKED_FOR_READ; 07772 switch (packlength) { 07773 case 1: 07774 return (longlong) (uchar) ptr[0]; 07775 case 2: 07776 { 07777 uint16 tmp; 07778 #ifdef WORDS_BIGENDIAN 07779 if (table->s->db_low_byte_first) 07780 tmp=sint2korr(ptr); 07781 else 07782 #endif 07783 shortget(tmp,ptr); 07784 return (longlong) tmp; 07785 } 07786 case 3: 07787 return (longlong) uint3korr(ptr); 07788 case 4: 07789 { 07790 uint32 tmp; 07791 #ifdef WORDS_BIGENDIAN 07792 if (table->s->db_low_byte_first) 07793 tmp=uint4korr(ptr); 07794 else 07795 #endif 07796 longget(tmp,ptr); 07797 return (longlong) tmp; 07798 } 07799 case 8: 07800 { 07801 longlong tmp; 07802 #ifdef WORDS_BIGENDIAN 07803 if (table->s->db_low_byte_first) 07804 tmp=sint8korr(ptr); 07805 else 07806 #endif 07807 longlongget(tmp,ptr); 07808 return tmp; 07809 } 07810 } 07811 return 0; // impossible 07812 } 07813 07814 07815 String *Field_enum::val_str(String *val_buffer __attribute__((unused)), 07816 String *val_ptr) 07817 { 07818 uint tmp=(uint) Field_enum::val_int(); 07819 if (!tmp || tmp > typelib->count) 07820 val_ptr->set("", 0, field_charset); 07821 else 07822 val_ptr->set((const char*) typelib->type_names[tmp-1], 07823 typelib->type_lengths[tmp-1], 07824 field_charset); 07825 return val_ptr; 07826 } 07827 07828 int Field_enum::cmp(const char *a_ptr, const char *b_ptr) 07829 { 07830 char *old=ptr; 07831 ptr=(char*) a_ptr; 07832 ulonglong a=Field_enum::val_int(); 07833 ptr=(char*) b_ptr; 07834 ulonglong b=Field_enum::val_int(); 07835 ptr=old; 07836 return (a < b) ? -1 : (a > b) ? 1 : 0; 07837 } 07838 07839 void Field_enum::sort_string(char *to,uint length __attribute__((unused))) 07840 { 07841 ulonglong value=Field_enum::val_int(); 07842 to+=packlength-1; 07843 for (uint i=0 ; i < packlength ; i++) 07844 { 07845 *to-- = (uchar) (value & 255); 07846 value>>=8; 07847 } 07848 } 07849 07850 07851 void Field_enum::sql_type(String &res) const 07852 { 07853 char buffer[255]; 07854 String enum_item(buffer, sizeof(buffer), res.charset()); 07855 07856 res.length(0); 07857 res.append(STRING_WITH_LEN("enum(")); 07858 07859 bool flag=0; 07860 uint *len= typelib->type_lengths; 07861 for (const char **pos= typelib->type_names; *pos; pos++, len++) 07862 { 07863 uint dummy_errors; 07864 if (flag) 07865 res.append(','); 07866 /* convert to res.charset() == utf8, then quote */ 07867 enum_item.copy(*pos, *len, charset(), res.charset(), &dummy_errors); 07868 append_unescaped(&res, enum_item.ptr(), enum_item.length()); 07869 flag= 1; 07870 } 07871 res.append(')'); 07872 } 07873 07874 07875 /* 07876 set type. 07877 This is a string which can have a collection of different values. 07878 Each string value is separated with a ','. 07879 For example "One,two,five" 07880 If one uses this string in a number context one gets the bits as a longlong 07881 number. 07882 */ 07883 07884 07885 int Field_set::store(const char *from,uint length,CHARSET_INFO *cs) 07886 { 07887 ASSERT_COLUMN_MARKED_FOR_WRITE; 07888 bool got_warning= 0; 07889 int err= 0; 07890 char *not_used; 07891 uint not_used2; 07892 uint32 not_used_offset; 07893 char buff[STRING_BUFFER_USUAL_SIZE]; 07894 String tmpstr(buff,sizeof(buff), &my_charset_bin); 07895 07896 /* Convert character set if necessary */ 07897 if (String::needs_conversion(length, cs, field_charset, ¬_used_offset)) 07898 { 07899 uint dummy_errors; 07900 tmpstr.copy(from, length, cs, field_charset, &dummy_errors); 07901 from= tmpstr.ptr(); 07902 length= tmpstr.length(); 07903 } 07904 ulonglong tmp= find_set(typelib, from, length, field_charset, 07905 ¬_used, ¬_used2, &got_warning); 07906 if (!tmp && length && length < 22) 07907 { 07908 /* This is for reading numbers with LOAD DATA INFILE */ 07909 char *end; 07910 tmp=my_strntoull(cs,from,length,10,&end,&err); 07911 if (err || end != from+length || 07912 tmp > (ulonglong) (((longlong) 1 << typelib->count) - (longlong) 1)) 07913 { 07914 tmp=0; 07915 set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, 1); 07916 } 07917 } 07918 else if (got_warning) 07919 set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, 1); 07920 store_type(tmp); 07921 return err; 07922 } 07923 07924 07925 int Field_set::store(longlong nr, bool unsigned_val) 07926 { 07927 ASSERT_COLUMN_MARKED_FOR_WRITE; 07928 int error= 0; 07929 if ((ulonglong) nr > (ulonglong) (((longlong) 1 << typelib->count) - 07930 (longlong) 1)) 07931 { 07932 nr&= (longlong) (((longlong) 1 << typelib->count) - (longlong) 1); 07933 set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, 1); 07934 error=1; 07935 } 07936 store_type((ulonglong) nr); 07937 return error; 07938 } 07939 07940 07941 String *Field_set::val_str(String *val_buffer, 07942 String *val_ptr __attribute__((unused))) 07943 { 07944 ulonglong tmp=(ulonglong) Field_enum::val_int(); 07945 uint bitnr=0; 07946 07947 val_buffer->length(0); 07948 val_buffer->set_charset(field_charset); 07949 while (tmp && bitnr < (uint) typelib->count) 07950 { 07951 if (tmp & 1) 07952 { 07953 if (val_buffer->length()) 07954 val_buffer->append(&field_separator, 1, &my_charset_latin1); 07955 String str(typelib->type_names[bitnr], 07956 typelib->type_lengths[bitnr], 07957 field_charset); 07958 val_buffer->append(str); 07959 } 07960 tmp>>=1; 07961 bitnr++; 07962 } 07963 return val_buffer; 07964 } 07965 07966 07967 void Field_set::sql_type(String &res) const 07968 { 07969 char buffer[255]; 07970 String set_item(buffer, sizeof(buffer), res.charset()); 07971 07972 res.length(0); 07973 res.append(STRING_WITH_LEN("set(")); 07974 07975 bool flag=0; 07976 uint *len= typelib->type_lengths; 07977 for (const char **pos= typelib->type_names; *pos; pos++, len++) 07978 { 07979 uint dummy_errors; 07980 if (flag) 07981 res.append(','); 07982 /* convert to res.charset() == utf8, then quote */ 07983 set_item.copy(*pos, *len, charset(), res.charset(), &dummy_errors); 07984 append_unescaped(&res, set_item.ptr(), set_item.length()); 07985 flag= 1; 07986 } 07987 res.append(')'); 07988 } 07989 07990 /* returns 1 if the fields are equally defined */ 07991 07992 bool Field::eq_def(Field *field) 07993 { 07994 if (real_type() != field->real_type() || charset() != field->charset() || 07995 pack_length() != field->pack_length()) 07996 return 0; 07997 return 1; 07998 } 07999 08000 bool Field_enum::eq_def(Field *field) 08001 { 08002 if (!Field::eq_def(field)) 08003 return 0; 08004 TYPELIB *from_lib=((Field_enum*) field)->typelib; 08005 08006 if (typelib->count < from_lib->count) 08007 return 0; 08008 for (uint i=0 ; i < from_lib->count ; i++) 08009 if (my_strnncoll(field_charset, 08010 (const uchar*)typelib->type_names[i], 08011 (uint) strlen(typelib->type_names[i]), 08012 (const uchar*)from_lib->type_names[i], 08013 (uint) strlen(from_lib->type_names[i]))) 08014 return 0; 08015 return 1; 08016 } 08017 08018 bool Field_num::eq_def(Field *field) 08019 { 08020 if (!Field::eq_def(field)) 08021 return 0; 08022 Field_num *from_num= (Field_num*) field; 08023 08024 if (unsigned_flag != from_num->unsigned_flag || 08025 zerofill && !from_num->zerofill && !zero_pack() || 08026 dec != from_num->dec) 08027 return 0; 08028 return 1; 08029 } 08030 08031 08032 uint Field_num::is_equal(create_field *new_field) 08033 { 08034 return ((new_field->sql_type == real_type()) && 08035 ((new_field->flags & UNSIGNED_FLAG) == (uint) (flags & 08036 UNSIGNED_FLAG)) && 08037 ((new_field->flags & AUTO_INCREMENT_FLAG) == 08038 (uint) (flags & AUTO_INCREMENT_FLAG)) && 08039 (new_field->length <= max_length())); 08040 } 08041 08042 08043 /* 08044 Bit field. 08045 08046 We store the first 0 - 6 uneven bits among the null bits 08047 at the start of the record. The rest bytes are stored in 08048 the record itself. 08049 08050 For example: 08051 08052 CREATE TABLE t1 (a int, b bit(17), c bit(21) not null, d bit(8)); 08053 We would store data as follows in the record: 08054 08055 Byte Bit 08056 1 7 - reserve for delete 08057 6 - null bit for 'a' 08058 5 - null bit for 'b' 08059 4 - first (high) bit of 'b' 08060 3 - first (high) bit of 'c' 08061 2 - second bit of 'c' 08062 1 - third bit of 'c' 08063 0 - forth bit of 'c' 08064 2 7 - firth bit of 'c' 08065 6 - null bit for 'd' 08066 3 - 6 four bytes for 'a' 08067 7 - 8 two bytes for 'b' 08068 9 - 10 two bytes for 'c' 08069 11 one byte for 'd' 08070 */ 08071 08072 Field_bit::Field_bit(char *ptr_arg, uint32 len_arg, uchar *null_ptr_arg, 08073 uchar null_bit_arg, uchar *bit_ptr_arg, uchar bit_ofs_arg, 08074 enum utype unireg_check_arg, const char *field_name_arg) 08075 : Field(ptr_arg, len_arg, null_ptr_arg, null_bit_arg, 08076 unireg_check_arg, field_name_arg), 08077 bit_ptr(bit_ptr_arg), bit_ofs(bit_ofs_arg), bit_len(len_arg & 7), 08078 bytes_in_rec(len_arg / 8) 08079 { 08080 /* 08081 Ensure that Field::eq() can distinguish between two different bit fields. 08082 (two bit fields that are not null, may have same ptr and null_ptr) 08083 */ 08084 if (!null_ptr_arg) 08085 null_bit= bit_ofs_arg; 08086 } 08087 08088 08089 Field *Field_bit::new_key_field(MEM_ROOT *root, 08090 struct st_table *new_table, 08091 char *new_ptr, uchar *new_null_ptr, 08092 uint new_null_bit) 08093 { 08094 Field_bit *res; 08095 if ((res= (Field_bit*) Field::new_key_field(root, new_table, 08096 new_ptr, new_null_ptr, 08097 new_null_bit))) 08098 { 08099 /* Move bits normally stored in null_pointer to new_ptr */ 08100 res->bit_ptr= (uchar*) new_ptr; 08101 res->bit_ofs= 0; 08102 if (bit_len) 08103 res->ptr++; // Store rest of data here 08104 } 08105 return res; 08106 } 08107 08108 08109 int Field_bit::store(const char *from, uint length, CHARSET_INFO *cs) 08110 { 08111 ASSERT_COLUMN_MARKED_FOR_WRITE; 08112 int delta; 08113 08114 for (; length && !*from; from++, length--); // skip left 0's 08115 delta= bytes_in_rec - length; 08116 08117 if (delta < -1 || 08118 (delta == -1 && (uchar) *from > ((1 << bit_len) - 1)) || 08119 (!bit_len && delta < 0)) 08120 { 08121 set_rec_bits(0xff, bit_ptr, bit_ofs, bit_len); 08122 memset(ptr, 0xff, bytes_in_rec); 08123 if (table->in_use->really_abort_on_warning()) 08124 set_warning(MYSQL_ERROR::WARN_LEVEL_ERROR, ER_DATA_TOO_LONG, 1); 08125 else 08126 set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1); 08127 return 1; 08128 } 08129 /* delta is >= -1 here */ 08130 if (delta > 0) 08131 { 08132 if (bit_len) 08133 clr_rec_bits(bit_ptr, bit_ofs, bit_len); 08134 bzero(ptr, delta); 08135 memcpy(ptr + delta, from, length); 08136 } 08137 else if (delta == 0) 08138 { 08139 if (bit_len) 08140 clr_rec_bits(bit_ptr, bit_ofs, bit_len); 08141 memcpy(ptr, from, length); 08142 } 08143 else 08144 { 08145 if (bit_len) 08146 { 08147 set_rec_bits((uchar) *from, bit_ptr, bit_ofs, bit_len); 08148 from++; 08149 } 08150 memcpy(ptr, from, bytes_in_rec); 08151 } 08152 return 0; 08153 } 08154 08155 08156 int Field_bit::store(double nr) 08157 { 08158 return Field_bit::store((longlong) nr, FALSE); 08159 } 08160 08161 08162 int Field_bit::store(longlong nr, bool unsigned_val) 08163 { 08164 char buf[8]; 08165 08166 mi_int8store(buf, nr); 08167 return store(buf, 8, NULL); 08168 } 08169 08170 08171 int Field_bit::store_decimal(const my_decimal *val) 08172 { 08173 int err= 0; 08174 longlong i= convert_decimal2longlong(val, 1, &err); 08175 return test(err | store(i, TRUE)); 08176 } 08177 08178 08179 double Field_bit::val_real(void) 08180 { 08181 return (double) Field_bit::val_int(); 08182 } 08183 08184 08185 longlong Field_bit::val_int(void) 08186 { 08187 ASSERT_COLUMN_MARKED_FOR_READ; 08188 ulonglong bits= 0; 08189 if (bit_len) 08190 { 08191 bits= get_rec_bits(bit_ptr, bit_ofs, bit_len); 08192 bits<<= (bytes_in_rec * 8); 08193 } 08194 08195 switch (bytes_in_rec) { 08196 case 0: return bits; 08197 case 1: return bits | (ulonglong) (uchar) ptr[0]; 08198 case 2: return bits | mi_uint2korr(ptr); 08199 case 3: return bits | mi_uint3korr(ptr); 08200 case 4: return bits | mi_uint4korr(ptr); 08201 case 5: return bits | mi_uint5korr(ptr); 08202 case 6: return bits | mi_uint6korr(ptr); 08203 case 7: return bits | mi_uint7korr(ptr); 08204 default: return mi_uint8korr(ptr + bytes_in_rec - sizeof(longlong)); 08205 } 08206 } 08207 08208 08209 String *Field_bit::val_str(String *val_buffer, 08210 String *val_ptr __attribute__((unused))) 08211 { 08212 ASSERT_COLUMN_MARKED_FOR_READ; 08213 char buff[sizeof(longlong)]; 08214 uint length= min(pack_length(), sizeof(longlong)); 08215 ulonglong bits= val_int(); 08216 mi_int8store(buff,bits); 08217 08218 val_buffer->alloc(length); 08219 memcpy_fixed((char*) val_buffer->ptr(), buff+8-length, length); 08220 val_buffer->length(length); 08221 val_buffer->set_charset(&my_charset_bin); 08222 return val_buffer; 08223 } 08224 08225 08226 my_decimal *Field_bit::val_decimal(my_decimal *deciaml_value) 08227 { 08228 ASSERT_COLUMN_MARKED_FOR_READ; 08229 int2my_decimal(E_DEC_FATAL_ERROR, val_int(), 1, deciaml_value); 08230 return deciaml_value; 08231 } 08232 08233 08234 /* 08235 Compare two bit fields using pointers within the record. 08236 SYNOPSIS 08237 cmp_max() 08238 a Pointer to field->ptr in first record 08239 b Pointer to field->ptr in second record 08240 max_len Maximum length used in index 08241 DESCRIPTION 08242 This method is used from key_rec_cmp used by merge sorts used 08243 by partitioned index read and later other similar places. 08244 The a and b pointer must be pointers to the field in a record 08245 (not the table->record[0] necessarily) 08246 */ 08247 int Field_bit::cmp_max(const char *a, const char *b, uint max_len) 08248 { 08249 my_ptrdiff_t a_diff= a - ptr; 08250 my_ptrdiff_t b_diff= b - ptr; 08251 if (bit_len) 08252 { 08253 int flag; 08254 uchar bits_a= get_rec_bits(bit_ptr+a_diff, bit_ofs, bit_len); 08255 uchar bits_b= get_rec_bits(bit_ptr+b_diff, bit_ofs, bit_len); 08256 if ((flag= (int) (bits_a - bits_b))) 08257 return flag; 08258 } 08259 return memcmp(a, b, field_length); 08260 } 08261 08262 08263 int Field_bit::key_cmp(const byte *str, uint length) 08264 { 08265 if (bit_len) 08266 { 08267 int flag; 08268 uchar bits= get_rec_bits(bit_ptr, bit_ofs, bit_len); 08269 if ((flag= (int) (bits - *(uchar*) str))) 08270 return flag; 08271 str++; 08272 length--; 08273 } 08274 return memcmp(ptr, str, length); 08275 } 08276 08277 08278 int Field_bit::cmp_offset(uint row_offset) 08279 { 08280 if (bit_len) 08281 { 08282 int flag; 08283 uchar bits_a= get_rec_bits(bit_ptr, bit_ofs, bit_len); 08284 uchar bits_b= get_rec_bits(bit_ptr + row_offset, bit_ofs, bit_len); 08285 if ((flag= (int) (bits_a - bits_b))) 08286 return flag; 08287 } 08288 return memcmp(ptr, ptr + row_offset, bytes_in_rec); 08289 } 08290 08291 08292 void Field_bit::get_key_image(char *buff, uint length, imagetype type) 08293 { 08294 if (bit_len) 08295 { 08296 uchar bits= get_rec_bits(bit_ptr, bit_ofs, bit_len); 08297 *buff++= bits; 08298 length--; 08299 } 08300 memcpy(buff, ptr, min(length, bytes_in_rec)); 08301 } 08302 08303 08304 void Field_bit::sql_type(String &res) const 08305 { 08306 CHARSET_INFO *cs= res.charset(); 08307 ulong length= cs->cset->snprintf(cs, (char*) res.ptr(), res.alloced_length(), 08308 "bit(%d)", (int) field_length); 08309 res.length((uint) length); 08310 } 08311 08312 08313 char *Field_bit::pack(char *to, const char *from, uint max_length) 08314 { 08315 DBUG_ASSERT(max_length); 08316 uint length; 08317 if (bit_len) 08318 { 08319 uchar bits= get_rec_bits(bit_ptr, bit_ofs, bit_len); 08320 *to++= bits; 08321 } 08322 length= min(bytes_in_rec, max_length - (bit_len > 0)); 08323 memcpy(to, from, length); 08324 return to + length; 08325 } 08326 08327 08328 const char *Field_bit::unpack(char *to, const char *from) 08329 { 08330 if (bit_len) 08331 { 08332 set_rec_bits(*from, bit_ptr, bit_ofs, bit_len); 08333 from++; 08334 } 08335 memcpy(to, from, bytes_in_rec); 08336 return from + bytes_in_rec; 08337 } 08338 08339 08340 /* 08341 Bit field support for non-MyISAM tables. 08342 */ 08343 08344 Field_bit_as_char::Field_bit_as_char(char *ptr_arg, uint32 len_arg, 08345 uchar *null_ptr_arg, uchar null_bit_arg, 08346 enum utype unireg_check_arg, 08347 const char *field_name_arg) 08348 :Field_bit(ptr_arg, len_arg, null_ptr_arg, null_bit_arg, 0, 0, 08349 unireg_check_arg, field_name_arg) 08350 { 08351 bit_len= 0; 08352 bytes_in_rec= (len_arg + 7) / 8; 08353 } 08354 08355 08356 int Field_bit_as_char::store(const char *from, uint length, CHARSET_INFO *cs) 08357 { 08358 ASSERT_COLUMN_MARKED_FOR_WRITE; 08359 int delta; 08360 uchar bits= field_length & 7; 08361 08362 for (; length && !*from; from++, length--); // skip left 0's 08363 delta= bytes_in_rec - length; 08364 08365 if (delta < 0 || 08366 (delta == 0 && bits && (uint) (uchar) *from >= (uint) (1 << bits))) 08367 { 08368 memset(ptr, 0xff, bytes_in_rec); 08369 if (bits) 08370 *ptr&= ((1 << bits) - 1); /* set first byte */ 08371 if (table->in_use->really_abort_on_warning()) 08372 set_warning(MYSQL_ERROR::WARN_LEVEL_ERROR, ER_DATA_TOO_LONG, 1); 08373 else 08374 set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1); 08375 return 1; 08376 } 08377 bzero(ptr, delta); 08378 memcpy(ptr + delta, from, length); 08379 return 0; 08380 } 08381 08382 08383 void Field_bit_as_char::sql_type(String &res) const 08384 { 08385 CHARSET_INFO *cs= res.charset(); 08386 ulong length= cs->cset->snprintf(cs, (char*) res.ptr(), res.alloced_length(), 08387 "bit(%d)", (int) field_length); 08388 res.length((uint) length); 08389 } 08390 08391 08392 /***************************************************************************** 08393 Handling of field and create_field 08394 *****************************************************************************/ 08395 08396 /* 08397 Convert create_field::length from number of characters to number of bytes 08398 08399 SYNOPSIS 08400 create_field::create_length_to_internal_length() 08401 08402 DESCRIPTION 08403 Convert create_field::length from number of characters to number of bytes. 08404 */ 08405 08406 void create_field::create_length_to_internal_length(void) 08407 { 08408 switch (sql_type) { 08409 case MYSQL_TYPE_TINY_BLOB: 08410 case MYSQL_TYPE_MEDIUM_BLOB: 08411 case MYSQL_TYPE_LONG_BLOB: 08412 case MYSQL_TYPE_BLOB: 08413 case MYSQL_TYPE_VAR_STRING: 08414 case MYSQL_TYPE_STRING: 08415 case MYSQL_TYPE_VARCHAR: 08416 length*= charset->mbmaxlen; 08417 key_length= length; 08418 pack_length= calc_pack_length(sql_type, length); 08419 break; 08420 case MYSQL_TYPE_ENUM: 08421 case MYSQL_TYPE_SET: 08422 /* Pack_length already calculated in sql_parse.cc */ 08423 length*= charset->mbmaxlen; 08424 key_length= pack_length; 08425 break; 08426 case MYSQL_TYPE_BIT: 08427 if (f_bit_as_char(pack_flag)) 08428 { 08429 key_length= pack_length= ((length + 7) & ~7) / 8; 08430 } 08431 else 08432 { 08433 pack_length= length / 8; 08434 /* We need one extra byte to store the bits we save among the null bits */ 08435 key_length= pack_length + test(length & 7); 08436 } 08437 break; 08438 case MYSQL_TYPE_NEWDECIMAL: 08439 key_length= pack_length= 08440 my_decimal_get_binary_size(my_decimal_length_to_precision(length, 08441 decimals, 08442 flags & 08443 UNSIGNED_FLAG), 08444 decimals); 08445 break; 08446 default: 08447 key_length= pack_length= calc_pack_length(sql_type, length); 08448 break; 08449 } 08450 } 08451 08452 08453 void create_field::init_for_tmp_table(enum_field_types sql_type_arg, 08454 uint32 length_arg, uint32 decimals, 08455 bool maybe_null, bool is_unsigned) 08456 { 08457 field_name= ""; 08458 sql_type= sql_type_arg; 08459 char_length= length= length_arg;; 08460 unireg_check= Field::NONE; 08461 interval= 0; 08462 charset= &my_charset_bin; 08463 geom_type= Field::GEOM_GEOMETRY; 08464 pack_flag= (FIELDFLAG_NUMBER | 08465 ((decimals & FIELDFLAG_MAX_DEC) << FIELDFLAG_DEC_SHIFT) | 08466 (maybe_null ? FIELDFLAG_MAYBE_NULL : 0) | 08467 (is_unsigned ? 0 : FIELDFLAG_DECIMAL)); 08468 } 08469 08470 08471 /* 08472 Initialize field definition for create 08473 08474 SYNOPSIS 08475 thd Thread handle 08476 fld_name Field name 08477 fld_type Field type 08478 fld_length Field length 08479 fld_decimals Decimal (if any) 08480 fld_type_modifier Additional type information 08481 fld_default_value Field default value (if any) 08482 fld_on_update_value The value of ON UPDATE clause 08483 fld_comment Field comment 08484 fld_change Field change 08485 fld_interval_list Interval list (if any) 08486 fld_charset Field charset 08487 fld_geom_type Field geometry type (if any) 08488 08489 RETURN 08490 FALSE on success 08491 TRUE on error 08492 */ 08493 08494 bool create_field::init(THD *thd, char *fld_name, enum_field_types fld_type, 08495 char *fld_length, char *fld_decimals, 08496 uint fld_type_modifier, Item *fld_default_value, 08497 Item *fld_on_update_value, LEX_STRING *fld_comment, 08498 char *fld_change, List<String> *fld_interval_list, 08499 CHARSET_INFO *fld_charset, uint fld_geom_type) 08500 { 08501 uint sign_len, allowed_type_modifier= 0; 08502 ulong max_field_charlength= MAX_FIELD_CHARLENGTH; 08503 08504 DBUG_ENTER("create_field::init()"); 08505 08506 field= 0; 08507 field_name= fld_name; 08508 def= fld_default_value; 08509 flags= fld_type_modifier; 08510 unireg_check= (fld_type_modifier & AUTO_INCREMENT_FLAG ? 08511 Field::NEXT_NUMBER : Field::NONE); 08512 decimals= fld_decimals ? (uint)atoi(fld_decimals) : 0; 08513 if (decimals >= NOT_FIXED_DEC) 08514 { 08515 my_error(ER_TOO_BIG_SCALE, MYF(0), decimals, fld_name, 08516 NOT_FIXED_DEC-1); 08517 DBUG_RETURN(TRUE); 08518 } 08519 08520 sql_type= fld_type; 08521 length= 0; 08522 change= fld_change; 08523 interval= 0; 08524 pack_length= key_length= 0; 08525 charset= fld_charset; 08526 geom_type= (Field::geometry_type) fld_geom_type; 08527 interval_list.empty(); 08528 08529 comment= *fld_comment; 08530 /* 08531 Set NO_DEFAULT_VALUE_FLAG if this field doesn't have a default value and 08532 it is NOT NULL, not an AUTO_INCREMENT field and not a TIMESTAMP. 08533 */ 08534 if (!fld_default_value && !(fld_type_modifier & AUTO_INCREMENT_FLAG) && 08535 (fld_type_modifier & NOT_NULL_FLAG) && fld_type != FIELD_TYPE_TIMESTAMP) 08536 flags|= NO_DEFAULT_VALUE_FLAG; 08537 08538 if (fld_length && !(length= (uint) atoi(fld_length))) 08539 fld_length= 0; /* purecov: inspected */ 08540 sign_len= fld_type_modifier & UNSIGNED_FLAG ? 0 : 1; 08541 08542 switch (fld_type) { 08543 case FIELD_TYPE_TINY: 08544 if (!fld_length) 08545 length= MAX_TINYINT_WIDTH+sign_len; 08546 allowed_type_modifier= AUTO_INCREMENT_FLAG; 08547 break; 08548 case FIELD_TYPE_SHORT: 08549 if (!fld_length) 08550 length= MAX_SMALLINT_WIDTH+sign_len; 08551 allowed_type_modifier= AUTO_INCREMENT_FLAG; 08552 break; 08553 case FIELD_TYPE_INT24: 08554 if (!fld_length) 08555 length= MAX_MEDIUMINT_WIDTH+sign_len; 08556 allowed_type_modifier= AUTO_INCREMENT_FLAG; 08557 break; 08558 case FIELD_TYPE_LONG: 08559 if (!fld_length) 08560 length= MAX_INT_WIDTH+sign_len; 08561 allowed_type_modifier= AUTO_INCREMENT_FLAG; 08562 break; 08563 case FIELD_TYPE_LONGLONG: 08564 if (!fld_length) 08565 length= MAX_BIGINT_WIDTH; 08566 allowed_type_modifier= AUTO_INCREMENT_FLAG; 08567 break; 08568 case FIELD_TYPE_NULL: 08569 break; 08570 case FIELD_TYPE_NEWDECIMAL: 08571 if (!fld_length && !decimals) 08572 length= 10; 08573 if (length > DECIMAL_MAX_PRECISION) 08574 { 08575 my_error(ER_TOO_BIG_PRECISION, MYF(0), length, fld_name, 08576 DECIMAL_MAX_PRECISION); 08577 DBUG_RETURN(TRUE); 08578 } 08579 if (length < decimals) 08580 { 08581 my_error(ER_M_BIGGER_THAN_D, MYF(0), fld_name); 08582 DBUG_RETURN(TRUE); 08583 } 08584 length= 08585 my_decimal_precision_to_length(length, decimals, 08586 fld_type_modifier & UNSIGNED_FLAG);

