From a2bb9d263993783923ba8fc83d5b9ddd36dbe09d Mon Sep 17 00:00:00 2001 From: Sergey Vojtovich Date: Thu, 4 Jun 2015 16:04:05 +0400 Subject: [PATCH] MDEV-7505 - Too large scale in DECIMAL dynamic column getter crashes mysqld Server may crash if sanity checks of COLUMN_GET() fail. COLUMN_GET() description generator expects parent CAST item, which may not have been created due to failure of sanity checks. Then further attempt to report an error may crash the server. Fixed COLUMN_GET() description generator to handle such case. --- mysql-test/r/dyncol.result | 6 ++++++ mysql-test/t/dyncol.test | 6 ++++++ sql/item_strfunc.cc | 10 ++++++++++ 3 files changed, 22 insertions(+) diff --git a/mysql-test/r/dyncol.result b/mysql-test/r/dyncol.result index aacb5363717..ca6908f449c 100644 --- a/mysql-test/r/dyncol.result +++ b/mysql-test/r/dyncol.result @@ -1444,3 +1444,9 @@ column_get(column_create(1, "18446744073709552001" as char), 1 as int) Warnings: Warning 1918 Encountered illegal value '18446744073709552001' when converting to INT Note 1105 Cast to signed converted positive out-of-range integer to it's negative complement +# +# MDEV-7505 - Too large scale in DECIMAL dynamic column getter crashes +# mysqld +# +SELECT COLUMN_GET(`x`, 'y' AS DECIMAL(5,34)); +ERROR 42000: Too big scale 34 specified for ''y''. Maximum is 30. diff --git a/mysql-test/t/dyncol.test b/mysql-test/t/dyncol.test index 68e10a5fffe..f0d9467420a 100644 --- a/mysql-test/t/dyncol.test +++ b/mysql-test/t/dyncol.test @@ -643,3 +643,9 @@ SELECT # select column_get(column_create(1, "18446744073709552001" as char), 1 as int); +--echo # +--echo # MDEV-7505 - Too large scale in DECIMAL dynamic column getter crashes +--echo # mysqld +--echo # +--error ER_TOO_BIG_SCALE +SELECT COLUMN_GET(`x`, 'y' AS DECIMAL(5,34)); diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index eedf1499403..aca66fc29e0 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -4467,6 +4467,16 @@ null: void Item_dyncol_get::print(String *str, enum_query_type query_type) { + /* + Parent cast doesn't exist yet, only print dynamic column name. This happens + when called from create_func_cast() / wrong_precision_error(). + */ + if (!str->length()) + { + args[1]->print(str, query_type); + return; + } + /* see create_func_dyncol_get */ DBUG_ASSERT(str->length() >= 5); DBUG_ASSERT(strncmp(str->ptr() + str->length() - 5, "cast(", 5) == 0);