diff options
author | Alexander Barkov <bar@mariadb.org> | 2018-02-28 23:05:57 +0400 |
---|---|---|
committer | Alexander Barkov <bar@mariadb.org> | 2018-02-28 23:05:57 +0400 |
commit | 4025cfaec038594bfc97bea48aa2cfe139930cc2 (patch) | |
tree | 32644046fec0cd33ea703f891ecc11ad6329247a | |
parent | 5f7c764fe79501635c5f7695f6cb22fa69466c63 (diff) | |
download | mariadb-git-4025cfaec038594bfc97bea48aa2cfe139930cc2.tar.gz |
MDEV-15416 Crash when reading I_S.PARAMETERS
-rw-r--r-- | mysql-test/r/information_schema_parameters.result | 102 | ||||
-rw-r--r-- | mysql-test/suite/compat/oracle/r/information_schema_parameters.result | 816 | ||||
-rw-r--r-- | mysql-test/suite/compat/oracle/t/information_schema_parameters.test | 94 | ||||
-rw-r--r-- | mysql-test/t/information_schema_parameters.test | 25 | ||||
-rw-r--r-- | sql/field.h | 6 | ||||
-rw-r--r-- | sql/sp.cc | 17 | ||||
-rw-r--r-- | sql/sp.h | 18 | ||||
-rw-r--r-- | sql/sql_class.cc | 17 | ||||
-rw-r--r-- | sql/sql_class.h | 2 | ||||
-rw-r--r-- | sql/sql_show.cc | 128 |
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; +} @@ -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; |