summaryrefslogtreecommitdiff
path: root/sql/field.cc
diff options
context:
space:
mode:
authormonty@mysql.com <>2003-12-17 17:35:34 +0200
committermonty@mysql.com <>2003-12-17 17:35:34 +0200
commite0cc6799ecc831d296c568c5068947c1421fcaa5 (patch)
tree93924b5aab311e02a0f0931cf91e67cdfad04bdf /sql/field.cc
parent0462f48b344633c7d88d12d9667f4bd50b91c552 (diff)
parent30e318311b35b109d230f7184fe0be1b6e29f02b (diff)
downloadmariadb-git-e0cc6799ecc831d296c568c5068947c1421fcaa5.tar.gz
Merge with 4.0.17
Diffstat (limited to 'sql/field.cc')
-rw-r--r--sql/field.cc136
1 files changed, 81 insertions, 55 deletions
diff --git a/sql/field.cc b/sql/field.cc
index 23f6e1232b6..c54e27360b5 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -791,7 +791,7 @@ int Field_decimal::store(const char *from, uint len, CHARSET_INFO *cs)
if (zerofill)
{
left_wall=to-1;
- while (pos != left_wall) // Fill with zeros
+ while (pos > left_wall) // Fill with zeros
*pos--='0';
}
else
@@ -799,7 +799,7 @@ int Field_decimal::store(const char *from, uint len, CHARSET_INFO *cs)
left_wall=to+(sign_char != 0)-1;
if (!expo_sign_char) // If exponent was specified, ignore prezeros
{
- for (;pos != left_wall && pre_zeros_from !=pre_zeros_end;
+ for (;pos > left_wall && pre_zeros_from !=pre_zeros_end;
pre_zeros_from++)
*pos--= '0';
}
@@ -1016,7 +1016,7 @@ int Field_decimal::cmp(const char *a_ptr,const char *b_ptr)
return 0;
if (*a_ptr == '-')
return -1;
- else if (*b_ptr == '-')
+ if (*b_ptr == '-')
return 1;
while (a_ptr != end)
@@ -2853,34 +2853,71 @@ int Field_timestamp::store(double nr)
function.
*/
-static longlong fix_datetime(longlong nr)
+static longlong fix_datetime(longlong nr, TIME *time_res,
+ const char *field_name, bool *error)
{
- current_thd->last_cuted_field= 0;
+ long part1,part2;
+
+ *error= 0;
if (nr == LL(0) || nr >= LL(10000101000000))
- return nr; // Normal datetime >= Year 1000
+ goto ok;
if (nr < 101)
goto err;
if (nr <= (YY_PART_YEAR-1)*10000L+1231L)
- return (nr+20000000L)*1000000L; // YYMMDD, year: 2000-2069
+ {
+ nr= (nr+20000000L)*1000000L; // YYMMDD, year: 2000-2069
+ goto ok;
+ }
if (nr < (YY_PART_YEAR)*10000L+101L)
goto err;
if (nr <= 991231L)
- return (nr+19000000L)*1000000L; // YYMMDD, year: 1970-1999
+ {
+ nr= (nr+19000000L)*1000000L; // YYMMDD, year: 1970-1999
+ goto ok;
+ }
if (nr < 10000101L)
goto err;
if (nr <= 99991231L)
- return nr*1000000L;
+ {
+ nr= nr*1000000L;
+ goto ok;
+ }
if (nr < 101000000L)
goto err;
if (nr <= (YY_PART_YEAR-1)*LL(10000000000)+LL(1231235959))
- return nr+LL(20000000000000); // YYMMDDHHMMSS, 2000-2069
+ {
+ nr= nr+LL(20000000000000); // YYMMDDHHMMSS, 2000-2069
+ goto ok;
+ }
if (nr < YY_PART_YEAR*LL(10000000000)+ LL(101000000))
goto err;
if (nr <= LL(991231235959))
- return nr+LL(19000000000000); // YYMMDDHHMMSS, 1970-1999
-
+ nr= nr+LL(19000000000000); // YYMMDDHHMMSS, 1970-1999
+
+ ok:
+ part1=(long) (nr/LL(1000000));
+ part2=(long) (nr - (longlong) part1*LL(1000000));
+ time_res->year= (int) (part1/10000L); part1%=10000L;
+ time_res->month= (int) part1 / 100;
+ time_res->day= (int) part1 % 100;
+ time_res->hour= (int) (part2/10000L); part2%=10000L;
+ time_res->minute=(int) part2 / 100;
+ time_res->second=(int) part2 % 100;
+
+ if (time_res->year <= 9999 && time_res->month <= 12 &&
+ time_res->day <= 31 && time_res->hour <= 23 &&
+ time_res->minute <= 59 && time_res->second <= 59)
+ return nr;
+
err:
- current_thd->last_cuted_field= 1;
+ if (thd->count_cuted_fields)
+ {
+ thd->cuted_fields++;
+ push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_WARN_DATA_TRUNCATED, ER(ER_WARN_DATA_TRUNCATED),
+ field_name, thd->row_count);
+ }
+ *error= 1;
return LL(0);
}
@@ -2888,24 +2925,17 @@ static longlong fix_datetime(longlong nr)
int Field_timestamp::store(longlong nr)
{
TIME l_time;
- time_t timestamp;
- long part1,part2;
+ time_t timestamp= 0;
+ bool error;
- if ((nr=fix_datetime(nr)))
+ if ((nr= fix_datetime(nr, &l_time, field_name, &error)))
{
long not_used;
- part1=(long) (nr/LL(1000000));
- part2=(long) (nr - (longlong) part1*LL(1000000));
- l_time.year= (int) (part1/10000L); part1%=10000L;
- l_time.month= (int) part1 / 100;
- l_time.day= (int) part1 % 100;
- l_time.hour= (int) (part2/10000L); part2%=10000L;
- l_time.minute=(int) part2 / 100;
- l_time.second=(int) part2 % 100;
- timestamp=my_gmt_sec(&l_time, &not_used);
- }
- else
- timestamp=0;
+
+ if (l_time.year >= TIMESTAMP_MAX_YEAR || l_time.year < 1900+YY_PART_YEAR-1)
+ goto err;
+ timestamp= my_gmt_sec(&l_time, &not_used);
+ }
#ifdef WORDS_BIGENDIAN
if (table->db_low_byte_first)
{
@@ -2914,9 +2944,14 @@ int Field_timestamp::store(longlong nr)
else
#endif
longstore(ptr,(uint32) timestamp);
- if (current_thd->last_cuted_field)
- set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED);
- return 0;
+ return error;
+
+err:
+ longstore(ptr,(uint32) 0);
+ if (current_thd->count_cuted_fields)
+ set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED,
+ field_name, 0);
+ return 1;
}
@@ -3350,7 +3385,7 @@ int Field_year::store(const char *from, uint len,CHARSET_INFO *cs)
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE);
return 1;
}
- else if (current_thd->count_cuted_fields && !test_if_int(from,len,end,cs))
+ if (current_thd->count_cuted_fields && !test_if_int(from,len,end,cs))
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED);
if (nr != 0 || len != 4)
{
@@ -3363,6 +3398,7 @@ int Field_year::store(const char *from, uint len,CHARSET_INFO *cs)
return 0;
}
+
int Field_year::store(double nr)
{
if (nr < 0.0 || nr >= 2155.0)
@@ -3825,15 +3861,10 @@ int Field_datetime::store(double nr)
int Field_datetime::store(longlong nr)
{
- int error= 0;
- if (nr < 0 || nr > LL(99991231235959))
- {
- nr=0;
- set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE);
- error= 1;
- }
- else
- nr=fix_datetime(nr);
+ TIME not_used;
+ bool error;
+
+ nr= fix_datetime(nr, &not_used, field_name, &error);
#ifdef WORDS_BIGENDIAN
if (table->db_low_byte_first)
{
@@ -3842,11 +3873,10 @@ int Field_datetime::store(longlong nr)
else
#endif
longlongstore(ptr,nr);
- if (current_thd->last_cuted_field)
- set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED);
return error;
}
+
void Field_datetime::store_time(TIME *ltime,timestamp_type type)
{
longlong tmp;
@@ -5064,7 +5094,7 @@ int Field_enum::store(const char *from,uint length,CHARSET_INFO *cs)
uint tmp=find_type(typelib, from, length, 0);
if (!tmp)
{
- if (length < 6) // Can't be more than 99999 enums
+ if (length < 6) // Can't be more than 99999 enums
{
/* This is for reading numbers with LOAD DATA INFILE */
char *end;
@@ -5159,7 +5189,7 @@ String *Field_enum::val_str(String *val_buffer __attribute__((unused)),
{
uint tmp=(uint) Field_enum::val_int();
if (!tmp || tmp > typelib->count)
- val_ptr->length(0);
+ val_ptr->set((char*)"",0);
else
val_ptr->set((const char*) typelib->type_names[tmp-1],
(uint) strlen(typelib->type_names[tmp-1]),
@@ -5219,12 +5249,13 @@ void Field_enum::sql_type(String &res) const
int Field_set::store(const char *from,uint length,CHARSET_INFO *cs)
{
- bool set_warning= 0;
+ bool got_warning= 0;
int err= 0;
char *not_used;
uint not_used2;
char buff[80];
String tmpstr(buff,sizeof(buff), &my_charset_bin);
+
/* Convert character set if nesessary */
if (use_conversion(cs, field_charset))
{
@@ -5233,7 +5264,7 @@ int Field_set::store(const char *from,uint length,CHARSET_INFO *cs)
length= tmpstr.length();
}
ulonglong tmp= find_set(typelib, from, length, &not_used, &not_used2,
- &set_warning);
+ &got_warning);
if (!tmp && length && length < 22)
{
/* This is for reading numbers with LOAD DATA INFILE */
@@ -5243,16 +5274,11 @@ int Field_set::store(const char *from,uint length,CHARSET_INFO *cs)
tmp > (ulonglong) (((longlong) 1 << typelib->count) - (longlong) 1))
{
tmp=0;
- THD *thd= current_thd;
- if (thd->count_cuted_fields)
- {
- thd->cuted_fields++;
- push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
- ER_WARN_DATA_TRUNCATED, ER(ER_WARN_DATA_TRUNCATED),
- field_name, 0);
- }
+ set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED);
}
}
+ else if (got_warning)
+ set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED);
store_type(tmp);
return err;
}