Commit dba7cd25 authored by Nikita Malyavin's avatar Nikita Malyavin

MDEV-25560 Creating table with certain generated column crashes server

Fix RPAD() handling without 3rd argument of padding, in which case default
padding is used.
parent b50ea900
...@@ -5153,5 +5153,21 @@ c1 ...@@ -5153,5 +5153,21 @@ c1
42 42
DROP TABLE t1, t2; 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 # End of 10.3 tests
# #
...@@ -2090,6 +2090,24 @@ SELECT c1 FROM t2; ...@@ -2090,6 +2090,24 @@ SELECT c1 FROM t2;
DROP TABLE t1, t2; 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 #
--echo # End of 10.3 tests --echo # End of 10.3 tests
--echo # --echo #
...@@ -3192,6 +3192,14 @@ String *Item_func_binlog_gtid_pos::val_str(String *str) ...@@ -3192,6 +3192,14 @@ String *Item_func_binlog_gtid_pos::val_str(String *str)
} }
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() bool Item_func_pad::fix_length_and_dec()
{ {
if (arg_count == 3) if (arg_count == 3)
...@@ -3207,9 +3215,7 @@ bool Item_func_pad::fix_length_and_dec() ...@@ -3207,9 +3215,7 @@ bool Item_func_pad::fix_length_and_dec()
{ {
if (agg_arg_charsets_for_string_result(collation, &args[0], 1, 1)) if (agg_arg_charsets_for_string_result(collation, &args[0], 1, 1))
return TRUE; return TRUE;
pad_str.set_charset(collation.collation); default_pad_str(&pad_str, collation.collation);
pad_str.length(0);
pad_str.append(" ", 1);
} }
DBUG_ASSERT(collation.collation->mbmaxlen > 0); DBUG_ASSERT(collation.collation->mbmaxlen > 0);
...@@ -3232,9 +3238,9 @@ bool Item_func_pad::fix_length_and_dec() ...@@ -3232,9 +3238,9 @@ bool Item_func_pad::fix_length_and_dec()
Sql_mode_dependency Item_func_rpad::value_depends_on_sql_mode() const Sql_mode_dependency Item_func_rpad::value_depends_on_sql_mode() const
{ {
DBUG_ASSERT(fixed); DBUG_ASSERT(fixed);
DBUG_ASSERT(arg_count == 3); DBUG_ASSERT(arg_count >= 2);
if (!args[1]->value_depends_on_sql_mode_const_item() || 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(); return Item_func::value_depends_on_sql_mode();
Longlong_hybrid len= args[1]->to_longlong_hybrid(); Longlong_hybrid len= args[1]->to_longlong_hybrid();
if (args[1]->null_value || len.neg()) if (args[1]->null_value || len.neg())
...@@ -3242,7 +3248,8 @@ Sql_mode_dependency Item_func_rpad::value_depends_on_sql_mode() const ...@@ -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()) if (len.abs() > 0 && len.abs() < args[0]->max_char_length())
return Item_func::value_depends_on_sql_mode(); return Item_func::value_depends_on_sql_mode();
StringBuffer<64> padstrbuf; 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()) if (!padstr || !padstr->length())
return Sql_mode_dependency(); // will return NULL return Sql_mode_dependency(); // will return NULL
if (padstr->lengthsp() != 0) if (padstr->lengthsp() != 0)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment