mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
A cleanup for MDEV-20042 Implement EXTRA2_FIELD_DATA_TYPE_INFO in FRM
Adding error reporting (ER_UNKNOWN_DATA_TYPE) when a handler name read from EXTRA2_FIELD_DATA_TYPE_INFO is not known to the server.
This commit is contained in:
@ -11,11 +11,14 @@ SET SESSION debug_dbug="+d,frm_data_type_info";
|
||||
SET SESSION debug_dbug="+d,frm_data_type_info_emulate";
|
||||
CREATE TABLE t1 (c01 INT, c02 CHAR(20), c03 TEXT, c04 DOUBLE);
|
||||
Warnings:
|
||||
Note 1105 build_frm_image: Field data type info length: 12
|
||||
Note 1105 build_frm_image: Field data type info length: 14
|
||||
Note 1105 DBUG: [0] name='c01' type_info=''
|
||||
Note 1105 DBUG: [1] name='c02' type_info='char'
|
||||
Note 1105 DBUG: [2] name='c03' type_info='blob'
|
||||
Note 1105 DBUG: [1] name='c02' type_info='xchar'
|
||||
Note 1105 DBUG: [2] name='c03' type_info='xblob'
|
||||
Note 1105 DBUG: [3] name='c04' type_info=''
|
||||
DROP TABLE t1;
|
||||
SET SESSION debug_dbug="-d,frm_data_type_info_emulate";
|
||||
SET SESSION debug_dbug="-d,frm_data_type_info";
|
||||
FLUSH TABLES;
|
||||
SHOW CREATE TABLE t1;
|
||||
ERROR HY000: Unknown data type: 'xchar'
|
||||
DROP TABLE t1;
|
||||
|
@ -14,6 +14,9 @@ SET SESSION debug_dbug="-d,frm_data_type_info";
|
||||
SET SESSION debug_dbug="+d,frm_data_type_info";
|
||||
SET SESSION debug_dbug="+d,frm_data_type_info_emulate";
|
||||
CREATE TABLE t1 (c01 INT, c02 CHAR(20), c03 TEXT, c04 DOUBLE);
|
||||
DROP TABLE t1;
|
||||
SET SESSION debug_dbug="-d,frm_data_type_info_emulate";
|
||||
SET SESSION debug_dbug="-d,frm_data_type_info";
|
||||
FLUSH TABLES;
|
||||
--error ER_UNKNOWN_DATA_TYPE
|
||||
SHOW CREATE TABLE t1;
|
||||
DROP TABLE t1;
|
||||
|
@ -200,13 +200,31 @@ Type_handler::handler_by_name(const LEX_CSTRING &name)
|
||||
}
|
||||
|
||||
|
||||
#ifndef DBUG_OFF
|
||||
static const Type_handler *frm_data_type_info_emulate(const LEX_CSTRING &name)
|
||||
{
|
||||
if (Name(STRING_WITH_LEN("xchar")).eq(name))
|
||||
return &type_handler_string;
|
||||
if (Name(STRING_WITH_LEN("xblob")).eq(name))
|
||||
return &type_handler_blob;
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
const Type_handler *
|
||||
Type_handler::handler_by_name_or_error(const LEX_CSTRING &name)
|
||||
{
|
||||
const Type_handler *h= handler_by_name(name);
|
||||
if (!h)
|
||||
{
|
||||
DBUG_EXECUTE_IF("frm_data_type_info_emulate",
|
||||
if ((h= frm_data_type_info_emulate(name)))
|
||||
return h;
|
||||
);
|
||||
my_error(ER_UNKNOWN_DATA_TYPE, MYF(0),
|
||||
ErrConvString(name.str, name.length, system_charset_info).ptr());
|
||||
}
|
||||
return h;
|
||||
}
|
||||
|
||||
@ -8845,7 +8863,8 @@ bool Type_handler::Column_definition_data_type_info_image(Binary_string *to,
|
||||
// Have *some* columns write type info (let's use string fields as an example)
|
||||
DBUG_EXECUTE_IF("frm_data_type_info_emulate",
|
||||
if (cmp_type() == STRING_RESULT)
|
||||
return to->append(name().lex_cstring()););
|
||||
return to->append("x", 1) ||
|
||||
to->append(name().lex_cstring()););
|
||||
return false;
|
||||
}
|
||||
|
||||
|
25
sql/table.cc
25
sql/table.cc
@ -1632,7 +1632,7 @@ public:
|
||||
{
|
||||
return m_count;
|
||||
}
|
||||
const Elem element(uint i) const
|
||||
const Elem& element(uint i) const
|
||||
{
|
||||
DBUG_ASSERT(i < m_count);
|
||||
return m_array[i];
|
||||
@ -2340,12 +2340,31 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
|
||||
|
||||
if (field_data_type_info_array.count())
|
||||
{
|
||||
const LEX_CSTRING &info= field_data_type_info_array.
|
||||
element(i).type_info();
|
||||
DBUG_EXECUTE_IF("frm_data_type_info",
|
||||
push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE,
|
||||
ER_UNKNOWN_ERROR, "DBUG: [%u] name='%s' type_info='%.*s'",
|
||||
i, share->fieldnames.type_names[i],
|
||||
(uint) field_data_type_info_array.element(i).type_info().length,
|
||||
field_data_type_info_array.element(i).type_info().str););
|
||||
(uint) info.length, info.str););
|
||||
|
||||
if (info.length)
|
||||
{
|
||||
const Type_handler *h= Type_handler::handler_by_name_or_error(info);
|
||||
/*
|
||||
This code will eventually be extended here:
|
||||
- If the handler was not found by name, we could
|
||||
still open the table using the fallback type handler "handler",
|
||||
at least for a limited set of commands.
|
||||
- If the handler was found by name, we could check
|
||||
that "h" and "handler" have the same type code
|
||||
(and maybe some other properties) to make sure
|
||||
that the FRM data is consistent.
|
||||
*/
|
||||
if (!h)
|
||||
goto err;
|
||||
handler= h;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user