summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Barkov <bar@mariadb.com>2019-10-02 18:10:58 +0400
committerAlexander Barkov <bar@mariadb.com>2019-10-02 18:10:58 +0400
commitcefe5bb6b3be80df51e9580445b5c299abe61e60 (patch)
treed6fabf3b2b4072b5c06640004ee0a6a2f70770a2
parent5e356ce707610976e3267b8eada509f993ff8833 (diff)
downloadmariadb-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.result11
-rw-r--r--mysql-test/main/frm-debug.test5
-rw-r--r--sql/sql_type.cc21
-rw-r--r--sql/table.cc25
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;
+ }
}
}