diff options
Diffstat (limited to 'sql/field.cc')
-rw-r--r-- | sql/field.cc | 150 |
1 files changed, 100 insertions, 50 deletions
diff --git a/sql/field.cc b/sql/field.cc index 7850daac8c7..36a703a1b7a 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -3735,6 +3735,13 @@ int Field_timestamp::store(longlong nr) set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, nr, MYSQL_TIMESTAMP_DATETIME, 1); + if (!error && timestamp == 0 && + (table->in_use->variables.sql_mode & MODE_NO_ZERO_DATE)) + { + set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, + WARN_DATA_TRUNCATED, + nr, MYSQL_TIMESTAMP_DATETIME, 1); + } #ifdef WORDS_BIGENDIAN if (table->s->db_low_byte_first) @@ -4360,6 +4367,12 @@ int Field_date::store(double nr) } else tmp=(long) rint(nr); + + /* + We don't need to check for zero dates here as this date type is only + used in .frm tables from very old MySQL versions + */ + #ifdef WORDS_BIGENDIAN if (table->s->db_low_byte_first) { @@ -4388,6 +4401,7 @@ int Field_date::store(longlong nr) } else tmp=(long) nr; + #ifdef WORDS_BIGENDIAN if (table->s->db_low_byte_first) { @@ -4500,6 +4514,7 @@ void Field_date::sql_type(String &res) const res.set_ascii("date", 4); } + /**************************************************************************** ** The new date type ** This is identical to the old date type, but stored on 3 bytes instead of 4 @@ -4532,17 +4547,17 @@ int Field_newdate::store(const char *from,uint len,CHARSET_INFO *cs) return error; } + int Field_newdate::store(double nr) { if (nr < 0.0 || nr > 99991231235959.0) { - (void) Field_newdate::store((longlong) -1); + int3store(ptr,(int32) 0); set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, nr, MYSQL_TIMESTAMP_DATE); return 1; } - else - return Field_newdate::store((longlong) rint(nr)); + return Field_newdate::store((longlong) rint(nr)); } @@ -4562,6 +4577,8 @@ int Field_newdate::store(longlong nr) } else { + uint month, day; + tmp=(int32) nr; if (tmp) { @@ -4569,24 +4586,33 @@ int Field_newdate::store(longlong nr) tmp+= (uint32) 20000000L; else if (tmp < 999999L) tmp+= (uint32) 19000000L; + + month= (uint) ((tmp/100) % 100); + day= (uint) (tmp%100); + if (month > 12 || day > 31) + { + tmp=0L; // Don't allow date to change + set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, + ER_WARN_DATA_OUT_OF_RANGE, nr, + MYSQL_TIMESTAMP_DATE, 1); + error= 1; + } + else + tmp= day + month*32 + (tmp/10000)*16*32; } - uint month= (uint) ((tmp/100) % 100); - uint day= (uint) (tmp%100); - if (month > 12 || day > 31) + else if (table->in_use->variables.sql_mode & MODE_NO_ZERO_DATE) { - tmp=0L; // Don't allow date to change set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, - ER_WARN_DATA_OUT_OF_RANGE, nr, - MYSQL_TIMESTAMP_DATE, 1); + ER_WARN_DATA_OUT_OF_RANGE, + 0, MYSQL_TIMESTAMP_DATE); error= 1; } - else - tmp= day + month*32 + (tmp/10000)*16*32; } - int3store(ptr,(int32) tmp); + int3store(ptr, tmp); return error; } + int Field_newdate::store_time(TIME *ltime,timestamp_type type) { long tmp; @@ -4603,6 +4629,7 @@ int Field_newdate::store_time(TIME *ltime,timestamp_type type) return error; } + bool Field_newdate::send_binary(Protocol *protocol) { TIME tm; @@ -4610,11 +4637,13 @@ bool Field_newdate::send_binary(Protocol *protocol) return protocol->store_date(&tm); } + double Field_newdate::val_real(void) { return (double) Field_newdate::val_int(); } + longlong Field_newdate::val_int(void) { ulong j= uint3korr(ptr); @@ -4622,6 +4651,7 @@ longlong Field_newdate::val_int(void) return (longlong) j; } + String *Field_newdate::val_str(String *val_buffer, String *val_ptr __attribute__((unused))) { @@ -4649,6 +4679,7 @@ String *Field_newdate::val_str(String *val_buffer, return val_buffer; } + bool Field_newdate::get_date(TIME *ltime,uint fuzzydate) { uint32 tmp=(uint32) uint3korr(ptr); @@ -4661,11 +4692,13 @@ bool Field_newdate::get_date(TIME *ltime,uint fuzzydate) 1 : 0); } + bool Field_newdate::get_time(TIME *ltime) { return Field_newdate::get_date(ltime,0); } + int Field_newdate::cmp(const char *a_ptr, const char *b_ptr) { uint32 a,b; @@ -4674,6 +4707,7 @@ int Field_newdate::cmp(const char *a_ptr, const char *b_ptr) return (a < b) ? -1 : (a > b) ? 1 : 0; } + void Field_newdate::sort_string(char *to,uint length __attribute__((unused))) { to[0] = ptr[2]; @@ -4681,6 +4715,7 @@ void Field_newdate::sort_string(char *to,uint length __attribute__((unused))) to[2] = ptr[0]; } + void Field_newdate::sql_type(String &res) const { res.set_ascii("date", 4); @@ -4737,10 +4772,10 @@ int Field_datetime::store(double nr) set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, nr, MYSQL_TIMESTAMP_DATETIME); - nr=0.0; + nr= 0.0; error= 1; } - error |= Field_datetime::store((longlong) rint(nr)); + error|= Field_datetime::store((longlong) rint(nr)); return error; } @@ -4757,6 +4792,13 @@ int Field_datetime::store(longlong nr) set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, initial_nr, MYSQL_TIMESTAMP_DATETIME, 1); + else if (nr == 0 && table->in_use->variables.sql_mode & MODE_NO_ZERO_DATE) + { + set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, + ER_WARN_DATA_OUT_OF_RANGE, + initial_nr, MYSQL_TIMESTAMP_DATE); + error= 1; + } #ifdef WORDS_BIGENDIAN if (table->s->db_low_byte_first) @@ -7542,7 +7584,37 @@ create_field::create_field(Field *old_field,Field *orig_field) } -/* Warning handling */ +/* + maximum possible display length for blob + + SYNOPSIS + Field_blob::max_length() + + RETURN + length +*/ +uint32 Field_blob::max_length() +{ + switch (packlength) + { + case 1: + return 255; + case 2: + return 65535; + case 3: + return 16777215; + case 4: + return (uint32) 4294967295U; + default: + DBUG_ASSERT(0); // we should never go here + return 0; + } +} + + +/***************************************************************************** + Warning handling +*****************************************************************************/ /* Produce warning or note about data saved into field @@ -7558,18 +7630,20 @@ create_field::create_field(Field *old_field,Field *orig_field) if count_cuted_fields == FIELD_CHECK_IGNORE for current thread. RETURN VALUE - true - if count_cuted_fields == FIELD_CHECK_IGNORE - false - otherwise + 1 if count_cuted_fields == FIELD_CHECK_IGNORE + 0 otherwise */ + bool -Field::set_warning(uint level, uint code, int cuted_increment) +Field::set_warning(MYSQL_ERROR::enum_warning_level level, uint code, + int cuted_increment) { THD *thd= table->in_use; if (thd->count_cuted_fields) { thd->cuted_fields+= cuted_increment; - push_warning_printf(thd, (MYSQL_ERROR::enum_warning_level) level, - code, ER(code), field_name, thd->row_count); + push_warning_printf(thd, level, code, ER(code), field_name, + thd->row_count); return 0; } return 1; @@ -7593,8 +7667,9 @@ Field::set_warning(uint level, uint code, int cuted_increment) fields counter if count_cuted_fields == FIELD_CHECK_IGNORE for current thread. */ + void -Field::set_datetime_warning(const uint level, const uint code, +Field::set_datetime_warning(MYSQL_ERROR::enum_warning_level level, uint code, const char *str, uint str_length, timestamp_type ts_type, int cuted_increment) { @@ -7621,8 +7696,9 @@ Field::set_datetime_warning(const uint level, const uint code, fields counter if count_cuted_fields == FIELD_CHECK_IGNORE for current thread. */ + void -Field::set_datetime_warning(const uint level, const uint code, +Field::set_datetime_warning(MYSQL_ERROR::enum_warning_level level, uint code, longlong nr, timestamp_type ts_type, int cuted_increment) { @@ -7652,8 +7728,9 @@ Field::set_datetime_warning(const uint level, const uint code, fields counter if count_cuted_fields == FIELD_CHECK_IGNORE for current thread. */ + void -Field::set_datetime_warning(const uint level, const uint code, +Field::set_datetime_warning(MYSQL_ERROR::enum_warning_level level, uint code, double nr, timestamp_type ts_type) { if (table->in_use->really_abort_on_warning() || @@ -7666,30 +7743,3 @@ Field::set_datetime_warning(const uint level, const uint code, field_name); } } - -/* - maximum possible display length for blob - - SYNOPSIS - Field_blob::max_length() - - RETURN - length -*/ -uint32 Field_blob::max_length() -{ - switch (packlength) - { - case 1: - return 255; - case 2: - return 65535; - case 3: - return 16777215; - case 4: - return (uint32) 4294967295U; - default: - DBUG_ASSERT(0); // we should never go here - return 0; - } -} |