diff --git a/dbms/src/Interpreters/Settings.h b/dbms/src/Interpreters/Settings.h index fdeba24b92e..00d31543c6e 100644 --- a/dbms/src/Interpreters/Settings.h +++ b/dbms/src/Interpreters/Settings.h @@ -300,6 +300,7 @@ struct Settings M(SettingBool, allow_experimental_multiple_joins_emulation, false, "Emulate multiple joins using subselects") \ M(SettingBool, allow_experimental_cross_to_join_conversion, false, "Convert CROSS JOIN to INNER JOIN if possible") \ M(SettingBool, cancel_http_readonly_queries_on_client_close, false, "Cancel HTTP readonly queries when a client closes the connection without waiting for response.") \ + M(SettingBool, external_tables_use_nulls, true, "If it is set to true, external tables will implicitly use Nullable type if needed.") \ #define DECLARE(TYPE, NAME, DEFAULT, DESCRIPTION) \ TYPE NAME {DEFAULT}; diff --git a/dbms/src/TableFunctions/TableFunctionMySQL.cpp b/dbms/src/TableFunctions/TableFunctionMySQL.cpp index cccfb76dd80..50fef8844c0 100644 --- a/dbms/src/TableFunctions/TableFunctionMySQL.cpp +++ b/dbms/src/TableFunctions/TableFunctionMySQL.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -34,49 +35,53 @@ namespace ErrorCodes } -DataTypePtr getDataType(const String & mysql_data_type, bool is_unsigned, size_t length) +DataTypePtr getDataType(const String & mysql_data_type, bool is_nullable, bool is_unsigned, size_t length) { + DataTypePtr res; if (mysql_data_type == "tinyint") { if (is_unsigned) - return std::make_shared(); + res = std::make_shared(); else - return std::make_shared(); + res = std::make_shared(); } - if (mysql_data_type == "smallint") + else if (mysql_data_type == "smallint") { if (is_unsigned) - return std::make_shared(); + res = std::make_shared(); else - return std::make_shared(); + res = std::make_shared(); } - if (mysql_data_type == "int" || mysql_data_type == "mediumint") + else if (mysql_data_type == "int" || mysql_data_type == "mediumint") { if (is_unsigned) - return std::make_shared(); + res = std::make_shared(); else - return std::make_shared(); + res = std::make_shared(); } - if (mysql_data_type == "bigint") + else if (mysql_data_type == "bigint") { if (is_unsigned) - return std::make_shared(); + res = std::make_shared(); else - return std::make_shared(); + res = std::make_shared(); } - if (mysql_data_type == "float") - return std::make_shared(); - if (mysql_data_type == "double") - return std::make_shared(); - if (mysql_data_type == "date") - return std::make_shared(); - if (mysql_data_type == "datetime" || mysql_data_type == "timestamp") - return std::make_shared(); - if (mysql_data_type == "binary") - return std::make_shared(length); - - /// Also String is fallback for all unknown types. - return std::make_shared(); + else if (mysql_data_type == "float") + res = std::make_shared(); + else if (mysql_data_type == "double") + res = std::make_shared(); + else if (mysql_data_type == "date") + res = std::make_shared(); + else if (mysql_data_type == "datetime" || mysql_data_type == "timestamp") + res = std::make_shared(); + else if (mysql_data_type == "binary") + res = std::make_shared(length); + else + /// Also String is fallback for all unknown types. + res = std::make_shared(); + if (is_nullable) + res = std::make_shared(res); + return res; } @@ -153,10 +158,10 @@ StoragePtr TableFunctionMySQL::executeImpl(const ASTPtr & ast_function, const Co (*block.getByPosition(0).column)[i].safeGet(), getDataType( (*block.getByPosition(1).column)[i].safeGet(), + (*block.getByPosition(2).column)[i].safeGet() && context.getSettings().external_tables_use_nulls, (*block.getByPosition(3).column)[i].safeGet(), (*block.getByPosition(4).column)[i].safeGet())); - /// TODO is_nullable is ignored. } auto res = StorageMySQL::create(