Further simplify the type compatibility checking code

This commit is contained in:
Alexey Arno 2014-12-14 22:43:37 +03:00
parent b857667cc2
commit 72ca080f64
6 changed files with 25 additions and 92 deletions

View File

@ -30,6 +30,8 @@ public:
return "FixedString(" + toString(n) + ")";
}
bool behavesAsString() const { return true; }
DataTypePtr clone() const
{
return new DataTypeFixedString(n);

View File

@ -23,6 +23,8 @@ public:
return "String";
}
bool behavesAsString() const { return true; }
DataTypePtr clone() const
{
return new DataTypeString;

View File

@ -30,6 +30,9 @@ public:
/// Если тип числовой, уместны ли с ним все арифметические операции и приведение типов.
/// true для чисел, false для даты и даты-с-временем.
virtual bool behavesAsNumber() const { return false; }
/// Является ли тип строковым.
virtual bool behavesAsString() const { return false; }
/// Клонировать
virtual SharedPtr<IDataType> clone() const = 0;

View File

@ -1,12 +0,0 @@
#pragma once
#include <DB/DataTypes/IDataType.h>
namespace DB
{
/** Проверить, что типы совместимые.
*/
bool typesAreCompatible(const IDataType& lhs, const IDataType& rhs);
}

View File

@ -9,7 +9,6 @@
#include <DB/Columns/ColumnArray.h>
#include <DB/DataTypes/DataTypeNested.h>
#include <DB/DataTypes/typesAreCompatible.h>
#include <DB/Parsers/ASTExpressionList.h>
#include <DB/Interpreters/ExpressionAnalyzer.h>
@ -17,6 +16,24 @@
#include <DB/Parsers/formatAST.h>
namespace
{
bool typesAreCompatible(const DB::IDataType & lhs, const DB::IDataType & rhs)
{
if (lhs.behavesAsNumber() && rhs.behavesAsNumber())
return true;
if (lhs.behavesAsString() && rhs.behavesAsString())
return true;
if (lhs.getName() == rhs.getName())
return true;
return false;
}
}
namespace DB
{

View File

@ -1,79 +0,0 @@
#include <DB/DataTypes/typesAreCompatible.h>
#include <DB/DataTypes/DataTypeFixedString.h>
#include <DB/DataTypes/DataTypeString.h>
#include <DB/DataTypes/DataTypesNumberFixed.h>
#include <string>
#include <vector>
#include <map>
#include <algorithm>
namespace
{
typedef std::map<std::string, std::vector<std::string> > TypesCompatibilityList;
void addTypes(TypesCompatibilityList& tcl, const DB::IDataType & lhs, const DB::IDataType& rhs)
{
tcl[lhs.getName()].push_back(rhs.getName());
tcl[rhs.getName()].push_back(lhs.getName());
}
TypesCompatibilityList init()
{
TypesCompatibilityList tcl;
addTypes(tcl, DB::DataTypeString(), DB::DataTypeFixedString(1));
addTypes(tcl, DB::DataTypeFloat32(), DB::DataTypeFloat64());
addTypes(tcl, DB::DataTypeInt8(), DB::DataTypeUInt8());
addTypes(tcl, DB::DataTypeInt8(), DB::DataTypeInt16());
addTypes(tcl, DB::DataTypeInt8(), DB::DataTypeUInt16());
addTypes(tcl, DB::DataTypeInt8(), DB::DataTypeInt32());
addTypes(tcl, DB::DataTypeInt8(), DB::DataTypeUInt32());
addTypes(tcl, DB::DataTypeInt8(), DB::DataTypeInt64());
addTypes(tcl, DB::DataTypeInt8(), DB::DataTypeUInt64());
addTypes(tcl, DB::DataTypeInt16(), DB::DataTypeUInt16()),
addTypes(tcl, DB::DataTypeInt16(), DB::DataTypeInt32()),
addTypes(tcl, DB::DataTypeInt16(), DB::DataTypeUInt32()),
addTypes(tcl, DB::DataTypeInt16(), DB::DataTypeInt64()),
addTypes(tcl, DB::DataTypeInt16(), DB::DataTypeUInt64()),
addTypes(tcl, DB::DataTypeInt32(), DB::DataTypeUInt32()),
addTypes(tcl, DB::DataTypeInt32(), DB::DataTypeInt64());
addTypes(tcl, DB::DataTypeInt32(), DB::DataTypeUInt64());
addTypes(tcl, DB::DataTypeInt64(), DB::DataTypeUInt64());
for (auto & it : tcl)
{
auto & types_list = it.second;
std::sort(types_list.begin(), types_list.end());
}
return tcl;
}
}
namespace DB
{
bool typesAreCompatible(const IDataType & lhs, const IDataType & rhs)
{
static const auto types_compatibility_list = init();
if (lhs.getName() == rhs.getName())
return true;
auto it = types_compatibility_list.find(lhs.getName());
if (it == types_compatibility_list.end())
return false;
const auto & types_list = it->second;
return std::binary_search(types_list.begin(), types_list.end(), rhs.getName());
}
}