diff options
author | Alexander Barkov <bar@mariadb.com> | 2019-10-02 18:10:58 +0400 |
---|---|---|
committer | Alexander Barkov <bar@mariadb.com> | 2019-10-02 18:10:58 +0400 |
commit | cefe5bb6b3be80df51e9580445b5c299abe61e60 (patch) | |
tree | d6fabf3b2b4072b5c06640004ee0a6a2f70770a2 | |
parent | 5e356ce707610976e3267b8eada509f993ff8833 (diff) | |
download | mariadb-git-cefe5bb6b3be80df51e9580445b5c299abe61e60.tar.gz |
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.
-rw-r--r-- | mysql-test/main/frm-debug.result | 11 | ||||
-rw-r--r-- | mysql-test/main/frm-debug.test | 5 | ||||
-rw-r--r-- | sql/sql_type.cc | 21 | ||||
-rw-r--r-- | sql/table.cc | 25 |
4 files changed, 53 insertions, 9 deletions
diff --git a/mysql-test/main/frm-debug.result b/mysql-test/main/frm-debug.result index d4d71caacbd..332d7e00a8f 100644 --- a/mysql-test/main/frm-debug.result +++ b/mysql-test/main/frm-debug.result @@ -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; diff --git a/mysql-test/main/frm-debug.test b/mysql-test/main/frm-debug.test index 95207354bdc..d86acdbc7e3 100644 --- a/mysql-test/main/frm-debug.test +++ b/mysql-test/main/frm-debug.test @@ -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; diff --git a/sql/sql_type.cc b/sql/sql_type.cc index 05cef27e0da..9b4cd1b0c48 100644 --- a/sql/sql_type.cc +++ b/sql/sql_type.cc @@ -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; } diff --git a/sql/table.cc b/sql/table.cc index 6c4d01852f5..55ffc1142ea 100644 --- a/sql/table.cc +++ b/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; + } } } |