mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-27 18:12:02 +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(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(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. */ \
|
/** 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) \
|
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;
|
DataTypePtr tuple;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DataTypeCustomPointSerialization() : tuple(std::make_unique<DataTypeTuple>(
|
DataTypeCustomPointSerialization()
|
||||||
DataTypes({std::make_unique<DataTypeFloat64>(), std::make_unique<DataTypeFloat64>()})))
|
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void serializeText(const IColumn & column, size_t row_num, WriteBuffer & ostr, const FormatSettings & settings) const override
|
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
|
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
|
class DataTypeCustomPolygonSerialization : public DataTypeCustomSimpleTextSerialization
|
||||||
{
|
{
|
||||||
private:
|
|
||||||
DataTypePtr array;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DataTypeCustomPolygonSerialization() : array(std::make_unique<DataTypeArray>(std::make_unique<DataTypeArray>(std::make_unique<DataTypeTuple>(
|
DataTypeCustomPolygonSerialization()
|
||||||
DataTypes({std::make_unique<DataTypeFloat64>(), std::make_unique<DataTypeFloat64>()})))))
|
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void serializeText(const IColumn & column, size_t row_num, WriteBuffer & ostr, const FormatSettings & settings) const override
|
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
|
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
|
class DataTypeCustomMultiPolygonSerialization : public DataTypeCustomSimpleTextSerialization
|
||||||
{
|
{
|
||||||
private:
|
|
||||||
DataTypePtr array;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DataTypeCustomMultiPolygonSerialization() : array(
|
DataTypeCustomMultiPolygonSerialization()
|
||||||
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>()}))))))
|
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void serializeText(const IColumn & column, size_t row_num, WriteBuffer & ostr, const FormatSettings & settings) const override
|
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
|
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>()));
|
std::make_unique<DataTypeCustomDesc>(std::make_unique<DataTypeCustomFixedName>("Point"), std::make_unique<DataTypeCustomPointSerialization>()));
|
||||||
});
|
});
|
||||||
|
|
||||||
// Custom type for polygon with holes stored as Array(Array(Point))
|
// Custom type for simple polygon without holes stored as Array(Point)
|
||||||
// Each element of outer array represents a simple polygon without holes stored as array of points
|
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
|
// First element of outer array is outer shape of polygon and all the following are holes
|
||||||
factory.registerSimpleDataTypeCustom("Polygon", []
|
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>()));
|
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 BAD_DATABASE_FOR_TEMPORARY_TABLE;
|
||||||
extern const int SUSPICIOUS_TYPE_FOR_LOW_CARDINALITY;
|
extern const int SUSPICIOUS_TYPE_FOR_LOW_CARDINALITY;
|
||||||
extern const int DICTIONARY_ALREADY_EXISTS;
|
extern const int DICTIONARY_ALREADY_EXISTS;
|
||||||
|
extern const int ILLEGAL_COLUMN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -381,7 +382,6 @@ ConstraintsDescription InterpreterCreateQuery::getConstraintsDescription(const A
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
InterpreterCreateQuery::TableProperties InterpreterCreateQuery::setProperties(ASTCreateQuery & create) const
|
InterpreterCreateQuery::TableProperties InterpreterCreateQuery::setProperties(ASTCreateQuery & create) const
|
||||||
{
|
{
|
||||||
TableProperties properties;
|
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
|
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