3727 Alexander Barkov 2012-01-13
BUG#13354387 - CRASH IN IN MY_DECIMAL::OPERATOR FOR VIEW AND FUNCTION UNIX_TIME
Fixing the 5.6 part (the 5.5 was earlier committed in a separate commit).
Problem:
UNIX_TIMESTAMP() could return NULL in case of maybe_null==0.
Fix:
Moving NULL/0 decision logic from
Item_func_unix_timestamp::val_timeval()
to
Item::get_timeval()
Item_field::get_timeval()
modified:
mysql-test/r/func_time.result
mysql-test/t/func_time.test
sql/item.cc
sql/item_timefunc.cc
3726 Tor Didriksen 2012-01-12 [merge]
empty merge 5.5 => trunk
=== modified file 'mysql-test/r/func_time.result'
--- a/mysql-test/r/func_time.result 2012-01-12 13:27:57 +0000
+++ b/mysql-test/r/func_time.result 2012-01-13 08:36:43 +0000
@@ -1505,3 +1505,31 @@ select 1 from t1 where 1 < some (select
1
1
drop table t1;
+#
+# End of 5.5 tests
+#
+#
+# Start of 5.6 tests
+#
+#
+# BUG#13354387 - CRASH IN IN MY_DECIMAL::OPERATOR FOR VIEW AND FUNCTION UNIX_TIMESTAMP
+# Part2 (5.6)
+CREATE TABLE t1 (a VARCHAR(32) NOT NULL);
+INSERT INTO t1 VALUES ('a');
+SELECT 1 FROM t1 GROUP BY @a:=UNIX_TIMESTAMP(a);
+1
+1
+Warnings:
+Warning 1292 Incorrect datetime value: 'a'
+SELECT a, UNIX_TIMESTAMP(a), UNIX_TIMESTAMP('a') FROM t1;
+a UNIX_TIMESTAMP(a) UNIX_TIMESTAMP('a')
+a 0.000000 0.000000
+Warnings:
+Warning 1292 Incorrect datetime value: 'a'
+Warning 1292 Incorrect datetime value: 'a'
+DELETE FROM t1;
+INSERT INTO t1 VALUES ('5000-01-01 00:00:00');
+SELECT a, UNIX_TIMESTAMP(a), UNIX_TIMESTAMP('5000-01-01 00:00:00') FROM t1;
+a UNIX_TIMESTAMP(a) UNIX_TIMESTAMP('5000-01-01 00:00:00')
+5000-01-01 00:00:00 0.000000 0
+DROP TABLE t1;
=== modified file 'mysql-test/t/func_time.test'
--- a/mysql-test/t/func_time.test 2012-01-12 13:27:57 +0000
+++ b/mysql-test/t/func_time.test 2012-01-13 08:36:43 +0000
@@ -995,3 +995,23 @@ create table t1(a time);
insert into t1 values ('00:00:00'),('00:01:00');
select 1 from t1 where 1 < some (select cast(a as datetime) from t1);
drop table t1;
+
+--echo #
+--echo # End of 5.5 tests
+--echo #
+
+--echo #
+--echo # Start of 5.6 tests
+--echo #
+
+--echo #
+--echo # BUG#13354387 - CRASH IN IN MY_DECIMAL::OPERATOR FOR VIEW AND FUNCTION UNIX_TIMESTAMP
+--echo # Part2 (5.6)
+CREATE TABLE t1 (a VARCHAR(32) NOT NULL);
+INSERT INTO t1 VALUES ('a');
+SELECT 1 FROM t1 GROUP BY @a:=UNIX_TIMESTAMP(a);
+SELECT a, UNIX_TIMESTAMP(a), UNIX_TIMESTAMP('a') FROM t1;
+DELETE FROM t1;
+INSERT INTO t1 VALUES ('5000-01-01 00:00:00');
+SELECT a, UNIX_TIMESTAMP(a), UNIX_TIMESTAMP('5000-01-01 00:00:00') FROM t1;
+DROP TABLE t1;
=== modified file 'sql/item.cc'
--- a/sql/item.cc 2012-01-12 13:27:57 +0000
+++ b/sql/item.cc 2012-01-13 08:36:43 +0000
@@ -1378,12 +1378,27 @@ bool Item::get_time_from_non_temporal(MY
}
+/*
+- Return NULL if argument is NULL.
+- Return zero if argument is not NULL, but we could not convert it to DATETIME.
+- Return zero if argument is not NULL and represents a valid DATETIME value,
+ but the value is out of the supported Unix timestamp range.
+*/
bool Item::get_timeval(struct timeval *tm, int *warnings)
{
MYSQL_TIME ltime;
- return (null_value=
- (get_date(<ime, TIME_FUZZY_DATE) ||
- datetime_to_timeval(current_thd, <ime, tm, warnings)));
+ if (get_date(<ime, TIME_FUZZY_DATE))
+ {
+ if (null_value)
+ return true; /* Value is NULL */
+ goto zero; /* Could not extract date from the value */
+ }
+ if (datetime_to_timeval(current_thd, <ime, tm, warnings))
+ goto zero; /* Value is out of the supported range */
+ return false; /* Value is a good Unix timestamp */
+zero:
+ tm->tv_sec= tm->tv_usec= 0;
+ return false;
}
@@ -2670,8 +2685,11 @@ bool Item_field::get_time(MYSQL_TIME *lt
bool Item_field::get_timeval(struct timeval *tm, int *warnings)
{
- return (null_value= (field->is_null() ||
- field->get_timestamp(tm, warnings)));
+ if ((null_value= field->is_null()))
+ return true;
+ if (field->get_timestamp(tm, warnings))
+ tm->tv_sec= tm->tv_usec= 0;
+ return false;
}
double Item_field::val_result()
=== modified file 'sql/item_timefunc.cc'
--- a/sql/item_timefunc.cc 2011-12-16 16:57:46 +0000
+++ b/sql/item_timefunc.cc 2012-01-13 08:36:43 +0000
@@ -1456,20 +1456,7 @@ bool Item_func_unix_timestamp::val_timev
return false; // no args: null_value is set in constructor and is always 0.
}
int warnings= 0;
- if (args[0]->get_timeval(tm, &warnings)) // Don't set null_value here
- {
- /*
- We set null_value only if args[0]->get_date() invoked
- inside args[0]->get_timeval() returned null,
- which is indicated by "warnings == 0".
- In case of wrong non-null datetime parameter we return 0.
- "warnings" will not be equal to 0 in this case.
- */
- if (warnings == 0)
- return (null_value= true);
- tm->tv_sec= tm->tv_usec= 0;
- }
- return (null_value= false);
+ return (null_value= args[0]->get_timeval(tm, &warnings));
}
No bundle (reason: useless for push emails).
| Thread |
|---|
| • bzr push into mysql-trunk branch (alexander.barkov:3726 to 3727) Bug#13354387 | Alexander Barkov | 13 Jan |