Commit ac875690 authored by anozdrin/alik@station.'s avatar anozdrin/alik@station.
Browse files

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().
parent 7f554deb
Loading
Loading
Loading
Loading
+49 −1
Original line number Diff line number Diff line
@@ -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
+84 −0
Original line number Diff line number Diff line
@@ -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
+5 −0
Original line number Diff line number Diff line
@@ -1535,6 +1535,11 @@ class Item_func_sp :public Item_func
  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;
  }
};


+30 −0
Original line number Diff line number Diff line
@@ -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: