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";
|
SET SESSION debug_dbug="+d,frm_data_type_info_emulate";
|
||||||
CREATE TABLE t1 (c01 INT, c02 CHAR(20), c03 TEXT, c04 DOUBLE);
|
CREATE TABLE t1 (c01 INT, c02 CHAR(20), c03 TEXT, c04 DOUBLE);
|
||||||
Warnings:
|
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: [0] name='c01' type_info=''
|
||||||
Note 1105 DBUG: [1] name='c02' type_info='char'
|
Note 1105 DBUG: [1] name='c02' type_info='xchar'
|
||||||
Note 1105 DBUG: [2] name='c03' type_info='blob'
|
Note 1105 DBUG: [2] name='c03' type_info='xblob'
|
||||||
Note 1105 DBUG: [3] name='c04' type_info=''
|
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_emulate";
|
||||||
SET SESSION debug_dbug="-d,frm_data_type_info";
|
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";
|
||||||
SET SESSION debug_dbug="+d,frm_data_type_info_emulate";
|
SET SESSION debug_dbug="+d,frm_data_type_info_emulate";
|
||||||
CREATE TABLE t1 (c01 INT, c02 CHAR(20), c03 TEXT, c04 DOUBLE);
|
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_emulate";
|
||||||
SET SESSION debug_dbug="-d,frm_data_type_info";
|
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 *
|
const Type_handler *
|
||||||
Type_handler::handler_by_name_or_error(const LEX_CSTRING &name)
|
Type_handler::handler_by_name_or_error(const LEX_CSTRING &name)
|
||||||
{
|
{
|
||||||
const Type_handler *h= handler_by_name(name);
|
const Type_handler *h= handler_by_name(name);
|
||||||
if (!h)
|
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),
|
my_error(ER_UNKNOWN_DATA_TYPE, MYF(0),
|
||||||
ErrConvString(name.str, name.length, system_charset_info).ptr());
|
ErrConvString(name.str, name.length, system_charset_info).ptr());
|
||||||
|
}
|
||||||
return h;
|
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)
|
// Have *some* columns write type info (let's use string fields as an example)
|
||||||
DBUG_EXECUTE_IF("frm_data_type_info_emulate",
|
DBUG_EXECUTE_IF("frm_data_type_info_emulate",
|
||||||
if (cmp_type() == STRING_RESULT)
|
if (cmp_type() == STRING_RESULT)
|
||||||
return to->append(name().lex_cstring()););
|
return to->append("x", 1) ||
|
||||||
|
to->append(name().lex_cstring()););
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
25
sql/table.cc
25
sql/table.cc
@ -1632,7 +1632,7 @@ public:
|
|||||||
{
|
{
|
||||||
return m_count;
|
return m_count;
|
||||||
}
|
}
|
||||||
const Elem element(uint i) const
|
const Elem& element(uint i) const
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(i < m_count);
|
DBUG_ASSERT(i < m_count);
|
||||||
return m_array[i];
|
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())
|
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",
|
DBUG_EXECUTE_IF("frm_data_type_info",
|
||||||
push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE,
|
push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE,
|
||||||
ER_UNKNOWN_ERROR, "DBUG: [%u] name='%s' type_info='%.*s'",
|
ER_UNKNOWN_ERROR, "DBUG: [%u] name='%s' type_info='%.*s'",
|
||||||
i, share->fieldnames.type_names[i],
|
i, share->fieldnames.type_names[i],
|
||||||
(uint) field_data_type_info_array.element(i).type_info().length,
|
(uint) info.length, info.str););
|
||||||
field_data_type_info_array.element(i).type_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