summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Barkov <bar@mariadb.org>2018-02-28 23:05:57 +0400
committerAlexander Barkov <bar@mariadb.org>2018-02-28 23:05:57 +0400
commit4025cfaec038594bfc97bea48aa2cfe139930cc2 (patch)
tree32644046fec0cd33ea703f891ecc11ad6329247a
parent5f7c764fe79501635c5f7695f6cb22fa69466c63 (diff)
downloadmariadb-git-4025cfaec038594bfc97bea48aa2cfe139930cc2.tar.gz
MDEV-15416 Crash when reading I_S.PARAMETERS
-rw-r--r--mysql-test/r/information_schema_parameters.result102
-rw-r--r--mysql-test/suite/compat/oracle/r/information_schema_parameters.result816
-rw-r--r--mysql-test/suite/compat/oracle/t/information_schema_parameters.test94
-rw-r--r--mysql-test/t/information_schema_parameters.test25
-rw-r--r--sql/field.h6
-rw-r--r--sql/sp.cc17
-rw-r--r--sql/sp.h18
-rw-r--r--sql/sql_class.cc17
-rw-r--r--sql/sql_class.h2
-rw-r--r--sql/sql_show.cc128
10 files changed, 1202 insertions, 23 deletions
diff --git a/mysql-test/r/information_schema_parameters.result b/mysql-test/r/information_schema_parameters.result
index 1d974851133..a215c86c388 100644
--- a/mysql-test/r/information_schema_parameters.result
+++ b/mysql-test/r/information_schema_parameters.result
@@ -524,3 +524,105 @@ SPECIFIC_CATALOG SPECIFIC_SCHEMA SPECIFIC_NAME ORDINAL_POSITION PARAMETER_MODE P
def i_s_parameters_test test_func5 0 NULL NULL varchar 30 90 NULL NULL NULL utf8 utf8_general_ci varchar(30) FUNCTION
def i_s_parameters_test test_func5 1 IN s char 20 60 NULL NULL NULL utf8 utf8_general_ci char(20) FUNCTION
DROP DATABASE i_s_parameters_test;
+USE test;
+#
+# Start of 10.3 tests
+#
+#
+# MDEV-15416 Crash when reading I_S.PARAMETERS
+#
+CREATE PROCEDURE p1(a0 TYPE OF t1.a,
+a1 TYPE OF test.t1.a,
+b0 ROW TYPE OF t1,
+b1 ROW TYPE OF test.t1,
+c ROW(a INT,b DOUBLE))
+BEGIN
+END;
+$$
+SELECT *, '--------' FROM INFORMATION_SCHEMA.PARAMETERS WHERE SPECIFIC_NAME = 'p1';
+SPECIFIC_CATALOG def
+SPECIFIC_SCHEMA test
+SPECIFIC_NAME p1
+ORDINAL_POSITION 1
+PARAMETER_MODE IN
+PARAMETER_NAME a0
+DATA_TYPE TYPE OF
+CHARACTER_MAXIMUM_LENGTH NULL
+CHARACTER_OCTET_LENGTH NULL
+NUMERIC_PRECISION NULL
+NUMERIC_SCALE NULL
+DATETIME_PRECISION NULL
+CHARACTER_SET_NAME NULL
+COLLATION_NAME NULL
+DTD_IDENTIFIER TYPE OF `t1`.`a`
+ROUTINE_TYPE PROCEDURE
+-------- --------
+SPECIFIC_CATALOG def
+SPECIFIC_SCHEMA test
+SPECIFIC_NAME p1
+ORDINAL_POSITION 2
+PARAMETER_MODE IN
+PARAMETER_NAME a1
+DATA_TYPE TYPE OF
+CHARACTER_MAXIMUM_LENGTH NULL
+CHARACTER_OCTET_LENGTH NULL
+NUMERIC_PRECISION NULL
+NUMERIC_SCALE NULL
+DATETIME_PRECISION NULL
+CHARACTER_SET_NAME NULL
+COLLATION_NAME NULL
+DTD_IDENTIFIER TYPE OF `test`.`t1`.`a`
+ROUTINE_TYPE PROCEDURE
+-------- --------
+SPECIFIC_CATALOG def
+SPECIFIC_SCHEMA test
+SPECIFIC_NAME p1
+ORDINAL_POSITION 3
+PARAMETER_MODE IN
+PARAMETER_NAME b0
+DATA_TYPE ROW TYPE OF
+CHARACTER_MAXIMUM_LENGTH NULL
+CHARACTER_OCTET_LENGTH NULL
+NUMERIC_PRECISION NULL
+NUMERIC_SCALE NULL
+DATETIME_PRECISION NULL
+CHARACTER_SET_NAME NULL
+COLLATION_NAME NULL
+DTD_IDENTIFIER ROW TYPE OF `t1`
+ROUTINE_TYPE PROCEDURE
+-------- --------
+SPECIFIC_CATALOG def
+SPECIFIC_SCHEMA test
+SPECIFIC_NAME p1
+ORDINAL_POSITION 4
+PARAMETER_MODE IN
+PARAMETER_NAME b1
+DATA_TYPE ROW TYPE OF
+CHARACTER_MAXIMUM_LENGTH NULL
+CHARACTER_OCTET_LENGTH NULL
+NUMERIC_PRECISION NULL
+NUMERIC_SCALE NULL
+DATETIME_PRECISION NULL
+CHARACTER_SET_NAME NULL
+COLLATION_NAME NULL
+DTD_IDENTIFIER ROW TYPE OF `test`.`t1`
+ROUTINE_TYPE PROCEDURE
+-------- --------
+SPECIFIC_CATALOG def
+SPECIFIC_SCHEMA test
+SPECIFIC_NAME p1
+ORDINAL_POSITION 5
+PARAMETER_MODE IN
+PARAMETER_NAME c
+DATA_TYPE ROW
+CHARACTER_MAXIMUM_LENGTH NULL
+CHARACTER_OCTET_LENGTH NULL
+NUMERIC_PRECISION NULL
+NUMERIC_SCALE NULL
+DATETIME_PRECISION NULL
+CHARACTER_SET_NAME NULL
+COLLATION_NAME NULL
+DTD_IDENTIFIER ROW
+ROUTINE_TYPE PROCEDURE
+-------- --------
+DROP PROCEDURE p1;
diff --git a/mysql-test/suite/compat/oracle/r/information_schema_parameters.result b/mysql-test/suite/compat/oracle/r/information_schema_parameters.result
new file mode 100644
index 00000000000..e1ed53c39de
--- /dev/null
+++ b/mysql-test/suite/compat/oracle/r/information_schema_parameters.result
@@ -0,0 +1,816 @@
+#
+# MDEV-15416 Crash when reading I_S.PARAMETERS
+#
+# Create in sql_mode=ORACLE, display in sql_mode=ORACLE and sql_mode=DEFAULT
+SET sql_mode=ORACLE;
+CREATE PROCEDURE p1(a0 t1.a%TYPE,
+a1 test.t1.a%TYPE,
+b0 t1%ROWTYPE,
+b1 test.t1%ROWTYPE,
+d ROW(a INT,b DOUBLE))
+AS
+BEGIN
+NULL;
+END;
+$$
+SET sql_mode=ORACLE;
+SELECT *, '--------' FROM INFORMATION_SCHEMA.PARAMETERS WHERE SPECIFIC_NAME='p1';
+SPECIFIC_CATALOG def
+SPECIFIC_SCHEMA test
+SPECIFIC_NAME p1
+ORDINAL_POSITION 1
+PARAMETER_MODE IN
+PARAMETER_NAME a0
+DATA_TYPE TYPE OF
+CHARACTER_MAXIMUM_LENGTH NULL
+CHARACTER_OCTET_LENGTH NULL
+NUMERIC_PRECISION NULL
+NUMERIC_SCALE NULL
+DATETIME_PRECISION NULL
+CHARACTER_SET_NAME NULL
+COLLATION_NAME NULL
+DTD_IDENTIFIER "t1"."a"%TYPE
+ROUTINE_TYPE PROCEDURE
+-------- --------
+SPECIFIC_CATALOG def
+SPECIFIC_SCHEMA test
+SPECIFIC_NAME p1
+ORDINAL_POSITION 2
+PARAMETER_MODE IN
+PARAMETER_NAME a1
+DATA_TYPE TYPE OF
+CHARACTER_MAXIMUM_LENGTH NULL
+CHARACTER_OCTET_LENGTH NULL
+NUMERIC_PRECISION NULL
+NUMERIC_SCALE NULL
+DATETIME_PRECISION NULL
+CHARACTER_SET_NAME NULL
+COLLATION_NAME NULL
+DTD_IDENTIFIER "test"."t1"."a"%TYPE
+ROUTINE_TYPE PROCEDURE
+-------- --------
+SPECIFIC_CATALOG def
+SPECIFIC_SCHEMA test
+SPECIFIC_NAME p1
+ORDINAL_POSITION 3
+PARAMETER_MODE IN
+PARAMETER_NAME b0
+DATA_TYPE ROW TYPE OF
+CHARACTER_MAXIMUM_LENGTH NULL
+CHARACTER_OCTET_LENGTH NULL
+NUMERIC_PRECISION NULL
+NUMERIC_SCALE NULL
+DATETIME_PRECISION NULL
+CHARACTER_SET_NAME NULL
+COLLATION_NAME NULL
+DTD_IDENTIFIER "t1"%ROWTYPE
+ROUTINE_TYPE PROCEDURE
+-------- --------
+SPECIFIC_CATALOG def
+SPECIFIC_SCHEMA test
+SPECIFIC_NAME p1
+ORDINAL_POSITION 4
+PARAMETER_MODE IN
+PARAMETER_NAME b1
+DATA_TYPE ROW TYPE OF
+CHARACTER_MAXIMUM_LENGTH NULL
+CHARACTER_OCTET_LENGTH NULL
+NUMERIC_PRECISION NULL
+NUMERIC_SCALE NULL
+DATETIME_PRECISION NULL
+CHARACTER_SET_NAME NULL
+COLLATION_NAME NULL
+DTD_IDENTIFIER "test"."t1"%ROWTYPE
+ROUTINE_TYPE PROCEDURE
+-------- --------
+SPECIFIC_CATALOG def
+SPECIFIC_SCHEMA test
+SPECIFIC_NAME p1
+ORDINAL_POSITION 5
+PARAMETER_MODE IN
+PARAMETER_NAME d
+DATA_TYPE ROW
+CHARACTER_MAXIMUM_LENGTH NULL
+CHARACTER_OCTET_LENGTH NULL
+NUMERIC_PRECISION NULL
+NUMERIC_SCALE NULL
+DATETIME_PRECISION NULL
+CHARACTER_SET_NAME NULL
+COLLATION_NAME NULL
+DTD_IDENTIFIER ROW
+ROUTINE_TYPE PROCEDURE
+-------- --------
+SET sql_mode=DEFAULT;
+SELECT *, '--------' FROM INFORMATION_SCHEMA.PARAMETERS WHERE SPECIFIC_NAME='p1';
+SPECIFIC_CATALOG def
+SPECIFIC_SCHEMA test
+SPECIFIC_NAME p1
+ORDINAL_POSITION 1
+PARAMETER_MODE IN
+PARAMETER_NAME a0
+DATA_TYPE TYPE OF
+CHARACTER_MAXIMUM_LENGTH NULL
+CHARACTER_OCTET_LENGTH NULL
+NUMERIC_PRECISION NULL
+NUMERIC_SCALE NULL
+DATETIME_PRECISION NULL
+CHARACTER_SET_NAME NULL
+COLLATION_NAME NULL
+DTD_IDENTIFIER "t1"."a"%TYPE
+ROUTINE_TYPE PROCEDURE
+-------- --------
+SPECIFIC_CATALOG def
+SPECIFIC_SCHEMA test
+SPECIFIC_NAME p1
+ORDINAL_POSITION 2
+PARAMETER_MODE IN
+PARAMETER_NAME a1
+DATA_TYPE TYPE OF
+CHARACTER_MAXIMUM_LENGTH NULL
+CHARACTER_OCTET_LENGTH NULL
+NUMERIC_PRECISION NULL
+NUMERIC_SCALE NULL
+DATETIME_PRECISION NULL
+CHARACTER_SET_NAME NULL
+COLLATION_NAME NULL
+DTD_IDENTIFIER "test"."t1"."a"%TYPE
+ROUTINE_TYPE PROCEDURE
+-------- --------
+SPECIFIC_CATALOG def
+SPECIFIC_SCHEMA test
+SPECIFIC_NAME p1
+ORDINAL_POSITION 3
+PARAMETER_MODE IN
+PARAMETER_NAME b0
+DATA_TYPE ROW TYPE OF
+CHARACTER_MAXIMUM_LENGTH NULL
+CHARACTER_OCTET_LENGTH NULL
+NUMERIC_PRECISION NULL
+NUMERIC_SCALE NULL
+DATETIME_PRECISION NULL
+CHARACTER_SET_NAME NULL
+COLLATION_NAME NULL
+DTD_IDENTIFIER "t1"%ROWTYPE
+ROUTINE_TYPE PROCEDURE
+-------- --------
+SPECIFIC_CATALOG def
+SPECIFIC_SCHEMA test
+SPECIFIC_NAME p1
+ORDINAL_POSITION 4
+PARAMETER_MODE IN
+PARAMETER_NAME b1
+DATA_TYPE ROW TYPE OF
+CHARACTER_MAXIMUM_LENGTH NULL
+CHARACTER_OCTET_LENGTH NULL
+NUMERIC_PRECISION NULL
+NUMERIC_SCALE NULL
+DATETIME_PRECISION NULL
+CHARACTER_SET_NAME NULL
+COLLATION_NAME NULL
+DTD_IDENTIFIER "test"."t1"%ROWTYPE
+ROUTINE_TYPE PROCEDURE
+-------- --------
+SPECIFIC_CATALOG def
+SPECIFIC_SCHEMA test
+SPECIFIC_NAME p1
+ORDINAL_POSITION 5
+PARAMETER_MODE IN
+PARAMETER_NAME d
+DATA_TYPE ROW
+CHARACTER_MAXIMUM_LENGTH NULL
+CHARACTER_OCTET_LENGTH NULL
+NUMERIC_PRECISION NULL
+NUMERIC_SCALE NULL
+DATETIME_PRECISION NULL
+CHARACTER_SET_NAME NULL
+COLLATION_NAME NULL
+DTD_IDENTIFIER ROW
+ROUTINE_TYPE PROCEDURE
+-------- --------
+DROP PROCEDURE p1;
+SET sql_mode=ORACLE;
+CREATE FUNCTION f1(a0 t1.a%TYPE,
+a1 test.t1.a%TYPE,
+b0 t1%ROWTYPE,
+b1 test.t1%ROWTYPE,
+d ROW(a INT,b DOUBLE))
+RETURN INT
+AS
+BEGIN
+RETURN 0;
+END;
+$$
+SET sql_mode=ORACLE;
+SELECT *, '--------' FROM INFORMATION_SCHEMA.PARAMETERS WHERE SPECIFIC_NAME='f1';
+SPECIFIC_CATALOG def
+SPECIFIC_SCHEMA test
+SPECIFIC_NAME f1
+ORDINAL_POSITION 0
+PARAMETER_MODE NULL
+PARAMETER_NAME NULL
+DATA_TYPE int
+CHARACTER_MAXIMUM_LENGTH NULL
+CHARACTER_OCTET_LENGTH NULL
+NUMERIC_PRECISION 10
+NUMERIC_SCALE 0
+DATETIME_PRECISION NULL
+CHARACTER_SET_NAME NULL
+COLLATION_NAME NULL
+DTD_IDENTIFIER int(11)
+ROUTINE_TYPE FUNCTION
+-------- --------
+SPECIFIC_CATALOG def
+SPECIFIC_SCHEMA test
+SPECIFIC_NAME f1
+ORDINAL_POSITION 1
+PARAMETER_MODE IN
+PARAMETER_NAME a0
+DATA_TYPE TYPE OF
+CHARACTER_MAXIMUM_LENGTH NULL
+CHARACTER_OCTET_LENGTH NULL
+NUMERIC_PRECISION NULL
+NUMERIC_SCALE NULL
+DATETIME_PRECISION NULL
+CHARACTER_SET_NAME NULL
+COLLATION_NAME NULL
+DTD_IDENTIFIER "t1"."a"%TYPE
+ROUTINE_TYPE FUNCTION
+-------- --------
+SPECIFIC_CATALOG def
+SPECIFIC_SCHEMA test
+SPECIFIC_NAME f1
+ORDINAL_POSITION 2
+PARAMETER_MODE IN
+PARAMETER_NAME a1
+DATA_TYPE TYPE OF
+CHARACTER_MAXIMUM_LENGTH NULL
+CHARACTER_OCTET_LENGTH NULL
+NUMERIC_PRECISION NULL
+NUMERIC_SCALE NULL
+DATETIME_PRECISION NULL
+CHARACTER_SET_NAME NULL
+COLLATION_NAME NULL
+DTD_IDENTIFIER "test"."t1"."a"%TYPE
+ROUTINE_TYPE FUNCTION
+-------- --------
+SPECIFIC_CATALOG def
+SPECIFIC_SCHEMA test
+SPECIFIC_NAME f1
+ORDINAL_POSITION 3
+PARAMETER_MODE IN
+PARAMETER_NAME b0
+DATA_TYPE ROW TYPE OF
+CHARACTER_MAXIMUM_LENGTH NULL
+CHARACTER_OCTET_LENGTH NULL
+NUMERIC_PRECISION NULL
+NUMERIC_SCALE NULL
+DATETIME_PRECISION NULL
+CHARACTER_SET_NAME NULL
+COLLATION_NAME NULL
+DTD_IDENTIFIER "t1"%ROWTYPE
+ROUTINE_TYPE FUNCTION
+-------- --------
+SPECIFIC_CATALOG def
+SPECIFIC_SCHEMA test
+SPECIFIC_NAME f1
+ORDINAL_POSITION 4
+PARAMETER_MODE IN
+PARAMETER_NAME b1
+DATA_TYPE ROW TYPE OF
+CHARACTER_MAXIMUM_LENGTH NULL
+CHARACTER_OCTET_LENGTH NULL
+NUMERIC_PRECISION NULL
+NUMERIC_SCALE NULL
+DATETIME_PRECISION NULL
+CHARACTER_SET_NAME NULL
+COLLATION_NAME NULL
+DTD_IDENTIFIER "test"."t1"%ROWTYPE
+ROUTINE_TYPE FUNCTION
+-------- --------
+SPECIFIC_CATALOG def
+SPECIFIC_SCHEMA test
+SPECIFIC_NAME f1
+ORDINAL_POSITION 5
+PARAMETER_MODE IN
+PARAMETER_NAME d
+DATA_TYPE ROW
+CHARACTER_MAXIMUM_LENGTH NULL
+CHARACTER_OCTET_LENGTH NULL
+NUMERIC_PRECISION NULL
+NUMERIC_SCALE NULL
+DATETIME_PRECISION NULL
+CHARACTER_SET_NAME NULL
+COLLATION_NAME NULL
+DTD_IDENTIFIER ROW
+ROUTINE_TYPE FUNCTION
+-------- --------
+SET sql_mode=DEFAULT;
+SELECT *, '--------' FROM INFORMATION_SCHEMA.PARAMETERS WHERE SPECIFIC_NAME='f1';
+SPECIFIC_CATALOG def
+SPECIFIC_SCHEMA test
+SPECIFIC_NAME f1
+ORDINAL_POSITION 0
+PARAMETER_MODE NULL
+PARAMETER_NAME NULL
+DATA_TYPE int
+CHARACTER_MAXIMUM_LENGTH NULL
+CHARACTER_OCTET_LENGTH NULL
+NUMERIC_PRECISION 10
+NUMERIC_SCALE 0
+DATETIME_PRECISION NULL
+CHARACTER_SET_NAME NULL
+COLLATION_NAME NULL
+DTD_IDENTIFIER int(11)
+ROUTINE_TYPE FUNCTION
+-------- --------
+SPECIFIC_CATALOG def
+SPECIFIC_SCHEMA test
+SPECIFIC_NAME f1
+ORDINAL_POSITION 1
+PARAMETER_MODE IN
+PARAMETER_NAME a0
+DATA_TYPE TYPE OF
+CHARACTER_MAXIMUM_LENGTH NULL
+CHARACTER_OCTET_LENGTH NULL
+NUMERIC_PRECISION NULL
+NUMERIC_SCALE NULL
+DATETIME_PRECISION NULL
+CHARACTER_SET_NAME NULL
+COLLATION_NAME NULL
+DTD_IDENTIFIER "t1"."a"%TYPE
+ROUTINE_TYPE FUNCTION
+-------- --------
+SPECIFIC_CATALOG def
+SPECIFIC_SCHEMA test
+SPECIFIC_NAME f1
+ORDINAL_POSITION 2
+PARAMETER_MODE IN
+PARAMETER_NAME a1
+DATA_TYPE TYPE OF
+CHARACTER_MAXIMUM_LENGTH NULL
+CHARACTER_OCTET_LENGTH NULL
+NUMERIC_PRECISION NULL
+NUMERIC_SCALE NULL
+DATETIME_PRECISION NULL
+CHARACTER_SET_NAME NULL
+COLLATION_NAME NULL
+DTD_IDENTIFIER "test"."t1"."a"%TYPE
+ROUTINE_TYPE FUNCTION
+-------- --------
+SPECIFIC_CATALOG def
+SPECIFIC_SCHEMA test
+SPECIFIC_NAME f1
+ORDINAL_POSITION 3
+PARAMETER_MODE IN
+PARAMETER_NAME b0
+DATA_TYPE ROW TYPE OF
+CHARACTER_MAXIMUM_LENGTH NULL
+CHARACTER_OCTET_LENGTH NULL
+NUMERIC_PRECISION NULL
+NUMERIC_SCALE NULL
+DATETIME_PRECISION NULL
+CHARACTER_SET_NAME NULL
+COLLATION_NAME NULL
+DTD_IDENTIFIER "t1"%ROWTYPE
+ROUTINE_TYPE FUNCTION
+-------- --------
+SPECIFIC_CATALOG def
+SPECIFIC_SCHEMA test
+SPECIFIC_NAME f1
+ORDINAL_POSITION 4
+PARAMETER_MODE IN
+PARAMETER_NAME b1
+DATA_TYPE ROW TYPE OF
+CHARACTER_MAXIMUM_LENGTH NULL
+CHARACTER_OCTET_LENGTH NULL
+NUMERIC_PRECISION NULL
+NUMERIC_SCALE NULL
+DATETIME_PRECISION NULL
+CHARACTER_SET_NAME NULL
+COLLATION_NAME NULL
+DTD_IDENTIFIER "test"."t1"%ROWTYPE
+ROUTINE_TYPE FUNCTION
+-------- --------
+SPECIFIC_CATALOG def
+SPECIFIC_SCHEMA test
+SPECIFIC_NAME f1
+ORDINAL_POSITION 5
+PARAMETER_MODE IN
+PARAMETER_NAME d
+DATA_TYPE ROW
+CHARACTER_MAXIMUM_LENGTH NULL
+CHARACTER_OCTET_LENGTH NULL
+NUMERIC_PRECISION NULL
+NUMERIC_SCALE NULL
+DATETIME_PRECISION NULL
+CHARACTER_SET_NAME NULL
+COLLATION_NAME NULL
+DTD_IDENTIFIER ROW
+ROUTINE_TYPE FUNCTION
+-------- --------
+DROP FUNCTION f1;
+# Create in sql_mode=DEFAULT, display in sql_mode=DEFAULT and sql_mode=ORACLE
+SET sql_mode=DEFAULT;
+CREATE PROCEDURE p1(a0 TYPE OF t1.a,
+a1 TYPE OF test.t1.a,
+b0 ROW TYPE OF t1,
+b1 ROW TYPE OF test.t1,
+d ROW(a INT,b DOUBLE))
+BEGIN
+END;
+$$
+SET sql_mode=DEFAULT;
+SELECT *, '--------' FROM INFORMATION_SCHEMA.PARAMETERS WHERE SPECIFIC_NAME='p1';
+SPECIFIC_CATALOG def
+SPECIFIC_SCHEMA test
+SPECIFIC_NAME p1
+ORDINAL_POSITION 1
+PARAMETER_MODE IN
+PARAMETER_NAME a0
+DATA_TYPE TYPE OF
+CHARACTER_MAXIMUM_LENGTH NULL
+CHARACTER_OCTET_LENGTH NULL
+NUMERIC_PRECISION NULL
+NUMERIC_SCALE NULL
+DATETIME_PRECISION NULL
+CHARACTER_SET_NAME NULL
+COLLATION_NAME NULL
+DTD_IDENTIFIER TYPE OF `t1`.`a`
+ROUTINE_TYPE PROCEDURE
+-------- --------
+SPECIFIC_CATALOG def
+SPECIFIC_SCHEMA test
+SPECIFIC_NAME p1
+ORDINAL_POSITION 2
+PARAMETER_MODE IN
+PARAMETER_NAME a1
+DATA_TYPE TYPE OF
+CHARACTER_MAXIMUM_LENGTH NULL
+CHARACTER_OCTET_LENGTH NULL
+NUMERIC_PRECISION NULL
+NUMERIC_SCALE NULL
+DATETIME_PRECISION NULL
+CHARACTER_SET_NAME NULL
+COLLATION_NAME NULL
+DTD_IDENTIFIER TYPE OF `test`.`t1`.`a`
+ROUTINE_TYPE PROCEDURE
+-------- --------
+SPECIFIC_CATALOG def
+SPECIFIC_SCHEMA test
+SPECIFIC_NAME p1
+ORDINAL_POSITION 3
+PARAMETER_MODE IN
+PARAMETER_NAME b0
+DATA_TYPE ROW TYPE OF
+CHARACTER_MAXIMUM_LENGTH NULL
+CHARACTER_OCTET_LENGTH NULL
+NUMERIC_PRECISION NULL
+NUMERIC_SCALE NULL
+DATETIME_PRECISION NULL
+CHARACTER_SET_NAME NULL
+COLLATION_NAME NULL
+DTD_IDENTIFIER ROW TYPE OF `t1`
+ROUTINE_TYPE PROCEDURE
+-------- --------
+SPECIFIC_CATALOG def
+SPECIFIC_SCHEMA test
+SPECIFIC_NAME p1
+ORDINAL_POSITION 4
+PARAMETER_MODE IN
+PARAMETER_NAME b1
+DATA_TYPE ROW TYPE OF
+CHARACTER_MAXIMUM_LENGTH NULL
+CHARACTER_OCTET_LENGTH NULL
+NUMERIC_PRECISION NULL
+NUMERIC_SCALE NULL
+DATETIME_PRECISION NULL
+CHARACTER_SET_NAME NULL
+COLLATION_NAME NULL
+DTD_IDENTIFIER ROW TYPE OF `test`.`t1`
+ROUTINE_TYPE PROCEDURE
+-------- --------
+SPECIFIC_CATALOG def
+SPECIFIC_SCHEMA test
+SPECIFIC_NAME p1
+ORDINAL_POSITION 5
+PARAMETER_MODE IN
+PARAMETER_NAME d
+DATA_TYPE ROW
+CHARACTER_MAXIMUM_LENGTH NULL
+CHARACTER_OCTET_LENGTH NULL
+NUMERIC_PRECISION NULL
+NUMERIC_SCALE NULL
+DATETIME_PRECISION NULL
+CHARACTER_SET_NAME NULL
+COLLATION_NAME NULL
+DTD_IDENTIFIER ROW
+ROUTINE_TYPE PROCEDURE
+-------- --------
+SET sql_mode=ORACLE;
+SELECT *, '--------' FROM INFORMATION_SCHEMA.PARAMETERS WHERE SPECIFIC_NAME='p1';
+SPECIFIC_CATALOG def
+SPECIFIC_SCHEMA test
+SPECIFIC_NAME p1
+ORDINAL_POSITION 1
+PARAMETER_MODE IN
+PARAMETER_NAME a0
+DATA_TYPE TYPE OF
+CHARACTER_MAXIMUM_LENGTH NULL
+CHARACTER_OCTET_LENGTH NULL
+NUMERIC_PRECISION NULL
+NUMERIC_SCALE NULL
+DATETIME_PRECISION NULL
+CHARACTER_SET_NAME NULL
+COLLATION_NAME NULL
+DTD_IDENTIFIER TYPE OF `t1`.`a`
+ROUTINE_TYPE PROCEDURE
+-------- --------
+SPECIFIC_CATALOG def
+SPECIFIC_SCHEMA test
+SPECIFIC_NAME p1
+ORDINAL_POSITION 2
+PARAMETER_MODE IN
+PARAMETER_NAME a1
+DATA_TYPE TYPE OF
+CHARACTER_MAXIMUM_LENGTH NULL
+CHARACTER_OCTET_LENGTH NULL
+NUMERIC_PRECISION NULL
+NUMERIC_SCALE NULL
+DATETIME_PRECISION NULL
+CHARACTER_SET_NAME NULL
+COLLATION_NAME NULL
+DTD_IDENTIFIER TYPE OF `test`.`t1`.`a`
+ROUTINE_TYPE PROCEDURE
+-------- --------
+SPECIFIC_CATALOG def
+SPECIFIC_SCHEMA test
+SPECIFIC_NAME p1
+ORDINAL_POSITION 3
+PARAMETER_MODE IN
+PARAMETER_NAME b0
+DATA_TYPE ROW TYPE OF
+CHARACTER_MAXIMUM_LENGTH NULL
+CHARACTER_OCTET_LENGTH NULL
+NUMERIC_PRECISION NULL
+NUMERIC_SCALE NULL
+DATETIME_PRECISION NULL
+CHARACTER_SET_NAME NULL
+COLLATION_NAME NULL
+DTD_IDENTIFIER ROW TYPE OF `t1`
+ROUTINE_TYPE PROCEDURE
+-------- --------
+SPECIFIC_CATALOG def
+SPECIFIC_SCHEMA test
+SPECIFIC_NAME p1
+ORDINAL_POSITION 4
+PARAMETER_MODE IN
+PARAMETER_NAME b1
+DATA_TYPE ROW TYPE OF
+CHARACTER_MAXIMUM_LENGTH NULL
+CHARACTER_OCTET_LENGTH NULL
+NUMERIC_PRECISION NULL
+NUMERIC_SCALE NULL
+DATETIME_PRECISION NULL
+CHARACTER_SET_NAME NULL
+COLLATION_NAME NULL
+DTD_IDENTIFIER ROW TYPE OF `test`.`t1`
+ROUTINE_TYPE PROCEDURE
+-------- --------
+SPECIFIC_CATALOG def
+SPECIFIC_SCHEMA test
+SPECIFIC_NAME p1
+ORDINAL_POSITION 5
+PARAMETER_MODE IN
+PARAMETER_NAME d
+DATA_TYPE ROW
+CHARACTER_MAXIMUM_LENGTH NULL
+CHARACTER_OCTET_LENGTH NULL
+NUMERIC_PRECISION NULL
+NUMERIC_SCALE NULL
+DATETIME_PRECISION NULL
+CHARACTER_SET_NAME NULL
+COLLATION_NAME NULL
+DTD_IDENTIFIER ROW
+ROUTINE_TYPE PROCEDURE
+-------- --------
+DROP PROCEDURE p1;
+SET sql_mode=DEFAULT;
+CREATE FUNCTION f1(a0 TYPE OF t1.a,
+a1 TYPE OF test.t1.a,
+b0 ROW TYPE OF t1,
+b1 ROW TYPE OF test.t1,
+d ROW(a INT,b DOUBLE))
+RETURNS INT
+BEGIN
+RETURN 0;
+END;
+$$
+SET sql_mode=DEFAULT;
+SELECT *, '--------' FROM INFORMATION_SCHEMA.PARAMETERS WHERE SPECIFIC_NAME='f1';
+SPECIFIC_CATALOG def
+SPECIFIC_SCHEMA test
+SPECIFIC_NAME f1
+ORDINAL_POSITION 0
+PARAMETER_MODE NULL
+PARAMETER_NAME NULL
+DATA_TYPE int
+CHARACTER_MAXIMUM_LENGTH NULL
+CHARACTER_OCTET_LENGTH NULL
+NUMERIC_PRECISION 10
+NUMERIC_SCALE 0
+DATETIME_PRECISION NULL
+CHARACTER_SET_NAME NULL
+COLLATION_NAME NULL
+DTD_IDENTIFIER int(11)
+ROUTINE_TYPE FUNCTION
+-------- --------
+SPECIFIC_CATALOG def
+SPECIFIC_SCHEMA test
+SPECIFIC_NAME f1
+ORDINAL_POSITION 1
+PARAMETER_MODE IN
+PARAMETER_NAME a0
+DATA_TYPE TYPE OF
+CHARACTER_MAXIMUM_LENGTH NULL
+CHARACTER_OCTET_LENGTH NULL
+NUMERIC_PRECISION NULL
+NUMERIC_SCALE NULL
+DATETIME_PRECISION NULL
+CHARACTER_SET_NAME NULL
+COLLATION_NAME NULL
+DTD_IDENTIFIER TYPE OF `t1`.`a`
+ROUTINE_TYPE FUNCTION
+-------- --------
+SPECIFIC_CATALOG def
+SPECIFIC_SCHEMA test
+SPECIFIC_NAME f1
+ORDINAL_POSITION 2
+PARAMETER_MODE IN
+PARAMETER_NAME a1
+DATA_TYPE TYPE OF
+CHARACTER_MAXIMUM_LENGTH NULL
+CHARACTER_OCTET_LENGTH NULL
+NUMERIC_PRECISION NULL
+NUMERIC_SCALE NULL
+DATETIME_PRECISION NULL
+CHARACTER_SET_NAME NULL
+COLLATION_NAME NULL
+DTD_IDENTIFIER TYPE OF `test`.`t1`.`a`
+ROUTINE_TYPE FUNCTION
+-------- --------
+SPECIFIC_CATALOG def
+SPECIFIC_SCHEMA test
+SPECIFIC_NAME f1
+ORDINAL_POSITION 3
+PARAMETER_MODE IN
+PARAMETER_NAME b0
+DATA_TYPE ROW TYPE OF
+CHARACTER_MAXIMUM_LENGTH NULL
+CHARACTER_OCTET_LENGTH NULL
+NUMERIC_PRECISION NULL
+NUMERIC_SCALE NULL
+DATETIME_PRECISION NULL
+CHARACTER_SET_NAME NULL
+COLLATION_NAME NULL
+DTD_IDENTIFIER ROW TYPE OF `t1`
+ROUTINE_TYPE FUNCTION
+-------- --------
+SPECIFIC_CATALOG def
+SPECIFIC_SCHEMA test
+SPECIFIC_NAME f1
+ORDINAL_POSITION 4
+PARAMETER_MODE IN
+PARAMETER_NAME b1
+DATA_TYPE ROW TYPE OF
+CHARACTER_MAXIMUM_LENGTH NULL
+CHARACTER_OCTET_LENGTH NULL
+NUMERIC_PRECISION NULL
+NUMERIC_SCALE NULL
+DATETIME_PRECISION NULL
+CHARACTER_SET_NAME NULL
+COLLATION_NAME NULL
+DTD_IDENTIFIER ROW TYPE OF `test`.`t1`
+ROUTINE_TYPE FUNCTION
+-------- --------
+SPECIFIC_CATALOG def
+SPECIFIC_SCHEMA test
+SPECIFIC_NAME f1
+ORDINAL_POSITION 5
+PARAMETER_MODE IN
+PARAMETER_NAME d
+DATA_TYPE ROW
+CHARACTER_MAXIMUM_LENGTH NULL
+CHARACTER_OCTET_LENGTH NULL
+NUMERIC_PRECISION NULL
+NUMERIC_SCALE NULL
+DATETIME_PRECISION NULL
+CHARACTER_SET_NAME NULL
+COLLATION_NAME NULL
+DTD_IDENTIFIER ROW
+ROUTINE_TYPE FUNCTION
+-------- --------
+SET sql_mode=ORACLE;
+SELECT *, '--------' FROM INFORMATION_SCHEMA.PARAMETERS WHERE SPECIFIC_NAME='f1';
+SPECIFIC_CATALOG def
+SPECIFIC_SCHEMA test
+SPECIFIC_NAME f1
+ORDINAL_POSITION 0
+PARAMETER_MODE NULL
+PARAMETER_NAME NULL
+DATA_TYPE int
+CHARACTER_MAXIMUM_LENGTH NULL
+CHARACTER_OCTET_LENGTH NULL
+NUMERIC_PRECISION 10
+NUMERIC_SCALE 0
+DATETIME_PRECISION NULL
+CHARACTER_SET_NAME NULL
+COLLATION_NAME NULL
+DTD_IDENTIFIER int(11)
+ROUTINE_TYPE FUNCTION
+-------- --------
+SPECIFIC_CATALOG def
+SPECIFIC_SCHEMA test
+SPECIFIC_NAME f1
+ORDINAL_POSITION 1
+PARAMETER_MODE IN
+PARAMETER_NAME a0
+DATA_TYPE TYPE OF
+CHARACTER_MAXIMUM_LENGTH NULL
+CHARACTER_OCTET_LENGTH NULL
+NUMERIC_PRECISION NULL
+NUMERIC_SCALE NULL
+DATETIME_PRECISION NULL
+CHARACTER_SET_NAME NULL
+COLLATION_NAME NULL
+DTD_IDENTIFIER TYPE OF `t1`.`a`
+ROUTINE_TYPE FUNCTION
+-------- --------
+SPECIFIC_CATALOG def
+SPECIFIC_SCHEMA test
+SPECIFIC_NAME f1
+ORDINAL_POSITION 2
+PARAMETER_MODE IN
+PARAMETER_NAME a1
+DATA_TYPE TYPE OF
+CHARACTER_MAXIMUM_LENGTH NULL
+CHARACTER_OCTET_LENGTH NULL
+NUMERIC_PRECISION NULL
+NUMERIC_SCALE NULL
+DATETIME_PRECISION NULL
+CHARACTER_SET_NAME NULL
+COLLATION_NAME NULL
+DTD_IDENTIFIER TYPE OF `test`.`t1`.`a`
+ROUTINE_TYPE FUNCTION
+-------- --------
+SPECIFIC_CATALOG def
+SPECIFIC_SCHEMA test
+SPECIFIC_NAME f1
+ORDINAL_POSITION 3
+PARAMETER_MODE IN
+PARAMETER_NAME b0
+DATA_TYPE ROW TYPE OF
+CHARACTER_MAXIMUM_LENGTH NULL
+CHARACTER_OCTET_LENGTH NULL
+NUMERIC_PRECISION NULL
+NUMERIC_SCALE NULL
+DATETIME_PRECISION NULL
+CHARACTER_SET_NAME NULL
+COLLATION_NAME NULL
+DTD_IDENTIFIER ROW TYPE OF `t1`
+ROUTINE_TYPE FUNCTION
+-------- --------
+SPECIFIC_CATALOG def
+SPECIFIC_SCHEMA test
+SPECIFIC_NAME f1
+ORDINAL_POSITION 4
+PARAMETER_MODE IN
+PARAMETER_NAME b1
+DATA_TYPE ROW TYPE OF
+CHARACTER_MAXIMUM_LENGTH NULL
+CHARACTER_OCTET_LENGTH NULL
+NUMERIC_PRECISION NULL
+NUMERIC_SCALE NULL
+DATETIME_PRECISION NULL
+CHARACTER_SET_NAME NULL
+COLLATION_NAME NULL
+DTD_IDENTIFIER ROW TYPE OF `test`.`t1`
+ROUTINE_TYPE FUNCTION
+-------- --------
+SPECIFIC_CATALOG def
+SPECIFIC_SCHEMA test
+SPECIFIC_NAME f1
+ORDINAL_POSITION 5
+PARAMETER_MODE IN
+PARAMETER_NAME d
+DATA_TYPE ROW
+CHARACTER_MAXIMUM_LENGTH NULL
+CHARACTER_OCTET_LENGTH NULL
+NUMERIC_PRECISION NULL
+NUMERIC_SCALE NULL
+DATETIME_PRECISION NULL
+CHARACTER_SET_NAME NULL
+COLLATION_NAME NULL
+DTD_IDENTIFIER ROW
+ROUTINE_TYPE FUNCTION
+-------- --------
+DROP FUNCTION f1;
diff --git a/mysql-test/suite/compat/oracle/t/information_schema_parameters.test b/mysql-test/suite/compat/oracle/t/information_schema_parameters.test
new file mode 100644
index 00000000000..af241661939
--- /dev/null
+++ b/mysql-test/suite/compat/oracle/t/information_schema_parameters.test
@@ -0,0 +1,94 @@
+
+--echo #
+--echo # MDEV-15416 Crash when reading I_S.PARAMETERS
+--echo #
+
+--echo # Create in sql_mode=ORACLE, display in sql_mode=ORACLE and sql_mode=DEFAULT
+
+SET sql_mode=ORACLE;
+DELIMITER $$;
+CREATE PROCEDURE p1(a0 t1.a%TYPE,
+ a1 test.t1.a%TYPE,
+ b0 t1%ROWTYPE,
+ b1 test.t1%ROWTYPE,
+ d ROW(a INT,b DOUBLE))
+AS
+BEGIN
+ NULL;
+END;
+$$
+DELIMITER ;$$
+--vertical_results
+SET sql_mode=ORACLE;
+SELECT *, '--------' FROM INFORMATION_SCHEMA.PARAMETERS WHERE SPECIFIC_NAME='p1';
+SET sql_mode=DEFAULT;
+SELECT *, '--------' FROM INFORMATION_SCHEMA.PARAMETERS WHERE SPECIFIC_NAME='p1';
+--horizontal_results
+DROP PROCEDURE p1;
+
+
+SET sql_mode=ORACLE;
+DELIMITER $$;
+CREATE FUNCTION f1(a0 t1.a%TYPE,
+ a1 test.t1.a%TYPE,
+ b0 t1%ROWTYPE,
+ b1 test.t1%ROWTYPE,
+ d ROW(a INT,b DOUBLE))
+ RETURN INT
+AS
+BEGIN
+ RETURN 0;
+END;
+$$
+DELIMITER ;$$
+--vertical_results
+SET sql_mode=ORACLE;
+SELECT *, '--------' FROM INFORMATION_SCHEMA.PARAMETERS WHERE SPECIFIC_NAME='f1';
+SET sql_mode=DEFAULT;
+SELECT *, '--------' FROM INFORMATION_SCHEMA.PARAMETERS WHERE SPECIFIC_NAME='f1';
+--horizontal_results
+DROP FUNCTION f1;
+
+
+--echo # Create in sql_mode=DEFAULT, display in sql_mode=DEFAULT and sql_mode=ORACLE
+
+SET sql_mode=DEFAULT;
+DELIMITER $$;
+CREATE PROCEDURE p1(a0 TYPE OF t1.a,
+ a1 TYPE OF test.t1.a,
+ b0 ROW TYPE OF t1,
+ b1 ROW TYPE OF test.t1,
+ d ROW(a INT,b DOUBLE))
+BEGIN
+END;
+$$
+DELIMITER ;$$
+--vertical_results
+SET sql_mode=DEFAULT;
+SELECT *, '--------' FROM INFORMATION_SCHEMA.PARAMETERS WHERE SPECIFIC_NAME='p1';
+SET sql_mode=ORACLE;
+SELECT *, '--------' FROM INFORMATION_SCHEMA.PARAMETERS WHERE SPECIFIC_NAME='p1';
+--horizontal_results
+DROP PROCEDURE p1;
+
+
+SET sql_mode=DEFAULT;
+DELIMITER $$;
+CREATE FUNCTION f1(a0 TYPE OF t1.a,
+ a1 TYPE OF test.t1.a,
+ b0 ROW TYPE OF t1,
+ b1 ROW TYPE OF test.t1,
+ d ROW(a INT,b DOUBLE))
+ RETURNS INT
+BEGIN
+ RETURN 0;
+END;
+$$
+DELIMITER ;$$
+--vertical_results
+SET sql_mode=DEFAULT;
+SELECT *, '--------' FROM INFORMATION_SCHEMA.PARAMETERS WHERE SPECIFIC_NAME='f1';
+SET sql_mode=ORACLE;
+SELECT *, '--------' FROM INFORMATION_SCHEMA.PARAMETERS WHERE SPECIFIC_NAME='f1';
+--horizontal_results
+DROP FUNCTION f1;
diff --git a/mysql-test/t/information_schema_parameters.test b/mysql-test/t/information_schema_parameters.test
index 3f0b11cba5f..bf25a6757f0 100644
--- a/mysql-test/t/information_schema_parameters.test
+++ b/mysql-test/t/information_schema_parameters.test
@@ -249,3 +249,28 @@ WHERE SPECIFIC_SCHEMA = 'i_s_parameters_test' AND SPECIFIC_NAME = 'test_func5';
# Cleanup
DROP DATABASE i_s_parameters_test;
+USE test;
+
+
+--echo #
+--echo # Start of 10.3 tests
+--echo #
+
+--echo #
+--echo # MDEV-15416 Crash when reading I_S.PARAMETERS
+--echo #
+
+DELIMITER $$;
+CREATE PROCEDURE p1(a0 TYPE OF t1.a,
+ a1 TYPE OF test.t1.a,
+ b0 ROW TYPE OF t1,
+ b1 ROW TYPE OF test.t1,
+ c ROW(a INT,b DOUBLE))
+BEGIN
+END;
+$$
+DELIMITER ;$$
+--vertical_results
+SELECT *, '--------' FROM INFORMATION_SCHEMA.PARAMETERS WHERE SPECIFIC_NAME = 'p1';
+--horizontal_results
+DROP PROCEDURE p1;
diff --git a/sql/field.h b/sql/field.h
index 74d2e2301c4..e69bc3a956f 100644
--- a/sql/field.h
+++ b/sql/field.h
@@ -4169,6 +4169,12 @@ public:
bool is_column_type_ref() const { return m_column_type_ref != 0; }
bool is_table_rowtype_ref() const { return m_table_rowtype_ref != 0; }
bool is_cursor_rowtype_ref() const { return m_cursor_rowtype_ref; }
+ bool is_explicit_data_type() const
+ {
+ return !is_column_type_ref() &&
+ !is_table_rowtype_ref() &&
+ !is_cursor_rowtype_ref();
+ }
class Qualified_column_ident *column_type_ref() const
{
return m_column_type_ref;
diff --git a/sql/sp.cc b/sql/sp.cc
index e2eaf277fd9..f953f70a3e8 100644
--- a/sql/sp.cc
+++ b/sql/sp.cc
@@ -2962,7 +2962,7 @@ Sp_handler::sp_load_for_information_schema(THD *thd, TABLE *proc_table,
defstr.set_charset(creation_ctx->get_client_cs());
if (show_create_sp(thd, &defstr,
sp_name_obj.m_db, sp_name_obj.m_name,
- params, returns, empty_body_lex_cstring(),
+ params, returns, empty_body_lex_cstring(sql_mode),
Sp_chistics(), definer, DDL_options(), sql_mode))
return 0;
@@ -2976,3 +2976,18 @@ Sp_handler::sp_load_for_information_schema(THD *thd, TABLE *proc_table,
return sp;
}
+
+LEX_CSTRING Sp_handler_procedure::empty_body_lex_cstring(sql_mode_t mode) const
+{
+ static LEX_CSTRING m_empty_body_std= {C_STRING_WITH_LEN("BEGIN END")};
+ static LEX_CSTRING m_empty_body_ora= {C_STRING_WITH_LEN("AS BEGIN NULL; END")};
+ return mode & MODE_ORACLE ? m_empty_body_ora : m_empty_body_std;
+}
+
+
+LEX_CSTRING Sp_handler_function::empty_body_lex_cstring(sql_mode_t mode) const
+{
+ static LEX_CSTRING m_empty_body_std= {C_STRING_WITH_LEN("RETURN NULL")};
+ static LEX_CSTRING m_empty_body_ora= {C_STRING_WITH_LEN("AS BEGIN RETURN NULL; END")};
+ return mode & MODE_ORACLE ? m_empty_body_ora : m_empty_body_std;
+}
diff --git a/sql/sp.h b/sql/sp.h
index 0061b18d78b..d256814cb95 100644
--- a/sql/sp.h
+++ b/sql/sp.h
@@ -146,7 +146,7 @@ public:
}
virtual stored_procedure_type type() const= 0;
virtual LEX_CSTRING type_lex_cstring() const= 0;
- virtual LEX_CSTRING empty_body_lex_cstring() const
+ virtual LEX_CSTRING empty_body_lex_cstring(sql_mode_t mode) const
{
static LEX_CSTRING m_empty_body= {C_STRING_WITH_LEN("???")};
DBUG_ASSERT(0);
@@ -244,11 +244,7 @@ public:
static LEX_CSTRING m_type_str= {C_STRING_WITH_LEN("PROCEDURE")};
return m_type_str;
}
- LEX_CSTRING empty_body_lex_cstring() const
- {
- static LEX_CSTRING m_empty_body= {C_STRING_WITH_LEN("BEGIN END")};
- return m_empty_body;
- }
+ LEX_CSTRING empty_body_lex_cstring(sql_mode_t mode) const;
const char *show_create_routine_col1_caption() const
{
return "Procedure";
@@ -298,11 +294,7 @@ public:
static LEX_CSTRING m_type_str= {C_STRING_WITH_LEN("FUNCTION")};
return m_type_str;
}
- LEX_CSTRING empty_body_lex_cstring() const
- {
- static LEX_CSTRING m_empty_body= {C_STRING_WITH_LEN("RETURN NULL")};
- return m_empty_body;
- }
+ LEX_CSTRING empty_body_lex_cstring(sql_mode_t mode) const;
const char *show_create_routine_col1_caption() const
{
return "Function";
@@ -371,7 +363,7 @@ public:
static LEX_CSTRING m_type_str= {C_STRING_WITH_LEN("PACKAGE")};
return m_type_str;
}
- LEX_CSTRING empty_body_lex_cstring() const
+ LEX_CSTRING empty_body_lex_cstring(sql_mode_t mode) const
{
static LEX_CSTRING m_empty_body= {C_STRING_WITH_LEN("BEGIN END")};
return m_empty_body;
@@ -404,7 +396,7 @@ public:
static LEX_CSTRING m_type_str= {C_STRING_WITH_LEN("PACKAGE BODY")};
return m_type_str;
}
- LEX_CSTRING empty_body_lex_cstring() const
+ LEX_CSTRING empty_body_lex_cstring(sql_mode_t mode) const
{
static LEX_CSTRING m_empty_body= {C_STRING_WITH_LEN("BEGIN END")};
return m_empty_body;
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index 71a686efcb8..91fa1c2cbc2 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -58,6 +58,7 @@
#include "sp_head.h"
#include "sp_rcontext.h"
#include "sp_cache.h"
+#include "sql_show.h" // append_identifier
#include "transaction.h"
#include "sql_select.h" /* declares create_tmp_table() */
#include "debug_sync.h"
@@ -7626,4 +7627,20 @@ void Database_qualified_name::copy(MEM_ROOT *mem_root,
}
+bool Table_ident::append_to(THD *thd, String *str) const
+{
+ return (db.length &&
+ (append_identifier(thd, str, db.str, db.length) ||
+ str->append('.'))) ||
+ append_identifier(thd, str, table.str, table.length);
+}
+
+
+bool Qualified_column_ident::append_to(THD *thd, String *str) const
+{
+ return Table_ident::append_to(thd, str) || str->append('.') ||
+ append_identifier(thd, str, m_column.str, m_column.length);
+}
+
+
#endif /* !defined(MYSQL_CLIENT) */
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 57bc7e8a89b..125abce4bf2 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -5607,6 +5607,7 @@ public:
db= *db_name;
}
bool resolve_table_rowtype_ref(THD *thd, Row_definition_list &defs);
+ bool append_to(THD *thd, String *to) const;
};
@@ -5631,6 +5632,7 @@ public:
m_column(*column)
{ }
bool resolve_type_ref(THD *thd, Column_definition *def);
+ bool append_to(THD *thd, String *to) const;
};
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index fb57cb28d66..0408bdab47d 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -5677,6 +5677,118 @@ static void store_column_type(TABLE *table, Field *field, CHARSET_INFO *cs,
}
+/*
+ Print DATA_TYPE independently from sql_mode.
+ It's only a brief human-readable description, without attributes,
+ so it should not be used by client programs to generate SQL scripts.
+*/
+static bool print_anchor_data_type(const Spvar_definition *def,
+ String *data_type)
+{
+ if (def->column_type_ref())
+ return data_type->append(STRING_WITH_LEN("TYPE OF"));
+ if (def->is_table_rowtype_ref())
+ return data_type->append(STRING_WITH_LEN("ROW TYPE OF"));
+ /*
+ "ROW TYPE OF cursor" is not possible yet.
+ May become possible when we add package-wide cursors.
+ */
+ DBUG_ASSERT(0);
+ return false;
+}
+
+
+/*
+ DTD_IDENTIFIER is the full data type description with attributes.
+ It can be used by client programs to generate SQL scripts.
+ Let's print it according to the current sql_mode.
+ It will make output in line with the value in mysql.proc.param_list,
+ so both I_S.XXX.DTD_IDENTIFIER and mysql.proc.param_list use the same notation:
+ default or Oracle, according to the sql_mode at the SP creation time.
+ The caller must make sure to set thd->variables.sql_mode to the routine sql_mode.
+*/
+static bool print_anchor_dtd_identifier(THD *thd, const Spvar_definition *def,
+ String *dtd_identifier)
+{
+ if (def->column_type_ref())
+ return (thd->variables.sql_mode & MODE_ORACLE) ?
+ def->column_type_ref()->append_to(thd, dtd_identifier) ||
+ dtd_identifier->append(STRING_WITH_LEN("%TYPE")) :
+ dtd_identifier->append(STRING_WITH_LEN("TYPE OF ")) ||
+ def->column_type_ref()->append_to(thd, dtd_identifier);
+ if (def->is_table_rowtype_ref())
+ return (thd->variables.sql_mode & MODE_ORACLE) ?
+ def->table_rowtype_ref()->append_to(thd, dtd_identifier) ||
+ dtd_identifier->append(STRING_WITH_LEN("%ROWTYPE")) :
+ dtd_identifier->append(STRING_WITH_LEN("ROW TYPE OF ")) ||
+ def->table_rowtype_ref()->append_to(thd, dtd_identifier);
+ DBUG_ASSERT(0); // See comments in print_anchor_data_type()
+ return false;
+}
+
+
+/*
+ Set columns DATA_TYPE and DTD_IDENTIFIER from an SP variable definition
+*/
+static void store_variable_type(THD *thd, const sp_variable *spvar,
+ TABLE *tmptbl,
+ TABLE_SHARE *tmpshare,
+ CHARSET_INFO *cs,
+ TABLE *table, uint offset)
+{
+ if (spvar->field_def.is_explicit_data_type())
+ {
+ if (spvar->field_def.is_row())
+ {
+ // Explicit ROW
+ table->field[offset]->store(STRING_WITH_LEN("ROW"), cs);
+ table->field[offset]->set_notnull();
+ // Perhaps eventually we need to print all ROW elements in DTD_IDENTIFIER
+ table->field[offset + 8]->store(STRING_WITH_LEN("ROW"), cs);
+ table->field[offset + 8]->set_notnull();
+ }
+ else
+ {
+ // Explicit scalar data type
+ Field *field= spvar->field_def.make_field(tmpshare, thd->mem_root,
+ &spvar->name);
+ field->table= tmptbl;
+ tmptbl->in_use= thd;
+ store_column_type(table, field, cs, offset);
+ }
+ }
+ else
+ {
+ StringBuffer<128> data_type(cs), dtd_identifier(cs);
+
+ if (print_anchor_data_type(&spvar->field_def, &data_type))
+ {
+ table->field[offset]->store(STRING_WITH_LEN("ERROR"), cs); // EOM?
+ table->field[offset]->set_notnull();
+ }
+ else
+ {
+ DBUG_ASSERT(data_type.length());
+ table->field[offset]->store(data_type.ptr(), data_type.length(), cs);
+ table->field[offset]->set_notnull();
+ }
+
+ if (print_anchor_dtd_identifier(thd, &spvar->field_def, &dtd_identifier))
+ {
+ table->field[offset + 8]->store(STRING_WITH_LEN("ERROR"), cs); // EOM?
+ table->field[offset + 8]->set_notnull();
+ }
+ else
+ {
+ DBUG_ASSERT(dtd_identifier.length());
+ table->field[offset + 8]->store(dtd_identifier.ptr(),
+ dtd_identifier.length(), cs);
+ table->field[offset + 8]->set_notnull();
+ }
+ }
+}
+
+
static int get_schema_column_record(THD *thd, TABLE_LIST *tables,
TABLE *table, bool res,
const LEX_CSTRING *db_name,
@@ -6032,6 +6144,7 @@ bool store_schema_params(THD *thd, TABLE *table, TABLE *proc_table,
const Sp_handler *sph;
bool free_sp_head;
bool error= 0;
+ sql_mode_t sql_mode;
DBUG_ENTER("store_schema_params");
bzero((char*) &tbl, sizeof(TABLE));
@@ -6041,6 +6154,7 @@ bool store_schema_params(THD *thd, TABLE *table, TABLE *proc_table,
proc_table->field[MYSQL_PROC_FIELD_DB]->val_str_nopad(thd->mem_root, &db);
proc_table->field[MYSQL_PROC_FIELD_NAME]->val_str_nopad(thd->mem_root, &name);
proc_table->field[MYSQL_PROC_FIELD_DEFINER]->val_str_nopad(thd->mem_root, &definer);
+ sql_mode= (sql_mode_t) proc_table->field[MYSQL_PROC_FIELD_SQL_MODE]->val_int();
sph= Sp_handler::handler((stored_procedure_type) proc_table->field[MYSQL_PROC_MYSQL_TYPE]->val_int());
if (!sph)
sph= &sp_handler_procedure;
@@ -6057,15 +6171,15 @@ bool store_schema_params(THD *thd, TABLE *table, TABLE *proc_table,
proc_table->field[MYSQL_PROC_FIELD_RETURNS]->val_str_nopad(thd->mem_root,
&returns);
sp= sph->sp_load_for_information_schema(thd, proc_table, db, name,
- params, returns,
- (ulong) proc_table->
- field[MYSQL_PROC_FIELD_SQL_MODE]->
- val_int(),
+ params, returns, sql_mode,
&free_sp_head);
if (sp)
{
Field *field;
LEX_CSTRING tmp_string;
+ Sql_mode_save sql_mode_backup(thd);
+ thd->variables.sql_mode= sql_mode;
+
if (sph->type() == TYPE_ENUM_FUNCTION)
{
restore_record(table, s->default_values);
@@ -6124,11 +6238,7 @@ bool store_schema_params(THD *thd, TABLE *table, TABLE *proc_table,
&tmp_string);
table->field[15]->store(tmp_string, cs);
- field= spvar->field_def.make_field(&share, thd->mem_root,
- &spvar->name);
- field->table= &tbl;
- tbl.in_use= thd;
- store_column_type(table, field, cs, 6);
+ store_variable_type(thd, spvar, &tbl, &share, cs, table, 6);
if (schema_table_store_record(thd, table))
{
error= 1;