80
80
const char *end=str+length;
82
while (str != end && isspace(*str)) // Allow start space
83
while (str != end && my_isspace(system_charset_info,*str))
83
84
str++; /* purecov: inspected */
84
85
if (str != end && (*str == '-' || *str == '+'))
118
119
if (*str == '+' || *str == '-')
121
if (!length || !(isdigit(*str) || *str == '.'))
122
if (!length || !(my_isdigit(system_charset_info,*str) || *str == '.'))
124
while (length && isdigit(*str))
125
while (length && my_isdigit(system_charset_info,*str))
140
141
if (*str == 'E' || *str == 'e')
142
if (length < 3 || (str[1] != '+' && str[1] != '-') || !isdigit(str[2]))
143
if (length < 3 || (str[1] != '+' && str[1] != '-') ||
144
!my_isdigit(system_charset_info,str[2]))
146
while (length && isdigit(*str))
148
while (length && my_isdigit(system_charset_info,*str))
151
153
for (; length ; length--, str++)
152
154
{ // Allow end space
155
if (!my_isspace(system_charset_info,*str))
199
203
return net_store_null(packet);
200
204
char buff[MAX_FIELD_WIDTH];
201
String tmp(buff,sizeof(buff));
205
String tmp(buff,sizeof(buff),default_charset_info);
202
206
val_str(&tmp,&tmp);
203
207
CONVERT *convert;
204
208
if ((convert=thd->variables.convert_set))
219
223
void Field_num::make_field(Send_field *field)
225
/* table_cache_key is not set for temp tables */
226
field->db_name=table->table_cache_key ? table->table_cache_key : "";
227
field->org_table_name=table->real_name;
221
228
field->table_name=table_name;
222
field->col_name=field_name;
229
field->col_name=field->org_col_name=field_name;
223
230
field->length=field_length;
224
231
field->type=type();
225
232
field->flags=table->maybe_null ? (flags & ~NOT_NULL_FLAG) : flags;
230
237
void Field_str::make_field(Send_field *field)
239
/* table_cache_key is not set for temp tables */
240
field->db_name=table->table_cache_key ? table->table_cache_key : "";
241
field->org_table_name=table->real_name;
232
242
field->table_name=table_name;
233
field->col_name=field_name;
243
field->col_name=field->org_col_name=field_name;
234
244
field->length=field_length;
235
245
field->type=type();
236
246
field->flags=table->maybe_null ? (flags & ~NOT_NULL_FLAG) : flags;
261
271
bool Field::get_date(TIME *ltime,bool fuzzydate)
264
String tmp(buff,sizeof(buff)),tmp2,*res;
274
String tmp(buff,sizeof(buff),default_charset_info),tmp2,*res;
265
275
if (!(res=val_str(&tmp,&tmp2)) ||
266
276
str_to_TIME(res->ptr(),res->length(),ltime,fuzzydate) == TIMESTAMP_NONE)
271
281
bool Field::get_time(TIME *ltime)
274
String tmp(buff,sizeof(buff)),tmp2,*res;
284
String tmp(buff,sizeof(buff),default_charset_info),tmp2,*res;
275
285
if (!(res=val_str(&tmp,&tmp2)) ||
276
286
str_to_time(res->ptr(),res->length(),ltime))
287
297
case TIMESTAMP_NONE:
288
store("",0); // Probably an error
298
store("",0,default_charset_info); // Probably an error
290
300
case TIMESTAMP_DATE:
291
301
sprintf(buff,"%04d-%02d-%02d", ltime->year,ltime->month,ltime->day);
302
store(buff,10,default_charset_info);
294
304
case TIMESTAMP_FULL:
295
305
sprintf(buff,"%04d-%02d-%02d %02d:%02d:%02d",
296
306
ltime->year,ltime->month,ltime->day,
297
307
ltime->hour,ltime->minute,ltime->second);
308
store(buff,19,default_charset_info);
300
310
case TIMESTAMP_TIME:
301
sprintf(buff, "%02d:%02d:%02d",
302
ltime->hour,ltime->minute,ltime->second);
303
store(buff,(uint) strlen(buff));
312
ulong length= my_sprintf(buff, (buff, "%02d:%02d:%02d",
313
ltime->hour,ltime->minute,ltime->second));
314
store(buff,(uint) length, default_charset_info);
320
331
Field_decimal::reset(void)
322
Field_decimal::store("0",1);
333
Field_decimal::store("0",1,default_charset_info);
325
336
void Field_decimal::overflow(bool negative)
364
void Field_decimal::store(const char *from,uint len)
375
int Field_decimal::store(const char *from, uint len, CHARSET_INFO *cs)
366
377
const char *end= from+len;
367
378
/* The pointer where the field value starts (i.e., "where to write") */
372
383
specified), '+' or '-'
374
385
char sign_char=0;
375
/* The pointers where prezeros start and stop */
386
/* The pointers where prezeros start and stop */
376
387
const char *pre_zeros_from, *pre_zeros_end;
377
/* The pointers where digits at the left of '.' start and stop */
388
/* The pointers where digits at the left of '.' start and stop */
378
389
const char *int_digits_from, *int_digits_end;
379
/* The pointers where digits at the right of '.' start and stop */
390
/* The pointers where digits at the right of '.' start and stop */
380
391
const char *frac_digits_from, *frac_digits_end;
381
/* The sign of the exponent : will be 0 (means no exponent), '+' or '-' */
392
/* The sign of the exponent : will be 0 (means no exponent), '+' or '-' */
382
393
char expo_sign_char=0;
383
394
uint exponent=0; // value of the exponent
388
399
const char *int_digits_tail_from;
389
400
/* Number of 0 that need to be added at the left of the '.' (1E3: 3 zeros) */
390
401
uint int_digits_added_zeros;
392
Pointer used when digits move from the right of the '.' to the left
403
Pointer used when digits move from the right of the '.' to the left
395
406
const char *frac_digits_head_end;
396
/* Number of 0 that need to be added at the right of the '.' (for 1E-3) */
407
/* Number of 0 that need to be added at the right of the '.' (for 1E-3) */
397
408
uint frac_digits_added_zeros;
398
409
char *pos,*tmp_left_pos,*tmp_right_pos;
399
410
/* Pointers that are used as limits (begin and end of the field buffer) */
400
411
char *left_wall,*right_wall;
403
To remember if current_thd->cuted_fields has already been incremented,
414
To remember if current_thd->cuted_fields has already been incremented,
406
417
bool is_cuted_fields_incr=0;
408
419
LINT_INIT(int_digits_tail_from);
414
425
There are three steps in this function :
415
- parse the input string
416
- modify the position of digits around the decimal dot '.'
417
according to the exponent value (if specified)
418
- write the formatted number
426
- parse the input string
427
- modify the position of digits around the decimal dot '.'
428
according to the exponent value (if specified)
429
- write the formatted number
421
432
if ((tmp_dec=dec))
424
for (; from !=end && isspace(*from); from++) ; // Read spaces
436
while (from != end && my_isspace(system_charset_info,*from))
427
440
current_thd->cuted_fields++;
440
453
if (sign_char=='-')
442
455
Field_decimal::overflow(1);
446
Defining this will not store "+" for unsigned decimal type even if
447
it is passed in numeric string. This will make some tests to fail
459
Defining this will not store "+" for unsigned decimal type even if
460
it is passed in numeric string. This will make some tests to fail
449
462
#ifdef DONT_ALLOW_UNSIGNED_PLUS
457
470
for (; from!=end && *from == '0'; from++) ; // Read prezeros
458
471
pre_zeros_end=int_digits_from=from;
459
472
/* Read non zero digits at the left of '.'*/
460
for (; from!=end && isdigit(*from);from++) ;
473
for (; from != end && my_isdigit(system_charset_info, *from) ; from++) ;
461
474
int_digits_end=from;
462
475
if (from!=end && *from == '.') // Some '.' ?
464
477
frac_digits_from= from;
465
478
/* Read digits at the right of '.' */
466
for (;from!=end && isdigit(*from); from++) ;
479
for (;from!=end && my_isdigit(system_charset_info, (*from); from++) ;
467
480
frac_digits_end=from;
468
481
// Some exponentiation symbol ?
469
482
if (from != end && (*from == 'e' || *from == 'E'))
479
492
(the value of the field will be overflow anyway, or 0 anyway,
480
493
it does not change anything if the exponent is 2^32 or more
482
for (;from!=end && isdigit(*from); from++)
495
for (;from!=end && my_isdigit(system_charset_info, (*from)); from++)
483
496
exponent=10*exponent+(*from-'0');
504
517
Now "move" digits around the decimal dot according to the exponent value,
505
518
and add necessary zeros.
507
- 1E+3 : needs 3 more zeros at the left of '.' (int_digits_added_zeros=3)
508
- 1E-3 : '1' moves at the right of '.', and 2 more zeros are needed
520
- 1E+3 : needs 3 more zeros at the left of '.' (int_digits_added_zeros=3)
521
- 1E-3 : '1' moves at the right of '.', and 2 more zeros are needed
510
523
- 1234.5E-3 : '234' moves at the right of '.'
511
These moves are implemented with pointers which point at the begin
512
and end of each moved segment. Examples :
524
These moves are implemented with pointers which point at the begin
525
and end of each moved segment. Examples :
513
526
- 1234.5E-3 : before the code below is executed, the int_digits part is
514
from '1' to '4' and the frac_digits part from '5' to '5'. After the code
515
below, the int_digits part is from '1' to '1', the frac_digits_head
516
part is from '2' to '4', and the frac_digits part from '5' to '5'.
527
from '1' to '4' and the frac_digits part from '5' to '5'. After the code
528
below, the int_digits part is from '1' to '1', the frac_digits_head
529
part is from '2' to '4', and the frac_digits part from '5' to '5'.
517
530
- 1234.5E3 : before the code below is executed, the int_digits part is
518
from '1' to '4' and the frac_digits part from '5' to '5'. After the code
519
below, the int_digits part is from '1' to '4', the int_digits_tail
520
part is from '5' to '5', the frac_digits part is empty, and
521
int_digits_added_zeros=2 (to make 1234500).
531
from '1' to '4' and the frac_digits part from '5' to '5'. After the code
532
below, the int_digits part is from '1' to '4', the int_digits_tail
533
part is from '5' to '5', the frac_digits part is empty, and
534
int_digits_added_zeros=2 (to make 1234500).
524
537
if (!expo_sign_char)
695
708
while (pos != right_wall)
696
709
*pos++='0'; // Fill with zeros at right of '.'
701
void Field_decimal::store(double nr)
715
int Field_decimal::store(double nr)
703
717
if (unsigned_flag && nr < 0)
709
723
#ifdef HAVE_FINITE
710
724
if (!finite(nr)) // Handle infinity as special case
712
726
overflow(nr < 0.0);
717
731
reg4 uint i,length;
718
732
char fyllchar,*to;
728
742
length=(uint) strlen(buff);
730
744
if (length > field_length)
731
746
overflow(nr < 0.0);
735
752
for (i=field_length-length ; i-- > 0 ;)
736
753
*to++ = fyllchar;
737
754
memcpy(to,buff,length);
742
void Field_decimal::store(longlong nr)
760
int Field_decimal::store(longlong nr)
744
762
if (unsigned_flag && nr < 0)
750
768
uint length=(uint) (longlong10_to_str(nr,buff,-10)-buff);
751
769
uint int_part=field_length- (dec ? dec+1 : 0);
753
771
if (length > int_part)
754
773
overflow(test(nr < 0L)); /* purecov: inspected */
757
778
char fyllchar = zerofill ? (char) '0' : (char) ' ';
797
819
if (field_length < tmp_length) // Error in data
798
820
val_ptr->length(0);
800
val_ptr->set((const char*) str,field_length-tmp_length);
822
val_ptr->set((const char*) str,field_length-tmp_length,default_charset_info);
814
836
for (end=a_ptr+field_length;
816
838
(*a_ptr == *b_ptr ||
817
((isspace(*a_ptr) || *a_ptr == '+' || *a_ptr == '0') &&
818
(isspace(*b_ptr) || *b_ptr == '+' || *b_ptr == '0')));
839
((my_isspace(system_charset_info,*a_ptr) || *a_ptr == '+' ||
841
(my_isspace(system_charset_info,*b_ptr) || *b_ptr == '+' ||
821
845
if (*a_ptr == '-') // If both numbers are negative
879
904
****************************************************************************/
881
void Field_tiny::store(const char *from,uint len)
906
int Field_tiny::store(const char *from,uint len,CHARSET_INFO *cs)
883
String tmp_str(from,len);
908
String tmp_str(from,len,default_charset_info);
884
909
long tmp= strtol(tmp_str.c_ptr(),NULL,10);
886
912
if (unsigned_flag)
890
916
tmp=0; /* purecov: inspected */
891
917
current_thd->cuted_fields++; /* purecov: inspected */
893
920
else if (tmp > 255)
896
923
current_thd->cuted_fields++;
898
926
else if (current_thd->count_cuted_fields && !test_if_int(from,len))
899
928
current_thd->cuted_fields++;
906
937
current_thd->cuted_fields++;
908
940
else if (tmp >= 128)
911
943
current_thd->cuted_fields++;
913
946
else if (current_thd->count_cuted_fields && !test_if_int(from,len))
914
948
current_thd->cuted_fields++;
916
952
ptr[0]= (char) tmp;
920
void Field_tiny::store(double nr)
957
int Field_tiny::store(double nr)
923
961
if (unsigned_flag)
942
982
*ptr= (char) -128;
943
983
current_thd->cuted_fields++;
945
986
else if (nr > 127.0)
948
989
current_thd->cuted_fields++;
955
void Field_tiny::store(longlong nr)
998
int Field_tiny::store(longlong nr)
957
1001
if (unsigned_flag)
962
1006
current_thd->cuted_fields++;
964
1009
else if (nr > 255L)
966
1011
*ptr= (char) 255;
967
1012
current_thd->cuted_fields++;
1049
1098
// Note: Sometimes this should be fixed to use one strtol() to use
1050
1099
// len and check for garbage after number.
1052
void Field_short::store(const char *from,uint len)
1101
int Field_short::store(const char *from,uint len,CHARSET_INFO *cs)
1054
String tmp_str(from,len);
1103
String tmp_str(from,len,default_charset_info);
1055
1104
long tmp= strtol(tmp_str.c_ptr(),NULL,10);
1056
1106
if (unsigned_flag)
1061
1111
current_thd->cuted_fields++;
1063
1114
else if (tmp > (uint16) ~0)
1065
1116
tmp=(uint16) ~0;
1066
1117
current_thd->cuted_fields++;
1068
1120
else if (current_thd->count_cuted_fields && !test_if_int(from,len))
1069
1122
current_thd->cuted_fields++;
1075
1130
tmp= INT_MIN16;
1076
1131
current_thd->cuted_fields++;
1078
1134
else if (tmp > INT_MAX16)
1081
1137
current_thd->cuted_fields++;
1083
1140
else if (current_thd->count_cuted_fields && !test_if_int(from,len))
1084
1142
current_thd->cuted_fields++;
1086
1146
#ifdef WORDS_BIGENDIAN
1087
1147
if (table->db_low_byte_first)
1289
1362
// Note: Sometimes this should be fixed to use one strtol() to use
1290
1363
// len and check for garbage after number.
1292
void Field_medium::store(const char *from,uint len)
1365
int Field_medium::store(const char *from,uint len,CHARSET_INFO *cs)
1294
String tmp_str(from,len);
1367
String tmp_str(from,len,default_charset_info);
1295
1368
long tmp= strtol(tmp_str.c_ptr(),NULL,10);
1297
1371
if (unsigned_flag)
1302
1376
current_thd->cuted_fields++;
1304
1379
else if (tmp >= (long) (1L << 24))
1306
1381
tmp=(long) (1L << 24)-1L;
1307
1382
current_thd->cuted_fields++;
1309
1385
else if (current_thd->count_cuted_fields && !test_if_int(from,len))
1310
1387
current_thd->cuted_fields++;
1316
1395
tmp= INT_MIN24;
1317
1396
current_thd->cuted_fields++;
1319
1399
else if (tmp > INT_MAX24)
1322
1402
current_thd->cuted_fields++;
1324
1405
else if (current_thd->count_cuted_fields && !test_if_int(from,len))
1325
1407
current_thd->cuted_fields++;
1328
1412
int3store(ptr,tmp);
1332
void Field_medium::store(double nr)
1417
int Field_medium::store(double nr)
1335
1421
if (unsigned_flag)
1339
1425
int3store(ptr,0);
1340
1426
current_thd->cuted_fields++;
1342
1429
else if (nr >= (double) (long) (1L << 24))
1344
1431
uint32 tmp=(uint32) (1L << 24)-1L;
1345
1432
int3store(ptr,tmp);
1346
1433
current_thd->cuted_fields++;
1349
1437
int3store(ptr,(uint32) nr);
1355
1443
long tmp=(long) INT_MIN24;
1356
1444
int3store(ptr,tmp);
1357
1445
current_thd->cuted_fields++;
1359
1448
else if (nr > (double) INT_MAX24)
1361
1450
long tmp=(long) INT_MAX24;
1362
1451
int3store(ptr,tmp);
1363
1452
current_thd->cuted_fields++;
1366
1456
int3store(ptr,(long) nr);
1370
void Field_medium::store(longlong nr)
1461
int Field_medium::store(longlong nr)
1372
1464
if (unsigned_flag)
1376
1468
int3store(ptr,0);
1377
1469
current_thd->cuted_fields++;
1379
1472
else if (nr >= (longlong) (long) (1L << 24))
1381
1474
long tmp=(long) (1L << 24)-1L;;
1382
1475
int3store(ptr,tmp);
1383
1476
current_thd->cuted_fields++;
1386
1480
int3store(ptr,(uint32) nr);
1392
1486
long tmp=(long) INT_MIN24;
1393
1487
int3store(ptr,tmp);
1394
1488
current_thd->cuted_fields++;
1396
1491
else if (nr > (longlong) INT_MAX24)
1398
1493
long tmp=(long) INT_MAX24;
1399
1494
int3store(ptr,tmp);
1400
1495
current_thd->cuted_fields++;
1403
1499
int3store(ptr,(long) nr);
1474
1571
// Note: Sometimes this should be fixed to use one strtol() to use
1475
1572
// len and check for garbage after number.
1477
void Field_long::store(const char *from,uint len)
1574
int Field_long::store(const char *from,uint len,CHARSET_INFO *cs)
1479
while (len && isspace(*from))
1576
while (len && my_isspace(system_charset_info,*from))
1484
String tmp_str(from,len);
1582
String tmp_str(from,len,default_charset_info);
1486
1584
if (unsigned_flag)
1497
1596
tmp=strtol(tmp_str.c_ptr(),NULL,10);
1498
1597
if (errno || current_thd->count_cuted_fields && !test_if_int(from,len))
1499
1599
current_thd->cuted_fields++;
1500
1602
#ifdef WORDS_BIGENDIAN
1501
1603
if (table->db_low_byte_first)
1702
1817
** longlong int
1703
1818
****************************************************************************/
1705
void Field_longlong::store(const char *from,uint len)
1820
int Field_longlong::store(const char *from,uint len,CHARSET_INFO *cs)
1707
while (len && isspace(*from))
1822
while (len && my_isspace(system_charset_info,*from))
1708
1823
{ // For easy error check
1712
String tmp_str(from,len);
1827
String tmp_str(from,len,default_charset_info);
1714
1830
if (unsigned_flag)
1725
1842
tmp=strtoll(tmp_str.c_ptr(),NULL,10);
1726
1843
if (errno || current_thd->count_cuted_fields && !test_if_int(from,len))
1727
1845
current_thd->cuted_fields++;
1728
1848
#ifdef WORDS_BIGENDIAN
1729
1849
if (table->db_low_byte_first)
1762
1886
res=(longlong) LONGLONG_MIN;
1763
1887
current_thd->cuted_fields++;
1765
1890
else if (nr >= (double) LONGLONG_MAX)
1767
1892
res=(longlong) LONGLONG_MAX;
1768
1893
current_thd->cuted_fields++;
1771
1897
res=(longlong) nr;
1909
2037
** single precision float
1910
2038
****************************************************************************/
1912
void Field_float::store(const char *from,uint len)
2040
int Field_float::store(const char *from,uint len,CHARSET_INFO *cs)
1914
String tmp_str(from,len);
2042
String tmp_str(from,len,default_charset_info);
1916
2044
Field_float::store(atof(tmp_str.c_ptr()));
1917
2045
if (errno || current_thd->count_cuted_fields && !test_if_real(from,len))
1918
2047
current_thd->cuted_fields++;
2050
return (errno) ? 1 : 0;
1922
void Field_float::store(double nr)
2054
int Field_float::store(double nr)
1925
2058
if (dec < NOT_FIXED_DEC)
1926
2059
nr=floor(nr*log_10[dec]+0.5)/log_10[dec]; // To fixed point
1927
2060
if (unsigned_flag && nr < 0)
1929
2062
current_thd->cuted_fields++;
1932
2066
if (nr < -FLT_MAX)
1935
2069
current_thd->cuted_fields++;
1937
2072
else if (nr > FLT_MAX)
1940
2075
current_thd->cuted_fields++;
1951
2087
memcpy_fixed(ptr,(byte*) &j,sizeof(j));
1955
void Field_float::store(longlong nr)
2092
int Field_float::store(longlong nr)
1957
2095
float j= (float) nr;
1958
2096
if (unsigned_flag && j < 0)
1960
2098
current_thd->cuted_fields++;
1963
2102
#ifdef WORDS_BIGENDIAN
1964
2103
if (table->db_low_byte_first)
2159
2299
** double precision floating point numbers
2160
2300
****************************************************************************/
2162
void Field_double::store(const char *from,uint len)
2302
int Field_double::store(const char *from,uint len,CHARSET_INFO *cs)
2164
String tmp_str(from,len);
2304
String tmp_str(from,len,default_charset_info);
2166
2307
double j= atof(tmp_str.c_ptr());
2167
2308
if (errno || current_thd->count_cuted_fields && !test_if_real(from,len))
2168
2310
current_thd->cuted_fields++;
2169
2313
if (unsigned_flag && j < 0)
2171
2315
current_thd->cuted_fields++;
2174
2319
#ifdef WORDS_BIGENDIAN
2175
2320
if (table->db_low_byte_first)
2181
2326
doublestore(ptr,j);
2185
void Field_double::store(double nr)
2331
int Field_double::store(double nr)
2187
2334
if (dec < NOT_FIXED_DEC)
2188
2335
nr=floor(nr*log_10[dec]+0.5)/log_10[dec]; // To fixed point
2189
2336
if (unsigned_flag && nr < 0)
2191
2338
current_thd->cuted_fields++;
2194
2342
#ifdef WORDS_BIGENDIAN
2195
2343
if (table->db_low_byte_first)
2418
void Field_timestamp::store(const char *from,uint len)
2570
int Field_timestamp::store(const char *from,uint len,CHARSET_INFO *cs)
2420
2572
long tmp=(long) str_to_timestamp(from,len);
2421
2573
#ifdef WORDS_BIGENDIAN
2460
void Field_timestamp::store(double nr)
2613
int Field_timestamp::store(double nr)
2462
2616
if (nr < 0 || nr > 99991231235959.0)
2464
nr=0; // Avoid overflow on buff
2618
nr= 0; // Avoid overflow on buff
2465
2619
current_thd->cuted_fields++;
2467
Field_timestamp::store((longlong) rint(nr));
2622
error|= Field_timestamp::store((longlong) rint(nr));
2754
2911
** Stored as a 3 byte unsigned int
2755
2912
****************************************************************************/
2757
void Field_time::store(const char *from,uint len)
2914
int Field_time::store(const char *from,uint len,CHARSET_INFO *cs)
2761
2919
if (str_to_time(from,len,<ime))
2765
2926
if (ltime.month)
2771
2932
current_thd->cuted_fields++;
2776
Field_time::store((longlong) tmp);
2938
error |= Field_time::store((longlong) tmp);
2780
void Field_time::store(double nr)
2943
int Field_time::store(double nr)
2783
2947
if (nr > 8385959.0)
2786
2950
current_thd->cuted_fields++;
2788
2953
else if (nr < -8385959.0)
2790
2955
tmp= -8385959L;
2791
2956
current_thd->cuted_fields++;
2801
2967
current_thd->cuted_fields++;
2804
2971
int3store(ptr,tmp);
2808
void Field_time::store(longlong nr)
2976
int Field_time::store(longlong nr)
2811
2980
if (nr > (longlong) 8385959L)
2814
2983
current_thd->cuted_fields++;
2816
2986
else if (nr < (longlong) -8385959L)
2818
2988
tmp= -8385959L;
2819
2989
current_thd->cuted_fields++;
2903
3076
** Can handle 2 byte or 4 byte years!
2904
3077
****************************************************************************/
2906
void Field_year::store(const char *from, uint len)
3079
int Field_year::store(const char *from, uint len,CHARSET_INFO *cs)
2908
String tmp_str(from,len);
3081
String tmp_str(from,len,default_charset_info);
2909
3082
long nr= strtol(tmp_str.c_ptr(),NULL,10);
2911
3084
if (nr < 0 || nr >= 100 && nr <= 1900 || nr > 2155)
2914
3087
current_thd->cuted_fields++;
2917
3090
else if (current_thd->count_cuted_fields && !test_if_int(from,len))
2918
3091
current_thd->cuted_fields++;
2926
3099
*ptr= (char) (unsigned char) nr;
2929
void Field_year::store(double nr)
3103
int Field_year::store(double nr)
2931
3105
if (nr < 0.0 || nr >= 2155.0)
2932
Field_year::store((longlong) -1);
3107
(void) Field_year::store((longlong) -1);
2934
Field_year::store((longlong) nr);
3111
return Field_year::store((longlong) nr);
2937
void Field_year::store(longlong nr)
3114
int Field_year::store(longlong nr)
2939
3116
if (nr < 0 || nr >= 100 && nr <= 1900 || nr > 2155)
2942
3119
current_thd->cuted_fields++;
2945
3122
if (nr != 0 || field_length != 4) // 0000 -> 0; 00 -> 2000
2992
3170
** Stored as a 4 byte unsigned int
2993
3171
****************************************************************************/
2995
void Field_date::store(const char *from, uint len)
3173
int Field_date::store(const char *from, uint len,CHARSET_INFO *cs)
2999
3178
if (str_to_TIME(from,len,&l_time,1) == TIMESTAMP_NONE)
3002
3184
tmp=(uint32) l_time.year*10000L + (uint32) (l_time.month*100+l_time.day);
3003
3185
#ifdef WORDS_BIGENDIAN
3010
3192
longstore(ptr,tmp);
3014
void Field_date::store(double nr)
3197
int Field_date::store(double nr)
3017
3201
if (nr >= 19000000000000.0 && nr <= 99991231235959.0)
3018
3202
nr=floor(nr/1000000.0); // Timestamp to date
3019
3203
if (nr < 0.0 || nr > 99991231.0)
3022
3206
current_thd->cuted_fields++;
3025
3210
tmp=(long) rint(nr);
3033
3218
longstore(ptr,tmp);
3037
void Field_date::store(longlong nr)
3223
int Field_date::store(longlong nr)
3040
3227
if (nr >= LL(19000000000000) && nr < LL(99991231235959))
3041
3228
nr=nr/LL(1000000); // Timestamp to date
3042
3229
if (nr < 0 || nr > LL(99991231))
3045
3232
current_thd->cuted_fields++;
3149
3338
** In number context: YYYYMMDD
3150
3339
****************************************************************************/
3152
void Field_newdate::store(const char *from,uint len)
3341
int Field_newdate::store(const char *from,uint len,CHARSET_INFO *cs)
3156
3346
if (str_to_TIME(from,len,&l_time,1) == TIMESTAMP_NONE)
3159
3352
tmp= l_time.day + l_time.month*32 + l_time.year*16*32;
3160
3353
int3store(ptr,tmp);
3163
void Field_newdate::store(double nr)
3357
int Field_newdate::store(double nr)
3165
3359
if (nr < 0.0 || nr > 99991231235959.0)
3166
Field_newdate::store((longlong) -1);
3361
(void) Field_newdate::store((longlong) -1);
3168
Field_newdate::store((longlong) rint(nr));
3365
return Field_newdate::store((longlong) rint(nr));
3172
void Field_newdate::store(longlong nr)
3369
int Field_newdate::store(longlong nr)
3175
3373
if (nr >= LL(100000000) && nr <= LL(99991231235959))
3176
3374
nr=nr/LL(1000000); // Timestamp to date
3177
3375
if (nr < 0L || nr > 99991231L)
3180
3378
current_thd->cuted_fields++;
3196
3395
tmp=0L; // Don't allow date to change
3197
3396
current_thd->cuted_fields++;
3200
3400
tmp= day + month*32 + (tmp/10000)*16*32;
3202
3402
int3store(ptr,(int32) tmp);
3205
3406
void Field_newdate::store_time(TIME *ltime,timestamp_type type)
3302
3503
** Stored as a 8 byte unsigned int. Should sometimes be change to a 6 byte int.
3303
3504
****************************************************************************/
3305
void Field_datetime::store(const char *from,uint len)
3506
int Field_datetime::store(const char *from,uint len,CHARSET_INFO *cs)
3307
3508
longlong tmp=str_to_datetime(from,len,1);
3308
3509
#ifdef WORDS_BIGENDIAN
3315
3516
longlongstore(ptr,tmp);
3319
void Field_datetime::store(double nr)
3521
int Field_datetime::store(double nr)
3321
3524
if (nr < 0.0 || nr > 99991231235959.0)
3324
3527
current_thd->cuted_fields++;
3326
Field_datetime::store((longlong) rint(nr));
3530
error |= Field_datetime::store((longlong) rint(nr));
3330
void Field_datetime::store(longlong nr)
3535
int Field_datetime::store(longlong nr)
3332
3538
if (nr < 0 || nr > LL(99991231235959))
3335
3541
current_thd->cuted_fields++;
3338
3545
nr=fix_datetime(nr);
3519
3727
/* Copy a string and fill with space */
3521
void Field_string::store(const char *from,uint length)
3729
int Field_string::store(const char *from,uint length,CHARSET_INFO *cs)
3523
3733
#ifdef USE_TIS620
3524
3734
if (!binary_flag) {
3525
3735
ThNormalize((uchar *)ptr, field_length, (uchar *)from, length);
3542
3752
const char *end=from+length;
3543
3753
for (from+=field_length ; from != end ; from++)
3545
if (!isspace(*from))
3755
if (!my_isspace(field_charset,*from))
3547
3757
current_thd->cuted_fields++;
3553
3764
#endif /* USE_TIS620 */
3557
void Field_string::store(double nr)
3769
int Field_string::store(double nr)
3559
3771
char buff[MAX_FIELD_WIDTH],*end;
3560
3772
int width=min(field_length,DBL_DIG+5);
3561
3773
sprintf(buff,"%-*.*g",width,max(width-5,0),nr);
3562
3774
end=strcend(buff,' ');
3563
Field_string::store(buff,(uint) (end - buff));
3775
return Field_string::store(buff,(uint) (end - buff), default_charset_info);
3567
void Field_string::store(longlong nr)
3779
int Field_string::store(longlong nr)
3570
3782
char *end=longlong10_to_str(nr,buff,-10);
3571
Field_string::store(buff,(uint) (end-buff));
3783
return Field_string::store(buff,(uint) (end-buff), default_charset_info);
3604
3816
while (end > ptr && end[-1] == ' ')
3606
val_ptr->set((const char*) ptr,(uint) (end - ptr));
3818
val_ptr->set((const char*) ptr,(uint) (end - ptr),field_charset);
3607
3819
return val_ptr;
3613
3825
if (binary_flag)
3614
3826
return memcmp(a_ptr,b_ptr,field_length);
3616
return my_sortcmp(a_ptr,b_ptr,field_length);
3828
return my_sortcmp(field_charset,a_ptr,b_ptr,field_length);
3619
3831
void Field_string::sort_string(char *to,uint length)
3625
3837
#ifdef USE_STRCOLL
3626
if (use_strcoll(default_charset_info)) {
3627
uint tmp=my_strnxfrm(default_charset_info,
3628
(unsigned char *)to, (unsigned char *) ptr,
3629
length, field_length);
3838
if (use_strcoll(field_charset)) {
3839
uint tmp=my_strnxfrm(field_charset,
3840
(unsigned char *)to, length,
3841
(unsigned char *) ptr, field_length);
3630
3842
if (tmp < length)
3631
3843
bzero(to + tmp, length - tmp);
3635
3847
for (char *from=ptr,*end=ptr+length ; from != end ;)
3636
*to++=(char) my_sort_order[(uint) (uchar) *from++];
3848
*to++=(char) field_charset->sort_order[(uint) (uchar) *from++];
3682
3899
int cmp= memcmp(a,b,min(a_length,b_length));
3683
3900
return cmp ? cmp : (int) (a_length - b_length);
3685
return my_sortncmp(a,a_length, b,b_length);
3902
return my_sortncmp(field_charset, a,a_length, b,b_length);
3699
3916
int cmp= memcmp(ptr,b,min(a_length,b_length));
3700
3917
return cmp ? cmp : (int) (a_length - b_length);
3702
return my_sortncmp(ptr,a_length, b, b_length);
3919
return my_sortncmp(field_charset, ptr,a_length, b, b_length);
3722
3939
****************************************************************************/
3725
void Field_varstring::store(const char *from,uint length)
3942
int Field_varstring::store(const char *from,uint length,CHARSET_INFO *cs)
3727
3946
#ifdef USE_TIS620
3728
3947
if (!binary_flag)
3739
3958
length=field_length;
3740
3959
memcpy(ptr+2,from,field_length);
3741
3960
current_thd->cuted_fields++;
3743
3963
#endif /* USE_TIS620 */
3744
3964
int2store(ptr,length);
3748
void Field_varstring::store(double nr)
3969
int Field_varstring::store(double nr)
3750
3971
char buff[MAX_FIELD_WIDTH],*end;
3751
3972
int width=min(field_length,DBL_DIG+5);
3752
3973
sprintf(buff,"%-*.*g",width,max(width-5,0),nr);
3753
3974
end=strcend(buff,' ');
3754
Field_varstring::store(buff,(uint) (end - buff));
3975
return Field_varstring::store(buff,(uint) (end - buff), default_charset_info);
3758
void Field_varstring::store(longlong nr)
3979
int Field_varstring::store(longlong nr)
3761
3982
char *end=longlong10_to_str(nr,buff,-10);
3762
Field_varstring::store(buff,(uint) (end-buff));
3983
return Field_varstring::store(buff,(uint) (end-buff), default_charset_info);
3791
4012
String *val_ptr)
3793
4014
uint length=uint2korr(ptr);
3794
val_ptr->set((const char*) ptr+2,length);
4015
val_ptr->set((const char*) ptr+2,length,field_charset);
3795
4016
return val_ptr;
3804
4025
if (binary_flag)
3805
4026
diff=memcmp(a_ptr+2,b_ptr+2,min(a_length,b_length));
3807
diff=my_sortcmp(a_ptr+2,b_ptr+2,min(a_length,b_length));
4028
diff=my_sortcmp(field_charset, a_ptr+2,b_ptr+2,min(a_length,b_length));
3808
4029
return diff ? diff : (int) (a_length - b_length);
3818
4039
#ifdef USE_STRCOLL
3819
if (use_strcoll(default_charset_info))
3820
tot_length=my_strnxfrm(default_charset_info,
3821
(unsigned char *) to, (unsigned char *)ptr+2,
3822
length, tot_length);
4040
if (use_strcoll(field_charset))
4041
tot_length=my_strnxfrm(field_charset,
4042
(unsigned char *) to, length,
4043
(unsigned char *)ptr+2, tot_length);
3843
4064
res.length((uint) strlen(res.ptr()));
3844
4065
if (binary_flag)
3845
4066
res.append(" binary");
4069
res.append(" character set ");
4070
res.append(field_charset->name);
3848
4074
char *Field_varstring::pack(char *to, const char *from, uint max_length)
3898
4124
int cmp= memcmp(a,b,min(a_length,b_length));
3899
4125
return cmp ? cmp : (int) (a_length - b_length);
3901
return my_sortncmp(a,a_length, b,b_length);
4127
return my_sortncmp(field_charset, a,a_length, b,b_length);
3904
4130
int Field_varstring::pack_cmp(const char *b, uint key_length)
3919
4145
int cmp= memcmp(a,b,min(a_length,b_length));
3920
4146
return cmp ? cmp : (int) (a_length - b_length);
3922
return my_sortncmp(a,a_length, b,b_length);
4148
return my_sortncmp(field_charset, a,a_length, b,b_length);
3925
4151
uint Field_varstring::packed_col_length(const char *ptr, uint length)
3944
4170
Field_blob::Field_blob(char *ptr_arg, uchar *null_ptr_arg, uchar null_bit_arg,
3945
4171
enum utype unireg_check_arg, const char *field_name_arg,
3946
4172
struct st_table *table_arg,uint blob_pack_length,
4173
bool binary_arg, CHARSET_INFO *cs)
3948
4174
:Field_str(ptr_arg, (1L << min(blob_pack_length,3)*8)-1L,
3949
4175
null_ptr_arg, null_bit_arg, unireg_check_arg, field_name_arg,
3951
packlength(blob_pack_length),binary_flag(binary_arg)
4177
packlength(blob_pack_length),binary_flag(binary_arg), geom_flag(true)
3953
4179
flags|= BLOB_FLAG;
3954
4180
if (binary_arg)
4042
void Field_blob::store(const char *from,uint len)
4268
int Field_blob::store(const char *from,uint len,CHARSET_INFO *cs)
4046
4273
bzero(ptr,Field_blob::pack_length());
4073
4300
bmove(ptr+packlength,(char*) &from,sizeof(char*));
4078
void Field_blob::store(double nr)
4081
Field_blob::store(value.ptr(),(uint) value.length());
4085
void Field_blob::store(longlong nr)
4088
Field_blob::store(value.ptr(), (uint) value.length());
4306
int Field_blob::store(double nr)
4309
return Field_blob::store(value.ptr(),(uint) value.length(),
4310
default_charset_info);
4314
int Field_blob::store(longlong nr)
4317
return Field_blob::store(value.ptr(), (uint) value.length(),
4318
default_charset_info);
4129
4359
memcpy_fixed(&blob,ptr+packlength,sizeof(char*));
4131
val_ptr->set("",0); // A bit safer than ->length(0)
4361
val_ptr->set("",0,field_charset); // A bit safer than ->length(0)
4133
val_ptr->set((const char*) blob,get_length(ptr));
4363
val_ptr->set((const char*) blob,get_length(ptr),field_charset);
4134
4364
return val_ptr;
4142
4372
if (binary_flag)
4143
4373
diff=memcmp(a,b,min(a_length,b_length));
4145
diff=my_sortcmp(a,b,min(a_length,b_length));
4375
diff=my_sortcmp(field_charset, a,b,min(a_length,b_length));
4146
4376
return diff ? diff : (int) (a_length - b_length);
4191
4421
/* The following is used only when comparing a key */
4193
void Field_blob::get_key_image(char *buff,uint length)
4423
void Field_blob::get_key_image(char *buff,uint length, imagetype type)
4425
length-= HA_KEY_BLOB_LENGTH;
4426
uint32 blob_length= get_length(ptr);
4437
gobj.create_from_wkb(blob,blob_length);
4439
float8store(buff, mbr.xmin);
4440
float8store(buff+8, mbr.xmax);
4441
float8store(buff+16, mbr.ymin);
4442
float8store(buff+24, mbr.ymax);
4195
4446
length-=HA_KEY_BLOB_LENGTH;
4196
uint32 blob_length=get_length(ptr);
4198
4447
if ((uint32) length > blob_length)
4200
4449
#ifdef HAVE_purify
4210
4459
void Field_blob::set_key_image(char *buff,uint length)
4212
4461
length=uint2korr(buff);
4213
Field_blob::store(buff+2,length);
4462
(void) Field_blob::store(buff+2,length, default_charset_info);
4466
void Field_geom::get_key_image(char *buff,uint length, imagetype type)
4468
length-=HA_KEY_BLOB_LENGTH;
4469
ulong blob_length=get_length(ptr);
4472
memcpy(buff+2,blob,length);
4476
gobj.create_from_wkb(blob,blob_length);
4478
float8store(buff, mbr.xmin);
4479
float8store(buff+8, mbr.xmax);
4480
float8store(buff+16, mbr.ymin);
4481
float8store(buff+24, mbr.ymax);
4485
void Field_geom::set_key_image(char *buff,uint length)
4216
4490
int Field_blob::key_cmp(const byte *key_ptr, uint max_key_length)
4254
4528
#ifdef USE_STRCOLL
4255
if (use_strcoll(default_charset_info))
4529
if (use_strcoll(field_charset))
4257
blob_length=my_strnxfrm(default_charset_info,
4258
(unsigned char *)to,(unsigned char *)blob,
4259
length,blob_org_length);
4531
blob_length=my_strnxfrm(field_charset,
4532
(unsigned char *)to, length,
4533
(unsigned char *)blob, blob_org_length);
4260
4534
if (blob_length >= length)
4262
4536
to+=blob_length;
4266
4540
for (char *end=blob+blob_length ; blob != end ;)
4267
*to++=(char) my_sort_order[(uint) (uchar) *blob++];
4541
*to++=(char) field_charset->sort_order[(uint) (uchar) *blob++];
4269
4543
bzero(to,length-blob_length);
4280
4554
case 3: str="medium"; break;
4281
4555
case 4: str="long"; break;
4283
res.set(str,(uint) strlen(str));
4557
res.set(str,(uint) strlen(str),default_charset_info);
4284
4558
res.append(binary_flag ? "blob" : "text");
4561
res.append(" character set ");
4562
res.append(field_charset->name);
4342
4621
int cmp= memcmp(a,b,min(a_length,b_length));
4343
4622
return cmp ? cmp : (int) (a_length - b_length);
4345
return my_sortncmp(a,a_length, b,b_length);
4624
return my_sortncmp(field_charset, a,a_length, b,b_length);
4368
4647
int cmp= memcmp(a,b,min(a_length,b_length));
4369
4648
return cmp ? cmp : (int) (a_length - b_length);
4371
return my_sortncmp(a,a_length, b,b_length);
4650
return my_sortncmp(field_charset, a,a_length, b,b_length);
4374
4653
/* Create a packed key that will be used for storage from a MySQL row */
4479
4758
uint find_enum(TYPELIB *lib,const char *x, uint length)
4481
4760
const char *end=x+length;
4482
while (end > x && isspace(end[-1]))
4761
while (end > x && my_isspace(system_charset_info,end[-1]))
4487
4766
for (uint pos=0 ; (j=lib->type_names[pos]) ; pos++)
4489
for (i=x ; i != end && toupper(*i) == toupper(*j) ; i++, j++) ;
4768
for (i=x ; i != end &&
4769
my_toupper(system_charset_info,*i) ==
4770
my_toupper(system_charset_info,*j) ; i++, j++) ;
4490
4771
if (i == end && ! *j)
4499
4780
** (if there isn't a empty value in the enum)
4502
void Field_enum::store(const char *from,uint length)
4783
int Field_enum::store(const char *from,uint length,CHARSET_INFO *cs)
4504
4786
uint tmp=find_enum(typelib,from,length);
4522
4804
current_thd->cuted_fields++;
4526
4809
current_thd->cuted_fields++;
4528
4811
store_type((ulonglong) tmp);
4532
void Field_enum::store(double nr)
4534
Field_enum::store((longlong) nr);
4538
void Field_enum::store(longlong nr)
4816
int Field_enum::store(double nr)
4818
return Field_enum::store((longlong) nr);
4822
int Field_enum::store(longlong nr)
4540
4825
if ((uint) nr > typelib->count || nr == 0)
4542
4827
current_thd->cuted_fields++;
4545
4831
store_type((ulonglong) (uint) nr);
4663
4949
ulonglong find_set(TYPELIB *lib,const char *x,uint length)
4665
4951
const char *end=x+length;
4666
while (end > x && isspace(end[-1]))
4952
while (end > x && my_isspace(system_charset_info, end[-1]))
4669
4955
ulonglong found=0;
4672
4958
const char *start=x;
4676
4962
const char *pos=start;
4694
void Field_set::store(const char *from,uint length)
4980
int Field_set::store(const char *from,uint length,CHARSET_INFO *cs)
4696
4983
ulonglong tmp=find_set(typelib,from,length);
4697
4984
if (!tmp && length && length < 22)
4708
4995
tmp=strtoull(conv,&end,10);
4709
4996
if (my_errno || end != conv+length ||
4710
4997
tmp > (ulonglong) (((longlong) 1 << typelib->count) - (longlong) 1))
4713
5003
current_thd->cuted_fields--; // Remove warning from find_set
4715
5005
store_type(tmp);
4719
void Field_set::store(longlong nr)
5010
int Field_set::store(longlong nr)
4721
5013
if ((ulonglong) nr > (ulonglong) (((longlong) 1 << typelib->count) -
4724
5016
nr&= (longlong) (((longlong) 1 << typelib->count) - (longlong) 1);
4725
5017
current_thd->cuted_fields++;
4727
5020
store_type((ulonglong) nr);
4742
5036
if (val_buffer->length())
4743
5037
val_buffer->append(field_separator);
4744
5038
String str(typelib->type_names[bitnr],
4745
(uint) strlen(typelib->type_names[bitnr]));
5039
(uint) strlen(typelib->type_names[bitnr]),
5040
default_charset_info);
4746
5041
val_buffer->append(str);
4789
5082
if (typelib->count < from_lib->count)
4791
5084
for (uint i=0 ; i < from_lib->count ; i++)
4792
if (my_strcasecmp(typelib->type_names[i],from_lib->type_names[i]))
5085
if (my_strcasecmp(field_charset,
5086
typelib->type_names[i],from_lib->type_names[i]))
4864
5158
Field *make_field(char *ptr, uint32 field_length,
4865
5159
uchar *null_pos, uchar null_bit,
4866
5160
uint pack_flag,
5161
enum_field_types field_type,
4867
5162
Field::utype unireg_check,
4868
5163
TYPELIB *interval,
4869
5164
const char *field_name,
4879
5174
if (!f_is_packed(pack_flag))
4880
5175
return new Field_string(ptr,field_length,null_pos,null_bit,
4881
5176
unireg_check, field_name, table,
4882
f_is_binary(pack_flag) != 0);
5177
f_is_binary(pack_flag) != 0,
5178
default_charset_info);
4884
5180
uint pack_length=calc_pack_length((enum_field_types)
4885
5181
f_packtype(pack_flag),
4888
5184
if (f_is_blob(pack_flag))
4889
5185
return new Field_blob(ptr,null_pos,null_bit,
4890
5186
unireg_check, field_name, table,
5187
pack_length,f_is_binary(pack_flag) != 0,
5188
default_charset_info);
5189
if (f_is_geom(pack_flag))
5190
return new Field_geom(ptr,null_pos,null_bit,
5191
unireg_check, field_name, table,
4891
5192
pack_length,f_is_binary(pack_flag) != 0);
4894
5196
if (f_is_enum(pack_flag))
4905
switch ((enum enum_field_types) f_packtype(pack_flag)) {
5207
switch (field_type) {
4906
5208
case FIELD_TYPE_DECIMAL:
4907
5209
return new Field_decimal(ptr,field_length,null_pos,null_bit,
4908
5210
unireg_check, field_name, table,
4983
5285
unireg_check=old_field->unireg_check;
4984
5286
pack_length=old_field->pack_length();
4985
5287
sql_type= old_field->real_type();
5288
charset= old_field->charset(); // May be NULL ptr
5289
comment= old_field->comment;
4987
5291
/* Fix if the original table had 4 byte pointer blobs */
4988
5292
if (flags & BLOB_FLAG)
5006
5311
char buff[MAX_FIELD_WIDTH],*pos;
5007
String tmp(buff,sizeof(buff));
5312
CHARSET_INFO *field_charset= charset ? charset : default_charset_info;
5313
String tmp(buff,sizeof(buff),field_charset);
5009
5315
/* Get the value from record[2] (the default value row) */
5010
5316
my_ptrdiff_t diff= (my_ptrdiff_t) (orig_field->table->rec_buff_length*2);
5017
5323
pos= (char*) sql_memdup(tmp.ptr(),tmp.length()+1);
5018
5324
pos[tmp.length()]=0;
5019
def=new Item_string(pos,tmp.length());
5325
def=new Item_string(pos,tmp.length(),field_charset);