mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-24 00:22:29 +00:00
Add allow_experimental_geo_types; add test
This commit is contained in:
parent
a65923b028
commit
b84c8fcbd8
@ -416,6 +416,8 @@ struct Settings : public SettingsCollection<Settings>
|
||||
M(SettingBool, allow_nondeterministic_mutations, false, "Allow non-deterministic functions in ALTER UPDATE/ALTER DELETE statements", 0) \
|
||||
M(SettingSeconds, lock_acquire_timeout, DBMS_DEFAULT_LOCK_ACQUIRE_TIMEOUT_SEC, "How long locking request should wait before failing", 0) \
|
||||
\
|
||||
M(SettingBool, allow_experimental_geo_types, false, "Allow geo data types such as Point, Ring, Polygon, MultiPolygon", 0) \
|
||||
\
|
||||
/** Obsolete settings that do nothing but left for compatibility reasons. Remove each one after half a year of obsolescence. */ \
|
||||
\
|
||||
M(SettingBool, allow_experimental_low_cardinality_type, true, "Obsolete setting, does nothing. Will be removed after 2019-08-13", 0) \
|
||||
|
@ -19,62 +19,89 @@ private:
|
||||
DataTypePtr tuple;
|
||||
|
||||
public:
|
||||
DataTypeCustomPointSerialization() : tuple(std::make_unique<DataTypeTuple>(
|
||||
DataTypes({std::make_unique<DataTypeFloat64>(), std::make_unique<DataTypeFloat64>()})))
|
||||
DataTypeCustomPointSerialization()
|
||||
{}
|
||||
|
||||
void serializeText(const IColumn & column, size_t row_num, WriteBuffer & ostr, const FormatSettings & settings) const override
|
||||
{
|
||||
tuple->serializeAsText(column, row_num, ostr, settings);
|
||||
nestedDataType()->serializeAsText(column, row_num, ostr, settings);
|
||||
}
|
||||
|
||||
void deserializeText(IColumn & column, ReadBuffer & istr, const FormatSettings & settings) const override
|
||||
{
|
||||
tuple->deserializeAsWholeText(column, istr, settings);
|
||||
nestedDataType()->deserializeAsWholeText(column, istr, settings);
|
||||
}
|
||||
|
||||
static DataTypePtr nestedDataType() {
|
||||
static auto dataType = DataTypePtr(std::make_unique<DataTypeTuple>(
|
||||
DataTypes({std::make_unique<DataTypeFloat64>(), std::make_unique<DataTypeFloat64>()})));
|
||||
return dataType;
|
||||
}
|
||||
};
|
||||
|
||||
class DataTypeCustomRingSerialization : public DataTypeCustomSimpleTextSerialization
|
||||
{
|
||||
public:
|
||||
DataTypeCustomRingSerialization()
|
||||
{}
|
||||
|
||||
void serializeText(const IColumn & column, size_t row_num, WriteBuffer & ostr, const FormatSettings & settings) const override
|
||||
{
|
||||
nestedDataType()->serializeAsText(column, row_num, ostr, settings);
|
||||
}
|
||||
|
||||
void deserializeText(IColumn & column, ReadBuffer & istr, const FormatSettings & settings) const override
|
||||
{
|
||||
nestedDataType()->deserializeAsWholeText(column, istr, settings);
|
||||
}
|
||||
|
||||
static DataTypePtr nestedDataType() {
|
||||
static auto dataType = DataTypePtr(std::make_unique<DataTypeArray>(DataTypeCustomPointSerialization::nestedDataType()));
|
||||
return dataType;
|
||||
}
|
||||
};
|
||||
|
||||
class DataTypeCustomPolygonSerialization : public DataTypeCustomSimpleTextSerialization
|
||||
{
|
||||
private:
|
||||
DataTypePtr array;
|
||||
|
||||
public:
|
||||
DataTypeCustomPolygonSerialization() : array(std::make_unique<DataTypeArray>(std::make_unique<DataTypeArray>(std::make_unique<DataTypeTuple>(
|
||||
DataTypes({std::make_unique<DataTypeFloat64>(), std::make_unique<DataTypeFloat64>()})))))
|
||||
DataTypeCustomPolygonSerialization()
|
||||
{}
|
||||
|
||||
void serializeText(const IColumn & column, size_t row_num, WriteBuffer & ostr, const FormatSettings & settings) const override
|
||||
{
|
||||
array->serializeAsText(column, row_num, ostr, settings);
|
||||
nestedDataType()->serializeAsText(column, row_num, ostr, settings);
|
||||
}
|
||||
|
||||
void deserializeText(IColumn & column, ReadBuffer & istr, const FormatSettings & settings) const override
|
||||
{
|
||||
array->deserializeAsWholeText(column, istr, settings);
|
||||
nestedDataType()->deserializeAsWholeText(column, istr, settings);
|
||||
}
|
||||
|
||||
static DataTypePtr nestedDataType() {
|
||||
static auto dataType = DataTypePtr(std::make_unique<DataTypeArray>(DataTypeCustomRingSerialization::nestedDataType()));
|
||||
return dataType;
|
||||
}
|
||||
};
|
||||
|
||||
class DataTypeCustomMultiPolygonSerialization : public DataTypeCustomSimpleTextSerialization
|
||||
{
|
||||
private:
|
||||
DataTypePtr array;
|
||||
|
||||
public:
|
||||
DataTypeCustomMultiPolygonSerialization() : array(
|
||||
std::make_unique<DataTypeArray>(std::make_unique<DataTypeArray>(
|
||||
std::make_unique<DataTypeArray>(std::make_unique<DataTypeTuple>(
|
||||
DataTypes({std::make_unique<DataTypeFloat64>(), std::make_unique<DataTypeFloat64>()}))))))
|
||||
DataTypeCustomMultiPolygonSerialization()
|
||||
{}
|
||||
|
||||
void serializeText(const IColumn & column, size_t row_num, WriteBuffer & ostr, const FormatSettings & settings) const override
|
||||
{
|
||||
array->serializeAsText(column, row_num, ostr, settings);
|
||||
nestedDataType()->serializeAsText(column, row_num, ostr, settings);
|
||||
}
|
||||
|
||||
void deserializeText(IColumn & column, ReadBuffer & istr, const FormatSettings & settings) const override
|
||||
{
|
||||
array->deserializeAsWholeText(column, istr, settings);
|
||||
nestedDataType()->deserializeAsWholeText(column, istr, settings);
|
||||
}
|
||||
|
||||
static DataTypePtr nestedDataType() {
|
||||
static auto dataType = DataTypePtr(std::make_unique<DataTypeArray>(DataTypeCustomPolygonSerialization::nestedDataType()));
|
||||
return dataType;
|
||||
}
|
||||
};
|
||||
|
||||
@ -89,12 +116,18 @@ void registerDataTypeDomainGeo(DataTypeFactory & factory)
|
||||
std::make_unique<DataTypeCustomDesc>(std::make_unique<DataTypeCustomFixedName>("Point"), std::make_unique<DataTypeCustomPointSerialization>()));
|
||||
});
|
||||
|
||||
// Custom type for polygon with holes stored as Array(Array(Point))
|
||||
// Each element of outer array represents a simple polygon without holes stored as array of points
|
||||
// Custom type for simple polygon without holes stored as Array(Point)
|
||||
factory.registerSimpleDataTypeCustom("Ring", []
|
||||
{
|
||||
return std::make_pair(DataTypeFactory::instance().get("Array(Point)"),
|
||||
std::make_unique<DataTypeCustomDesc>(std::make_unique<DataTypeCustomFixedName>("Ring"), std::make_unique<DataTypeCustomRingSerialization>()));
|
||||
});
|
||||
|
||||
// Custom type for polygon with holes stored as Array(Ring)
|
||||
// First element of outer array is outer shape of polygon and all the following are holes
|
||||
factory.registerSimpleDataTypeCustom("Polygon", []
|
||||
{
|
||||
return std::make_pair(DataTypeFactory::instance().get("Array(Array(Point))"),
|
||||
return std::make_pair(DataTypeFactory::instance().get("Array(Ring)"),
|
||||
std::make_unique<DataTypeCustomDesc>(std::make_unique<DataTypeCustomFixedName>("Polygon"), std::make_unique<DataTypeCustomPolygonSerialization>()));
|
||||
});
|
||||
|
||||
|
@ -70,6 +70,7 @@ namespace ErrorCodes
|
||||
extern const int BAD_DATABASE_FOR_TEMPORARY_TABLE;
|
||||
extern const int SUSPICIOUS_TYPE_FOR_LOW_CARDINALITY;
|
||||
extern const int DICTIONARY_ALREADY_EXISTS;
|
||||
extern const int ILLEGAL_COLUMN;
|
||||
}
|
||||
|
||||
|
||||
@ -381,7 +382,6 @@ ConstraintsDescription InterpreterCreateQuery::getConstraintsDescription(const A
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
InterpreterCreateQuery::TableProperties InterpreterCreateQuery::setProperties(ASTCreateQuery & create) const
|
||||
{
|
||||
TableProperties properties;
|
||||
@ -471,6 +471,21 @@ void InterpreterCreateQuery::validateTableStructure(const ASTCreateQuery & creat
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!create.attach && !context.getSettingsRef().allow_experimental_geo_types)
|
||||
{
|
||||
for (const auto & name_and_type_pair : properties.columns.getAllPhysical())
|
||||
{
|
||||
const auto& type = name_and_type_pair.type->getName();
|
||||
if (type == "MultiPolygon" || type == "Polygon" || type == "Ring" || type == "Point")
|
||||
{
|
||||
String message = "Cannot create table with column '" + name_and_type_pair.name + "' which type is '"
|
||||
+ type + "' because experimental geo types are not allowed. "
|
||||
+ "Set setting allow_experimental_geo_types = 1 in order to allow it.";
|
||||
throw Exception(message, ErrorCodes::ILLEGAL_COLUMN);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void InterpreterCreateQuery::setEngine(ASTCreateQuery & create) const
|
||||
|
1
tests/queries/0_stateless/01291_geo_types.reference
Normal file
1
tests/queries/0_stateless/01291_geo_types.reference
Normal file
@ -0,0 +1 @@
|
||||
(0,0) [(0,0),(10,0),(10,10),(0,10)] [[(20,20),(50,20),(50,50),(20,50)],[(30,30),(50,50),(50,30)]] [[[(0,0),(10,0),(10,10),(0,10)]],[[(20,20),(50,20),(50,50),(20,50)],[(30,30),(50,50),(50,30)]]]
|
9
tests/queries/0_stateless/01291_geo_types.sql
Normal file
9
tests/queries/0_stateless/01291_geo_types.sql
Normal file
@ -0,0 +1,9 @@
|
||||
DROP TABLE IF EXISTS geo;
|
||||
|
||||
SET allow_experimental_geo_types = 1;
|
||||
|
||||
CREATE TABLE geo (a Point, b Ring, c Polygon, d MultiPolygon) ENGINE=Memory();
|
||||
|
||||
INSERT INTO geo VALUES((0, 0), [(0, 0), (10, 0), (10, 10), (0, 10)], [[(20, 20), (50, 20), (50, 50), (20, 50)], [(30, 30), (50, 50), (50, 30)]], [[[(0, 0), (10, 0), (10, 10), (0, 10)]], [[(20, 20), (50, 20), (50, 50), (20, 50)],[(30, 30), (50, 50), (50, 30)]]]);
|
||||
|
||||
SELECT * from geo;
|
Loading…
Reference in New Issue
Block a user