summaryrefslogtreecommitdiff
path: root/sql/field.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/field.cc')
-rw-r--r--sql/field.cc150
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;
- }
-}