post review changes 2

sql/event_parse_data.cc:
  don't use "not_used" variable
sql/item_timefunc.cc:
  Item_temporal_func::fix_length_and_dec()
  and other changes
sql/item_timefunc.h:
  introducing Item_timefunc::fix_length_and_dec()
sql/share/errmsg.txt:
  don't say "column X" in the error message that used not only for columns
This commit is contained in:
Sergei Golubchik 2011-05-19 19:16:17 +02:00
parent 03b33425e5
commit f06cac336b
35 changed files with 462 additions and 441 deletions

View File

@ -549,7 +549,7 @@ uint32 String::numchars()
return str_charset->cset->numchars(str_charset, Ptr, Ptr+str_length); return str_charset->cset->numchars(str_charset, Ptr, Ptr+str_length);
} }
int String::charpos(int i,uint32 offset) int String::charpos(longlong i,uint32 offset)
{ {
if (i <= 0) if (i <= 0)
return i; return i;

View File

@ -269,7 +269,7 @@ public:
friend int stringcmp(const String *a,const String *b); friend int stringcmp(const String *a,const String *b);
friend String *copy_if_not_alloced(String *a,String *b,uint32 arg_length); friend String *copy_if_not_alloced(String *a,String *b,uint32 arg_length);
uint32 numchars(); uint32 numchars();
int charpos(int i,uint32 offset=0); int charpos(longlong i,uint32 offset=0);
int reserve(uint32 space_needed) int reserve(uint32 space_needed)
{ {

View File

@ -80,6 +80,8 @@ typedef long my_time_t;
my_bool check_date(const MYSQL_TIME *ltime, my_bool not_zero_date, my_bool check_date(const MYSQL_TIME *ltime, my_bool not_zero_date,
ulong flags, int *was_cut); ulong flags, int *was_cut);
enum enum_mysql_timestamp_type enum enum_mysql_timestamp_type
str_to_time(const char *str, uint length, MYSQL_TIME *l_time, int *warning);
enum enum_mysql_timestamp_type
str_to_datetime(const char *str, uint length, MYSQL_TIME *l_time, str_to_datetime(const char *str, uint length, MYSQL_TIME *l_time,
uint flags, int *was_cut); uint flags, int *was_cut);
longlong number_to_datetime(longlong nr, MYSQL_TIME *time_res, longlong number_to_datetime(longlong nr, MYSQL_TIME *time_res,

View File

@ -3588,7 +3588,7 @@ static void fetch_string_with_conversion(MYSQL_BIND *param, char *value,
case MYSQL_TYPE_TIME: case MYSQL_TYPE_TIME:
{ {
MYSQL_TIME *tm= (MYSQL_TIME *)buffer; MYSQL_TIME *tm= (MYSQL_TIME *)buffer;
str_to_datetime(value, length, tm, TIME_TIME_ONLY, &err); str_to_time(value, length, tm, &err);
*param->error= test(err); *param->error= test(err);
break; break;
} }

View File

@ -452,6 +452,12 @@ SELECT CONVERT(t2.a USING UTF8) FROM t1, t1 t2 LIMIT 1
1 1
DROP TABLE t1; DROP TABLE t1;
End of 5.1 tests End of 5.1 tests
select cast("2101-00-01 02:03:04" as datetime);
cast("2101-00-01 02:03:04" as datetime)
2101-00-01 02:03:04
select cast(cast("2101-00-01 02:03:04" as datetime) as time);
cast(cast("2101-00-01 02:03:04" as datetime) as time)
02:03:04
create table t1 (f1 time, f2 date, f3 datetime); create table t1 (f1 time, f2 date, f3 datetime);
insert into t1 values ('11:22:33','2011-12-13','2011-12-13 11:22:33'); insert into t1 values ('11:22:33','2011-12-13','2011-12-13 11:22:33');
select cast(f1 as unsigned), cast(f2 as unsigned), cast(f3 as unsigned) from t1; select cast(f1 as unsigned), cast(f2 as unsigned), cast(f3 as unsigned) from t1;

View File

@ -24,7 +24,7 @@ select count(*),b from t1;
ERROR 42S22: Unknown column 'b' in 'field list' ERROR 42S22: Unknown column 'b' in 'field list'
drop table t1; drop table t1;
create table t1 (a int(256)); create table t1 (a int(256));
ERROR 42000: Display width out of range for column 'a' (max = 255) ERROR 42000: Display width out of range for 'a' (max = 255)
set sql_mode='traditional'; set sql_mode='traditional';
create table t1 (a varchar(66000)); create table t1 (a varchar(66000));
ERROR 42000: Column length too big for column 'a' (max = 65535); use BLOB or TEXT instead ERROR 42000: Column length too big for column 'a' (max = 65535); use BLOB or TEXT instead

View File

@ -1036,7 +1036,7 @@ SELECT SEC_TO_TIME(CAST(-1 AS UNSIGNED));
SEC_TO_TIME(CAST(-1 AS UNSIGNED)) SEC_TO_TIME(CAST(-1 AS UNSIGNED))
838:59:59 838:59:59
Warnings: Warnings:
Warning 1292 Truncated incorrect time value: '18446744073709551616' Warning 1292 Truncated incorrect time value: '1.84467440737096e+19'
SET NAMES latin1; SET NAMES latin1;
SET character_set_results = NULL; SET character_set_results = NULL;
SHOW VARIABLES LIKE 'character_set_results'; SHOW VARIABLES LIKE 'character_set_results';
@ -1223,6 +1223,11 @@ str_to_date('10:00 PM', '%h:%i %p') + INTERVAL 10 MINUTE
NULL NULL
Warnings: Warnings:
Error 1411 Incorrect datetime value: '10:00 PM' for function str_to_date Error 1411 Incorrect datetime value: '10:00 PM' for function str_to_date
select str_to_date("1997-00-04 22:23:00","%Y-%m-%D") + interval 10 minute;
str_to_date("1997-00-04 22:23:00","%Y-%m-%D") + interval 10 minute
NULL
Warnings:
Error 1411 Incorrect datetime value: '1997-00-04 22:23:00' for function str_to_date
create table t1 (field DATE); create table t1 (field DATE);
insert into t1 values ('2006-11-06'); insert into t1 values ('2006-11-06');
select * from t1 where field < '2006-11-06 04:08:36.0'; select * from t1 where field < '2006-11-06 04:08:36.0';
@ -1545,3 +1550,12 @@ select cast(f1 AS time) from t1;
cast(f1 AS time) cast(f1 AS time)
00:00:00 00:00:00
drop table t1; drop table t1;
select greatest(cast("0-0-0" as date), cast("10:20:05" as time));
greatest(cast("0-0-0" as date), cast("10:20:05" as time))
0000-00-00
select greatest(cast("0-0-0" as date), cast("10:20:05" as time)) = '0000-00-00';
greatest(cast("0-0-0" as date), cast("10:20:05" as time)) = '0000-00-00'
1
select cast(greatest(cast("0-0-0" as date), cast("10:20:05" as time)) as datetime(6));
cast(greatest(cast("0-0-0" as date), cast("10:20:05" as time)) as datetime(6))
0000-00-00 00:00:00.000000

View File

@ -64,6 +64,19 @@ localtimestamp(6) 2011-01-01 01:01:01.123456
time_to_sec('12:34:56') 45296 time_to_sec('12:34:56') 45296
time_to_sec('12:34:56.789') 45296.789 time_to_sec('12:34:56.789') 45296.789
drop table t1; drop table t1;
select sec_to_time(3020399.99999), sec_to_time(3020399.999999), sec_to_time(3020399.9999999);
sec_to_time(3020399.99999) sec_to_time(3020399.999999) sec_to_time(3020399.9999999)
838:59:59.99998 838:59:59.999999 838:59:59.999999
Warnings:
Warning 1292 Truncated incorrect time value: '3020399.9999999'
select sec_to_time(-3020399.99999), sec_to_time(-3020399.999999), sec_to_time(-3020399.9999999);
sec_to_time(-3020399.99999) sec_to_time(-3020399.999999) sec_to_time(-3020399.9999999)
-838:59:59.99998 -838:59:59.999999 -838:59:59.999999
Warnings:
Warning 1292 Truncated incorrect time value: '-3020399.9999999'
select 20010101000203.000000004 + interval 1 day;
20010101000203.000000004 + interval 1 day
2001-01-02 00:02:03.000000
set @a=cast('2011-01-02 12:13:14' as datetime); set @a=cast('2011-01-02 12:13:14' as datetime);
select @a + interval 1 minute; select @a + interval 1 minute;
@a + interval 1 minute @a + interval 1 minute

View File

@ -36,7 +36,7 @@ select 0 + b'1000000000000001';
32769 32769
drop table if exists t1,t2; drop table if exists t1,t2;
create table t1 (a bit(65)); create table t1 (a bit(65));
ERROR 42000: Display width out of range for column 'a' (max = 64) ERROR 42000: Display width out of range for 'a' (max = 64)
create table t1 (a bit(0)); create table t1 (a bit(0));
show create table t1; show create table t1;
Table Create Table Table Create Table

View File

@ -36,7 +36,7 @@ select 0 + b'1000000000000001';
32769 32769
drop table if exists t1; drop table if exists t1;
create table t1 (a bit(65)) engine=innodb; create table t1 (a bit(65)) engine=innodb;
ERROR 42000: Display width out of range for column 'a' (max = 64) ERROR 42000: Display width out of range for 'a' (max = 64)
create table t1 (a bit(0)) engine=innodb; create table t1 (a bit(0)) engine=innodb;
show create table t1; show create table t1;
Table Create Table Table Create Table

View File

@ -833,7 +833,7 @@ drop table b15776;
create table b15776 (data blob(4294967295)); create table b15776 (data blob(4294967295));
drop table b15776; drop table b15776;
create table b15776 (data blob(4294967296)); create table b15776 (data blob(4294967296));
ERROR 42000: Display width out of range for column 'data' (max = 4294967295) ERROR 42000: Display width out of range for 'data' (max = 4294967295)
CREATE TABLE b15776 (a blob(2147483647), b blob(2147483648), c blob(4294967295), a1 text(2147483647), b1 text(2147483648), c1 text(4294967295) ); CREATE TABLE b15776 (a blob(2147483647), b blob(2147483648), c blob(4294967295), a1 text(2147483647), b1 text(2147483648), c1 text(4294967295) );
show columns from b15776; show columns from b15776;
Field Type Null Key Default Extra Field Type Null Key Default Extra
@ -845,13 +845,13 @@ b1 longtext YES NULL
c1 longtext YES NULL c1 longtext YES NULL
drop table b15776; drop table b15776;
CREATE TABLE b15776 (a blob(4294967296)); CREATE TABLE b15776 (a blob(4294967296));
ERROR 42000: Display width out of range for column 'a' (max = 4294967295) ERROR 42000: Display width out of range for 'a' (max = 4294967295)
CREATE TABLE b15776 (a text(4294967296)); CREATE TABLE b15776 (a text(4294967296));
ERROR 42000: Display width out of range for column 'a' (max = 4294967295) ERROR 42000: Display width out of range for 'a' (max = 4294967295)
CREATE TABLE b15776 (a blob(999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999)); CREATE TABLE b15776 (a blob(999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999));
ERROR 42000: Display width out of range for column 'a' (max = 4294967295) ERROR 42000: Display width out of range for 'a' (max = 4294967295)
CREATE TABLE b15776 (a text(999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999)); CREATE TABLE b15776 (a text(999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999));
ERROR 42000: Display width out of range for column 'a' (max = 4294967295) ERROR 42000: Display width out of range for 'a' (max = 4294967295)
CREATE TABLE b15776 (a int(0)); CREATE TABLE b15776 (a int(0));
INSERT INTO b15776 values (NULL), (1), (42), (654); INSERT INTO b15776 values (NULL), (1), (42), (654);
SELECT * from b15776 ORDER BY a; SELECT * from b15776 ORDER BY a;
@ -866,7 +866,7 @@ ERROR 42000: You have an error in your SQL syntax; check the manual that corresp
CREATE TABLE b15776 (a int(255)); CREATE TABLE b15776 (a int(255));
DROP TABLE b15776; DROP TABLE b15776;
CREATE TABLE b15776 (a int(256)); CREATE TABLE b15776 (a int(256));
ERROR 42000: Display width out of range for column 'a' (max = 255) ERROR 42000: Display width out of range for 'a' (max = 255)
CREATE TABLE b15776 (data blob(-1)); CREATE TABLE b15776 (data blob(-1));
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '-1))' at line 1 ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '-1))' at line 1
CREATE TABLE b15776 (a char(2147483647)); CREATE TABLE b15776 (a char(2147483647));
@ -876,7 +876,7 @@ ERROR 42000: Column length too big for column 'a' (max = 255); use BLOB or TEXT
CREATE TABLE b15776 (a char(4294967295)); CREATE TABLE b15776 (a char(4294967295));
ERROR 42000: Column length too big for column 'a' (max = 255); use BLOB or TEXT instead ERROR 42000: Column length too big for column 'a' (max = 255); use BLOB or TEXT instead
CREATE TABLE b15776 (a char(4294967296)); CREATE TABLE b15776 (a char(4294967296));
ERROR 42000: Display width out of range for column 'a' (max = 4294967295) ERROR 42000: Display width out of range for 'a' (max = 4294967295)
CREATE TABLE b15776 (a year(4294967295)); CREATE TABLE b15776 (a year(4294967295));
INSERT INTO b15776 VALUES (42); INSERT INTO b15776 VALUES (42);
SELECT * FROM b15776; SELECT * FROM b15776;
@ -884,7 +884,7 @@ a
2042 2042
DROP TABLE b15776; DROP TABLE b15776;
CREATE TABLE b15776 (a year(4294967296)); CREATE TABLE b15776 (a year(4294967296));
ERROR 42000: Display width out of range for column 'a' (max = 4294967295) ERROR 42000: Display width out of range for 'a' (max = 4294967295)
CREATE TABLE b15776 (a year(0)); CREATE TABLE b15776 (a year(0));
DROP TABLE b15776; DROP TABLE b15776;
CREATE TABLE b15776 (a year(-2)); CREATE TABLE b15776 (a year(-2));
@ -894,19 +894,19 @@ ERROR 42000: Too big precision 4294967294 specified for 'a'. Maximum is 6.
CREATE TABLE b15776 (a timestamp(4294967295)); CREATE TABLE b15776 (a timestamp(4294967295));
ERROR 42000: Too big precision 4294967295 specified for 'a'. Maximum is 6. ERROR 42000: Too big precision 4294967295 specified for 'a'. Maximum is 6.
CREATE TABLE b15776 (a timestamp(4294967296)); CREATE TABLE b15776 (a timestamp(4294967296));
ERROR 42000: Display width out of range for column 'a' (max = 4294967295) ERROR 42000: Display width out of range for 'a' (max = 4294967295)
CREATE TABLE b15776 (a timestamp(-1)); CREATE TABLE b15776 (a timestamp(-1));
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '-1))' at line 1 ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '-1))' at line 1
CREATE TABLE b15776 (a timestamp(-2)); CREATE TABLE b15776 (a timestamp(-2));
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '-2))' at line 1 ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '-2))' at line 1
CREATE TABLE b15776 (a int(999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999)); CREATE TABLE b15776 (a int(999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999));
ERROR 42000: Display width out of range for column 'a' (max = 4294967295) ERROR 42000: Display width out of range for 'a' (max = 4294967295)
CREATE TABLE b15776 (a char(999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999)); CREATE TABLE b15776 (a char(999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999));
ERROR 42000: Display width out of range for column 'a' (max = 4294967295) ERROR 42000: Display width out of range for 'a' (max = 4294967295)
CREATE TABLE b15776 (a year(999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999)); CREATE TABLE b15776 (a year(999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999));
ERROR 42000: Display width out of range for column 'a' (max = 4294967295) ERROR 42000: Display width out of range for 'a' (max = 4294967295)
CREATE TABLE b15776 (a timestamp(999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999)); CREATE TABLE b15776 (a timestamp(999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999));
ERROR 42000: Display width out of range for column 'a' (max = 4294967295) ERROR 42000: Display width out of range for 'a' (max = 4294967295)
CREATE TABLE b15776 select cast(null as char(4294967295)); CREATE TABLE b15776 select cast(null as char(4294967295));
show columns from b15776; show columns from b15776;
Field Type Null Key Default Extra Field Type Null Key Default Extra
@ -932,11 +932,11 @@ explain select cast(1 as binary(4294967295));
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL No tables used 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL No tables used
explain select cast(1 as char(4294967296)); explain select cast(1 as char(4294967296));
ERROR 42000: Display width out of range for column 'cast as char' (max = 4294967295) ERROR 42000: Display width out of range for '1' (max = 4294967295)
explain select cast(1 as nchar(4294967296)); explain select cast(1 as nchar(4294967296));
ERROR 42000: Display width out of range for column 'cast as char' (max = 4294967295) ERROR 42000: Display width out of range for '1' (max = 4294967295)
explain select cast(1 as binary(4294967296)); explain select cast(1 as binary(4294967296));
ERROR 42000: Display width out of range for column 'cast as char' (max = 4294967295) ERROR 42000: Display width out of range for '1' (max = 4294967295)
explain select cast(1 as decimal(-1)); explain select cast(1 as decimal(-1));
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '-1))' at line 1 ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '-1))' at line 1
explain select cast(1 as decimal(64, 30)); explain select cast(1 as decimal(64, 30));
@ -952,23 +952,23 @@ explain select convert(1, char(4294967295));
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL No tables used 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL No tables used
explain select convert(1, char(4294967296)); explain select convert(1, char(4294967296));
ERROR 42000: Display width out of range for column 'cast as char' (max = 4294967295) ERROR 42000: Display width out of range for '1' (max = 4294967295)
explain select convert(1, char(999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999)); explain select convert(1, char(999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999));
ERROR 42000: Display width out of range for column 'cast as char' (max = 4294967295) ERROR 42000: Display width out of range for '1' (max = 4294967295)
explain select convert(1, nchar(4294967295)); explain select convert(1, nchar(4294967295));
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL No tables used 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL No tables used
explain select convert(1, nchar(4294967296)); explain select convert(1, nchar(4294967296));
ERROR 42000: Display width out of range for column 'cast as char' (max = 4294967295) ERROR 42000: Display width out of range for '1' (max = 4294967295)
explain select convert(1, nchar(999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999)); explain select convert(1, nchar(999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999));
ERROR 42000: Display width out of range for column 'cast as char' (max = 4294967295) ERROR 42000: Display width out of range for '1' (max = 4294967295)
explain select convert(1, binary(4294967295)); explain select convert(1, binary(4294967295));
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL No tables used 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL No tables used
explain select convert(1, binary(4294967296)); explain select convert(1, binary(4294967296));
ERROR 42000: Display width out of range for column 'cast as char' (max = 4294967295) ERROR 42000: Display width out of range for '1' (max = 4294967295)
explain select convert(1, binary(999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999)); explain select convert(1, binary(999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999));
ERROR 42000: Display width out of range for column 'cast as char' (max = 4294967295) ERROR 42000: Display width out of range for '1' (max = 4294967295)
End of 5.0 tests End of 5.0 tests
# Bug #52160: crash and inconsistent results when grouping # Bug #52160: crash and inconsistent results when grouping
# by a function and column # by a function and column

View File

@ -2516,7 +2516,7 @@ INSERT INTO t1 VALUES (0);
SET SQL_MODE='STRICT_ALL_TABLES'; SET SQL_MODE='STRICT_ALL_TABLES';
CREATE TABLE t2 CREATE TABLE t2
SELECT LEAST((SELECT '' FROM t1),NOW()) FROM `t1`; SELECT LEAST((SELECT '' FROM t1),NOW()) FROM `t1`;
ERROR 22007: Incorrect datetime value: '' for column 'NOW()' at row 1 ERROR 22007: Truncated incorrect datetime value: ''
DROP TABLE t1; DROP TABLE t1;
SET SQL_MODE=DEFAULT; SET SQL_MODE=DEFAULT;
# #

View File

@ -140,7 +140,7 @@ create table t3 select 1 union select UUID();
create table t4 select * from t1 where 3 in (select 1 union select 2 union select UUID() union select 3); create table t4 select * from t1 where 3 in (select 1 union select 2 union select UUID() union select 3);
create table t5 select * from t1 where 3 in (select 1 union select 2 union select curdate() union select 3); create table t5 select * from t1 where 3 in (select 1 union select 2 union select curdate() union select 3);
Warnings: Warnings:
Warning 1292 Incorrect date value: '3' for column '<result>' at row 1 Warning 1292 Truncated incorrect date value: '3'
insert into t5 select UUID() from t1 where 3 in (select 1 union select 2 union select 3 union select * from t4); insert into t5 select UUID() from t1 where 3 in (select 1 union select 2 union select 3 union select * from t4);
create procedure foo() create procedure foo()
begin begin

View File

@ -285,6 +285,10 @@ DROP TABLE t1;
--echo End of 5.1 tests --echo End of 5.1 tests
select cast("2101-00-01 02:03:04" as datetime);
select cast(cast("2101-00-01 02:03:04" as datetime) as time);
# #
# lp:737458 Casting dates and times into integers works differently in 5.1-micro # lp:737458 Casting dates and times into integers works differently in 5.1-micro
# #

View File

@ -724,6 +724,7 @@ set time_zone= @@global.time_zone;
# #
select str_to_date('10:00 PM', '%h:%i %p') + INTERVAL 10 MINUTE; select str_to_date('10:00 PM', '%h:%i %p') + INTERVAL 10 MINUTE;
select str_to_date("1997-00-04 22:23:00","%Y-%m-%D") + interval 10 minute;
# #
# Bug #21103: DATE column not compared as DATE # Bug #21103: DATE column not compared as DATE
@ -986,3 +987,7 @@ insert into t1 values ('0000-00-00 00:00:00');
select cast(f1 AS time) from t1; select cast(f1 AS time) from t1;
drop table t1; drop table t1;
select greatest(cast("0-0-0" as date), cast("10:20:05" as time));
select greatest(cast("0-0-0" as date), cast("10:20:05" as time)) = '0000-00-00';
select cast(greatest(cast("0-0-0" as date), cast("10:20:05" as time)) as datetime(6));

View File

@ -27,6 +27,9 @@ show create table t1;
--query_vertical select * from t1 --query_vertical select * from t1
drop table t1; drop table t1;
select sec_to_time(3020399.99999), sec_to_time(3020399.999999), sec_to_time(3020399.9999999);
select sec_to_time(-3020399.99999), sec_to_time(-3020399.999999), sec_to_time(-3020399.9999999);
select 20010101000203.000000004 + interval 1 day;
# #
# precision of expressions # precision of expressions
# #

View File

@ -19,9 +19,6 @@
/* Windows version of localtime_r() is declared in my_ptrhead.h */ /* Windows version of localtime_r() is declared in my_ptrhead.h */
#include <my_pthread.h> #include <my_pthread.h>
static enum enum_mysql_timestamp_type str_to_time(const char *, uint,
MYSQL_TIME *, int *);
ulonglong log_10_int[20]= ulonglong log_10_int[20]=
{ {
1, 10, 100, 1000, 10000UL, 100000UL, 1000000UL, 10000000UL, 1, 10, 100, 1000, 10000UL, 100000UL, 1000000UL, 10000000UL,
@ -491,7 +488,7 @@ err:
MYSQL_TIMESTAMP_ERROR MYSQL_TIMESTAMP_ERROR
*/ */
static enum enum_mysql_timestamp_type enum enum_mysql_timestamp_type
str_to_time(const char *str, uint length, MYSQL_TIME *l_time, int *warning) str_to_time(const char *str, uint length, MYSQL_TIME *l_time, int *warning)
{ {
ulong date[5]; ulong date[5];
@ -716,7 +713,7 @@ int check_time_range(struct st_mysql_time *my_time, uint dec, int *warning)
my_time->hour= TIME_MAX_HOUR; my_time->hour= TIME_MAX_HOUR;
my_time->minute= TIME_MAX_MINUTE; my_time->minute= TIME_MAX_MINUTE;
my_time->second= TIME_MAX_SECOND; my_time->second= TIME_MAX_SECOND;
my_time->second_part= TIME_MAX_SECOND_PART; my_time->second_part= max_sec_part[dec];
*warning|= MYSQL_TIME_WARN_OUT_OF_RANGE; *warning|= MYSQL_TIME_WARN_OUT_OF_RANGE;
return 0; return 0;
} }
@ -1245,7 +1242,7 @@ int number_to_time(double nr, MYSQL_TIME *ltime, int *was_cut)
ltime->hour = tmp/100/100; ltime->hour = tmp/100/100;
ltime->minute= tmp/100%100; ltime->minute= tmp/100%100;
ltime->second= tmp%100; ltime->second= tmp%100;
ltime->second_part= (ulong)((nr-tmp)*1e6); ltime->second_part= (ulong)((nr-tmp)*TIME_SECOND_PART_FACTOR);
if (ltime->minute < 60 && ltime->second < 60) if (ltime->minute < 60 && ltime->second < 60)
return 0; return 0;
@ -1336,7 +1333,7 @@ double TIME_to_double(const MYSQL_TIME *my_time)
if (my_time->time_type == MYSQL_TIMESTAMP_DATE) if (my_time->time_type == MYSQL_TIMESTAMP_DATE)
return d; return d;
d+= my_time->second_part/1e6; d+= my_time->second_part/(double)TIME_SECOND_PART_FACTOR;
return my_time->neg ? -d : d; return my_time->neg ? -d : d;
} }

View File

@ -198,7 +198,7 @@ Event_parse_data::check_dates(THD *thd, int previous_on_completion)
int int
Event_parse_data::init_execute_at(THD *thd) Event_parse_data::init_execute_at(THD *thd)
{ {
my_bool not_used; uint not_used;
MYSQL_TIME ltime; MYSQL_TIME ltime;
my_time_t ltime_utc; my_time_t ltime_utc;
@ -215,7 +215,7 @@ Event_parse_data::init_execute_at(THD *thd)
(starts_null && ends_null))); (starts_null && ends_null)));
DBUG_ASSERT(starts_null && ends_null); DBUG_ASSERT(starts_null && ends_null);
if ((not_used= item_execute_at->get_date(&ltime, TIME_NO_ZERO_DATE))) if (item_execute_at->get_date(&ltime, TIME_NO_ZERO_DATE))
goto wrong_value; goto wrong_value;
ltime_utc= TIME_to_timestamp(thd,&ltime,&not_used); ltime_utc= TIME_to_timestamp(thd,&ltime,&not_used);
@ -368,7 +368,7 @@ wrong_value:
int int
Event_parse_data::init_starts(THD *thd) Event_parse_data::init_starts(THD *thd)
{ {
my_bool not_used; uint not_used;
MYSQL_TIME ltime; MYSQL_TIME ltime;
my_time_t ltime_utc; my_time_t ltime_utc;
@ -379,7 +379,7 @@ Event_parse_data::init_starts(THD *thd)
if (item_starts->fix_fields(thd, &item_starts)) if (item_starts->fix_fields(thd, &item_starts))
goto wrong_value; goto wrong_value;
if ((not_used= item_starts->get_date(&ltime, TIME_NO_ZERO_DATE))) if (item_starts->get_date(&ltime, TIME_NO_ZERO_DATE))
goto wrong_value; goto wrong_value;
ltime_utc= TIME_to_timestamp(thd, &ltime, &not_used); ltime_utc= TIME_to_timestamp(thd, &ltime, &not_used);
@ -422,7 +422,7 @@ wrong_value:
int int
Event_parse_data::init_ends(THD *thd) Event_parse_data::init_ends(THD *thd)
{ {
my_bool not_used; uint not_used;
MYSQL_TIME ltime; MYSQL_TIME ltime;
my_time_t ltime_utc; my_time_t ltime_utc;
@ -434,7 +434,7 @@ Event_parse_data::init_ends(THD *thd)
goto error_bad_params; goto error_bad_params;
DBUG_PRINT("info", ("convert to TIME")); DBUG_PRINT("info", ("convert to TIME"));
if ((not_used= item_ends->get_date(&ltime, TIME_NO_ZERO_DATE))) if (item_ends->get_date(&ltime, TIME_NO_ZERO_DATE))
goto error_bad_params; goto error_bad_params;
ltime_utc= TIME_to_timestamp(thd, &ltime, &not_used); ltime_utc= TIME_to_timestamp(thd, &ltime, &not_used);

View File

@ -47,6 +47,17 @@ template class List<Create_field>;
template class List_iterator<Create_field>; template class List_iterator<Create_field>;
#endif #endif
static const char *zero_timestamp="0000-00-00 00:00:00.000000";
/* number of bytes to store second_part part of the TIMESTAMP(N) */
static uint sec_part_bytes[MAX_DATETIME_PRECISION+1]= { 0, 1, 1, 2, 2, 3, 3 };
/* number of bytes to store DATETIME(N) */
static uint datetime_hires_bytes[MAX_DATETIME_PRECISION+1]= { 5, 6, 6, 7, 7, 7, 8 };
/* number of bytes to store TIME(N) */
static uint time_hires_bytes[MAX_DATETIME_PRECISION+1]= { 3, 4, 4, 5, 5, 5, 6 };
uchar Field_null::null[1]={1}; uchar Field_null::null[1]={1};
const char field_separator=','; const char field_separator=',';
@ -4693,6 +4704,7 @@ long Field_timestamp::get_timestamp(ulong *sec_part) const
return tmp; return tmp;
} }
int Field_timestamp::store_TIME_with_warning(THD *thd, MYSQL_TIME *l_time, int Field_timestamp::store_TIME_with_warning(THD *thd, MYSQL_TIME *l_time,
const Lazy_string *str, const Lazy_string *str,
bool was_cut, bool have_smth_to_conv) bool was_cut, bool have_smth_to_conv)
@ -4700,7 +4712,6 @@ int Field_timestamp::store_TIME_with_warning(THD *thd, MYSQL_TIME *l_time,
ASSERT_COLUMN_MARKED_FOR_WRITE; ASSERT_COLUMN_MARKED_FOR_WRITE;
uint error = 0; uint error = 0;
my_time_t timestamp; my_time_t timestamp;
my_bool in_dst_time_gap;
if (was_cut || !have_smth_to_conv) if (was_cut || !have_smth_to_conv)
{ {
@ -4708,19 +4719,14 @@ int Field_timestamp::store_TIME_with_warning(THD *thd, MYSQL_TIME *l_time,
set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED,
str, MYSQL_TIMESTAMP_DATETIME, 1); str, MYSQL_TIMESTAMP_DATETIME, 1);
} }
/* Only convert a correct date (not a zero date) */
if (have_smth_to_conv && l_time->month) if (have_smth_to_conv && l_time->month)
{ {
if (!(timestamp= TIME_to_timestamp(thd, l_time, &in_dst_time_gap))) uint conversion_error;
timestamp= TIME_to_timestamp(thd, l_time, &conversion_error);
if (conversion_error)
{ {
set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, conversion_error,
ER_WARN_DATA_OUT_OF_RANGE,
str, MYSQL_TIMESTAMP_DATETIME, !error);
error= 1;
}
else if (in_dst_time_gap)
{
set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
ER_WARN_INVALID_TIMESTAMP,
str, MYSQL_TIMESTAMP_DATETIME, !error); str, MYSQL_TIMESTAMP_DATETIME, !error);
error= 1; error= 1;
} }
@ -4736,7 +4742,7 @@ int Field_timestamp::store_TIME_with_warning(THD *thd, MYSQL_TIME *l_time,
int Field_timestamp::store_time(MYSQL_TIME *ltime,timestamp_type time_type) int Field_timestamp::store_time(MYSQL_TIME *ltime,timestamp_type time_type)
{ {
THD *thd= table ? table->in_use : current_thd; THD *thd= table->in_use;
int unused; int unused;
MYSQL_TIME l_time= *ltime; MYSQL_TIME l_time= *ltime;
Lazy_string_time str(ltime); Lazy_string_time str(ltime);
@ -4753,7 +4759,7 @@ int Field_timestamp::store(const char *from,uint len,CHARSET_INFO *cs)
int error; int error;
int have_smth_to_conv; int have_smth_to_conv;
Lazy_string_str str(from, len); Lazy_string_str str(from, len);
THD *thd= table ? table->in_use : current_thd; THD *thd= table->in_use;
/* We don't want to store invalid or fuzzy datetime values in TIMESTAMP */ /* We don't want to store invalid or fuzzy datetime values in TIMESTAMP */
have_smth_to_conv= (str_to_datetime(from, len, &l_time, have_smth_to_conv= (str_to_datetime(from, len, &l_time,
@ -4769,16 +4775,18 @@ int Field_timestamp::store(double nr)
{ {
MYSQL_TIME l_time; MYSQL_TIME l_time;
int error; int error;
Lazy_string_dbl str(nr); Lazy_string_double str(nr);
THD *thd= table ? table->in_use : current_thd; THD *thd= table->in_use;
/* We don't want to store invalid or fuzzy datetime values in TIMESTAMP */ /* We don't want to store invalid or fuzzy datetime values in TIMESTAMP */
if (nr < 0 || nr > LONGLONG_MAX)
nr= LONGLONG_MAX;
longlong tmp= number_to_datetime((longlong) floor(nr), longlong tmp= number_to_datetime((longlong) floor(nr),
&l_time, (thd->variables.sql_mode & &l_time, (thd->variables.sql_mode &
MODE_NO_ZERO_DATE) | MODE_NO_ZERO_DATE) |
MODE_NO_ZERO_IN_DATE, &error); MODE_NO_ZERO_IN_DATE, &error);
l_time.second_part= (ulong)((nr-floor(nr))*1e6); l_time.second_part= (ulong)((nr-floor(nr))*TIME_SECOND_PART_FACTOR);
return store_TIME_with_warning(thd, &l_time, &str, error, tmp != LL(-1)); return store_TIME_with_warning(thd, &l_time, &str, error, tmp != -1);
} }
@ -4787,7 +4795,7 @@ int Field_timestamp::store(longlong nr, bool unsigned_val)
MYSQL_TIME l_time; MYSQL_TIME l_time;
int error; int error;
Lazy_string_num str(nr); Lazy_string_num str(nr);
THD *thd= table ? table->in_use : current_thd; THD *thd= table->in_use;
/* We don't want to store invalid or fuzzy datetime values in TIMESTAMP */ /* We don't want to store invalid or fuzzy datetime values in TIMESTAMP */
longlong tmp= number_to_datetime(nr, &l_time, (thd->variables.sql_mode & longlong tmp= number_to_datetime(nr, &l_time, (thd->variables.sql_mode &
@ -4804,12 +4812,17 @@ double Field_timestamp::val_real(void)
longlong Field_timestamp::val_int(void) longlong Field_timestamp::val_int(void)
{ {
MYSQL_TIME time_tmp; MYSQL_TIME time_tmp;
THD *thd= table ? table->in_use : current_thd; THD *thd= table->in_use;
thd->time_zone_used= 1; thd->time_zone_used= 1;
ulong sec_part; ulong sec_part;
uint32 temp= get_timestamp(&sec_part); uint32 temp= get_timestamp(&sec_part);
/*
Field_timestamp() and Field_timestamp_hres() shares this code.
This is why are also testing sec_part below.
*/
if (temp == 0 && sec_part == 0) if (temp == 0 && sec_part == 0)
return(0); return(0);
@ -4820,11 +4833,10 @@ longlong Field_timestamp::val_int(void)
time_tmp.minute * 100 + time_tmp.second; time_tmp.minute * 100 + time_tmp.second;
} }
static const char *zero_timestamp="0000-00-00 00:00:00.000000";
String *Field_timestamp::val_str(String *val_buffer, String *val_ptr) String *Field_timestamp::val_str(String *val_buffer, String *val_ptr)
{ {
uint32 temp2; uint32 temp2;
THD *thd= table ? table->in_use : current_thd; THD *thd= table->in_use;
MYSQL_TIME time_tmp; MYSQL_TIME time_tmp;
char *to; char *to;
@ -4891,7 +4903,7 @@ String *Field_timestamp::val_str(String *val_buffer, String *val_ptr)
bool Field_timestamp::get_date(MYSQL_TIME *ltime, uint fuzzydate) bool Field_timestamp::get_date(MYSQL_TIME *ltime, uint fuzzydate)
{ {
THD *thd= table ? table->in_use : current_thd; THD *thd= table->in_use;
thd->time_zone_used= 1; thd->time_zone_used= 1;
ulong sec_part; ulong sec_part;
uint32 temp= get_timestamp(&sec_part); uint32 temp= get_timestamp(&sec_part);
@ -4961,7 +4973,7 @@ void Field_timestamp::sql_type(String &res) const
int Field_timestamp::set_time() int Field_timestamp::set_time()
{ {
THD *thd= table ? table->in_use : current_thd; THD *thd= table->in_use;
set_notnull(); set_notnull();
store_TIME(thd->query_start(), 0); store_TIME(thd->query_start(), 0);
return 0; return 0;
@ -5052,12 +5064,6 @@ static longlong read_bigendian(const uchar *from, uint bytes)
} }
} }
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, 5, 5, 5, 6 };
void Field_timestamp_hires::store_TIME(my_time_t timestamp, ulong sec_part) void Field_timestamp_hires::store_TIME(my_time_t timestamp, ulong sec_part)
{ {
mi_int4store(ptr, timestamp); mi_int4store(ptr, timestamp);
@ -5074,7 +5080,7 @@ long Field_timestamp_hires::get_timestamp(ulong *sec_part) const
double Field_timestamp_hires::val_real(void) double Field_timestamp_hires::val_real(void)
{ {
MYSQL_TIME time_tmp; MYSQL_TIME time_tmp;
THD *thd= table ? table->in_use : current_thd; THD *thd= table->in_use;
thd->time_zone_used= 1; thd->time_zone_used= 1;
ulong sec_part; ulong sec_part;
@ -5119,7 +5125,7 @@ int Field_timestamp_hires::store_decimal(const my_decimal *d)
int Field_timestamp_hires::set_time() int Field_timestamp_hires::set_time()
{ {
THD *thd= table ? table->in_use : current_thd; THD *thd= table->in_use;
set_notnull(); set_notnull();
store_TIME(thd->query_start(), thd->query_start_sec_part()); store_TIME(thd->query_start(), thd->query_start_sec_part());
return 0; return 0;
@ -5238,7 +5244,7 @@ int Field_temporal::store(const char *from,uint len,CHARSET_INFO *cs)
MYSQL_TIME ltime; MYSQL_TIME ltime;
int error; int error;
enum enum_mysql_timestamp_type func_res; enum enum_mysql_timestamp_type func_res;
THD *thd= table ? table->in_use : current_thd; THD *thd= table->in_use;
Lazy_string_str str(from, len); Lazy_string_str str(from, len);
func_res= str_to_datetime(from, len, &ltime, func_res= str_to_datetime(from, len, &ltime,
@ -5255,22 +5261,18 @@ int Field_temporal::store(double nr)
{ {
int error= 0; int error= 0;
MYSQL_TIME ltime; MYSQL_TIME ltime;
longlong tmp; THD *thd= table->in_use;
THD *thd= table ? table->in_use : current_thd; Lazy_string_double str(nr);
Lazy_string_dbl str(nr);
if (nr < 0.0 || nr > 99991231235959.0) if (nr < 0 || nr > LONGLONG_MAX)
{ nr= LONGLONG_MAX;
tmp= -1; longlong tmp= number_to_datetime((longlong) floor(nr), &ltime,
error= 1; (TIME_FUZZY_DATE |
}
else
tmp= number_to_datetime((longlong) floor(nr), &ltime, (TIME_FUZZY_DATE |
(thd->variables.sql_mode & (thd->variables.sql_mode &
(MODE_NO_ZERO_IN_DATE | (MODE_NO_ZERO_IN_DATE |
MODE_NO_ZERO_DATE | MODE_NO_ZERO_DATE |
MODE_INVALID_DATES))), &error); MODE_INVALID_DATES))), &error);
ltime.second_part= (ulong)((nr-floor(nr))*1e6); ltime.second_part= (ulong)((nr-floor(nr))*TIME_SECOND_PART_FACTOR);
return store_TIME_with_warning(&ltime, &str, error, tmp != -1); return store_TIME_with_warning(&ltime, &str, error, tmp != -1);
} }
@ -5280,7 +5282,7 @@ int Field_temporal::store(longlong nr, bool unsigned_val)
int error; int error;
MYSQL_TIME ltime; MYSQL_TIME ltime;
longlong tmp; longlong tmp;
THD *thd= table ? table->in_use : current_thd; THD *thd= table->in_use;
Lazy_string_num str(nr); Lazy_string_num str(nr);
tmp= number_to_datetime(nr, &ltime, (TIME_FUZZY_DATE | tmp= number_to_datetime(nr, &ltime, (TIME_FUZZY_DATE |
@ -5340,8 +5342,8 @@ int Field_time::store(const char *from,uint len,CHARSET_INFO *cs)
MYSQL_TIME ltime; MYSQL_TIME ltime;
Lazy_string_str str(from, len); Lazy_string_str str(from, len);
int was_cut; int was_cut;
int have_smth_to_conv= str_to_datetime(from, len, &ltime, TIME_TIME_ONLY, int have_smth_to_conv=
&was_cut) > MYSQL_TIMESTAMP_ERROR; str_to_time(from, len, &ltime, &was_cut) > MYSQL_TIMESTAMP_ERROR;
return store_TIME_with_warning(&ltime, &str, was_cut, have_smth_to_conv); return store_TIME_with_warning(&ltime, &str, was_cut, have_smth_to_conv);
} }
@ -5361,7 +5363,7 @@ int Field_time::store_time(MYSQL_TIME *ltime, timestamp_type time_type)
int Field_time::store(double nr) int Field_time::store(double nr)
{ {
MYSQL_TIME ltime; MYSQL_TIME ltime;
Lazy_string_dbl str(nr); Lazy_string_double str(nr);
int was_cut; int was_cut;
int have_smth_to_conv= !number_to_time(nr, &ltime, &was_cut); int have_smth_to_conv= !number_to_time(nr, &ltime, &was_cut);
@ -5405,7 +5407,6 @@ String *Field_time::val_str(String *val_buffer,
{ {
ASSERT_COLUMN_MARKED_FOR_READ; ASSERT_COLUMN_MARKED_FOR_READ;
MYSQL_TIME ltime; MYSQL_TIME ltime;
val_buffer->alloc(MAX_DATE_STRING_REP_LENGTH);
long tmp=(long) sint3korr(ptr); long tmp=(long) sint3korr(ptr);
ltime.neg= 0; ltime.neg= 0;
if (tmp < 0) if (tmp < 0)
@ -5432,7 +5433,7 @@ String *Field_time::val_str(String *val_buffer,
bool Field_time::get_date(MYSQL_TIME *ltime, uint fuzzydate) bool Field_time::get_date(MYSQL_TIME *ltime, uint fuzzydate)
{ {
THD *thd= table ? table->in_use : current_thd; THD *thd= table->in_use;
if (!(fuzzydate & (TIME_FUZZY_DATE|TIME_TIME_ONLY))) if (!(fuzzydate & (TIME_FUZZY_DATE|TIME_TIME_ONLY)))
{ {
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
@ -5751,7 +5752,6 @@ String *Field_date::val_str(String *val_buffer,
{ {
ASSERT_COLUMN_MARKED_FOR_READ; ASSERT_COLUMN_MARKED_FOR_READ;
MYSQL_TIME ltime; MYSQL_TIME ltime;
val_buffer->alloc(field_length);
int32 tmp; int32 tmp;
if (ARCH_BIGENDIAN && table && table->s->db_low_byte_first) if (ARCH_BIGENDIAN && table && table->s->db_low_byte_first)
tmp=sint4korr(ptr); tmp=sint4korr(ptr);
@ -10085,7 +10085,7 @@ Field::set_warning(MYSQL_ERROR::enum_warning_level level, uint code,
If this field was created only for type conversion purposes it If this field was created only for type conversion purposes it
will have table == NULL. will have table == NULL.
*/ */
THD *thd= table ? table->in_use : current_thd; THD *thd= table->in_use;
if (thd->count_cuted_fields) if (thd->count_cuted_fields)
{ {
thd->cuted_fields+= cuted_increment; thd->cuted_fields+= cuted_increment;
@ -10119,7 +10119,7 @@ void Field::set_datetime_warning(MYSQL_ERROR::enum_warning_level level,
uint code, const Lazy_string *str, uint code, const Lazy_string *str,
timestamp_type ts_type, int cuted_increment) timestamp_type ts_type, int cuted_increment)
{ {
THD *thd= table ? table->in_use : current_thd; THD *thd= table->in_use;
if ((thd->really_abort_on_warning() && if ((thd->really_abort_on_warning() &&
level >= MYSQL_ERROR::WARN_LEVEL_WARN) || level >= MYSQL_ERROR::WARN_LEVEL_WARN) ||
set_warning(level, code, cuted_increment)) set_warning(level, code, cuted_increment))

View File

@ -149,7 +149,6 @@ public:
virtual bool str_needs_quotes() { return FALSE; } virtual bool str_needs_quotes() { return FALSE; }
virtual Item_result result_type () const=0; virtual Item_result result_type () const=0;
virtual Item_result cmp_type () const { return result_type(); } virtual Item_result cmp_type () const { return result_type(); }
virtual Item_result cast_to_int_type () const { return cmp_type(); }
static bool type_can_have_key_part(enum_field_types); static bool type_can_have_key_part(enum_field_types);
static enum_field_types field_type_merge(enum_field_types, enum_field_types); static enum_field_types field_type_merge(enum_field_types, enum_field_types);
static Item_result result_merge_type(enum_field_types); static Item_result result_merge_type(enum_field_types);
@ -1437,7 +1436,6 @@ public:
{} {}
enum_field_types type() const { return MYSQL_TYPE_DATETIME;} enum_field_types type() const { return MYSQL_TYPE_DATETIME;}
enum ha_base_keytype key_type() const { return HA_KEYTYPE_ULONGLONG; } enum ha_base_keytype key_type() const { return HA_KEYTYPE_ULONGLONG; }
enum Item_result cmp_type () const { return TIME_RESULT; }
uint decimals() const { return 0; } uint decimals() const { return 0; }
double val_real(void); double val_real(void);
longlong val_int(void); longlong val_int(void);
@ -1934,7 +1932,6 @@ public:
Field *new_field(MEM_ROOT *root, struct st_table *new_table, bool keep_type); Field *new_field(MEM_ROOT *root, struct st_table *new_table, bool keep_type);
enum_field_types type() const { return MYSQL_TYPE_STRING; } enum_field_types type() const { return MYSQL_TYPE_STRING; }
enum Item_result cmp_type () const { return INT_RESULT; } enum Item_result cmp_type () const { return INT_RESULT; }
enum Item_result cast_to_int_type () const { return INT_RESULT; }
enum ha_base_keytype key_type() const; enum ha_base_keytype key_type() const;
int store(const char *to,uint length,CHARSET_INFO *charset); int store(const char *to,uint length,CHARSET_INFO *charset);
int store(double nr); int store(double nr);

View File

@ -194,10 +194,11 @@ bool Item::val_bool()
case STRING_RESULT: case STRING_RESULT:
return val_real() != 0.0; return val_real() != 0.0;
case ROW_RESULT: case ROW_RESULT:
default: case TIME_RESULT:
DBUG_ASSERT(0); DBUG_ASSERT(0);
return 0; // Wrong (but safe) return 0; // Wrong (but safe)
} }
return 0; // Wrong (but safe)
} }
@ -472,18 +473,17 @@ void Item::print_value(String *str)
{ {
switch (result_type()) switch (result_type())
{ {
default:
DBUG_ASSERT(0);
case STRING_RESULT: case STRING_RESULT:
str->append('\''); append_unescaped(str, ptr->ptr(), ptr->length());
str->append(*ptr);
str->append('\'');
break; break;
case DECIMAL_RESULT: case DECIMAL_RESULT:
case REAL_RESULT: case REAL_RESULT:
case INT_RESULT: case INT_RESULT:
str->append(*ptr); str->append(*ptr);
break; break;
case ROW_RESULT:
case TIME_RESULT:
DBUG_ASSERT(0);
} }
} }
} }
@ -1020,7 +1020,7 @@ err:
bool Item::get_time(MYSQL_TIME *ltime) bool Item::get_time(MYSQL_TIME *ltime)
{ {
return get_date(ltime, TIME_TIME_ONLY); return get_date(ltime, TIME_TIME_ONLY | TIME_FUZZY_DATE);
} }
CHARSET_INFO *Item::default_charset() CHARSET_INFO *Item::default_charset()
@ -2187,10 +2187,11 @@ bool Item_field::val_bool_result()
case STRING_RESULT: case STRING_RESULT:
return result_field->val_real() != 0.0; return result_field->val_real() != 0.0;
case ROW_RESULT: case ROW_RESULT:
default: case TIME_RESULT:
DBUG_ASSERT(0); DBUG_ASSERT(0);
return 0; // Shut up compiler return 0; // Shut up compiler
} }
return 0;
} }
@ -2748,8 +2749,6 @@ void Item_param::set_time(MYSQL_TIME *tm, timestamp_type time_type,
value.time= *tm; value.time= *tm;
value.time.time_type= time_type; value.time.time_type= time_type;
decimals= value.time.second_part > 0 ? TIME_SECOND_PART_DIGITS : 0;
if (value.time.year > 9999 || value.time.month > 12 || if (value.time.year > 9999 || value.time.month > 12 ||
value.time.day > 31 || value.time.day > 31 ||
(time_type != MYSQL_TIMESTAMP_TIME && value.time.hour > 23) || (time_type != MYSQL_TIMESTAMP_TIME && value.time.hour > 23) ||
@ -2765,6 +2764,7 @@ void Item_param::set_time(MYSQL_TIME *tm, timestamp_type time_type,
state= TIME_VALUE; state= TIME_VALUE;
maybe_null= 0; maybe_null= 0;
max_length= max_length_arg; max_length= max_length_arg;
decimals= tm->second_part > 0 ? TIME_SECOND_PART_DIGITS : 0;
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
@ -2888,7 +2888,8 @@ bool Item_param::set_from_user_var(THD *thd, const user_var_entry *entry)
param_type= MYSQL_TYPE_NEWDECIMAL; param_type= MYSQL_TYPE_NEWDECIMAL;
break; break;
} }
default: case ROW_RESULT:
case TIME_RESULT:
DBUG_ASSERT(0); DBUG_ASSERT(0);
set_null(); set_null();
} }
@ -3355,7 +3356,8 @@ Item_copy *Item_copy::create (Item *item)
new Item_copy_uint (item) : new Item_copy_int (item); new Item_copy_uint (item) : new Item_copy_int (item);
case DECIMAL_RESULT: case DECIMAL_RESULT:
return new Item_copy_decimal (item); return new Item_copy_decimal (item);
default: case TIME_RESULT:
case ROW_RESULT:
DBUG_ASSERT (0); DBUG_ASSERT (0);
} }
/* should not happen */ /* should not happen */
@ -4810,10 +4812,11 @@ enum_field_types Item::field_type() const
case DECIMAL_RESULT: return MYSQL_TYPE_NEWDECIMAL; case DECIMAL_RESULT: return MYSQL_TYPE_NEWDECIMAL;
case REAL_RESULT: return MYSQL_TYPE_DOUBLE; case REAL_RESULT: return MYSQL_TYPE_DOUBLE;
case ROW_RESULT: case ROW_RESULT:
default: case TIME_RESULT:
DBUG_ASSERT(0); DBUG_ASSERT(0);
return MYSQL_TYPE_VARCHAR; return MYSQL_TYPE_VARCHAR;
} }
return MYSQL_TYPE_VARCHAR;
} }
@ -6232,7 +6235,7 @@ bool Item_ref::val_bool_result()
case STRING_RESULT: case STRING_RESULT:
return result_field->val_real() != 0.0; return result_field->val_real() != 0.0;
case ROW_RESULT: case ROW_RESULT:
default: case TIME_RESULT:
DBUG_ASSERT(0); DBUG_ASSERT(0);
} }
} }
@ -6885,6 +6888,7 @@ void resolve_const_item(THD *thd, Item **ref, Item *comp_item)
{ {
bool is_null; bool is_null;
Item **ref_copy= ref; Item **ref_copy= ref;
/* the following call creates a constant and puts it in new_item */
get_datetime_value(thd, &ref_copy, &new_item, comp_item, &is_null); get_datetime_value(thd, &ref_copy, &new_item, comp_item, &is_null);
if (is_null) if (is_null)
new_item= new Item_null(name); new_item= new Item_null(name);
@ -6964,8 +6968,6 @@ void resolve_const_item(THD *thd, Item **ref, Item *comp_item)
(Item*) new Item_decimal(name, result, length, decimals)); (Item*) new Item_decimal(name, result, length, decimals));
break; break;
} }
default:
DBUG_ASSERT(0);
} }
if (new_item) if (new_item)
thd->change_item_tree(ref, new_item); thd->change_item_tree(ref, new_item);
@ -7045,6 +7047,10 @@ int stored_field_cmp_to_item(THD *thd, Field *field, Item *item)
field_val= field->val_decimal(&field_buf); field_val= field->val_decimal(&field_buf);
return my_decimal_cmp(item_val, field_val); return my_decimal_cmp(item_val, field_val);
} }
/*
We have to check field->cmp_type() instead of res_type,
as result_type() - and thus res_type - can never be TIME_RESULT (yet).
*/
if (field->cmp_type() == TIME_RESULT) if (field->cmp_type() == TIME_RESULT)
{ {
MYSQL_TIME field_time, item_time; MYSQL_TIME field_time, item_time;
@ -7101,11 +7107,8 @@ Item_cache* Item_cache::get_cache(const Item *item, const Item_result type)
return new Item_cache_row(); return new Item_cache_row();
case TIME_RESULT: case TIME_RESULT:
return new Item_cache_int(MYSQL_TYPE_DATETIME); return new Item_cache_int(MYSQL_TYPE_DATETIME);
default:
// should never be in real life
DBUG_ASSERT(0);
return 0;
} }
return 0;
} }
void Item_cache::store(Item *item) void Item_cache::store(Item *item)
@ -7614,7 +7617,7 @@ enum_field_types Item_type_holder::get_real_type(Item *item)
case DECIMAL_RESULT: case DECIMAL_RESULT:
return MYSQL_TYPE_NEWDECIMAL; return MYSQL_TYPE_NEWDECIMAL;
case ROW_RESULT: case ROW_RESULT:
default: case TIME_RESULT:
DBUG_ASSERT(0); DBUG_ASSERT(0);
return MYSQL_TYPE_VAR_STRING; return MYSQL_TYPE_VAR_STRING;
} }

View File

@ -568,7 +568,9 @@ public:
{ return save_in_field(field, 1); } { return save_in_field(field, 1); }
virtual bool send(Protocol *protocol, String *str); virtual bool send(Protocol *protocol, String *str);
virtual bool eq(const Item *, bool binary_cmp) const; virtual bool eq(const Item *, bool binary_cmp) const;
/* result_type() of an item specifies how the value should be returned */
virtual Item_result result_type() const { return REAL_RESULT; } virtual Item_result result_type() const { return REAL_RESULT; }
/* ... while cmp_type() specifies how it should be compared */
virtual Item_result cmp_type() const; virtual Item_result cmp_type() const;
virtual Item_result cast_to_int_type() const { return cmp_type(); } virtual Item_result cast_to_int_type() const { return cmp_type(); }
virtual enum_field_types string_field_type() const; virtual enum_field_types string_field_type() const;
@ -731,6 +733,8 @@ public:
/* This is also used to create fields in CREATE ... SELECT: */ /* This is also used to create fields in CREATE ... SELECT: */
virtual Field *tmp_table_field(TABLE *t_arg) { return 0; } virtual Field *tmp_table_field(TABLE *t_arg) { return 0; }
virtual const char *full_name() const { return name ? name : "???"; } virtual const char *full_name() const { return name ? name : "???"; }
const char *field_name_or_null()
{ return real_item()->type() == Item::FIELD_ITEM ? name : NULL; }
/* /*
*result* family of methods is analog of *val* family (see above) but *result* family of methods is analog of *val* family (see above) but
@ -1492,7 +1496,7 @@ public:
} }
Item_result cast_to_int_type() const Item_result cast_to_int_type() const
{ {
return field->cast_to_int_type(); return field->cmp_type();
} }
enum_field_types field_type() const enum_field_types field_type() const
{ {

View File

@ -614,8 +614,6 @@ int Arg_comparator::set_compare_func(Item_result_field *item, Item_result type)
} }
break; break;
} }
default:
DBUG_ASSERT(0);
} }
return 0; return 0;
} }
@ -708,6 +706,18 @@ static ulonglong get_date_from_str(THD *thd, String *str,
return pack_time(&l_time); return pack_time(&l_time);
} }
/**
Prepare the comparator (set the comparison function) for comparing
items *a1 and *a2 in the context of 'type'.
@param[in] owner_arg Item, peforming the comparison (e.g. Item_func_eq)
@param[in,out] a1 first argument to compare
@param[in,out] a2 second argument to compare
@param[in] type type context to compare in
Both *a1 and *a2 can be replaced by this method - typically by constant
items, holding the cached converted value of the original (constant) item.
*/
int Arg_comparator::set_cmp_func(Item_result_field *owner_arg, int Arg_comparator::set_cmp_func(Item_result_field *owner_arg,
Item **a1, Item **a2, Item **a1, Item **a2,
@ -791,19 +801,16 @@ void Arg_comparator::set_datetime_cmp_func(Item_result_field *owner_arg,
func= comparator_matrix[TIME_RESULT][is_owner_equal_func()]; func= comparator_matrix[TIME_RESULT][is_owner_equal_func()];
} }
/**
/*
Retrieves correct DATETIME value from given item. Retrieves correct DATETIME value from given item.
SYNOPSIS @param[in] thd thread handle
get_datetime_value() @param[in,out] item_arg item to retrieve DATETIME value from
thd thread handle @param[in,out] cache_arg pointer to place to store the caching item to
item_arg [in/out] item to retrieve DATETIME value from @param[in] warn_item item for issuing the conversion warning
cache_arg [in/out] pointer to place to store the caching item to @param[out] is_null TRUE <=> the item_arg is null
warn_item [in] item for issuing the conversion warning
is_null [out] TRUE <=> the item_arg is null
DESCRIPTION @details
Retrieves the correct DATETIME value from given item for comparison by the Retrieves the correct DATETIME value from given item for comparison by the
compare_datetime() function. compare_datetime() function.
@ -818,7 +825,10 @@ void Arg_comparator::set_datetime_cmp_func(Item_result_field *owner_arg,
depending on the other operand (when comparing a string with a date, it's depending on the other operand (when comparing a string with a date, it's
parsed as a date, when comparing a string with a time it's parsed as a time) parsed as a date, when comparing a string with a time it's parsed as a time)
RETURN If the item is a constant it is replaced by the Item_cache_int, that
holds the packed datetime value.
@return
MYSQL_TIME value, packed in a longlong, suitable for comparison. MYSQL_TIME value, packed in a longlong, suitable for comparison.
*/ */
@ -829,16 +839,15 @@ get_datetime_value(THD *thd, Item ***item_arg, Item **cache_arg,
longlong UNINIT_VAR(value); longlong UNINIT_VAR(value);
Item *item= **item_arg; Item *item= **item_arg;
enum_field_types f_type= warn_item->field_type(); enum_field_types f_type= warn_item->field_type();
timestamp_type t_type=
f_type == MYSQL_TYPE_DATE ? MYSQL_TIMESTAMP_DATE :
f_type == MYSQL_TYPE_TIME ? MYSQL_TIMESTAMP_TIME :
MYSQL_TIMESTAMP_DATETIME;
switch (item->cmp_type()) { switch (item->cmp_type()) {
case TIME_RESULT: case TIME_RESULT:
/* if it's our Item_cache_int, as created below, we simply use the value */ /* if it's our Item_cache_int, as created below, we simply use the value */
if (item->result_type() == INT_RESULT) if (item->result_type() == INT_RESULT)
{
value= item->val_int(); value= item->val_int();
cache_arg= 0;
}
else else
{ {
MYSQL_TIME buf; MYSQL_TIME buf;
@ -872,7 +881,7 @@ get_datetime_value(THD *thd, Item ***item_arg, Item **cache_arg,
int was_cut; int was_cut;
longlong res; longlong res;
if (t_type == MYSQL_TIMESTAMP_TIME) if (f_type == MYSQL_TYPE_TIME)
res= number_to_time((double)value, &buf, &was_cut); res= number_to_time((double)value, &buf, &was_cut);
else else
res= number_to_datetime(value, &buf, TIME_INVALID_DATES|TIME_FUZZY_DATE, res= number_to_datetime(value, &buf, TIME_INVALID_DATES|TIME_FUZZY_DATE,
@ -880,8 +889,9 @@ get_datetime_value(THD *thd, Item ***item_arg, Item **cache_arg,
if (res == -1) if (res == -1)
{ {
const Lazy_string_num str(value); const Lazy_string_num str(value);
make_truncated_value_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, make_truncated_value_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, &str,
&str, t_type, warn_item->name); mysql_type_to_time_type(f_type),
warn_item->field_name_or_null());
value= 0; value= 0;
} }
else else
@ -903,7 +913,10 @@ get_datetime_value(THD *thd, Item ***item_arg, Item **cache_arg,
some insignificant zeros. some insignificant zeros.
*/ */
bool error; bool error;
value= (longlong) get_date_from_str(thd, str, t_type, warn_item->name, &error); value= (longlong) get_date_from_str(thd, str,
mysql_type_to_time_type(f_type),
warn_item->field_name_or_null(),
&error);
/* /*
If str did not contain a valid date according to the current If str did not contain a valid date according to the current
SQL_MODE, get_date_from_str() has already thrown a warning, SQL_MODE, get_date_from_str() has already thrown a warning,
@ -913,12 +926,23 @@ get_datetime_value(THD *thd, Item ***item_arg, Item **cache_arg,
} }
break; break;
} }
default: DBUG_ASSERT(0); case ROW_RESULT:
DBUG_ASSERT(0);
} }
if ((*is_null= item->null_value)) if ((*is_null= item->null_value))
return ~(ulonglong) 0; return ~(ulonglong) 0;
if (cache_arg && item->const_item() && item->type() != Item::CACHE_ITEM) if (cache_arg && item->const_item())
{ {
/*
cache the packed datetime value in the Item_cache object.
Because the packed datetime value is longlong, we use Item_cache_int,
and it has result_type() == INT_RESULT.
But we create it to have field_type() == MYSQL_TYPE_TIME (or
MYSQL_TIMESTAMP_DATE or MYSQL_TYPE_DATETIME), and thus it will have
cmp_type() == TIME_RESULT.
As no other item can have this combination of cmp_type() and result_type(),
it allows us to identify our cache items, see 'case TIME_RESULT:' above.
*/
Item_cache_int *cache= new Item_cache_int(f_type); Item_cache_int *cache= new Item_cache_int(f_type);
cache->store(item, value); cache->store(item, value);
*cache_arg= cache; *cache_arg= cache;
@ -976,9 +1000,6 @@ int Arg_comparator::compare_e_datetime()
bool a_is_null, b_is_null; bool a_is_null, b_is_null;
longlong a_value, b_value; longlong a_value, b_value;
if (set_null)
owner->null_value= 0;
/* Get DATE/DATETIME/TIME value of the 'a' item. */ /* Get DATE/DATETIME/TIME value of the 'a' item. */
a_value= get_datetime_value(thd, &a, &a_cache, *b, &a_is_null); a_value= get_datetime_value(thd, &a, &a_cache, *b, &a_is_null);
@ -1961,10 +1982,9 @@ bool Item_func_between::fix_fields(THD *thd, Item **ref)
void Item_func_between::fix_length_and_dec() void Item_func_between::fix_length_and_dec()
{ {
max_length= 1;
int i;
compare_as_dates= 0;
THD *thd= current_thd; THD *thd= current_thd;
max_length= 1;
compare_as_dates= 0;
/* /*
As some compare functions are generated after sql_yacc, As some compare functions are generated after sql_yacc,
@ -1980,7 +2000,7 @@ void Item_func_between::fix_length_and_dec()
/* /*
When comparing as date/time, we need to convert non-temporal values When comparing as date/time, we need to convert non-temporal values
(e.g. strings) to MYSQL_TIME. get_datetime_value() doees it (e.g. strings) to MYSQL_TIME. get_datetime_value() does it
automatically when one of the operands is a date/time. But here we automatically when one of the operands is a date/time. But here we
may need to compare two strings as dates (str1 BETWEEN str2 AND date). may need to compare two strings as dates (str1 BETWEEN str2 AND date).
For this to work, we need to know what date/time type we compare For this to work, we need to know what date/time type we compare
@ -1988,7 +2008,7 @@ void Item_func_between::fix_length_and_dec()
*/ */
if (cmp_type == TIME_RESULT) if (cmp_type == TIME_RESULT)
{ {
for (i= 0; i < 3; i++) for (int i= 0; i < 3; i++)
{ {
if (args[i]->cmp_type() == TIME_RESULT) if (args[i]->cmp_type() == TIME_RESULT)
{ {
@ -2149,7 +2169,7 @@ longlong Item_func_between::val_int()
} }
break; break;
} }
default: case ROW_RESULT:
DBUG_ASSERT(0); DBUG_ASSERT(0);
null_value= 1; null_value= 1;
return 0; return 0;
@ -2203,7 +2223,7 @@ Item_func_ifnull::fix_length_and_dec()
decimals= 0; decimals= 0;
break; break;
case ROW_RESULT: case ROW_RESULT:
default: case TIME_RESULT:
DBUG_ASSERT(0); DBUG_ASSERT(0);
} }
cached_field_type= agg_field_type(args, 2); cached_field_type= agg_field_type(args, 2);
@ -2942,6 +2962,7 @@ void Item_func_coalesce::fix_length_and_dec()
agg_result_type(&hybrid_type, args, arg_count); agg_result_type(&hybrid_type, args, arg_count);
Item_result cmp_type; Item_result cmp_type;
agg_cmp_type(&cmp_type, args, arg_count); agg_cmp_type(&cmp_type, args, arg_count);
///< @todo let result_type() return TIME_RESULT and remove this special case
if (cmp_type == TIME_RESULT) if (cmp_type == TIME_RESULT)
{ {
count_real_length(); count_real_length();
@ -2964,7 +2985,7 @@ void Item_func_coalesce::fix_length_and_dec()
decimals= 0; decimals= 0;
break; break;
case ROW_RESULT: case ROW_RESULT:
default: case TIME_RESULT:
DBUG_ASSERT(0); DBUG_ASSERT(0);
} }
} }
@ -3293,7 +3314,7 @@ cmp_item* cmp_item::get_comparator(Item_result type,
return new cmp_item_row; return new cmp_item_row;
case DECIMAL_RESULT: case DECIMAL_RESULT:
return new cmp_item_decimal; return new cmp_item_decimal;
default: case TIME_RESULT:
DBUG_ASSERT(0); DBUG_ASSERT(0);
break; break;
} }
@ -3741,9 +3762,9 @@ void Item_func_in::fix_length_and_dec()
case DECIMAL_RESULT: case DECIMAL_RESULT:
array= new in_decimal(arg_count - 1); array= new in_decimal(arg_count - 1);
break; break;
default: case TIME_RESULT:
DBUG_ASSERT(0); DBUG_ASSERT(0);
return; break;
} }
} }
if (array && !(thd->is_fatal_error)) // If not EOM if (array && !(thd->is_fatal_error)) // If not EOM

View File

@ -5044,7 +5044,7 @@ find_qualified_function_builder(THD *thd)
return & Create_sp_func::s_singleton; return & Create_sp_func::s_singleton;
} }
static inline const char* item_name(Item *a, String *str) static const char* item_name(Item *a, String *str)
{ {
if (a->name) if (a->name)
return a->name; return a->name;
@ -5053,14 +5053,32 @@ static inline const char* item_name(Item *a, String *str)
return str->c_ptr_safe(); return str->c_ptr_safe();
} }
Item * static uint get_number(Item *a, const char *c_len, bool *err,
create_func_cast(THD *thd, Item *a, Cast_target cast_type, uint maximum, uint errcode)
{
if (!c_len)
return 0;
int unused;
char buff[1024];
String buf(buff, sizeof(buff), system_charset_info);
ulonglong decoded_size= my_strtoll10(c_len, NULL, &unused);
uint len= min(decoded_size, UINT_MAX32);
if (decoded_size > maximum)
{
my_error(errcode, MYF(0), len, item_name(a, &buf), maximum);
*err= true;
}
return len;
}
Item *create_func_cast(THD *thd, Item *a, Cast_target cast_type,
const char *c_len, const char *c_dec, const char *c_len, const char *c_dec,
CHARSET_INFO *cs) CHARSET_INFO *cs)
{ {
Item *UNINIT_VAR(res); Item *UNINIT_VAR(res);
char buff[1024];
String buf(buff, sizeof(buff), system_charset_info);
switch (cast_type) { switch (cast_type) {
case ITEM_CAST_BINARY: case ITEM_CAST_BINARY:
@ -5078,20 +5096,11 @@ create_func_cast(THD *thd, Item *a, Cast_target cast_type,
case ITEM_CAST_TIME: case ITEM_CAST_TIME:
case ITEM_CAST_DATETIME: case ITEM_CAST_DATETIME:
{ {
uint len; bool err= false;
if (c_len) uint len= get_number(a, c_len, &err, MAX_DATETIME_PRECISION,
{ ER_TOO_BIG_PRECISION);
errno= 0; if (err)
len= strtoul(c_len, NULL, 10);
if (errno != 0 || len > MAX_DATETIME_PRECISION)
{
my_error(ER_TOO_BIG_PRECISION, MYF(0), len,
item_name(a, &buf), MAX_DATETIME_PRECISION);
return NULL; return NULL;
}
}
else
len= 0;
if (cast_type == ITEM_CAST_TIME) if (cast_type == ITEM_CAST_TIME)
res= new (thd->mem_root) Item_time_typecast(a, len); res= new (thd->mem_root) Item_time_typecast(a, len);
@ -5101,72 +5110,40 @@ create_func_cast(THD *thd, Item *a, Cast_target cast_type,
} }
case ITEM_CAST_DECIMAL: case ITEM_CAST_DECIMAL:
{ {
ulong len= 0; bool err= false;
uint dec= 0; ulong len= get_number(a, c_len, &err, DECIMAL_MAX_PRECISION,
ER_TOO_BIG_PRECISION);
if (c_len) uint dec= get_number(a, c_dec, &err, DECIMAL_MAX_SCALE,
{ ER_TOO_BIG_SCALE);
ulong decoded_size; if (err)
errno= 0;
decoded_size= strtoul(c_len, NULL, 10);
if (errno != 0)
{
my_error(ER_TOO_BIG_PRECISION, MYF(0), decoded_size,
item_name(a, &buf), DECIMAL_MAX_PRECISION);
return NULL; return NULL;
}
len= decoded_size;
}
if (c_dec)
{
ulong decoded_size;
errno= 0;
decoded_size= strtoul(c_dec, NULL, 10);
if ((errno != 0) || (decoded_size > UINT_MAX))
{
my_error(ER_TOO_BIG_SCALE, MYF(0), decoded_size,
item_name(a, &buf), DECIMAL_MAX_SCALE);
return NULL;
}
dec= decoded_size;
}
my_decimal_trim(&len, &dec);
if (len < dec) if (len < dec)
{ {
my_error(ER_M_BIGGER_THAN_D, MYF(0), ""); my_error(ER_M_BIGGER_THAN_D, MYF(0), "");
return 0; return NULL;
}
if (len > DECIMAL_MAX_PRECISION)
{
my_error(ER_TOO_BIG_PRECISION, MYF(0), len,
item_name(a, &buf), DECIMAL_MAX_PRECISION);
return 0;
}
if (dec > DECIMAL_MAX_SCALE)
{
my_error(ER_TOO_BIG_SCALE, MYF(0), dec, item_name(a, &buf),
DECIMAL_MAX_SCALE);
return 0;
} }
my_decimal_trim(&len, &dec);
res= new (thd->mem_root) Item_decimal_typecast(a, len, dec); res= new (thd->mem_root) Item_decimal_typecast(a, len, dec);
break; break;
} }
case ITEM_CAST_CHAR: case ITEM_CAST_CHAR:
{ {
int len= -1; uint len= ~0U;
CHARSET_INFO *real_cs= (cs ? cs : thd->variables.collation_connection); CHARSET_INFO *real_cs= (cs ? cs : thd->variables.collation_connection);
if (c_len) if (c_len)
{ {
ulong decoded_size; int err;
errno= 0; ulonglong decoded_size= my_strtoll10(c_len, NULL, &err);
decoded_size= strtoul(c_len, NULL, 10); if (decoded_size> MAX_FIELD_BLOBLENGTH)
if ((errno != 0) || (decoded_size > MAX_FIELD_BLOBLENGTH))
{ {
my_error(ER_TOO_BIG_DISPLAYWIDTH, MYF(0), "cast as char", MAX_FIELD_BLOBLENGTH); char buff[1024];
String buf(buff, sizeof(buff), system_charset_info);
my_error(ER_TOO_BIG_DISPLAYWIDTH, MYF(0),
item_name(a, &buf), MAX_FIELD_BLOBLENGTH);
return NULL; return NULL;
} }
len= (int) decoded_size; len= decoded_size;
} }
res= new (thd->mem_root) Item_char_typecast(a, len, real_cs); res= new (thd->mem_root) Item_char_typecast(a, len, real_cs);
break; break;

View File

@ -461,7 +461,7 @@ Field *Item_func::tmp_table_field(TABLE *table)
field= Field_new_decimal::create_from_item(this); field= Field_new_decimal::create_from_item(this);
break; break;
case ROW_RESULT: case ROW_RESULT:
default: case TIME_RESULT:
// This case should never be chosen // This case should never be chosen
DBUG_ASSERT(0); DBUG_ASSERT(0);
field= 0; field= 0;
@ -716,7 +716,8 @@ void Item_func_num1::find_num_type()
break; break;
case DECIMAL_RESULT: case DECIMAL_RESULT:
break; break;
default: case TIME_RESULT:
case ROW_RESULT:
DBUG_ASSERT(0); DBUG_ASSERT(0);
} }
DBUG_PRINT("info", ("Type: %s", DBUG_PRINT("info", ("Type: %s",
@ -773,7 +774,8 @@ String *Item_func_numhybrid::val_str(String *str)
} }
case STRING_RESULT: case STRING_RESULT:
return str_op(&str_value); return str_op(&str_value);
default: case TIME_RESULT:
case ROW_RESULT:
DBUG_ASSERT(0); DBUG_ASSERT(0);
} }
return str; return str;
@ -808,7 +810,8 @@ double Item_func_numhybrid::val_real()
return (res ? my_strntod(res->charset(), (char*) res->ptr(), res->length(), return (res ? my_strntod(res->charset(), (char*) res->ptr(), res->length(),
&end_not_used, &err_not_used) : 0.0); &end_not_used, &err_not_used) : 0.0);
} }
default: case TIME_RESULT:
case ROW_RESULT:
DBUG_ASSERT(0); DBUG_ASSERT(0);
} }
return 0.0; return 0.0;
@ -843,7 +846,8 @@ longlong Item_func_numhybrid::val_int()
CHARSET_INFO *cs= str_value.charset(); CHARSET_INFO *cs= str_value.charset();
return (*(cs->cset->strtoll10))(cs, res->ptr(), &end, &err_not_used); return (*(cs->cset->strtoll10))(cs, res->ptr(), &end, &err_not_used);
} }
default: case TIME_RESULT:
case ROW_RESULT:
DBUG_ASSERT(0); DBUG_ASSERT(0);
} }
return 0; return 0;
@ -881,7 +885,7 @@ my_decimal *Item_func_numhybrid::val_decimal(my_decimal *decimal_value)
break; break;
} }
case ROW_RESULT: case ROW_RESULT:
default: case TIME_RESULT:
DBUG_ASSERT(0); DBUG_ASSERT(0);
} }
return val; return val;
@ -1340,7 +1344,9 @@ void Item_func_div::fix_length_and_dec()
case DECIMAL_RESULT: case DECIMAL_RESULT:
result_precision(); result_precision();
break; break;
default: case STRING_RESULT:
case ROW_RESULT:
case TIME_RESULT:
DBUG_ASSERT(0); DBUG_ASSERT(0);
} }
maybe_null= 1; // devision by zero maybe_null= 1; // devision by zero
@ -1833,7 +1839,8 @@ void Item_func_int_val::find_num_type()
hybrid_type= INT_RESULT; hybrid_type= INT_RESULT;
} }
break; break;
default: case ROW_RESULT:
case TIME_RESULT:
DBUG_ASSERT(0); DBUG_ASSERT(0);
} }
DBUG_PRINT("info", ("Type: %s", DBUG_PRINT("info", ("Type: %s",
@ -2009,7 +2016,8 @@ void Item_func_round::fix_length_and_dec()
unsigned_flag); unsigned_flag);
break; break;
} }
default: case ROW_RESULT:
case TIME_RESULT:
DBUG_ASSERT(0); /* This result type isn't handled */ DBUG_ASSERT(0); /* This result type isn't handled */
} }
} }
@ -2284,20 +2292,21 @@ bool Item_func_min_max::get_date(MYSQL_TIME *ltime, uint fuzzy_date)
longlong res= get_datetime_value(thd, &arg, 0, compare_as_dates, &is_null); longlong res= get_datetime_value(thd, &arg, 0, compare_as_dates, &is_null);
/* Check if we need to stop (because of error or KILL) and stop the loop */ /* Check if we need to stop (because of error or KILL) and stop the loop */
if (thd->is_error()) if (thd->is_error() || args[i]->null_value)
{ {
null_value= 1; null_value= 1;
return 1; return 1;
} }
if ((null_value= args[i]->null_value))
return 1;
if (i == 0 || (res < min_max ? cmp_sign : -cmp_sign) > 0) if (i == 0 || (res < min_max ? cmp_sign : -cmp_sign) > 0)
min_max= res; min_max= res;
} }
unpack_time(min_max, ltime); unpack_time(min_max, ltime);
if (compare_as_dates->field_type() == MYSQL_TYPE_DATE) if (compare_as_dates->field_type() == MYSQL_TYPE_DATE)
{
ltime->time_type= MYSQL_TIMESTAMP_DATE; ltime->time_type= MYSQL_TIMESTAMP_DATE;
ltime->hour= ltime->minute= ltime->second= ltime->second_part= 0;
}
return 0; return 0;
} }
@ -2312,9 +2321,9 @@ String *Item_func_min_max::val_str(String *str)
if (get_date(&ltime, TIME_FUZZY_DATE)) if (get_date(&ltime, TIME_FUZZY_DATE))
return 0; return 0;
char buf[MAX_DATE_STRING_REP_LENGTH]; str->alloc(MAX_DATE_STRING_REP_LENGTH);
int len= my_TIME_to_str(&ltime, buf, decimals); str->set_charset(collation.collation);
str->copy(buf, len, collation.collation); str->length(my_TIME_to_str(&ltime, const_cast<char*>(str->ptr()), decimals));
return str; return str;
} }
switch (cmp_type) { switch (cmp_type) {
@ -2367,7 +2376,7 @@ String *Item_func_min_max::val_str(String *str)
return res; return res;
} }
case ROW_RESULT: case ROW_RESULT:
default: case TIME_RESULT:
// This case should never be chosen // This case should never be chosen
DBUG_ASSERT(0); DBUG_ASSERT(0);
return 0; return 0;
@ -2955,7 +2964,7 @@ udf_handler::fix_fields(THD *thd, Item_result_field *func,
to+= ALIGN_SIZE(sizeof(double)); to+= ALIGN_SIZE(sizeof(double));
break; break;
case ROW_RESULT: case ROW_RESULT:
default: case TIME_RESULT:
// This case should never be chosen // This case should never be chosen
DBUG_ASSERT(0); DBUG_ASSERT(0);
break; break;
@ -3030,7 +3039,7 @@ bool udf_handler::get_arguments()
} }
break; break;
case ROW_RESULT: case ROW_RESULT:
default: case TIME_RESULT:
// This case should never be chosen // This case should never be chosen
DBUG_ASSERT(0); DBUG_ASSERT(0);
break; break;
@ -3634,7 +3643,7 @@ longlong Item_func_benchmark::val_int()
(void) args[1]->val_decimal(&tmp_decimal); (void) args[1]->val_decimal(&tmp_decimal);
break; break;
case ROW_RESULT: case ROW_RESULT:
default: case TIME_RESULT:
// This case should never be chosen // This case should never be chosen
DBUG_ASSERT(0); DBUG_ASSERT(0);
return 0; return 0;
@ -3968,7 +3977,8 @@ double user_var_entry::val_real(my_bool *null_value)
} }
case STRING_RESULT: case STRING_RESULT:
return my_atof(value); // This is null terminated return my_atof(value); // This is null terminated
default: case ROW_RESULT:
case TIME_RESULT:
DBUG_ASSERT(1); // Impossible DBUG_ASSERT(1); // Impossible
break; break;
} }
@ -3999,7 +4009,8 @@ longlong user_var_entry::val_int(my_bool *null_value) const
int error; int error;
return my_strtoll10(value, (char**) 0, &error);// String is null terminated return my_strtoll10(value, (char**) 0, &error);// String is null terminated
} }
default: case ROW_RESULT:
case TIME_RESULT:
DBUG_ASSERT(1); // Impossible DBUG_ASSERT(1); // Impossible
break; break;
} }
@ -4031,7 +4042,8 @@ String *user_var_entry::val_str(my_bool *null_value, String *str,
case STRING_RESULT: case STRING_RESULT:
if (str->copy(value, length, collation.collation)) if (str->copy(value, length, collation.collation))
str= 0; // EOM error str= 0; // EOM error
default: case ROW_RESULT:
case TIME_RESULT:
DBUG_ASSERT(1); // Impossible DBUG_ASSERT(1); // Impossible
break; break;
} }
@ -4058,7 +4070,8 @@ my_decimal *user_var_entry::val_decimal(my_bool *null_value, my_decimal *val)
case STRING_RESULT: case STRING_RESULT:
str2my_decimal(E_DEC_FATAL_ERROR, value, length, collation.collation, val); str2my_decimal(E_DEC_FATAL_ERROR, value, length, collation.collation, val);
break; break;
default: case ROW_RESULT:
case TIME_RESULT:
DBUG_ASSERT(1); // Impossible DBUG_ASSERT(1); // Impossible
break; break;
} }
@ -4115,7 +4128,7 @@ Item_func_set_user_var::check(bool use_result_field)
break; break;
} }
case ROW_RESULT: case ROW_RESULT:
default: case TIME_RESULT:
// This case should never be chosen // This case should never be chosen
DBUG_ASSERT(0); DBUG_ASSERT(0);
break; break;
@ -4150,7 +4163,7 @@ void Item_func_set_user_var::save_item_result(Item *item)
save_result.vdec= item->val_decimal_result(&decimal_buff); save_result.vdec= item->val_decimal_result(&decimal_buff);
break; break;
case ROW_RESULT: case ROW_RESULT:
default: case TIME_RESULT:
// Should never happen // Should never happen
DBUG_ASSERT(0); DBUG_ASSERT(0);
break; break;
@ -4218,7 +4231,7 @@ Item_func_set_user_var::update()
break; break;
} }
case ROW_RESULT: case ROW_RESULT:
default: case TIME_RESULT:
// This case should never be chosen // This case should never be chosen
DBUG_ASSERT(0); DBUG_ASSERT(0);
break; break;
@ -4669,7 +4682,7 @@ void Item_func_get_user_var::fix_length_and_dec()
decimals= DECIMAL_MAX_SCALE; decimals= DECIMAL_MAX_SCALE;
break; break;
case ROW_RESULT: // Keep compiler happy case ROW_RESULT: // Keep compiler happy
default: case TIME_RESULT:
DBUG_ASSERT(0); DBUG_ASSERT(0);
break; break;
} }

View File

@ -64,9 +64,12 @@ static bool make_datetime(MYSQL_TIME *ltime, String *str, uint decimals)
0 otherwise 0 otherwise
*/ */
static bool sec_to_time(double seconds, MYSQL_TIME *ltime) bool Item_func_sec_to_time::sec_to_time(double seconds, MYSQL_TIME *ltime)
{ {
Lazy_string_double str(seconds);
uint sec; uint sec;
const double max_sec_val= TIME_MAX_VALUE_SECONDS +
TIME_MAX_SECOND_PART/(double)TIME_SECOND_PART_FACTOR;
bzero((char *)ltime, sizeof(*ltime)); bzero((char *)ltime, sizeof(*ltime));
@ -75,32 +78,28 @@ static bool sec_to_time(double seconds, MYSQL_TIME *ltime)
if (seconds < 0) if (seconds < 0)
{ {
ltime->neg= 1; ltime->neg= 1;
if (seconds < -3020399) if (seconds < -max_sec_val)
goto overflow; goto overflow;
seconds= -seconds; seconds= -seconds;
} }
else if (seconds > 3020399) else if (seconds > max_sec_val)
goto overflow; goto overflow;
sec= (uint) ((ulonglong) seconds % 3600); sec= (uint) ((ulonglong) seconds % 3600);
ltime->hour= (uint) (seconds/3600); ltime->hour= (uint) (seconds/3600);
ltime->minute= sec/60; ltime->minute= sec/60;
ltime->second= sec % 60; ltime->second= sec % 60;
ltime->second_part= (ulong)((seconds - floor(seconds))*1e6); ltime->second_part= (ulong)((seconds - floor(seconds))*TIME_SECOND_PART_FACTOR);
return 0; return 0;
overflow: overflow:
ltime->hour= TIME_MAX_HOUR; /* use check_time_range() to set ltime to the max value depending on dec */
ltime->minute= TIME_MAX_MINUTE; int unused;
ltime->second= TIME_MAX_SECOND; ltime->hour= TIME_MAX_HOUR+1;
check_time_range(ltime, decimals, &unused);
char buf[100];
uint len= snprintf(buf, sizeof(buf), "%.80g", ltime->neg ? -seconds: seconds);
make_truncated_value_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, make_truncated_value_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
buf, len, MYSQL_TIMESTAMP_TIME, &str, MYSQL_TIMESTAMP_TIME, NullS);
NullS);
return 1; return 1;
} }
@ -908,7 +907,7 @@ longlong Item_func_dayofyear::val_int()
{ {
DBUG_ASSERT(fixed == 1); DBUG_ASSERT(fixed == 1);
MYSQL_TIME ltime; MYSQL_TIME ltime;
if (get_arg0_date(&ltime,TIME_NO_ZERO_DATE)) if (get_arg0_date(&ltime, TIME_NO_ZERO_IN_DATE | TIME_NO_ZERO_DATE))
return 0; return 0;
return (longlong) calc_daynr(ltime.year,ltime.month,ltime.day) - return (longlong) calc_daynr(ltime.year,ltime.month,ltime.day) -
calc_daynr(ltime.year,1,1) + 1; calc_daynr(ltime.year,1,1) + 1;
@ -1180,7 +1179,7 @@ longlong Item_func_year::val_int_endpoint(bool left_endp, bool *incl_endp)
longlong Item_func_unix_timestamp::val_int() longlong Item_func_unix_timestamp::val_int()
{ {
MYSQL_TIME ltime; MYSQL_TIME ltime;
my_bool not_used; uint not_used;
DBUG_ASSERT(fixed == 1); DBUG_ASSERT(fixed == 1);
if (arg_count == 0) if (arg_count == 0)
@ -1430,15 +1429,12 @@ bool Item_func_from_days::get_date(MYSQL_TIME *ltime, uint fuzzy_date)
void Item_func_curdate::fix_length_and_dec() void Item_func_curdate::fix_length_and_dec()
{ {
collation.set(&my_charset_bin);
decimals=0;
max_length=MAX_DATE_WIDTH*MY_CHARSET_BIN_MB_MAXLEN;
store_now_in_TIME(&ltime); store_now_in_TIME(&ltime);
/* We don't need to set second_part and neg because they already 0 */ /* We don't need to set second_part and neg because they already 0 */
ltime.hour= ltime.minute= ltime.second= 0; ltime.hour= ltime.minute= ltime.second= 0;
ltime.time_type= MYSQL_TIMESTAMP_DATE; ltime.time_type= MYSQL_TIMESTAMP_DATE;
Item_datefunc::fix_length_and_dec();
} }
/** /**
@ -1461,7 +1457,6 @@ void Item_func_curdate_utc::store_now_in_TIME(MYSQL_TIME *now_time)
{ {
THD *thd= current_thd; THD *thd= current_thd;
my_tz_UTC->gmt_sec_to_TIME(now_time, thd->query_start()); my_tz_UTC->gmt_sec_to_TIME(now_time, thd->query_start());
thd->time_zone_used= 1;
/* /*
We are not flagging this query as using time zone, since it uses fixed We are not flagging this query as using time zone, since it uses fixed
UTC-SYSTEM time-zone. UTC-SYSTEM time-zone.
@ -1488,14 +1483,6 @@ bool Item_func_curtime::fix_fields(THD *thd, Item **items)
return Item_timefunc::fix_fields(thd, items); return Item_timefunc::fix_fields(thd, items);
} }
void Item_func_curtime::fix_length_and_dec()
{
collation.set(&my_charset_bin);
store_now_in_TIME(&ltime);
max_length= MAX_TIME_WIDTH +
(decimals ? min(decimals, TIME_SECOND_PART_DIGITS)+1 : 0);
}
bool Item_func_curtime::get_date(MYSQL_TIME *res, bool Item_func_curtime::get_date(MYSQL_TIME *res,
uint fuzzy_date __attribute__((unused))) uint fuzzy_date __attribute__((unused)))
{ {
@ -1558,15 +1545,6 @@ bool Item_func_now::fix_fields(THD *thd, Item **items)
return Item_temporal_func::fix_fields(thd, items); return Item_temporal_func::fix_fields(thd, items);
} }
void Item_func_now::fix_length_and_dec()
{
collation.set(&my_charset_bin);
store_now_in_TIME(&ltime);
max_length= MAX_DATETIME_WIDTH +
(decimals ? min(decimals, TIME_SECOND_PART_DIGITS)+1 : 0);
}
/** /**
Converts current time in my_time_t to MYSQL_TIME represenatation for local Converts current time in my_time_t to MYSQL_TIME represenatation for local
time zone. Defines time zone (local) used for whole NOW function. time zone. Defines time zone (local) used for whole NOW function.
@ -1621,9 +1599,7 @@ void Item_func_sysdate_local::store_now_in_TIME(MYSQL_TIME *now_time)
bool Item_func_sysdate_local::get_date(MYSQL_TIME *res, bool Item_func_sysdate_local::get_date(MYSQL_TIME *res,
uint fuzzy_date __attribute__((unused))) uint fuzzy_date __attribute__((unused)))
{ {
MYSQL_TIME ltime; store_now_in_TIME(res);
store_now_in_TIME(&ltime);
*res= ltime;
return 0; return 0;
} }
@ -1819,11 +1795,9 @@ null_date:
void Item_func_from_unixtime::fix_length_and_dec() void Item_func_from_unixtime::fix_length_and_dec()
{ {
thd= current_thd; thd= current_thd;
collation.set(&my_charset_bin);
decimals= 0;
max_length=MAX_DATETIME_WIDTH*MY_CHARSET_BIN_MB_MAXLEN;
maybe_null= 1; maybe_null= 1;
thd->time_zone_used= 1; thd->time_zone_used= 1;
Item_temporal_func::fix_length_and_dec();
} }
@ -1846,12 +1820,9 @@ bool Item_func_from_unixtime::get_date(MYSQL_TIME *ltime,
void Item_func_convert_tz::fix_length_and_dec() void Item_func_convert_tz::fix_length_and_dec()
{ {
collation.set(&my_charset_bin);
max_length= MAX_DATETIME_WIDTH;
decimals= args[0]->decimals;
if (decimals && decimals != NOT_FIXED_DEC)
max_length+= min(decimals, TIME_SECOND_PART_DIGITS) + 1;
maybe_null= 1; maybe_null= 1;
decimals= args[0]->decimals;
Item_temporal_func::fix_length_and_dec();
} }
@ -1907,10 +1878,7 @@ void Item_func_convert_tz::cleanup()
void Item_date_add_interval::fix_length_and_dec() void Item_date_add_interval::fix_length_and_dec()
{ {
enum_field_types arg0_field_type; enum_field_types arg0_field_type;
collation.set(&my_charset_bin);
maybe_null=1; maybe_null=1;
max_length=MAX_DATETIME_WIDTH*MY_CHARSET_BIN_MB_MAXLEN;
/* /*
The field type for the result of an Item_date function is defined as The field type for the result of an Item_date function is defined as
@ -1950,8 +1918,8 @@ void Item_date_add_interval::fix_length_and_dec()
decimals= 6; decimals= 6;
else else
decimals= args[0]->decimals; decimals= args[0]->decimals;
if (decimals)
max_length+= min(decimals, TIME_SECOND_PART_DIGITS) + 1; Item_temporal_func::fix_length_and_dec();
value.alloc(max_length); value.alloc(max_length);
} }
@ -2159,13 +2127,13 @@ void Item_char_typecast::print(String *str, enum_query_type query_type)
str->append(STRING_WITH_LEN("cast(")); str->append(STRING_WITH_LEN("cast("));
args[0]->print(str, query_type); args[0]->print(str, query_type);
str->append(STRING_WITH_LEN(" as char")); str->append(STRING_WITH_LEN(" as char"));
if (cast_length >= 0) if (cast_length != ~0U)
{ {
str->append('('); str->append('(');
char buffer[20]; char buffer[20];
// my_charset_bin is good enough for numbers // my_charset_bin is good enough for numbers
String st(buffer, sizeof(buffer), &my_charset_bin); String st(buffer, sizeof(buffer), &my_charset_bin);
st.set((ulonglong)cast_length, &my_charset_bin); st.set(static_cast<ulonglong>(cast_length), &my_charset_bin);
str->append(st); str->append(st);
str->append(')'); str->append(')');
} }
@ -2212,7 +2180,7 @@ String *Item_char_typecast::val_str(String *str)
and the result is longer than cast length, e.g. and the result is longer than cast length, e.g.
CAST('string' AS CHAR(1)) CAST('string' AS CHAR(1))
*/ */
if (cast_length >= 0) if (cast_length != ~0U)
{ {
if (res->length() > (length= (uint32) res->charpos(cast_length))) if (res->length() > (length= (uint32) res->charpos(cast_length)))
{ // Safe even if const arg { // Safe even if const arg
@ -2232,16 +2200,15 @@ String *Item_char_typecast::val_str(String *str)
res->c_ptr_safe()); res->c_ptr_safe());
res->length((uint) length); res->length((uint) length);
} }
else if (cast_cs == &my_charset_bin && res->length() < (uint) cast_length) else if (cast_cs == &my_charset_bin && res->length() < cast_length)
{ {
if (res->alloced_length() < (uint) cast_length) if (res->alloced_length() < cast_length)
{ {
str_value.alloc(cast_length); str_value.alloc(cast_length);
str_value.copy(*res); str_value.copy(*res);
res= &str_value; res= &str_value;
} }
bzero((char*) res->ptr() + res->length(), bzero((char*) res->ptr() + res->length(), cast_length - res->length());
(uint) cast_length - res->length());
res->length(cast_length); res->length(cast_length);
} }
} }
@ -2287,7 +2254,7 @@ void Item_char_typecast::fix_length_and_dec()
from_cs != &my_charset_bin && from_cs != &my_charset_bin &&
cast_cs != &my_charset_bin); cast_cs != &my_charset_bin);
collation.set(cast_cs, DERIVATION_IMPLICIT); collation.set(cast_cs, DERIVATION_IMPLICIT);
char_length= (cast_length >= 0) ? cast_length : char_length= (cast_length != ~0U) ? cast_length :
args[0]->max_length / args[0]->max_length /
(cast_cs == &my_charset_bin ? 1 : args[0]->collation.collation->mbmaxlen); (cast_cs == &my_charset_bin ? 1 : args[0]->collation.collation->mbmaxlen);
max_length= char_length * cast_cs->mbmaxlen; max_length= char_length * cast_cs->mbmaxlen;
@ -2381,7 +2348,6 @@ err:
void Item_func_add_time::fix_length_and_dec() void Item_func_add_time::fix_length_and_dec()
{ {
enum_field_types arg0_field_type; enum_field_types arg0_field_type;
max_length= MAX_DATETIME_WIDTH;
decimals= max(args[0]->decimals, args[1]->decimals); decimals= max(args[0]->decimals, args[1]->decimals);
maybe_null= 1; maybe_null= 1;
@ -2403,8 +2369,7 @@ void Item_func_add_time::fix_length_and_dec()
cached_field_type= MYSQL_TYPE_DATETIME; cached_field_type= MYSQL_TYPE_DATETIME;
else if (arg0_field_type == MYSQL_TYPE_TIME) else if (arg0_field_type == MYSQL_TYPE_TIME)
cached_field_type= MYSQL_TYPE_TIME; cached_field_type= MYSQL_TYPE_TIME;
if (decimals) Item_temporal_func::fix_length_and_dec();
max_length+= min(decimals, TIME_SECOND_PART_DIGITS) + 1;
} }
/** /**
@ -2531,15 +2496,15 @@ bool Item_func_timediff::get_date(MYSQL_TIME *ltime, uint fuzzy_date)
MYSQL_TIME l_time1,l_time2,l_time3; MYSQL_TIME l_time1,l_time2,l_time3;
Lazy_string_time str(&l_time3); Lazy_string_time str(&l_time3);
null_value= 0; /* the following may be true in, for example, date_add(timediff(...), ... */
if (fuzzy_date & TIME_NO_ZERO_IN_DATE)
goto null_date;
if (args[0]->get_time(&l_time1) || if (args[0]->get_time(&l_time1) ||
args[1]->get_time(&l_time2) || args[1]->get_time(&l_time2) ||
l_time1.time_type != l_time2.time_type) l_time1.time_type != l_time2.time_type)
goto null_date; goto null_date;
if (fuzzy_date & TIME_NO_ZERO_IN_DATE)
goto null_date;
if (l_time1.neg != l_time2.neg) if (l_time1.neg != l_time2.neg)
l_sign= -l_sign; l_sign= -l_sign;
@ -2556,7 +2521,14 @@ bool Item_func_timediff::get_date(MYSQL_TIME *ltime, uint fuzzy_date)
if (l_time1.neg && (seconds || microseconds)) if (l_time1.neg && (seconds || microseconds))
l_time3.neg= 1-l_time3.neg; // Swap sign of result l_time3.neg= 1-l_time3.neg; // Swap sign of result
/*
seconds is longlong, when casted to long it may become a small number
even if the original seconds value was too large and invalid.
as a workaround we limit seconds by a large invalid long number
("invalid" means > TIME_MAX_SECOND)
*/
set_if_smaller(seconds, INT_MAX32); set_if_smaller(seconds, INT_MAX32);
calc_time_from_sec(&l_time3, (long) seconds, microseconds); calc_time_from_sec(&l_time3, (long) seconds, microseconds);
if ((fuzzy_date & TIME_NO_ZERO_DATE) && (seconds == 0) && (microseconds == 0)) if ((fuzzy_date & TIME_NO_ZERO_DATE) && (seconds == 0) && (microseconds == 0))
@ -2933,9 +2905,7 @@ void Item_func_str_to_date::fix_length_and_dec()
{ {
maybe_null= 1; maybe_null= 1;
cached_field_type= MYSQL_TYPE_DATETIME; cached_field_type= MYSQL_TYPE_DATETIME;
max_length= MAX_DATETIME_WIDTH + TIME_SECOND_PART_DIGITS; decimals= NOT_FIXED_DEC;
cached_timestamp_type= MYSQL_TIMESTAMP_DATETIME;
decimals= AUTO_SEC_PART_DIGITS;
if ((const_item= args[1]->const_item())) if ((const_item= args[1]->const_item()))
{ {
char format_buff[64]; char format_buff[64];
@ -2948,31 +2918,25 @@ void Item_func_str_to_date::fix_length_and_dec()
get_date_time_result_type(format->ptr(), format->length()); get_date_time_result_type(format->ptr(), format->length());
switch (cached_format_type) { switch (cached_format_type) {
case DATE_ONLY: case DATE_ONLY:
cached_timestamp_type= MYSQL_TIMESTAMP_DATE;
cached_field_type= MYSQL_TYPE_DATE; cached_field_type= MYSQL_TYPE_DATE;
max_length= MAX_DATE_WIDTH * MY_CHARSET_BIN_MB_MAXLEN;
break; break;
case TIME_MICROSECOND: case TIME_MICROSECOND:
decimals= 6; decimals= 6;
/* fall through */ /* fall through */
case TIME_ONLY: case TIME_ONLY:
cached_timestamp_type= MYSQL_TIMESTAMP_TIME;
cached_field_type= MYSQL_TYPE_TIME; cached_field_type= MYSQL_TYPE_TIME;
max_length= MAX_TIME_WIDTH * MY_CHARSET_BIN_MB_MAXLEN;
break; break;
case DATE_TIME_MICROSECOND: case DATE_TIME_MICROSECOND:
decimals= 6; decimals= 6;
/* fall through */ /* fall through */
case DATE_TIME: case DATE_TIME:
cached_timestamp_type= MYSQL_TIMESTAMP_DATETIME;
cached_field_type= MYSQL_TYPE_DATETIME; cached_field_type= MYSQL_TYPE_DATETIME;
max_length= MAX_DATETIME_WIDTH;
break; break;
} }
if (decimals)
max_length+= decimals + 1;
} }
} }
cached_timestamp_type= mysql_type_to_time_type(cached_field_type);
Item_temporal_func::fix_length_and_dec();
} }

