Commit c215e78d authored by unknown's avatar unknown

Fix for BUG#20550: Stored function: wrong RETURN type metadata

when used in a VIEW.

The problem was that wrong function (create_tmp_from_item())
was used to create a temporary field for Item_func_sp.

The fix is to use create_tmp_from_field().


mysql-test/r/sp.result:
  Update result file.
mysql-test/t/sp.test:
  Add a test case for BUG#20550.
sql/item_func.h:
  Add a getter for Item_func_sp::sp_result_field.
sql/sql_select.cc:
  Use create_tmp_from_field() to create a temporary field
  for Item_func_sp.
parent 11476cfc
...@@ -4914,7 +4914,7 @@ create table t3 as select * from v1| ...@@ -4914,7 +4914,7 @@ create table t3 as select * from v1|
show create table t3| show create table t3|
Table Create Table Table Create Table
t3 CREATE TABLE `t3` ( t3 CREATE TABLE `t3` (
`j` bigint(11) DEFAULT NULL `j` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1 ) ENGINE=MyISAM DEFAULT CHARSET=latin1
select * from t3| select * from t3|
j j
...@@ -6599,3 +6599,51 @@ DROP TABLE t1; ...@@ -6599,3 +6599,51 @@ DROP TABLE t1;
DROP PROCEDURE p1; DROP PROCEDURE p1;
DROP PROCEDURE p2; DROP PROCEDURE p2;
End of 5.0 tests End of 5.0 tests
#
# Bug#20550.
#
#
# - Prepare.
#
DROP VIEW IF EXISTS v1;
DROP VIEW IF EXISTS v2;
DROP FUNCTION IF EXISTS f1;
DROP FUNCTION IF EXISTS f2;
#
# - Create required objects.
#
CREATE FUNCTION f1() RETURNS VARCHAR(65525) RETURN 'Hello';
CREATE FUNCTION f2() RETURNS TINYINT RETURN 1;
CREATE VIEW v1 AS SELECT f1();
CREATE VIEW v2 AS SELECT f2();
#
# - Check.
#
SELECT DATA_TYPE FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'v1';
DATA_TYPE
varchar
SELECT DATA_TYPE FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'v2';
DATA_TYPE
tinyint
#
# - Cleanup.
#
DROP FUNCTION f1;
DROP FUNCTION f2;
DROP VIEW v1;
DROP VIEW v2;
End of 5.1 tests
...@@ -7549,3 +7549,87 @@ DROP PROCEDURE p1; ...@@ -7549,3 +7549,87 @@ DROP PROCEDURE p1;
DROP PROCEDURE p2; DROP PROCEDURE p2;
--echo End of 5.0 tests --echo End of 5.0 tests
###########################################################################
#
# Bug#20550: Stored function: wrong RETURN type metadata when used in a VIEW.
#
###########################################################################
--echo
--echo #
--echo # Bug#20550.
--echo #
--echo
--echo #
--echo # - Prepare.
--echo #
--echo
--disable_warnings
DROP VIEW IF EXISTS v1;
DROP VIEW IF EXISTS v2;
DROP FUNCTION IF EXISTS f1;
DROP FUNCTION IF EXISTS f2;
--enable_warnings
--echo
--echo #
--echo # - Create required objects.
--echo #
--echo
CREATE FUNCTION f1() RETURNS VARCHAR(65525) RETURN 'Hello';
--echo
CREATE FUNCTION f2() RETURNS TINYINT RETURN 1;
--echo
CREATE VIEW v1 AS SELECT f1();
--echo
CREATE VIEW v2 AS SELECT f2();
--echo
--echo #
--echo # - Check.
--echo #
--echo
SELECT DATA_TYPE FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'v1';
--echo
SELECT DATA_TYPE FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'v2';
--echo
--echo #
--echo # - Cleanup.
--echo #
--echo
DROP FUNCTION f1;
DROP FUNCTION f2;
DROP VIEW v1;
DROP VIEW v2;
--echo
###########################################################################
--echo End of 5.1 tests
...@@ -1535,6 +1535,11 @@ class Item_func_sp :public Item_func ...@@ -1535,6 +1535,11 @@ class Item_func_sp :public Item_func
bool fix_fields(THD *thd, Item **ref); bool fix_fields(THD *thd, Item **ref);
void fix_length_and_dec(void); void fix_length_and_dec(void);
bool is_expensive() { return 1; } bool is_expensive() { return 1; }
inline Field *get_sp_result_field()
{
return sp_result_field;
}
}; };
......
...@@ -9301,6 +9301,36 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type, ...@@ -9301,6 +9301,36 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type,
} }
/* Fall through */ /* Fall through */
case Item::FUNC_ITEM: case Item::FUNC_ITEM:
if (((Item_func *) item)->functype() == Item_func::FUNC_SP)
{
Item_func_sp *item_func_sp= (Item_func_sp *) item;
Field *sp_result_field= item_func_sp->get_sp_result_field();
if (make_copy_field)
{
DBUG_ASSERT(item_func_sp->result_field);
*from_field= item_func_sp->result_field;
}
else
{
*((*copy_func)++)= item;
}
Field *result_field=
create_tmp_field_from_field(thd,
sp_result_field,
item_func_sp->name,
table,
NULL,
convert_blob_length);
if (modify_item)
item->set_result_field(result_field);
return result_field;
}
/* Fall through */
case Item::COND_ITEM: case Item::COND_ITEM:
case Item::FIELD_AVG_ITEM: case Item::FIELD_AVG_ITEM:
case Item::FIELD_STD_ITEM: case Item::FIELD_STD_ITEM:
......
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