diff options
author | Nikita Malyavin <nikitamalyavin@gmail.com> | 2021-06-28 20:59:29 +0300 |
---|---|---|
committer | Nikita Malyavin <nikitamalyavin@gmail.com> | 2021-07-22 22:35:23 +0300 |
commit | dba7cd25e1449298f3122286dbf73f1b84bbdc5c (patch) | |
tree | 95a663fdf01becbff1eabc86447fe0072521c06f | |
parent | b50ea900636ba8d584b997649dd201014152f719 (diff) | |
download | mariadb-git-bb-10.3-MDEV-25560.tar.gz |
MDEV-25560 Creating table with certain generated column crashes serverbb-10.3-MDEV-25560
Fix RPAD() handling without 3rd argument of padding, in which case default
padding is used.
-rw-r--r-- | mysql-test/main/func_str.result | 16 | ||||
-rw-r--r-- | mysql-test/main/func_str.test | 18 | ||||
-rw-r--r-- | sql/item_strfunc.cc | 19 |
3 files changed, 47 insertions, 6 deletions
diff --git a/mysql-test/main/func_str.result b/mysql-test/main/func_str.result index 9e63f6e4580..eccec315a45 100644 --- a/mysql-test/main/func_str.result +++ b/mysql-test/main/func_str.result @@ -5153,5 +5153,21 @@ c1 42 DROP TABLE t1, t2; # +# MDEV-25560 Creating table with certain generated column crashes server +# +CREATE TABLE t1 (i int, b int AS (RPAD(123,1)) stored); +# Original case from the reporter +CREATE TABLE crash_test_2 ( +DATA_VALUE CHAR(10) NULL, +HAS_DATA BIT NOT NULL, +TEST_COLUMN CHAR(10) AS (RPAD(CASE WHEN HAS_DATA = 1 +THEN DATA_VALUE ELSE NULL END, 10)) STORED); +Warnings: +Warning 1901 Function or expression 'rpad(case when `HAS_DATA` = 1 then `DATA_VALUE` else NULL end,10)' cannot be used in the GENERATED ALWAYS AS clause of `TEST_COLUMN` +Warning 1105 Expression depends on the @@sql_mode value PAD_CHAR_TO_FULL_LENGTH +# Cleanup +DROP TABLE t1; +DROP TABLE crash_test_2; +# # End of 10.3 tests # diff --git a/mysql-test/main/func_str.test b/mysql-test/main/func_str.test index 780783e316f..8f8628f7142 100644 --- a/mysql-test/main/func_str.test +++ b/mysql-test/main/func_str.test @@ -2091,5 +2091,23 @@ DROP TABLE t1, t2; --echo # +--echo # MDEV-25560 Creating table with certain generated column crashes server +--echo # + +CREATE TABLE t1 (i int, b int AS (RPAD(123,1)) stored); + +--echo # Original case from the reporter +CREATE TABLE crash_test_2 ( + DATA_VALUE CHAR(10) NULL, + HAS_DATA BIT NOT NULL, + TEST_COLUMN CHAR(10) AS (RPAD(CASE WHEN HAS_DATA = 1 + THEN DATA_VALUE ELSE NULL END, 10)) STORED); + +--echo # Cleanup +DROP TABLE t1; +DROP TABLE crash_test_2; + + +--echo # --echo # End of 10.3 tests --echo # diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 0e63bb2a50c..361feb9055d 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -3192,6 +3192,14 @@ err: } +static String *default_pad_str(String *pad_str, CHARSET_INFO *collation) +{ + pad_str->set_charset(collation); + pad_str->length(0); + pad_str->append(" ", 1); + return pad_str; +} + bool Item_func_pad::fix_length_and_dec() { if (arg_count == 3) @@ -3207,9 +3215,7 @@ bool Item_func_pad::fix_length_and_dec() { if (agg_arg_charsets_for_string_result(collation, &args[0], 1, 1)) return TRUE; - pad_str.set_charset(collation.collation); - pad_str.length(0); - pad_str.append(" ", 1); + default_pad_str(&pad_str, collation.collation); } DBUG_ASSERT(collation.collation->mbmaxlen > 0); @@ -3232,9 +3238,9 @@ bool Item_func_pad::fix_length_and_dec() Sql_mode_dependency Item_func_rpad::value_depends_on_sql_mode() const { DBUG_ASSERT(fixed); - DBUG_ASSERT(arg_count == 3); + DBUG_ASSERT(arg_count >= 2); if (!args[1]->value_depends_on_sql_mode_const_item() || - !args[2]->value_depends_on_sql_mode_const_item()) + (arg_count == 3 && !args[2]->value_depends_on_sql_mode_const_item())) return Item_func::value_depends_on_sql_mode(); Longlong_hybrid len= args[1]->to_longlong_hybrid(); if (args[1]->null_value || len.neg()) @@ -3242,7 +3248,8 @@ Sql_mode_dependency Item_func_rpad::value_depends_on_sql_mode() const if (len.abs() > 0 && len.abs() < args[0]->max_char_length()) return Item_func::value_depends_on_sql_mode(); StringBuffer<64> padstrbuf; - String *padstr= args[2]->val_str(&padstrbuf); + String *padstr= arg_count == 3 ? args[2]->val_str(&padstrbuf) : + default_pad_str(&padstrbuf, collation.collation); if (!padstr || !padstr->length()) return Sql_mode_dependency(); // will return NULL if (padstr->lengthsp() != 0) |