Commit fa0ea365 authored by evgen@moonbone.local's avatar evgen@moonbone.local

Fix bug #11335 View redefines TinyInt(1) column definition

Item_type_holder doesn't store information about length and exact type of
original item which results in redefining length to max_length and geometry 
type to longtext.

Changed the way derived tables except unions are built. Now they are created
from original field list instead of list of Item_type_holder.
parent f4d27c75
...@@ -1087,24 +1087,24 @@ CREATE TABLE t1 SELECT * FROM (SELECT 1 as a,(SELECT 1)) a; ...@@ -1087,24 +1087,24 @@ CREATE TABLE t1 SELECT * FROM (SELECT 1 as a,(SELECT 1)) a;
SHOW CREATE TABLE t1; SHOW CREATE TABLE t1;
Table Create Table Table Create Table
t1 CREATE TABLE `t1` ( t1 CREATE TABLE `t1` (
`a` bigint(20) NOT NULL default '0', `a` bigint(1) NOT NULL default '0',
`(SELECT 1)` bigint(20) NOT NULL default '0' `(SELECT 1)` bigint(1) NOT NULL default '0'
) ENGINE=MyISAM DEFAULT CHARSET=latin1 ) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1; drop table t1;
CREATE TABLE t1 SELECT * FROM (SELECT 1 as a,(SELECT a)) a; CREATE TABLE t1 SELECT * FROM (SELECT 1 as a,(SELECT a)) a;
SHOW CREATE TABLE t1; SHOW CREATE TABLE t1;
Table Create Table Table Create Table
t1 CREATE TABLE `t1` ( t1 CREATE TABLE `t1` (
`a` bigint(20) NOT NULL default '0', `a` bigint(1) NOT NULL default '0',
`(SELECT a)` bigint(20) NOT NULL default '0' `(SELECT a)` bigint(1) NOT NULL default '0'
) ENGINE=MyISAM DEFAULT CHARSET=latin1 ) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1; drop table t1;
CREATE TABLE t1 SELECT * FROM (SELECT 1 as a,(SELECT a+0)) a; CREATE TABLE t1 SELECT * FROM (SELECT 1 as a,(SELECT a+0)) a;
SHOW CREATE TABLE t1; SHOW CREATE TABLE t1;
Table Create Table Table Create Table
t1 CREATE TABLE `t1` ( t1 CREATE TABLE `t1` (
`a` bigint(20) NOT NULL default '0', `a` bigint(1) NOT NULL default '0',
`(SELECT a+0)` bigint(20) NOT NULL default '0' `(SELECT a+0)` bigint(3) NOT NULL default '0'
) ENGINE=MyISAM DEFAULT CHARSET=latin1 ) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1; drop table t1;
CREATE TABLE t1 SELECT (SELECT 1 as a UNION SELECT 1+1 limit 1,1) as a; CREATE TABLE t1 SELECT (SELECT 1 as a UNION SELECT 1+1 limit 1,1) as a;
......
...@@ -566,7 +566,7 @@ select * from v1; ...@@ -566,7 +566,7 @@ select * from v1;
col1 col1
describe v1; describe v1;
Field Type Null Key Default Extra Field Type Null Key Default Extra
col1 varchar(2) YES NULL col1 char(2) YES NULL
drop view v1; drop view v1;
drop table `t1a``b`; drop table `t1a``b`;
create table t1 (col1 char(5),col2 char(5)); create table t1 (col1 char(5),col2 char(5));
...@@ -1977,3 +1977,14 @@ A ...@@ -1977,3 +1977,14 @@ A
B B
DROP VIEW v1; DROP VIEW v1;
DROP TABLE t1; DROP TABLE t1;
create table t1 (f1 tinyint(1), f2 char(1), f3 varchar(1), f4 geometry, f5 datetime);
create view v1 as select * from t1;
desc v1;
Field Type Null Key Default Extra
f1 tinyint(1) YES NULL
f2 char(1) YES NULL
f3 varchar(1) YES NULL
f4 geometry YES NULL
f5 datetime YES NULL
drop view v1;
drop table t1;
...@@ -72,12 +72,12 @@ select c from mysqltest.v4; ...@@ -72,12 +72,12 @@ select c from mysqltest.v4;
c c
show columns from mysqltest.v1; show columns from mysqltest.v1;
Field Type Null Key Default Extra Field Type Null Key Default Extra
c bigint(20) YES NULL c bigint(12) YES NULL
d bigint(20) YES NULL d bigint(12) YES NULL
show columns from mysqltest.v2; show columns from mysqltest.v2;
Field Type Null Key Default Extra Field Type Null Key Default Extra
c bigint(20) YES NULL c bigint(12) YES NULL
d bigint(20) YES NULL d bigint(12) YES NULL
explain select c from mysqltest.v1; explain select c from mysqltest.v1;
ERROR HY000: EXPLAIN/SHOW can not be issued; lacking privileges for underlying table ERROR HY000: EXPLAIN/SHOW can not be issued; lacking privileges for underlying table
show create view mysqltest.v1; show create view mysqltest.v1;
......
...@@ -1815,3 +1815,12 @@ SELECT * FROM t1; ...@@ -1815,3 +1815,12 @@ SELECT * FROM t1;
DROP VIEW v1; DROP VIEW v1;
DROP TABLE t1; DROP TABLE t1;
#
# Bug #11335 View redefines column types
#
create table t1 (f1 tinyint(1), f2 char(1), f3 varchar(1), f4 geometry, f5 datetime);
create view v1 as select * from t1;
desc v1;
drop view v1;
drop table t1;
...@@ -321,6 +321,22 @@ Field *Item_sum_hybrid::create_tmp_field(bool group, TABLE *table, ...@@ -321,6 +321,22 @@ Field *Item_sum_hybrid::create_tmp_field(bool group, TABLE *table,
field->flags&= ~NOT_NULL_FLAG; field->flags&= ~NOT_NULL_FLAG;
return field; return field;
} }
/*
DATE/TIME fields have STRING_RESULT result types.
In order to preserve field type, it's needed to handle DATE/TIME
fields creations separately.
*/
switch (args[0]->field_type()) {
case MYSQL_TYPE_DATE:
return new Field_date(maybe_null, name, table, collation.collation);
case MYSQL_TYPE_TIME:
return new Field_time(maybe_null, name, table, collation.collation);
case MYSQL_TYPE_TIMESTAMP:
case MYSQL_TYPE_DATETIME:
return new Field_datetime(maybe_null, name, table, collation.collation);
default:
break;
}
return Item_sum::create_tmp_field(group, table, convert_blob_length); return Item_sum::create_tmp_field(group, table, convert_blob_length);
} }
......
...@@ -7875,7 +7875,15 @@ static Field *create_tmp_field_from_item(THD *thd, Item *item, TABLE *table, ...@@ -7875,7 +7875,15 @@ static Field *create_tmp_field_from_item(THD *thd, Item *item, TABLE *table,
item->name, table, item->unsigned_flag); item->name, table, item->unsigned_flag);
break; break;
case STRING_RESULT: case STRING_RESULT:
if (item->max_length > 255 && convert_blob_length) enum enum_field_types type;
/*
DATE/TIME fields have STRING_RESULT result type. To preserve
type they needed to be handled separately.
*/
if ((type= item->field_type()) == MYSQL_TYPE_DATETIME ||
type == MYSQL_TYPE_TIME || type == MYSQL_TYPE_DATE)
new_field= item->tmp_table_field_from_field_type(table);
else if (item->max_length > 255 && convert_blob_length)
new_field= new Field_varstring(convert_blob_length, maybe_null, new_field= new Field_varstring(convert_blob_length, maybe_null,
item->name, table, item->name, table,
item->collation.collation); item->collation.collation);
...@@ -7981,6 +7989,20 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type, ...@@ -7981,6 +7989,20 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type,
if (table_cant_handle_bit_fields && field->field->type() == FIELD_TYPE_BIT) if (table_cant_handle_bit_fields && field->field->type() == FIELD_TYPE_BIT)
return create_tmp_field_from_item(thd, item, table, copy_func, return create_tmp_field_from_item(thd, item, table, copy_func,
modify_item, convert_blob_length); modify_item, convert_blob_length);
/*
If item have to be able to store NULLs but underlaid field can't do it,
create_tmp_field_from_field() can't be used for tmp field creation.
*/
if (field->maybe_null && !field->field->maybe_null())
{
Field *res= create_tmp_field_from_item(thd, item, table, NULL,
modify_item, convert_blob_length);
*from_field= field->field;
if (res && modify_item)
((Item_field*)item)->result_field= res;
return res;
}
return create_tmp_field_from_field(thd, (*from_field= field->field), return create_tmp_field_from_field(thd, (*from_field= field->field),
item->name, table, item->name, table,
modify_item ? (Item_field*) item : NULL, modify_item ? (Item_field*) item : NULL,
......
...@@ -235,7 +235,13 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result, ...@@ -235,7 +235,13 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
if ((res= (res || thd_arg->is_fatal_error))) if ((res= (res || thd_arg->is_fatal_error)))
goto err; goto err;
if (sl == first_select) /*
Use items list of underlaid select for derived tables to preserve
information about fields lengths and exact types
*/
if (!is_union)
types= first_select_in_union()->item_list;
else if (sl == first_select)
{ {
/* /*
We need to create an empty table object. It is used We need to create an empty table object. It is used
......
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