Merge pull request #4198 from edonin/master

Support of Nullable types in MySQL tables
This commit is contained in:
alexey-milovidov 2019-02-10 02:45:45 +03:00 committed by GitHub
commit 5853de4d2b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 32 additions and 26 deletions

View File

@ -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};

View File

@ -6,6 +6,7 @@
#include <DataTypes/DataTypeDateTime.h>
#include <DataTypes/DataTypeFixedString.h>
#include <DataTypes/DataTypeString.h>
#include <DataTypes/DataTypeNullable.h>
#include <Dictionaries/MySQLBlockInputStream.h>
#include <Interpreters/evaluateConstantExpression.h>
#include <Parsers/ASTFunction.h>
@ -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<DataTypeUInt8>();
res = std::make_shared<DataTypeUInt8>();
else
return std::make_shared<DataTypeInt8>();
res = std::make_shared<DataTypeInt8>();
}
if (mysql_data_type == "smallint")
else if (mysql_data_type == "smallint")
{
if (is_unsigned)
return std::make_shared<DataTypeUInt16>();
res = std::make_shared<DataTypeUInt16>();
else
return std::make_shared<DataTypeInt16>();
res = std::make_shared<DataTypeInt16>();
}
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<DataTypeUInt32>();
res = std::make_shared<DataTypeUInt32>();
else
return std::make_shared<DataTypeInt32>();
res = std::make_shared<DataTypeInt32>();
}
if (mysql_data_type == "bigint")
else if (mysql_data_type == "bigint")
{
if (is_unsigned)
return std::make_shared<DataTypeUInt64>();
res = std::make_shared<DataTypeUInt64>();
else
return std::make_shared<DataTypeInt64>();
res = std::make_shared<DataTypeInt64>();
}
if (mysql_data_type == "float")
return std::make_shared<DataTypeFloat32>();
if (mysql_data_type == "double")
return std::make_shared<DataTypeFloat64>();
if (mysql_data_type == "date")
return std::make_shared<DataTypeDate>();
if (mysql_data_type == "datetime" || mysql_data_type == "timestamp")
return std::make_shared<DataTypeDateTime>();
if (mysql_data_type == "binary")
return std::make_shared<DataTypeFixedString>(length);
/// Also String is fallback for all unknown types.
return std::make_shared<DataTypeString>();
else if (mysql_data_type == "float")
res = std::make_shared<DataTypeFloat32>();
else if (mysql_data_type == "double")
res = std::make_shared<DataTypeFloat64>();
else if (mysql_data_type == "date")
res = std::make_shared<DataTypeDate>();
else if (mysql_data_type == "datetime" || mysql_data_type == "timestamp")
res = std::make_shared<DataTypeDateTime>();
else if (mysql_data_type == "binary")
res = std::make_shared<DataTypeFixedString>(length);
else
/// Also String is fallback for all unknown types.
res = std::make_shared<DataTypeString>();
if (is_nullable)
res = std::make_shared<DataTypeNullable>(res);
return res;
}
@ -153,10 +158,10 @@ StoragePtr TableFunctionMySQL::executeImpl(const ASTPtr & ast_function, const Co
(*block.getByPosition(0).column)[i].safeGet<String>(),
getDataType(
(*block.getByPosition(1).column)[i].safeGet<String>(),
(*block.getByPosition(2).column)[i].safeGet<UInt64>() && context.getSettings().external_tables_use_nulls,
(*block.getByPosition(3).column)[i].safeGet<UInt64>(),
(*block.getByPosition(4).column)[i].safeGet<UInt64>()));
/// TODO is_nullable is ignored.
}
auto res = StorageMySQL::create(