summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/r/sp.result50
-rw-r--r--mysql-test/t/sp.test84
-rw-r--r--sql/item_func.h5
-rw-r--r--sql/sql_select.cc30
4 files changed, 168 insertions, 1 deletions
diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result
index fd09701c125..2274a9103e8 100644
--- a/mysql-test/r/sp.result
+++ b/mysql-test/r/sp.result
@@ -4914,7 +4914,7 @@ create table t3 as select * from v1|
show create table t3|
Table Create Table
t3 CREATE TABLE `t3` (
- `j` bigint(11) DEFAULT NULL
+ `j` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
select * from t3|
j
@@ -6599,3 +6599,51 @@ DROP TABLE t1;
DROP PROCEDURE p1;
DROP PROCEDURE p2;
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
diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test
index 27e559f4463..938bbc27777 100644
--- a/mysql-test/t/sp.test
+++ b/mysql-test/t/sp.test
@@ -7549,3 +7549,87 @@ DROP PROCEDURE p1;
DROP PROCEDURE p2;
--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
diff --git a/sql/item_func.h b/sql/item_func.h
index ea22e35773d..66a417f31fa 100644
--- a/sql/item_func.h
+++ b/sql/item_func.h
@@ -1535,6 +1535,11 @@ public:
bool fix_fields(THD *thd, Item **ref);
void fix_length_and_dec(void);
bool is_expensive() { return 1; }
+
+ inline Field *get_sp_result_field()
+ {
+ return sp_result_field;
+ }
};
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index fd3be1aef08..9b79b706438 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -9301,6 +9301,36 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type,
}
/* Fall through */
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::FIELD_AVG_ITEM:
case Item::FIELD_STD_ITEM: