summaryrefslogtreecommitdiff
path: root/sql/table.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/table.cc')
-rw-r--r--sql/table.cc22
1 files changed, 19 insertions, 3 deletions
diff --git a/sql/table.cc b/sql/table.cc
index 561b7fb9ff4..a9e75b066f5 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -1,5 +1,5 @@
/* Copyright (c) 2000, 2017, Oracle and/or its affiliates.
- Copyright (c) 2008, 2021, MariaDB
+ Copyright (c) 2008, 2022, MariaDB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -1741,6 +1741,7 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
Field_data_type_info_array field_data_type_info_array;
MEM_ROOT *old_root= thd->mem_root;
Virtual_column_info **table_check_constraints;
+ bool *interval_unescaped= NULL;
extra2_fields extra2;
DBUG_ENTER("TABLE_SHARE::init_from_binary_frm_image");
@@ -2181,6 +2182,13 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
goto err;
+ if (interval_count)
+ {
+ if (!(interval_unescaped= (bool*) my_alloca(interval_count * sizeof(bool))))
+ goto err;
+ bzero(interval_unescaped, interval_count * sizeof(bool));
+ }
+
field_ptr= share->field;
table_check_constraints= share->check_constraints;
read_length=(uint) (share->fields * field_pack_length +
@@ -2532,11 +2540,17 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
if (share->mysql_version < 100200)
attr.pack_flag&= ~FIELDFLAG_LONG_DECIMAL;
- if (interval_nr && attr.charset->mbminlen > 1)
+ if (interval_nr && attr.charset->mbminlen > 1 &&
+ !interval_unescaped[interval_nr - 1])
{
- /* Unescape UCS2 intervals from HEX notation */
+ /*
+ Unescape UCS2/UTF16/UTF32 intervals from HEX notation.
+ Note, ENUM/SET columns with equal value list share a single
+ copy of TYPELIB. Unescape every TYPELIB only once.
+ */
TYPELIB *interval= share->intervals + interval_nr - 1;
unhex_type2(interval);
+ interval_unescaped[interval_nr - 1]= true;
}
#ifndef TO_BE_DELETED_ON_PRODUCTION
@@ -3256,6 +3270,7 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
share->error= OPEN_FRM_OK;
thd->status_var.opened_shares++;
thd->mem_root= old_root;
+ my_afree(interval_unescaped);
DBUG_RETURN(0);
err:
@@ -3283,6 +3298,7 @@ err:
open_table_error(share, OPEN_FRM_CORRUPTED, share->open_errno);
thd->mem_root= old_root;
+ my_afree(interval_unescaped);
DBUG_RETURN(HA_ERR_NOT_A_TABLE);
}