Commit 8de6199b authored by Sergei Golubchik's avatar Sergei Golubchik

lp:743017 Diverging results with TIME(3) and ranges depending on the execution plan in 5.1-micro

rewrite get_innobase_type_from_mysql_type() to use types as reported
by the Field objects, instead of relying on ad-hoc assumptions.
parent 6432b5f1
......@@ -8,8 +8,9 @@ drop table if exists t1, t2, t3;
--error ER_TOO_BIG_PRECISION
eval create table t1 (a $type(7));
eval create table t1 (a $type(3));
insert t1 values ('2010-12-11 01:02:03.4567');
eval create table t1 (a $type(3), key(a));
insert t1 values ('2010-12-11 00:20:03.1234');
insert t1 values ('2010-12-11 15:47:11.1234');
insert t1 values (20101211010203.45678);
insert t1 values (20101211030405.789e0);
insert t1 values (99991231235959e1);
......
drop table if exists t1, t2, t3;
create table t1 (a datetime(7));
ERROR 42000: Too big precision 7 specified for column 'a'. Maximum is 6.
create table t1 (a datetime(3));
insert t1 values ('2010-12-11 01:02:03.4567');
create table t1 (a datetime(3), key(a));
insert t1 values ('2010-12-11 00:20:03.1234');
insert t1 values ('2010-12-11 15:47:11.1234');
insert t1 values (20101211010203.45678);
insert t1 values (20101211030405.789e0);
insert t1 values (99991231235959e1);
......@@ -10,32 +11,36 @@ Warnings:
Warning 1265 Data truncated for column 'a' at row 1
select * from t1;
a
2010-12-11 01:02:03.456
0000-00-00 00:00:00.000
2010-12-11 00:20:03.123
2010-12-11 01:02:03.456
2010-12-11 03:04:05.789
0000-00-00 00:00:00.000
2010-12-11 15:47:11.123
select truncate(a, 6) from t1;
truncate(a, 6)
20101211010203.457031
0.000000
20101211002003.121094
20101211010203.457031
20101211030405.789062
0.000000
20101211154711.121094
select a DIV 1 from t1;
a DIV 1
20101211010203
0
20101211002003
20101211010203
20101211030405
0
20101211154711
select group_concat(distinct a) from t1;
group_concat(distinct a)
2010-12-11 01:02:03.456,2010-12-11 03:04:05.789,0000-00-00 00:00:00.000
0000-00-00 00:00:00.000,2010-12-11 00:20:03.123,2010-12-11 01:02:03.456,2010-12-11 03:04:05.789,2010-12-11 15:47:11.123
alter table t1 engine=innodb;
select * from t1;
a
2010-12-11 01:02:03.456
0000-00-00 00:00:00.000
2010-12-11 00:20:03.123
2010-12-11 01:02:03.456
2010-12-11 03:04:05.789
0000-00-00 00:00:00.000
2010-12-11 15:47:11.123
drop table t1;
create table t1 (a datetime(4)) engine=innodb;
insert t1 values ('2010-12-11 01:02:03.456789');
......
drop table if exists t1, t2, t3;
create table t1 (a time(7));
ERROR 42000: Too big precision 7 specified for column 'a'. Maximum is 6.
create table t1 (a time(3));
insert t1 values ('2010-12-11 01:02:03.4567');
create table t1 (a time(3), key(a));
insert t1 values ('2010-12-11 00:20:03.1234');
Warnings:
Note 1265 Data truncated for column 'a' at row 1
insert t1 values ('2010-12-11 15:47:11.1234');
Warnings:
Note 1265 Data truncated for column 'a' at row 1
insert t1 values (20101211010203.45678);
......@@ -16,29 +19,33 @@ Warnings:
Warning 1264 Out of range value for column 'a' at row 1
select * from t1;
a
01:02:03.456
00:20:03.123
15:47:11.123
838:59:59.999
838:59:59.999
838:59:59.999
select truncate(a, 6) from t1;
truncate(a, 6)
10203.456000
2003.123000
154711.123000
8385959.999000
8385959.999000
8385959.999000
select a DIV 1 from t1;
a DIV 1
10203
2003
154711
8385959
8385959
8385959
select group_concat(distinct a) from t1;
group_concat(distinct a)
01:02:03.456,838:59:59.999
00:20:03.123,15:47:11.123,838:59:59.999
alter table t1 engine=innodb;
select * from t1;
a
01:02:03.456
00:20:03.123
15:47:11.123
838:59:59.999
838:59:59.999
838:59:59.999
......
drop table if exists t1, t2, t3;
create table t1 (a timestamp(7));
ERROR 42000: Too big precision 7 specified for column 'a'. Maximum is 6.
create table t1 (a timestamp(3));
insert t1 values ('2010-12-11 01:02:03.4567');
create table t1 (a timestamp(3), key(a));
insert t1 values ('2010-12-11 00:20:03.1234');
insert t1 values ('2010-12-11 15:47:11.1234');
insert t1 values (20101211010203.45678);
insert t1 values (20101211030405.789e0);
insert t1 values (99991231235959e1);
......@@ -10,32 +11,36 @@ Warnings:
Warning 1265 Data truncated for column 'a' at row 1
select * from t1;
a
2010-12-11 01:02:03.456
0000-00-00 00:00:00.000
2010-12-11 00:20:03.123
2010-12-11 01:02:03.456
2010-12-11 03:04:05.789
0000-00-00 00:00:00.000
2010-12-11 15:47:11.123
select truncate(a, 6) from t1;
truncate(a, 6)
20101211010203.457031
0.000000
20101211002003.121094
20101211010203.457031
20101211030405.789062
0.000000
20101211154711.121094
select a DIV 1 from t1;
a DIV 1
20101211010203
0
20101211002003
20101211010203
20101211030405
0
20101211154711
select group_concat(distinct a) from t1;
group_concat(distinct a)
2010-12-11 01:02:03.456,2010-12-11 03:04:05.789,0000-00-00 00:00:00.000
0000-00-00 00:00:00.000,2010-12-11 00:20:03.123,2010-12-11 01:02:03.456,2010-12-11 03:04:05.789,2010-12-11 15:47:11.123
alter table t1 engine=innodb;
select * from t1;
a
2010-12-11 01:02:03.456
0000-00-00 00:00:00.000
2010-12-11 00:20:03.123
2010-12-11 01:02:03.456
2010-12-11 03:04:05.789
0000-00-00 00:00:00.000
2010-12-11 15:47:11.123
drop table t1;
create table t1 (a timestamp(4)) engine=innodb;
insert t1 values ('2010-12-11 01:02:03.456789');
......
CREATE TEMPORARY TABLE table_54044 ENGINE = INNODB
AS SELECT IF(NULL IS NOT NULL, NULL, NULL);
ERROR HY000: Can't create table 'test.table_54044' (errno: -1)
# This is the test for bug #54044. Special handle MYSQL_TYPE_NULL type
# during create table, so it will not trigger assertion failure.
--source include/have_innodb.inc
# This 'create table' operation should fail because of
# using NULL datatype
--error ER_CANT_CREATE_TABLE
CREATE TEMPORARY TABLE table_54044 ENGINE = INNODB
AS SELECT IF(NULL IS NOT NULL, NULL, NULL);
CREATE TEMPORARY TABLE table_54044 ENGINE = INNODB
AS SELECT IF(NULL IS NOT NULL, NULL, NULL);
ERROR HY000: Can't create table 'test.table_54044' (errno: -1)
......@@ -7,10 +7,10 @@ X RECORD `test`.```t'\"_str` `PRIMARY` 4 '3', 'abc', '\\abc', 'abc\\', 'a\\bc',
X RECORD `test`.```t'\"_str` `PRIMARY` 4 '3', 'abc', '\\abc', 'abc\\', 'a\\bc', 'a\\bc\\', '\\abc\\\\'
X RECORD `test`.```t'\"_str` `PRIMARY` 5 '4', 'abc', '\0abc', 'abc\0', 'a\0bc', 'a\0bc\0', 'a\0bc\0\0'
X RECORD `test`.```t'\"_str` `PRIMARY` 5 '4', 'abc', '\0abc', 'abc\0', 'a\0bc', 'a\0bc\0', 'a\0bc\0\0'
X RECORD `test`.`t_min` `PRIMARY` 2 -128, 0, -32768, 0, -8388608, 0, -2147483648, 0, -9223372036854775808, 0
X RECORD `test`.`t_min` `PRIMARY` 2 -128, 0, -32768, 0, -8388608, 0, -2147483648, 0, -9223372036854775808, 0
X RECORD `test`.`t_max` `PRIMARY` 2 127, 255, 32767, 65535, 8388607, 16777215, 2147483647, 4294967295, 9223372036854775807, 18446744073709551615
X RECORD `test`.`t_max` `PRIMARY` 2 127, 255, 32767, 65535, 8388607, 16777215, 2147483647, 4294967295, 9223372036854775807, 18446744073709551615
X RECORD `test`.`t_min` `PRIMARY` 2 -128, 0x00, -32768, 0, -8388608, 0, -2147483648, 0, -9223372036854775808, 0
X RECORD `test`.`t_min` `PRIMARY` 2 -128, 0x00, -32768, 0, -8388608, 0, -2147483648, 0, -9223372036854775808, 0
X RECORD `test`.`t_max` `PRIMARY` 2 127, 0xFF, 32767, 65535, 8388607, 16777215, 2147483647, 4294967295, 9223372036854775807, 18446744073709551615
X RECORD `test`.`t_max` `PRIMARY` 2 127, 0xFF, 32767, 65535, 8388607, 16777215, 2147483647, 4294967295, 9223372036854775807, 18446744073709551615
X RECORD `test`.```t'\"_str` `PRIMARY` 1 supremum pseudo-record
X RECORD `test`.```t'\"_str` `PRIMARY` 1 supremum pseudo-record
lock_table COUNT(*)
......
# This is the test for bug #54044. Special handle MYSQL_TYPE_NULL type
# during create table, so it will not trigger assertion failure.
--source include/have_innodb_plugin.inc
# This 'create table' operation should fail because of
# using NULL datatype
--error ER_CANT_CREATE_TABLE
CREATE TEMPORARY TABLE table_54044 ENGINE = INNODB
AS SELECT IF(NULL IS NOT NULL, NULL, NULL);
......@@ -1157,6 +1157,7 @@ public:
void sql_type(String &str) const;
uint size_of() const { return sizeof(*this); }
uint32 max_display_length() { return 4; }
void move_field_offset(my_ptrdiff_t ptr_diff) {}
};
......
......@@ -3184,90 +3184,59 @@ get_innobase_type_from_mysql_type(
8 bits: this is used in ibuf and also when DATA_NOT_NULL is ORed to
the type */
DBUG_ASSERT((ulint)MYSQL_TYPE_STRING < 256);
DBUG_ASSERT((ulint)MYSQL_TYPE_VAR_STRING < 256);
DBUG_ASSERT((ulint)MYSQL_TYPE_DOUBLE < 256);
DBUG_ASSERT((ulint)MYSQL_TYPE_FLOAT < 256);
DBUG_ASSERT((ulint)MYSQL_TYPE_DECIMAL < 256);
compile_time_assert((ulint)MYSQL_TYPE_STRING < 256);
compile_time_assert((ulint)MYSQL_TYPE_VAR_STRING < 256);
compile_time_assert((ulint)MYSQL_TYPE_DOUBLE < 256);
compile_time_assert((ulint)MYSQL_TYPE_FLOAT < 256);
compile_time_assert((ulint)MYSQL_TYPE_DECIMAL < 256);
if (field->flags & UNSIGNED_FLAG) {
*unsigned_flag = 0;
switch (field->key_type()) {
case HA_KEYTYPE_USHORT_INT:
case HA_KEYTYPE_ULONG_INT:
case HA_KEYTYPE_UINT24:
case HA_KEYTYPE_ULONGLONG:
*unsigned_flag = DATA_UNSIGNED;
} else {
*unsigned_flag = 0;
}
if (field->real_type() == MYSQL_TYPE_ENUM
|| field->real_type() == MYSQL_TYPE_SET) {
/* MySQL has field->type() a string type for these, but the
data is actually internally stored as an unsigned integer
code! */
*unsigned_flag = DATA_UNSIGNED; /* MySQL has its own unsigned
flag set to zero, even though
internally this is an unsigned
integer type */
/* fall through */
case HA_KEYTYPE_SHORT_INT:
case HA_KEYTYPE_LONG_INT:
case HA_KEYTYPE_INT24:
case HA_KEYTYPE_INT8:
case HA_KEYTYPE_LONGLONG:
return(DATA_INT);
}
switch (field->type()) {
/* NOTE that we only allow string types in DATA_MYSQL and
DATA_VARMYSQL */
case MYSQL_TYPE_VAR_STRING: /* old <= 4.1 VARCHAR */
case MYSQL_TYPE_VARCHAR: /* new >= 5.0.3 true VARCHAR */
if (field->binary()) {
return(DATA_BINARY);
} else if (strcmp(
field->charset()->name,
"latin1_swedish_ci") == 0) {
case HA_KEYTYPE_FLOAT:
return(DATA_FLOAT);
case HA_KEYTYPE_DOUBLE:
return(DATA_DOUBLE);
case HA_KEYTYPE_BINARY:
return(DATA_FIXBINARY);
case HA_KEYTYPE_VARBINARY2:
if (field->type() != MYSQL_TYPE_VARCHAR)
return(DATA_BLOB);
/* fall through */
case HA_KEYTYPE_VARBINARY1:
return(DATA_BINARY);
case HA_KEYTYPE_VARTEXT2:
if (field->type() != MYSQL_TYPE_VARCHAR)
return(DATA_BLOB);
/* fall through */
case HA_KEYTYPE_VARTEXT1:
if (field->charset() == &my_charset_latin1) {
return(DATA_VARCHAR);
} else {
return(DATA_VARMYSQL);
}
case MYSQL_TYPE_BIT:
case MYSQL_TYPE_STRING: if (field->binary()) {
return(DATA_FIXBINARY);
} else if (strcmp(
field->charset()->name,
"latin1_swedish_ci") == 0) {
case HA_KEYTYPE_TEXT:
if (field->charset() == &my_charset_latin1) {
return(DATA_CHAR);
} else {
return(DATA_MYSQL);
}
case MYSQL_TYPE_NEWDECIMAL:
return(DATA_FIXBINARY);
case MYSQL_TYPE_LONG:
case MYSQL_TYPE_LONGLONG:
case MYSQL_TYPE_TINY:
case MYSQL_TYPE_SHORT:
case MYSQL_TYPE_INT24:
case MYSQL_TYPE_DATE:
case MYSQL_TYPE_DATETIME:
case MYSQL_TYPE_YEAR:
case MYSQL_TYPE_NEWDATE:
case MYSQL_TYPE_TIME:
case MYSQL_TYPE_TIMESTAMP:
return(DATA_INT);
case MYSQL_TYPE_FLOAT:
return(DATA_FLOAT);
case MYSQL_TYPE_DOUBLE:
return(DATA_DOUBLE);
case MYSQL_TYPE_DECIMAL:
case HA_KEYTYPE_NUM:
return(DATA_DECIMAL);
case MYSQL_TYPE_GEOMETRY:
case MYSQL_TYPE_TINY_BLOB:
case MYSQL_TYPE_MEDIUM_BLOB:
case MYSQL_TYPE_BLOB:
case MYSQL_TYPE_LONG_BLOB:
return(DATA_BLOB);
case MYSQL_TYPE_NULL:
/* MySQL currently accepts "NULL" datatype, but will
reject such datatype in the next release. We will cope
with it and not trigger assertion failure in 5.1 */
break;
default:
case HA_KEYTYPE_BIT:
case HA_KEYTYPE_END:
assert(0);
}
......
......@@ -3893,90 +3893,59 @@ get_innobase_type_from_mysql_type(
8 bits: this is used in ibuf and also when DATA_NOT_NULL is ORed to
the type */
DBUG_ASSERT((ulint)MYSQL_TYPE_STRING < 256);
DBUG_ASSERT((ulint)MYSQL_TYPE_VAR_STRING < 256);
DBUG_ASSERT((ulint)MYSQL_TYPE_DOUBLE < 256);
DBUG_ASSERT((ulint)MYSQL_TYPE_FLOAT < 256);
DBUG_ASSERT((ulint)MYSQL_TYPE_DECIMAL < 256);
compile_time_assert((ulint)MYSQL_TYPE_STRING < 256);
compile_time_assert((ulint)MYSQL_TYPE_VAR_STRING < 256);
compile_time_assert((ulint)MYSQL_TYPE_DOUBLE < 256);
compile_time_assert((ulint)MYSQL_TYPE_FLOAT < 256);
compile_time_assert((ulint)MYSQL_TYPE_DECIMAL < 256);
if (field->flags & UNSIGNED_FLAG) {
*unsigned_flag = 0;
switch (field->key_type()) {
case HA_KEYTYPE_USHORT_INT:
case HA_KEYTYPE_ULONG_INT:
case HA_KEYTYPE_UINT24:
case HA_KEYTYPE_ULONGLONG:
*unsigned_flag = DATA_UNSIGNED;
} else {
*unsigned_flag = 0;
}
if (field->real_type() == MYSQL_TYPE_ENUM
|| field->real_type() == MYSQL_TYPE_SET) {
/* MySQL has field->type() a string type for these, but the
data is actually internally stored as an unsigned integer
code! */
*unsigned_flag = DATA_UNSIGNED; /* MySQL has its own unsigned
flag set to zero, even though
internally this is an unsigned
integer type */
/* fall through */
case HA_KEYTYPE_SHORT_INT:
case HA_KEYTYPE_LONG_INT:
case HA_KEYTYPE_INT24:
case HA_KEYTYPE_INT8:
case HA_KEYTYPE_LONGLONG:
return(DATA_INT);
}
switch (field->type()) {
/* NOTE that we only allow string types in DATA_MYSQL and
DATA_VARMYSQL */
case MYSQL_TYPE_VAR_STRING: /* old <= 4.1 VARCHAR */
case MYSQL_TYPE_VARCHAR: /* new >= 5.0.3 true VARCHAR */
if (field->binary()) {
return(DATA_BINARY);
} else if (strcmp(
field->charset()->name,
"latin1_swedish_ci") == 0) {
case HA_KEYTYPE_FLOAT:
return(DATA_FLOAT);
case HA_KEYTYPE_DOUBLE:
return(DATA_DOUBLE);
case HA_KEYTYPE_BINARY:
return(DATA_FIXBINARY);
case HA_KEYTYPE_VARBINARY2:
if (field->type() != MYSQL_TYPE_VARCHAR)
return(DATA_BLOB);
/* fall through */
case HA_KEYTYPE_VARBINARY1:
return(DATA_BINARY);
case HA_KEYTYPE_VARTEXT2:
if (field->type() != MYSQL_TYPE_VARCHAR)
return(DATA_BLOB);
/* fall through */
case HA_KEYTYPE_VARTEXT1:
if (field->charset() == &my_charset_latin1) {
return(DATA_VARCHAR);
} else {
return(DATA_VARMYSQL);
}
case MYSQL_TYPE_BIT:
case MYSQL_TYPE_STRING: if (field->binary()) {
return(DATA_FIXBINARY);
} else if (strcmp(
field->charset()->name,
"latin1_swedish_ci") == 0) {
case HA_KEYTYPE_TEXT:
if (field->charset() == &my_charset_latin1) {
return(DATA_CHAR);
} else {
return(DATA_MYSQL);
}
case MYSQL_TYPE_NEWDECIMAL:
return(DATA_FIXBINARY);
case MYSQL_TYPE_LONG:
case MYSQL_TYPE_LONGLONG:
case MYSQL_TYPE_TINY:
case MYSQL_TYPE_SHORT:
case MYSQL_TYPE_INT24:
case MYSQL_TYPE_DATE:
case MYSQL_TYPE_DATETIME:
case MYSQL_TYPE_YEAR:
case MYSQL_TYPE_NEWDATE:
case MYSQL_TYPE_TIME:
case MYSQL_TYPE_TIMESTAMP:
return(DATA_INT);
case MYSQL_TYPE_FLOAT:
return(DATA_FLOAT);
case MYSQL_TYPE_DOUBLE:
return(DATA_DOUBLE);
case MYSQL_TYPE_DECIMAL:
case HA_KEYTYPE_NUM:
return(DATA_DECIMAL);
case MYSQL_TYPE_GEOMETRY:
case MYSQL_TYPE_TINY_BLOB:
case MYSQL_TYPE_MEDIUM_BLOB:
case MYSQL_TYPE_BLOB:
case MYSQL_TYPE_LONG_BLOB:
return(DATA_BLOB);
case MYSQL_TYPE_NULL:
/* MySQL currently accepts "NULL" datatype, but will
reject such datatype in the next release. We will cope
with it and not trigger assertion failure in 5.1 */
break;
default:
case HA_KEYTYPE_BIT:
case HA_KEYTYPE_END:
ut_error;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment