1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-27 18:02:13 +03:00

MDEV-29968 Functions in default values in tables with some character sets break SHOW CREATE (and mysqldump)

Item:print_for_table_def() uses QT_TO_SYSTEM_CHARSET to print
the DEFAULT expression into FRM file during CREATE TABLE.
Therefore, the expression is encoded in utf8 in FRM.

get_field_default_value() erroneously used field->charset() to
print the DEFAULT expression at SHOW CREATE TABLE time.

Fixing get_field_default_value() to use &my_charset_utf8mb4_general_ci instead.
This makes DEFAULT work in the way way with:

- virtual column expressions:

    if (field->vcol_info)
    {
      StringBuffer<MAX_FIELD_WIDTH> str(&my_charset_utf8mb4_general_ci);
      field->vcol_info->print(&str);

- check constraint expressions:

    if (field->check_constraint)
    {
      StringBuffer<MAX_FIELD_WIDTH> str(&my_charset_utf8mb4_general_ci);
      field->check_constraint->print(&str);

Additional cleanup:
Fixing system_charset_info to &my_charset_utf8mb4_general_ci in a few
places to make non-BMP characters work in DEFAULT, virtual column,
check constraint expressions.
This commit is contained in:
Alexander Barkov
2024-11-26 13:34:28 +04:00
parent f521b8ac21
commit 350cc77fee
24 changed files with 413 additions and 179 deletions

View File

@ -1289,7 +1289,7 @@ mysqld_show_create(THD *thd, TABLE_LIST *table_list)
{
Protocol *protocol= thd->protocol;
char buff[2048];
String buffer(buff, sizeof(buff), system_charset_info);
String buffer(buff, sizeof(buff), &my_charset_utf8mb4_general_ci);
List<Item> field_list;
bool error= TRUE;
DBUG_ENTER("mysqld_show_create");
@ -1709,7 +1709,7 @@ static bool get_field_default_value(THD *thd, Field *field, String *def_value,
def_value->length(0);
if (has_default)
{
StringBuffer<MAX_FIELD_WIDTH> str(field->charset());
StringBuffer<MAX_FIELD_WIDTH> str(&my_charset_utf8mb4_general_ci);
if (field->default_value)
{
field->default_value->print(&str);
@ -2236,11 +2236,11 @@ int show_create_table_ex(THD *thd, TABLE_LIST *table_list,
{
packet->append(STRING_WITH_LEN(" INVISIBLE"));
}
def_value.set(def_value_buf, sizeof(def_value_buf), system_charset_info);
def_value.set(def_value_buf, sizeof(def_value_buf), &my_charset_utf8mb4_general_ci);
if (get_field_default_value(thd, field, &def_value, 1))
{
packet->append(STRING_WITH_LEN(" DEFAULT "));
packet->append(def_value.ptr(), def_value.length(), system_charset_info);
packet->append(def_value.ptr(), def_value.length(), &my_charset_utf8mb4_general_ci);
}
if (field->vers_update_unversioned())