diff options
author | Sergei Golubchik <sergii@pisem.net> | 2011-05-19 19:01:46 +0200 |
---|---|---|
committer | Sergei Golubchik <sergii@pisem.net> | 2011-05-19 19:01:46 +0200 |
commit | 8ddcd0cda8e6e90a58e9ea64f0f3773ea0037f0b (patch) | |
tree | 4765748aeb7aafb09e259e1a355e28c11819e9c0 /sql | |
parent | 5346cb8d2745acd660b301092458e231c9f53319 (diff) | |
download | mariadb-git-8ddcd0cda8e6e90a58e9ea64f0f3773ea0037f0b.tar.gz |
post-review changes 1
include/my_time.h:
remove duplicate defines.
cast to ulonglong to avoid overflow
sql/field.cc:
perform sign extension when reading packed TIME values
sql/item_cmpfunc.cc:
when converting a string to a date for the purpose of comparing it with another date,
we should ignore strict sql mode.
sql/item_timefunc.cc:
better error message
sql/item_timefunc.h:
limit decimals appropriately
sql/share/errmsg.txt:
don't refer to an object as a "column" in error messages that are used not only for columns.
Diffstat (limited to 'sql')
-rw-r--r-- | sql/field.cc | 11 | ||||
-rw-r--r-- | sql/field.h | 6 | ||||
-rw-r--r-- | sql/item.cc | 4 | ||||
-rw-r--r-- | sql/item_cmpfunc.cc | 16 | ||||
-rw-r--r-- | sql/item_timefunc.cc | 28 | ||||
-rw-r--r-- | sql/item_timefunc.h | 18 | ||||
-rw-r--r-- | sql/protocol.cc | 4 | ||||
-rw-r--r-- | sql/share/errmsg.txt | 8 |
8 files changed, 55 insertions, 40 deletions
diff --git a/sql/field.cc b/sql/field.cc index 914376b91e0..731aaea4659 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -5056,7 +5056,7 @@ static uint sec_part_bytes[MAX_DATETIME_PRECISION+1]= { 0, 1, 1, 2, 2, 3, 3 }; static uint datetime_hires_bytes[MAX_DATETIME_PRECISION+1]= { 5, 6, 6, 7, 7, 7, 8 }; static uint time_hires_bytes[MAX_DATETIME_PRECISION+1]= -{ 3, 4, 4, 4, 5, 5, 6 }; +{ 3, 4, 4, 5, 5, 5, 6 }; void Field_timestamp_hires::store_TIME(my_time_t timestamp, ulong sec_part) { @@ -5520,7 +5520,14 @@ String *Field_time_hires::val_str(String *str, bool Field_time_hires::get_date(MYSQL_TIME *ltime, uint fuzzydate) { - ulonglong packed= read_bigendian(ptr, Field_time_hires::pack_length()); + uint32 len= pack_length(); + longlong packed= read_bigendian(ptr, len); + + /* sign extension */ + longlong mask= 1LL << (len*8 - 1); + if (packed & mask) + packed|= ~(mask-1); + unpack_time(sec_part_unshift(packed, dec), ltime); /* unpack_time() returns MYSQL_TIMESTAMP_DATETIME. diff --git a/sql/field.h b/sql/field.h index d5d5ad32744..75cf3858e6f 100644 --- a/sql/field.h +++ b/sql/field.h @@ -1234,7 +1234,7 @@ public: dec(dec_arg) { DBUG_ASSERT(dec); - DBUG_ASSERT(dec <= MAX_SEC_PART_DIGITS); + DBUG_ASSERT(dec <= TIME_SECOND_PART_DIGITS); } void sql_type(String &str) const; long get_timestamp(ulong *sec_part) const; @@ -1407,7 +1407,7 @@ public: dec(dec_arg) { DBUG_ASSERT(dec); - DBUG_ASSERT(dec <= MAX_SEC_PART_DIGITS); + DBUG_ASSERT(dec <= TIME_SECOND_PART_DIGITS); } enum ha_base_keytype key_type() const { return HA_KEYTYPE_BINARY; } uint decimals() const { return dec; } @@ -1476,7 +1476,7 @@ public: field_name_arg, cs), dec(dec_arg) { DBUG_ASSERT(dec); - DBUG_ASSERT(dec <= MAX_SEC_PART_DIGITS); + DBUG_ASSERT(dec <= TIME_SECOND_PART_DIGITS); } enum ha_base_keytype key_type() const { return HA_KEYTYPE_BINARY; } int store_decimal(const my_decimal *d); diff --git a/sql/item.cc b/sql/item.cc index cce985fe80d..997ce821f9a 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -2748,13 +2748,13 @@ void Item_param::set_time(MYSQL_TIME *tm, timestamp_type time_type, value.time= *tm; value.time.time_type= time_type; - decimals= value.time.second_part > 0 ? MAX_SEC_PART_DIGITS : 0; + decimals= value.time.second_part > 0 ? TIME_SECOND_PART_DIGITS : 0; if (value.time.year > 9999 || value.time.month > 12 || value.time.day > 31 || (time_type != MYSQL_TIMESTAMP_TIME && value.time.hour > 23) || value.time.minute > 59 || value.time.second > 59 || - value.time.second_part > MAX_SEC_PART_VALUE) + value.time.second_part > TIME_MAX_SECOND_PART) { Lazy_string_time str(&value.time); make_truncated_value_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 1573dfddf98..e7418c2a53a 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -629,12 +629,14 @@ int Arg_comparator::set_compare_func(Item_result_field *item, Item_result type) @param[in] warn_name Field name for issuing the warning @param[out] l_time The MYSQL_TIME objects is initialized. - Parses a date provided in the string str into a MYSQL_TIME object. If the - string contains an incorrect date or doesn't correspond to a date at all - then a warning is issued. The warn_type and the warn_name arguments are used - as the name and the type of the field when issuing the warning. If any input - was discarded (trailing or non-timestamp-y characters), return value will be - TRUE. + Parses a date provided in the string str into a MYSQL_TIME object. + The date is used for comparison, that is fuzzy dates are allowed + independently of sql_mode. + If the string contains an incorrect date or doesn't correspond to a date at + all then a warning is issued. The warn_type and the warn_name arguments are + used as the name and the type of the field when issuing the warning. If any + input was discarded (trailing or non-timestamp-y characters), return value + will be TRUE. @return Status flag @retval FALSE Success. @@ -649,8 +651,6 @@ bool get_mysql_time_from_str(THD *thd, String *str, timestamp_type warn_type, enum_mysql_timestamp_type timestamp_type; int flags= TIME_FUZZY_DATE | MODE_INVALID_DATES; - flags|= thd->variables.sql_mode & (MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE); - if (warn_type == MYSQL_TIMESTAMP_TIME) flags|= TIME_TIME_ONLY; diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index 51da306af48..a173f50e605 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -1479,9 +1479,10 @@ bool Item_func_curdate::get_date(MYSQL_TIME *res, bool Item_func_curtime::fix_fields(THD *thd, Item **items) { - if (decimals > MAX_SEC_PART_DIGITS) + if (decimals > TIME_SECOND_PART_DIGITS) { - my_error(ER_WRONG_ARGUMENTS, MYF(0), func_name()); + my_error(ER_TOO_BIG_PRECISION, MYF(0), decimals, func_name(), + TIME_SECOND_PART_DIGITS); return 1; } return Item_timefunc::fix_fields(thd, items); @@ -1492,7 +1493,7 @@ void Item_func_curtime::fix_length_and_dec() collation.set(&my_charset_bin); store_now_in_TIME(<ime); max_length= MAX_TIME_WIDTH + - (decimals ? min(decimals, MAX_SEC_PART_DIGITS)+1 : 0); + (decimals ? min(decimals, TIME_SECOND_PART_DIGITS)+1 : 0); } bool Item_func_curtime::get_date(MYSQL_TIME *res, @@ -1505,11 +1506,11 @@ bool Item_func_curtime::get_date(MYSQL_TIME *res, static void set_sec_part(ulong sec_part, MYSQL_TIME *ltime, Item *item) { DBUG_ASSERT(item->decimals == AUTO_SEC_PART_DIGITS || - item->decimals <= MAX_SEC_PART_DIGITS); + item->decimals <= TIME_SECOND_PART_DIGITS); if (item->decimals) { ltime->second_part= sec_part; - if (item->decimals < MAX_SEC_PART_DIGITS) + if (item->decimals < TIME_SECOND_PART_DIGITS) ltime->second_part= sec_part_truncate(ltime->second_part, item->decimals); } } @@ -1548,9 +1549,10 @@ void Item_func_curtime_utc::store_now_in_TIME(MYSQL_TIME *now_time) bool Item_func_now::fix_fields(THD *thd, Item **items) { - if (decimals > MAX_SEC_PART_DIGITS) + if (decimals > TIME_SECOND_PART_DIGITS) { - my_error(ER_WRONG_ARGUMENTS, MYF(0), func_name()); + my_error(ER_TOO_BIG_PRECISION, MYF(0), decimals, func_name(), + TIME_SECOND_PART_DIGITS); return 1; } return Item_temporal_func::fix_fields(thd, items); @@ -1561,7 +1563,7 @@ void Item_func_now::fix_length_and_dec() collation.set(&my_charset_bin); store_now_in_TIME(<ime); max_length= MAX_DATETIME_WIDTH + - (decimals ? min(decimals, MAX_SEC_PART_DIGITS)+1 : 0); + (decimals ? min(decimals, TIME_SECOND_PART_DIGITS)+1 : 0); } @@ -1848,7 +1850,7 @@ void Item_func_convert_tz::fix_length_and_dec() max_length= MAX_DATETIME_WIDTH; decimals= args[0]->decimals; if (decimals && decimals != NOT_FIXED_DEC) - max_length+= min(decimals, MAX_SEC_PART_DIGITS) + 1; + max_length+= min(decimals, TIME_SECOND_PART_DIGITS) + 1; maybe_null= 1; } @@ -1949,7 +1951,7 @@ void Item_date_add_interval::fix_length_and_dec() else decimals= args[0]->decimals; if (decimals) - max_length+= min(decimals, MAX_SEC_PART_DIGITS) + 1; + max_length+= min(decimals, TIME_SECOND_PART_DIGITS) + 1; value.alloc(max_length); } @@ -2402,7 +2404,7 @@ void Item_func_add_time::fix_length_and_dec() else if (arg0_field_type == MYSQL_TYPE_TIME) cached_field_type= MYSQL_TYPE_TIME; if (decimals) - max_length+= min(decimals, MAX_SEC_PART_DIGITS) + 1; + max_length+= min(decimals, TIME_SECOND_PART_DIGITS) + 1; } /** @@ -2467,7 +2469,7 @@ bool Item_func_add_time::get_date(MYSQL_TIME *ltime, uint fuzzy_date) if (cached_field_type == MYSQL_TYPE_STRING && (l_time1.second_part || l_time2.second_part)) - dec= MAX_SEC_PART_DIGITS; + dec= TIME_SECOND_PART_DIGITS; if (!is_time) { @@ -2931,7 +2933,7 @@ void Item_func_str_to_date::fix_length_and_dec() { maybe_null= 1; cached_field_type= MYSQL_TYPE_DATETIME; - max_length= MAX_DATETIME_WIDTH+MAX_SEC_PART_DIGITS; + max_length= MAX_DATETIME_WIDTH + TIME_SECOND_PART_DIGITS; cached_timestamp_type= MYSQL_TIMESTAMP_DATETIME; decimals= AUTO_SEC_PART_DIGITS; if ((const_item= args[1]->const_item())) diff --git a/sql/item_timefunc.h b/sql/item_timefunc.h index 68fd34aa29e..9f45655add6 100644 --- a/sql/item_timefunc.h +++ b/sql/item_timefunc.h @@ -332,7 +332,9 @@ public: void fix_length_and_dec() { maybe_null= TRUE; - decimals=args[0]->decimals; + decimals= args[0]->decimals; + if (decimals != NOT_FIXED_DEC) + set_if_smaller(decimals, TIME_SECOND_PART_DIGITS); max_length=17; } bool check_partition_func_processor(uchar *int_arg) {return FALSE;} @@ -389,7 +391,7 @@ public: void fix_length_and_dec() { max_length= MAX_TIME_WIDTH + - (decimals ? min(decimals, MAX_SEC_PART_DIGITS)+1 : 0); + (decimals ? min(decimals, TIME_SECOND_PART_DIGITS)+1 : 0); } }; @@ -597,8 +599,8 @@ public: collation.set(&my_charset_bin); maybe_null=1; decimals= args[0]->decimals; - if (decimals != NOT_FIXED_DEC && decimals > MAX_SEC_PART_DIGITS) - decimals= MAX_SEC_PART_DIGITS; + if (decimals != NOT_FIXED_DEC) + set_if_smaller(decimals, TIME_SECOND_PART_DIGITS); Item_timefunc::fix_length_and_dec(); } const char *func_name() const { return "sec_to_time"; } @@ -700,9 +702,13 @@ public: maybe_null= 1; max_length= MIN_TIME_WIDTH; if (decimals == NOT_FIXED_DEC) + { decimals= args[0]->decimals; + if (decimals != NOT_FIXED_DEC) + set_if_smaller(decimals, TIME_SECOND_PART_DIGITS); + } if (decimals && decimals != NOT_FIXED_DEC) - max_length+= min(decimals, MAX_SEC_PART_DIGITS) + 1; + max_length+= min(decimals, TIME_SECOND_PART_DIGITS) + 1; } }; @@ -722,7 +728,7 @@ public: maybe_null= 1; max_length= MAX_DATETIME_WIDTH; if (decimals && decimals != NOT_FIXED_DEC) - max_length+= min(decimals, MAX_SEC_PART_DIGITS) + 1; + max_length+= min(decimals, TIME_SECOND_PART_DIGITS) + 1; } }; diff --git a/sql/protocol.cc b/sql/protocol.cc index 273e3b1fd28..9242b348f0b 100644 --- a/sql/protocol.cc +++ b/sql/protocol.cc @@ -1200,7 +1200,7 @@ bool Protocol_binary::store(MYSQL_TIME *tm, int decimals) pos[5]= (uchar) tm->minute; pos[6]= (uchar) tm->second; DBUG_ASSERT(decimals == AUTO_SEC_PART_DIGITS || - (decimals >= 0 && decimals <= MAX_SEC_PART_DIGITS)); + (decimals >= 0 && decimals <= TIME_SECOND_PART_DIGITS)); if (decimals != AUTO_SEC_PART_DIGITS) tm->second_part= sec_part_truncate(tm->second_part, decimals); int4store(pos+7, tm->second_part); @@ -1242,7 +1242,7 @@ bool Protocol_binary::store_time(MYSQL_TIME *tm, int decimals) pos[6]= (uchar) tm->minute; pos[7]= (uchar) tm->second; DBUG_ASSERT(decimals == AUTO_SEC_PART_DIGITS || - (decimals >= 0 && decimals <= MAX_SEC_PART_DIGITS)); + (decimals >= 0 && decimals <= TIME_SECOND_PART_DIGITS)); if (decimals != AUTO_SEC_PART_DIGITS) tm->second_part= sec_part_truncate(tm->second_part, decimals); int4store(pos+8, tm->second_part); diff --git a/sql/share/errmsg.txt b/sql/share/errmsg.txt index c2fa3d12829..a9880913c5e 100644 --- a/sql/share/errmsg.txt +++ b/sql/share/errmsg.txt @@ -5513,11 +5513,11 @@ ER_SP_NO_RECURSION eng "Recursive stored functions and triggers are not allowed." ger "Rekursive gespeicherte Routinen und Triggers sind nicht erlaubt" ER_TOO_BIG_SCALE 42000 S1009 - eng "Too big scale %u specified for column '%-.192s'. Maximum is %lu." - ger "Zu großer Skalierungsfaktor %u für Feld '%-.192s' angegeben. Maximum ist %lu" + eng "Too big scale %u specified for '%-.192s'. Maximum is %lu." + ger "Zu großer Skalierungsfaktor %u für '%-.192s' angegeben. Maximum ist %lu" ER_TOO_BIG_PRECISION 42000 S1009 - eng "Too big precision %u specified for column '%-.192s'. Maximum is %lu." - ger "Zu große Genauigkeit %u für Feld '%-.192s' angegeben. Maximum ist %lu" + eng "Too big precision %u specified for '%-.192s'. Maximum is %lu." + ger "Zu große Genauigkeit %u für '%-.192s' angegeben. Maximum ist %lu" ER_M_BIGGER_THAN_D 42000 S1009 eng "For float(M,D), double(M,D) or decimal(M,D), M must be >= D (column '%-.192s')." ger "Für FLOAT(M,D), DOUBLE(M,D) oder DECIMAL(M,D) muss M >= D sein (Feld '%-.192s')" |