View File

@ -360,6 +360,24 @@ public:
{ return tmp_table_field_from_field_type(table, 0); } { return tmp_table_field_from_field_type(table, 0); }
int save_in_field(Field *field, bool no_conversions) int save_in_field(Field *field, bool no_conversions)
{ return save_date_in_field(field); } { return save_date_in_field(field); }
void fix_length_and_dec()
{
static const uint max_time_type_width[5]=
{ MAX_DATETIME_WIDTH, MAX_DATETIME_WIDTH, MAX_DATE_WIDTH,
MAX_DATETIME_WIDTH, MIN_TIME_WIDTH };
max_length= max_time_type_width[mysql_type_to_time_type(field_type())+2];
if (decimals)
{
if (decimals == NOT_FIXED_DEC)
max_length+= TIME_SECOND_PART_DIGITS + 1;
else
{
set_if_smaller(decimals, TIME_SECOND_PART_DIGITS);
max_length+= decimals + 1;
}
}
}
}; };
class Item_datefunc :public Item_temporal_func class Item_datefunc :public Item_temporal_func
@ -371,12 +389,6 @@ public:
const char *func_name() const { return "date"; } const char *func_name() const { return "date"; }
bool get_date(MYSQL_TIME *res, uint fuzzy_date) bool get_date(MYSQL_TIME *res, uint fuzzy_date)
{ return get_arg0_date(res, fuzzy_date); } { return get_arg0_date(res, fuzzy_date); }
void fix_length_and_dec()
{
collation.set(&my_charset_bin);
decimals=0;
max_length=MAX_DATE_WIDTH*MY_CHARSET_BIN_MB_MAXLEN;
}
}; };
@ -388,11 +400,6 @@ public:
Item_timefunc(Item *a,Item *b) :Item_temporal_func(a,b) {} Item_timefunc(Item *a,Item *b) :Item_temporal_func(a,b) {}
Item_timefunc(Item *a, Item *b, Item *c) :Item_temporal_func(a, b ,c) {} Item_timefunc(Item *a, Item *b, Item *c) :Item_temporal_func(a, b ,c) {}
enum_field_types field_type() const { return MYSQL_TYPE_TIME; } enum_field_types field_type() const { return MYSQL_TYPE_TIME; }
void fix_length_and_dec()
{
max_length= MAX_TIME_WIDTH +
(decimals ? min(decimals, TIME_SECOND_PART_DIGITS)+1 : 0);
}
}; };
@ -404,7 +411,11 @@ class Item_func_curtime :public Item_timefunc
public: public:
Item_func_curtime(uint dec) :Item_timefunc() { decimals= dec; } Item_func_curtime(uint dec) :Item_timefunc() { decimals= dec; }
bool fix_fields(THD *, Item **); bool fix_fields(THD *, Item **);
void fix_length_and_dec(); void fix_length_and_dec()
{
store_now_in_TIME(&ltime);
Item_timefunc::fix_length_and_dec();
}
bool get_date(MYSQL_TIME *res, uint fuzzy_date); bool get_date(MYSQL_TIME *res, uint fuzzy_date);
/* /*
Abstract method that defines which time zone is used for conversion. Abstract method that defines which time zone is used for conversion.
@ -472,7 +483,11 @@ class Item_func_now :public Item_temporal_func
public: public:
Item_func_now(uint dec) :Item_temporal_func() { decimals= dec; } Item_func_now(uint dec) :Item_temporal_func() { decimals= dec; }
bool fix_fields(THD *, Item **); bool fix_fields(THD *, Item **);
void fix_length_and_dec(); void fix_length_and_dec()
{
store_now_in_TIME(&ltime);
Item_temporal_func::fix_length_and_dec();
}
bool get_date(MYSQL_TIME *res, uint fuzzy_date); bool get_date(MYSQL_TIME *res, uint fuzzy_date);
virtual void store_now_in_TIME(MYSQL_TIME *now_time)=0; virtual void store_now_in_TIME(MYSQL_TIME *now_time)=0;
}; };
@ -591,16 +606,14 @@ class Item_func_convert_tz :public Item_temporal_func
class Item_func_sec_to_time :public Item_timefunc class Item_func_sec_to_time :public Item_timefunc
{ {
bool sec_to_time(double seconds, MYSQL_TIME *ltime);
public: public:
Item_func_sec_to_time(Item *item) :Item_timefunc(item) {} Item_func_sec_to_time(Item *item) :Item_timefunc(item) {}
bool get_date(MYSQL_TIME *res, uint fuzzy_date); bool get_date(MYSQL_TIME *res, uint fuzzy_date);
void fix_length_and_dec() void fix_length_and_dec()
{ {
collation.set(&my_charset_bin);
maybe_null=1; maybe_null=1;
decimals= args[0]->decimals; decimals= args[0]->decimals;
if (decimals != NOT_FIXED_DEC)
set_if_smaller(decimals, TIME_SECOND_PART_DIGITS);
Item_timefunc::fix_length_and_dec(); Item_timefunc::fix_length_and_dec();
} }
const char *func_name() const { return "sec_to_time"; } const char *func_name() const { return "sec_to_time"; }
@ -645,12 +658,12 @@ class Item_extract :public Item_int_func
class Item_char_typecast :public Item_str_func class Item_char_typecast :public Item_str_func
{ {
int cast_length; uint cast_length;
CHARSET_INFO *cast_cs, *from_cs; CHARSET_INFO *cast_cs, *from_cs;
bool charset_conversion; bool charset_conversion;
String tmp_value; String tmp_value;
public: public:
Item_char_typecast(Item *a, int length_arg, CHARSET_INFO *cs_arg) Item_char_typecast(Item *a, uint length_arg, CHARSET_INFO *cs_arg)
:Item_str_func(a), cast_length(length_arg), cast_cs(cs_arg) {} :Item_str_func(a), cast_length(length_arg), cast_cs(cs_arg) {}
enum Functype functype() const { return CHAR_TYPECAST_FUNC; } enum Functype functype() const { return CHAR_TYPECAST_FUNC; }
bool eq(const Item *item, bool binary_cmp) const; bool eq(const Item *item, bool binary_cmp) const;
@ -667,6 +680,13 @@ public:
Item_temporal_typecast(Item *a) :Item_temporal_func(a) {} Item_temporal_typecast(Item *a) :Item_temporal_func(a) {}
virtual const char *cast_type() const = 0; virtual const char *cast_type() const = 0;
void print(String *str, enum_query_type query_type); void print(String *str, enum_query_type query_type);
void fix_length_and_dec()
{
maybe_null= 1;
if (decimals == NOT_FIXED_DEC)
decimals= args[0]->decimals;
Item_temporal_func::fix_length_and_dec();
}
}; };
class Item_date_typecast :public Item_temporal_typecast class Item_date_typecast :public Item_temporal_typecast
@ -677,13 +697,6 @@ public:
bool get_date(MYSQL_TIME *ltime, uint fuzzy_date); bool get_date(MYSQL_TIME *ltime, uint fuzzy_date);
const char *cast_type() const { return "date"; } const char *cast_type() const { return "date"; }
enum_field_types field_type() const { return MYSQL_TYPE_DATE; } enum_field_types field_type() const { return MYSQL_TYPE_DATE; }
void fix_length_and_dec()
{
collation.set(&my_charset_bin);
decimals= 0;
max_length= MAX_DATE_WIDTH;
maybe_null= 1;
}
}; };
@ -696,20 +709,6 @@ public:
bool get_date(MYSQL_TIME *ltime, uint fuzzy_date); bool get_date(MYSQL_TIME *ltime, uint fuzzy_date);
const char *cast_type() const { return "time"; } const char *cast_type() const { return "time"; }
enum_field_types field_type() const { return MYSQL_TYPE_TIME; } enum_field_types field_type() const { return MYSQL_TYPE_TIME; }
void fix_length_and_dec()
{
collation.set(&my_charset_bin);
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, TIME_SECOND_PART_DIGITS) + 1;
}
}; };
@ -722,14 +721,6 @@ public:
const char *cast_type() const { return "datetime"; } const char *cast_type() const { return "datetime"; }
enum_field_types field_type() const { return MYSQL_TYPE_DATETIME; } enum_field_types field_type() const { return MYSQL_TYPE_DATETIME; }
bool get_date(MYSQL_TIME *ltime, uint fuzzy_date); bool get_date(MYSQL_TIME *ltime, uint fuzzy_date);
void fix_length_and_dec()
{
collation.set(&my_charset_bin);
maybe_null= 1;
max_length= MAX_DATETIME_WIDTH;
if (decimals && decimals != NOT_FIXED_DEC)
max_length+= min(decimals, TIME_SECOND_PART_DIGITS) + 1;
}
}; };
class Item_func_makedate :public Item_temporal_func class Item_func_makedate :public Item_temporal_func
@ -740,10 +731,9 @@ public:
enum_field_types field_type() const { return MYSQL_TYPE_DATE; } enum_field_types field_type() const { return MYSQL_TYPE_DATE; }
void fix_length_and_dec() void fix_length_and_dec()
{ {
decimals=0;
max_length=MAX_DATE_WIDTH*MY_CHARSET_BIN_MB_MAXLEN;
/* It returns NULL when the second argument is less or equal to 0 */ /* It returns NULL when the second argument is less or equal to 0 */
maybe_null= 1; maybe_null= 1;
Item_temporal_func::fix_length_and_dec();
} }
bool get_date(MYSQL_TIME *ltime, uint fuzzy_date); bool get_date(MYSQL_TIME *ltime, uint fuzzy_date);
}; };

View File

@ -1978,12 +1978,10 @@ end:
delete td; delete td;
} }
#ifdef MYSQL_CLIENT
void free_table_map_log_event(Table_map_log_event *event) void free_table_map_log_event(Table_map_log_event *event)
{ {
delete event; delete event;
} }
#endif
void Log_event::print_base64(IO_CACHE* file, void Log_event::print_base64(IO_CACHE* file,
PRINT_EVENT_INFO* print_event_info, PRINT_EVENT_INFO* print_event_info,
@ -3614,7 +3612,7 @@ bool Start_log_event_v3::write(IO_CACHE* file)
int2store(buff + ST_BINLOG_VER_OFFSET,binlog_version); int2store(buff + ST_BINLOG_VER_OFFSET,binlog_version);
memcpy(buff + ST_SERVER_VER_OFFSET,server_version,ST_SERVER_VER_LEN); memcpy(buff + ST_SERVER_VER_OFFSET,server_version,ST_SERVER_VER_LEN);
if (!dont_set_created) if (!dont_set_created)
created= get_time(); created= get_time(); // this sets when and when_sec_part as a side effect
int4store(buff + ST_CREATED_OFFSET,created); int4store(buff + ST_CREATED_OFFSET,created);
return (write_header(file, sizeof(buff)) || return (write_header(file, sizeof(buff)) ||
my_b_safe_write(file, (uchar*) buff, sizeof(buff))); my_b_safe_write(file, (uchar*) buff, sizeof(buff)));

View File

@ -733,11 +733,11 @@ public:
void copy(String *dst) const { dst->set(num, &my_charset_bin); } void copy(String *dst) const { dst->set(num, &my_charset_bin); }
}; };
class Lazy_string_dbl: public Lazy_string class Lazy_string_double: public Lazy_string
{ {
double num; double num;
public: public:
Lazy_string_dbl(double num_arg) : Lazy_string(), num(num_arg) {} Lazy_string_double(double num_arg) : Lazy_string(), num(num_arg) {}
void copy(String *dst) const void copy(String *dst) const
{ dst->set_real(num, NOT_FIXED_DEC, &my_charset_bin); } { dst->set_real(num, NOT_FIXED_DEC, &my_charset_bin); }
}; };
@ -755,6 +755,19 @@ public:
} }
}; };
static inline enum enum_mysql_timestamp_type
mysql_type_to_time_type(enum enum_field_types mysql_type)
{
switch(mysql_type) {
case MYSQL_TYPE_TIME: return MYSQL_TIMESTAMP_TIME;
case MYSQL_TYPE_TIMESTAMP:
case MYSQL_TYPE_DATETIME: return MYSQL_TIMESTAMP_DATETIME;
case MYSQL_TYPE_NEWDATE:
case MYSQL_TYPE_DATE: return MYSQL_TIMESTAMP_DATE;
default: return MYSQL_TIMESTAMP_ERROR;
}
}
#include "sql_list.h" #include "sql_list.h"
#include "sql_map.h" #include "sql_map.h"
#include "my_decimal.h" #include "my_decimal.h"
@ -2212,7 +2225,7 @@ ulong convert_period_to_month(ulong period);
ulong convert_month_to_period(ulong month); ulong convert_month_to_period(ulong month);
void get_date_from_daynr(long daynr,uint *year, uint *month, void get_date_from_daynr(long daynr,uint *year, uint *month,
uint *day); uint *day);
my_time_t TIME_to_timestamp(THD *thd, const MYSQL_TIME *t, my_bool *not_exist); my_time_t TIME_to_timestamp(THD *thd, const MYSQL_TIME *t, uint *error_code);
timestamp_type str_to_datetime_with_warn(const char *str, uint length, timestamp_type str_to_datetime_with_warn(const char *str, uint length,
MYSQL_TIME *l_time, uint flags); MYSQL_TIME *l_time, uint flags);
void localtime_to_TIME(MYSQL_TIME *to, struct tm *from); void localtime_to_TIME(MYSQL_TIME *to, struct tm *from);
@ -2257,19 +2270,6 @@ int my_time_compare(MYSQL_TIME *a, MYSQL_TIME *b);
longlong get_datetime_value(THD *thd, Item ***item_arg, Item **cache_arg, longlong get_datetime_value(THD *thd, Item ***item_arg, Item **cache_arg,
Item *warn_item, bool *is_null); Item *warn_item, bool *is_null);
static inline enum enum_mysql_timestamp_type
mysql_type_to_time_type(enum enum_field_types mysql_type)
{
switch(mysql_type) {
case MYSQL_TYPE_TIME: return MYSQL_TIMESTAMP_TIME;
case MYSQL_TYPE_TIMESTAMP:
case MYSQL_TYPE_DATETIME: return MYSQL_TIMESTAMP_DATETIME;
case MYSQL_TYPE_NEWDATE:
case MYSQL_TYPE_DATE: return MYSQL_TIMESTAMP_DATE;
default: return MYSQL_TIMESTAMP_ERROR;
}
}
int test_if_number(char *str,int *res,bool allow_wildcards); int test_if_number(char *str,int *res,bool allow_wildcards);
void change_byte(uchar *,uint,char,char); void change_byte(uchar *,uint,char,char);
void init_read_record(READ_RECORD *info, THD *thd, TABLE *reg_form, void init_read_record(READ_RECORD *info, THD *thd, TABLE *reg_form,

View File

@ -2999,7 +2999,7 @@ void sys_var_thd_lc_time_names::set_default(THD *thd, enum_var_type type)
} }
/* /*
Handling of microseoncds given as seconds.part_seconds Handling of microseconds given as seconds.part_seconds
NOTES NOTES
The argument to long query time is in seconds in decimal The argument to long query time is in seconds in decimal

View File

@ -5555,8 +5555,8 @@ ER_WARN_CANT_DROP_DEFAULT_KEYCACHE
eng "Cannot drop default keycache" eng "Cannot drop default keycache"
ger "Der vorgabemäßige Schlüssel-Cache kann nicht gelöscht werden" ger "Der vorgabemäßige Schlüssel-Cache kann nicht gelöscht werden"
ER_TOO_BIG_DISPLAYWIDTH 42000 S1009 ER_TOO_BIG_DISPLAYWIDTH 42000 S1009
eng "Display width out of range for column '%-.192s' (max = %lu)" eng "Display width out of range for '%-.192s' (max = %lu)"
ger "Anzeigebreite außerhalb des zulässigen Bereichs für Spalte '%-.192s' (Maximum: %lu)" ger "Anzeigebreite außerhalb des zulässigen Bereichs für '%-.192s' (Maximum: %lu)"
ER_XAER_DUPID XAE08 ER_XAER_DUPID XAE08
eng "XAER_DUPID: The XID already exists" eng "XAER_DUPID: The XID already exists"
ger "XAER_DUPID: Die XID existiert bereits" ger "XAER_DUPID: Die XID existiert bereits"

View File

@ -2338,7 +2338,8 @@ bool select_max_min_finder_subselect::send_data(List<Item> &items)
case DECIMAL_RESULT: case DECIMAL_RESULT:
op= &select_max_min_finder_subselect::cmp_decimal; op= &select_max_min_finder_subselect::cmp_decimal;
break; break;
default: case ROW_RESULT:
case TIME_RESULT:
// This case should never be choosen // This case should never be choosen
DBUG_ASSERT(0); DBUG_ASSERT(0);
op= 0; op= 0;

View File

@ -551,7 +551,7 @@ uint32 String::numchars()
return str_charset->cset->numchars(str_charset, Ptr, Ptr+str_length); return str_charset->cset->numchars(str_charset, Ptr, Ptr+str_length);
} }
int String::charpos(int i,uint32 offset) int String::charpos(longlong i,uint32 offset)
{ {
if (i <= 0) if (i <= 0)
return i; return i;

View File

@ -286,7 +286,7 @@ public:
friend int stringcmp(const String *a,const String *b); friend int stringcmp(const String *a,const String *b);
friend String *copy_if_not_alloced(String *a,String *b,uint32 arg_length); friend String *copy_if_not_alloced(String *a,String *b,uint32 arg_length);
uint32 numchars(); uint32 numchars();
int charpos(int i,uint32 offset=0); int charpos(longlong i,uint32 offset=0);
int reserve(uint32 space_needed) int reserve(uint32 space_needed)
{ {

View File

@ -250,30 +250,36 @@ str_to_datetime_with_warn(const char *str, uint length, MYSQL_TIME *l_time,
TIME_to_timestamp() TIME_to_timestamp()
thd - current thread thd - current thread
t - datetime in broken-down representation, t - datetime in broken-down representation,
in_dst_time_gap - pointer to bool which is set to true if t represents error_code - 0, if the conversion was successful;
value which doesn't exists (falls into the spring ER_WARN_DATA_OUT_OF_RANGE, if t contains datetime value
time-gap) or to false otherwise. which is out of TIMESTAMP range;
ER_WARN_INVALID_TIMESTAMP, if t represents value which
doesn't exists (falls into the spring time-gap).
RETURN RETURN
Number seconds in UTC since start of Unix Epoch corresponding to t. Number seconds in UTC since start of Unix Epoch corresponding to t.
0 - t contains datetime value which is out of TIMESTAMP range. 0 - in case of ER_WARN_DATA_OUT_OF_RANGE
*/ */
my_time_t TIME_to_timestamp(THD *thd, const MYSQL_TIME *t, my_bool *in_dst_time_gap) my_time_t TIME_to_timestamp(THD *thd, const MYSQL_TIME *t, uint *error_code)
{ {
my_time_t timestamp; my_time_t timestamp;
my_bool in_dst_time_gap= 0;
*in_dst_time_gap= 0; *error_code= 0;
thd->time_zone_used= 1; thd->time_zone_used= 1;
timestamp= thd->variables.time_zone->TIME_to_gmt_sec(t, in_dst_time_gap); timestamp= thd->variables.time_zone->TIME_to_gmt_sec(t, &in_dst_time_gap);
if (timestamp) if (timestamp)
{ {
if (in_dst_time_gap)
*error_code= ER_WARN_INVALID_TIMESTAMP;
return timestamp; return timestamp;
} }
/* If we are here we have range error. */ /* If we are here we have range error. */
return(0); *error_code= ER_WARN_DATA_OUT_OF_RANGE;
return 0;
} }
@ -675,6 +681,7 @@ const char *get_date_time_format_str(KNOWN_DATE_TIME_FORMAT *format,
void make_time(const DATE_TIME_FORMAT *format __attribute__((unused)), void make_time(const DATE_TIME_FORMAT *format __attribute__((unused)),
const MYSQL_TIME *l_time, String *str) const MYSQL_TIME *l_time, String *str)
{ {
str->alloc(MAX_DATE_STRING_REP_LENGTH);
uint length= (uint) my_time_to_str(l_time, (char*) str->ptr(), 0); uint length= (uint) my_time_to_str(l_time, (char*) str->ptr(), 0);
str->length(length); str->length(length);
str->set_charset(&my_charset_bin); str->set_charset(&my_charset_bin);
@ -684,6 +691,7 @@ void make_time(const DATE_TIME_FORMAT *format __attribute__((unused)),
void make_date(const DATE_TIME_FORMAT *format __attribute__((unused)), void make_date(const DATE_TIME_FORMAT *format __attribute__((unused)),
const MYSQL_TIME *l_time, String *str) const MYSQL_TIME *l_time, String *str)
{ {
str->alloc(MAX_DATE_STRING_REP_LENGTH);
uint length= (uint) my_date_to_str(l_time, (char*) str->ptr()); uint length= (uint) my_date_to_str(l_time, (char*) str->ptr());
str->length(length); str->length(length);
str->set_charset(&my_charset_bin); str->set_charset(&my_charset_bin);
@ -693,6 +701,7 @@ void make_date(const DATE_TIME_FORMAT *format __attribute__((unused)),
void make_datetime(const DATE_TIME_FORMAT *format __attribute__((unused)), void make_datetime(const DATE_TIME_FORMAT *format __attribute__((unused)),
const MYSQL_TIME *l_time, String *str) const MYSQL_TIME *l_time, String *str)
{ {
str->alloc(MAX_DATE_STRING_REP_LENGTH);
uint length= (uint) my_datetime_to_str(l_time, (char*) str->ptr(), 0); uint length= (uint) my_datetime_to_str(l_time, (char*) str->ptr(), 0);
str->length(length); str->length(length);
str->set_charset(&my_charset_bin); str->set_charset(&my_charset_bin);
@ -776,7 +785,7 @@ bool date_add_interval(MYSQL_TIME *ltime, interval_type int_type, INTERVAL inter
my_bool neg= ltime->neg; my_bool neg= ltime->neg;
enum enum_mysql_timestamp_type time_type= ltime->time_type; enum enum_mysql_timestamp_type time_type= ltime->time_type;
if (ltime->time_type != MYSQL_TIMESTAMP_TIME) if (time_type != MYSQL_TIMESTAMP_TIME)
ltime->day+= calc_daynr(ltime->year, ltime->month, 1) - 1; ltime->day+= calc_daynr(ltime->year, ltime->month, 1) - 1;
usec= COMBINE(ltime) + sign*COMBINE(&interval); usec= COMBINE(ltime) + sign*COMBINE(&interval);
@ -791,7 +800,7 @@ bool date_add_interval(MYSQL_TIME *ltime, interval_type int_type, INTERVAL inter
if (int_type != INTERVAL_DAY) if (int_type != INTERVAL_DAY)
ltime->time_type= MYSQL_TIMESTAMP_DATETIME; // Return full date ltime->time_type= MYSQL_TIMESTAMP_DATETIME; // Return full date
daynr= ltime->day + 32*(ltime->month + 13*ltime->year); daynr= usec/1000000/24/60/60;
/* Day number from year 0 to 9999-12-31 */ /* Day number from year 0 to 9999-12-31 */
if ((ulonglong) daynr > MAX_DAY_NUMBER) if ((ulonglong) daynr > MAX_DAY_NUMBER)