diff options
author | monty@mysql.com <> | 2003-12-17 17:35:34 +0200 |
---|---|---|
committer | monty@mysql.com <> | 2003-12-17 17:35:34 +0200 |
commit | e0cc6799ecc831d296c568c5068947c1421fcaa5 (patch) | |
tree | 93924b5aab311e02a0f0931cf91e67cdfad04bdf /sql/field.cc | |
parent | 0462f48b344633c7d88d12d9667f4bd50b91c552 (diff) | |
parent | 30e318311b35b109d230f7184fe0be1b6e29f02b (diff) | |
download | mariadb-git-e0cc6799ecc831d296c568c5068947c1421fcaa5.tar.gz |
Merge with 4.0.17
Diffstat (limited to 'sql/field.cc')
-rw-r--r-- | sql/field.cc | 136 |
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, ¬_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, ¬_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, ¬_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, ¬_used, ¬_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; } |