Commit cefe5bb6 authored by Alexander Barkov's avatar Alexander Barkov

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.
parent 5e356ce7
......@@ -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;
}
......
......@@ -1632,7 +1632,7 @@ class Field_data_type_info_array
{
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;
}
}
}
......
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