From a6c8d50cc2b1156a36ee904b1550da78b01f7f22 Mon Sep 17 00:00:00 2001 From: Nikita Mikhailov Date: Fri, 26 Feb 2021 18:29:26 +0300 Subject: [PATCH] review fix --- src/Functions/geometryConverters.cpp | 137 -------------- src/Functions/geometryConverters.h | 178 +++++++++--------- src/Functions/pointInPolygon.cpp | 4 +- src/Functions/polygonArea.cpp | 28 +-- src/Functions/polygonConvexHull.cpp | 5 +- src/Functions/polygonPerimeter.cpp | 5 +- src/Functions/polygonsDistance.cpp | 6 +- src/Functions/polygonsEquals.cpp | 6 +- src/Functions/polygonsIntersection.cpp | 6 +- src/Functions/polygonsSymDifference.cpp | 6 +- src/Functions/polygonsUnion.cpp | 6 +- src/Functions/polygonsWithin.cpp | 6 +- src/Functions/readWkt.cpp | 74 +++----- src/Functions/svg.cpp | 13 +- src/Functions/wkt.cpp | 3 +- src/Functions/ya.make | 1 - src/IO/WriteBufferFromVector.h | 2 +- .../0_stateless/01303_polygons_equals.sql | 2 +- .../01306_polygons_intersection.sql | 2 +- .../0_stateless/01307_polygon_perimeter.sql | 2 +- .../0_stateless/01308_polygon_area.sql | 2 +- 21 files changed, 149 insertions(+), 345 deletions(-) delete mode 100644 src/Functions/geometryConverters.cpp diff --git a/src/Functions/geometryConverters.cpp b/src/Functions/geometryConverters.cpp deleted file mode 100644 index ea6d99787ef..00000000000 --- a/src/Functions/geometryConverters.cpp +++ /dev/null @@ -1,137 +0,0 @@ -#include - -#include - -namespace DB -{ - -namespace ErrorCodes -{ - extern const int BAD_ARGUMENTS; - extern const int LOGICAL_ERROR; - extern const int ILLEGAL_TYPE_OF_ARGUMENT; -} - -template -std::vector PointFromColumnConverter::convertImpl(size_t shift, size_t count) const -{ - const auto * tuple = typeid_cast(col.get()); - const auto & tuple_columns = tuple->getColumns(); - - const auto * x_data = typeid_cast(tuple_columns[0].get()); - const auto * y_data = typeid_cast(tuple_columns[1].get()); - - const auto * first_container = x_data->getData().data() + shift; - const auto * second_container = y_data->getData().data() + shift; - - std::vector answer(count); - - for (size_t i = 0; i < count; ++i) - { - const Float64 first = first_container[i]; - const Float64 second = second_container[i]; - - if (isNaN(first) || isNaN(second)) - throw Exception("Point's component must not be NaN", ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT); - - if (isinf(first) || isinf(second)) - throw Exception("Point's component must not be infinite", ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT); - - answer[i] = Point(first, second); - } - - return answer; -} - -template -std::vector> RingFromColumnConverter::convert() const -{ - const IColumn::Offsets & offsets = typeid_cast(*col).getOffsets(); - size_t prev_offset = 0; - std::vector> answer; - answer.reserve(offsets.size()); - for (size_t offset : offsets) - { - auto tmp = point_converter.convertImpl(prev_offset, offset - prev_offset); - answer.emplace_back(tmp.begin(), tmp.end()); - prev_offset = offset; - } - return answer; -} - -template -std::vector> PolygonFromColumnConverter::convert() const -{ - const IColumn::Offsets & offsets = typeid_cast(*col).getOffsets(); - std::vector> answer(offsets.size()); - auto all_rings = ring_converter.convert(); - - auto prev_offset = 0; - for (size_t iter = 0; iter < offsets.size(); ++iter) - { - const auto current_array_size = offsets[iter] - prev_offset; - answer[iter].outer() = std::move(all_rings[prev_offset]); - answer[iter].inners().reserve(current_array_size); - for (size_t inner_holes = prev_offset + 1; inner_holes < offsets[iter]; ++inner_holes) - answer[iter].inners().emplace_back(std::move(all_rings[inner_holes])); - prev_offset = offsets[iter]; - } - - return answer; -} - - -template -std::vector> MultiPolygonFromColumnConverter::convert() const -{ - const IColumn::Offsets & offsets = typeid_cast(*col).getOffsets(); - size_t prev_offset = 0; - std::vector> answer(offsets.size()); - - auto all_polygons = polygon_converter.convert(); - - for (size_t iter = 0; iter < offsets.size(); ++iter) - { - for (size_t polygon_iter = prev_offset; polygon_iter < offsets[iter]; ++polygon_iter) - answer[iter].emplace_back(std::move(all_polygons[polygon_iter])); - prev_offset = offsets[iter]; - } - - return answer; -} - - -template class PointFromColumnConverter; -template class PointFromColumnConverter; -template class RingFromColumnConverter; -template class RingFromColumnConverter; -template class PolygonFromColumnConverter; -template class PolygonFromColumnConverter; -template class MultiPolygonFromColumnConverter; -template class MultiPolygonFromColumnConverter; - -template typename Desired> -void checkColumnTypeOrThrow(const ColumnWithTypeAndName & column) -{ - DataTypePtr desired_type; - if constexpr (std::is_same_v, Ring>) - desired_type = DataTypeCustomRingSerialization::nestedDataType(); - else if constexpr (std::is_same_v, Polygon>) - desired_type = DataTypeCustomPolygonSerialization::nestedDataType(); - else if constexpr (std::is_same_v, MultiPolygon>) - desired_type = DataTypeCustomMultiPolygonSerialization::nestedDataType(); - else - throw Exception("Unexpected Desired type.", ErrorCodes::LOGICAL_ERROR); - - if (!desired_type->equals(*column.type)) - throw Exception(fmt::format("Expected type {} (MultiPolygon), but got {}", desired_type->getName(), column.type->getName()), ErrorCodes::BAD_ARGUMENTS); -} - -template void checkColumnTypeOrThrow(const ColumnWithTypeAndName &); -template void checkColumnTypeOrThrow(const ColumnWithTypeAndName &); -template void checkColumnTypeOrThrow(const ColumnWithTypeAndName &); -template void checkColumnTypeOrThrow(const ColumnWithTypeAndName &); -template void checkColumnTypeOrThrow(const ColumnWithTypeAndName &); -template void checkColumnTypeOrThrow(const ColumnWithTypeAndName &); - -} diff --git a/src/Functions/geometryConverters.h b/src/Functions/geometryConverters.h index fcce11467d0..283bb1bb7f4 100644 --- a/src/Functions/geometryConverters.h +++ b/src/Functions/geometryConverters.h @@ -3,7 +3,6 @@ #include #include -#include #include #include #include @@ -27,6 +26,7 @@ namespace DB namespace ErrorCodes { extern const int BAD_ARGUMENTS; + extern const int ILLEGAL_TYPE_OF_ARGUMENT; } template @@ -38,128 +38,123 @@ using Polygon = boost::geometry::model::polygon; template using MultiPolygon = boost::geometry::model::multi_polygon>; -template -using Geometry = boost::variant, Polygon, MultiPolygon>; - -template -using Figure = boost::variant, Polygon, MultiPolygon>; - - using CartesianPoint = boost::geometry::model::d2::point_xy; using CartesianRing = Ring; using CartesianPolygon = Polygon; using CartesianMultiPolygon = MultiPolygon; -using CartesianGeometry = Geometry; -// using SphericalPoint = boost::geometry::model::point>; using SphericalPoint = boost::geometry::model::point>; using SphericalRing = Ring; using SphericalPolygon = Polygon; using SphericalMultiPolygon = MultiPolygon; -using SphericalGeometry = Geometry; - - -template -class RingFromColumnConverter; - -template -class PolygonFromColumnConverter; - -template -class MultiPolygonFromColumnConverter; /** - * Class which takes some boost type and returns a pair of numbers. + * Class which takes converts Column with type Tuple(Float64, Float64) to a vector of boost point type. * They are (x,y) in case of cartesian coordinated and (lon,lat) in case of Spherical. */ template -class PointFromColumnConverter +struct ColumnToPointsConverter { -public: - explicit PointFromColumnConverter(ColumnPtr col_) : col(col_) + static std::vector convert(ColumnPtr col) { + const auto * tuple = typeid_cast(col.get()); + const auto & tuple_columns = tuple->getColumns(); + + const auto * x_data = typeid_cast(tuple_columns[0].get()); + const auto * y_data = typeid_cast(tuple_columns[1].get()); + + const auto * first_container = x_data->getData().data(); + const auto * second_container = y_data->getData().data(); + + std::vector answer(col->size()); + + for (size_t i = 0; i < col->size(); ++i) + { + const Float64 first = first_container[i]; + const Float64 second = second_container[i]; + + if (isNaN(first) || isNaN(second)) + throw Exception("Point's component must not be NaN", ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT); + + if (isinf(first) || isinf(second)) + throw Exception("Point's component must not be infinite", ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT); + + answer[i] = Point(first, second); + } + + return answer; } - - std::vector convert() const - { - return convertImpl(0, col->size()); - } - -private: - std::vector convertImpl(size_t shift, size_t count) const; - - friend class RingFromColumnConverter; - ColumnPtr col{nullptr}; }; -template -class RingFromColumnConverter +template +struct ColumnToRingsConverter { -public: - explicit RingFromColumnConverter(ColumnPtr col_) - : col(col_) - , point_converter(typeid_cast(*col_).getDataPtr()) + static std::vector> convert(ColumnPtr col) { + const IColumn::Offsets & offsets = typeid_cast(*col).getOffsets(); + size_t prev_offset = 0; + std::vector> answer; + answer.reserve(offsets.size()); + auto tmp = ColumnToPointsConverter::convert(typeid_cast(*col).getDataPtr()); + for (size_t offset : offsets) + { + answer.emplace_back(tmp.begin() + prev_offset, tmp.begin() + offset); + prev_offset = offset; + } + return answer; } - - std::vector> convert() const; - -private: - friend class PointFromColumnConverter; - /// To prevent use-after-free and increase column lifetime. - ColumnPtr col{nullptr}; - const PointFromColumnConverter point_converter{}; }; -template -class PolygonFromColumnConverter + +template +struct ColumnToPolygonsConverter { -public: - explicit PolygonFromColumnConverter(ColumnPtr col_) - : col(col_) - , ring_converter(typeid_cast(*col_).getDataPtr()) + static std::vector> convert(ColumnPtr col) { + const IColumn::Offsets & offsets = typeid_cast(*col).getOffsets(); + std::vector> answer(offsets.size()); + auto all_rings = ColumnToRingsConverter::convert(typeid_cast(*col).getDataPtr()); + + size_t prev_offset = 0; + for (size_t iter = 0; iter < offsets.size(); ++iter) + { + const auto current_array_size = offsets[iter] - prev_offset; + answer[iter].outer() = std::move(all_rings[prev_offset]); + answer[iter].inners().reserve(current_array_size); + for (size_t inner_holes = prev_offset + 1; inner_holes < offsets[iter]; ++inner_holes) + answer[iter].inners().emplace_back(std::move(all_rings[inner_holes])); + prev_offset = offsets[iter]; + } + + return answer; } - - std::vector> convert() const; - -private: - friend class MultiPolygonFromColumnConverter; - - /// To prevent use-after-free and increase column lifetime. - ColumnPtr col{nullptr}; - const RingFromColumnConverter ring_converter{}; }; -template -class MultiPolygonFromColumnConverter + +template +struct ColumnToMultiPolygonsConverter { -public: - explicit MultiPolygonFromColumnConverter(ColumnPtr col_) - : col(col_) - , polygon_converter(typeid_cast(*col_).getDataPtr()) - {} + static std::vector> convert(ColumnPtr col) + { + const IColumn::Offsets & offsets = typeid_cast(*col).getOffsets(); + size_t prev_offset = 0; + std::vector> answer(offsets.size()); - std::vector> convert() const; + auto all_polygons = ColumnToPolygonsConverter::convert(typeid_cast(*col).getDataPtr()); -private: - /// To prevent use-after-free and increase column lifetime. - ColumnPtr col{nullptr}; - const PolygonFromColumnConverter polygon_converter{}; + for (size_t iter = 0; iter < offsets.size(); ++iter) + { + for (size_t polygon_iter = prev_offset; polygon_iter < offsets[iter]; ++polygon_iter) + answer[iter].emplace_back(std::move(all_polygons[polygon_iter])); + prev_offset = offsets[iter]; + } + + return answer; + } }; -extern template class PointFromColumnConverter; -extern template class PointFromColumnConverter; -extern template class RingFromColumnConverter; -extern template class RingFromColumnConverter; -extern template class PolygonFromColumnConverter; -extern template class PolygonFromColumnConverter; -extern template class MultiPolygonFromColumnConverter; -extern template class MultiPolygonFromColumnConverter; - - /// To serialize Spherical or Cartesian point (a pair of numbers in both cases). template class PointSerializer @@ -256,6 +251,7 @@ public: void add(const Polygon & polygon) { + /// Outer ring + all inner rings (holes). size += 1 + polygon.inners().size(); offsets->insertValue(size); ring_serializer.add(polygon.outer()); @@ -334,13 +330,13 @@ static void callOnGeometryDataType(DataTypePtr type, F && f) { /// There is no Point type, because for most of geometry functions it is useless. if (DataTypeCustomPointSerialization::nestedDataType()->equals(*type)) - return f(ConverterType>()); + return f(ConverterType>()); else if (DataTypeCustomRingSerialization::nestedDataType()->equals(*type)) - return f(ConverterType>()); + return f(ConverterType>()); else if (DataTypeCustomPolygonSerialization::nestedDataType()->equals(*type)) - return f(ConverterType>()); + return f(ConverterType>()); else if (DataTypeCustomMultiPolygonSerialization::nestedDataType()->equals(*type)) - return f(ConverterType>()); + return f(ConverterType>()); throw Exception(fmt::format("Unknown geometry type {}", type->getName()), ErrorCodes::BAD_ARGUMENTS); } diff --git a/src/Functions/pointInPolygon.cpp b/src/Functions/pointInPolygon.cpp index ac5a41f6c81..8e4a05bdec5 100644 --- a/src/Functions/pointInPolygon.cpp +++ b/src/Functions/pointInPolygon.cpp @@ -427,8 +427,8 @@ private: out_container.reserve(end - begin); for (size_t i = begin; i < end; ++i) { - int64_t result = 0; - if (common::mulOverflow(static_cast(x_data[i]), static_cast(y_data[i]), result)) + Int64 result = 0; + if (common::mulOverflow(static_cast(x_data[i]), static_cast(y_data[i]), result)) throw Exception("The coordinates of the point are such that subsequent calculations cannot be performed correctly. " \ "Most likely they are very large in modulus.", ErrorCodes::BAD_ARGUMENTS); diff --git a/src/Functions/polygonArea.cpp b/src/Functions/polygonArea.cpp index 4291d31d72a..fb1ba7c4a01 100644 --- a/src/Functions/polygonArea.cpp +++ b/src/Functions/polygonArea.cpp @@ -69,35 +69,11 @@ public: using TypeConverter = std::decay_t; using Converter = typename TypeConverter::Type; - if constexpr (std::is_same_v, Converter>) + if constexpr (std::is_same_v, Converter>) throw Exception(fmt::format("The argument of function {} must not be Point", getName()), ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT); else { - Converter converter(arguments[0].column->convertToFullColumnIfConst()); - auto geometries = converter.convert(); - - if constexpr (std::is_same_v, Converter>) { - for (auto & polygon : geometries) { - std::cout << "OUTER" << std::endl; - for (auto point : polygon.outer()) { - if constexpr (std::is_same_v) { - std::cout << point.x() << ' ' << point.y() << std::endl; - } else { - std::cout << point.template get<0>() << ' ' << point.template get<1>() << std::endl; - } - } - std::cout << "INNER" << std::endl; - for (auto & inner : polygon.inners()) { - for (auto point : inner) { - if constexpr (std::is_same_v) { - std::cout << point.x() << ' ' << point.y() << std::endl; - } else { - std::cout << point.template get<0>() << ' ' << point.template get<1>() << std::endl; - } - } - } - } - } + auto geometries = Converter::convert(arguments[0].column->convertToFullColumnIfConst()); for (size_t i = 0; i < input_rows_count; i++) res_data.emplace_back(boost::geometry::area(geometries[i])); diff --git a/src/Functions/polygonConvexHull.cpp b/src/Functions/polygonConvexHull.cpp index 3181a1ae3b4..5f545cf8ea1 100644 --- a/src/Functions/polygonConvexHull.cpp +++ b/src/Functions/polygonConvexHull.cpp @@ -67,12 +67,11 @@ public: using TypeConverter = std::decay_t; using Converter = typename TypeConverter::Type; - if constexpr (std::is_same_v>) + if constexpr (std::is_same_v>) throw Exception(fmt::format("The argument of function {} must not be a Point", getName()), ErrorCodes::BAD_ARGUMENTS); else { - Converter converter(arguments[0].column->convertToFullColumnIfConst()); - auto geometries = converter.convert(); + auto geometries = Converter::convert(arguments[0].column->convertToFullColumnIfConst()); for (size_t i = 0; i < input_rows_count; i++) { diff --git a/src/Functions/polygonPerimeter.cpp b/src/Functions/polygonPerimeter.cpp index 9bad13d4817..c3aadbd187a 100644 --- a/src/Functions/polygonPerimeter.cpp +++ b/src/Functions/polygonPerimeter.cpp @@ -69,12 +69,11 @@ public: using TypeConverter = std::decay_t; using Converter = typename TypeConverter::Type; - if constexpr (std::is_same_v, Converter>) + if constexpr (std::is_same_v, Converter>) throw Exception(fmt::format("The argument of function {} must not be Point", getName()), ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT); else { - Converter converter(arguments[0].column->convertToFullColumnIfConst()); - auto geometries = converter.convert(); + auto geometries = Converter::convert(arguments[0].column->convertToFullColumnIfConst()); for (size_t i = 0; i < input_rows_count; i++) res_data.emplace_back(boost::geometry::perimeter(geometries[i])); diff --git a/src/Functions/polygonsDistance.cpp b/src/Functions/polygonsDistance.cpp index f961867caae..074fb5a9798 100644 --- a/src/Functions/polygonsDistance.cpp +++ b/src/Functions/polygonsDistance.cpp @@ -74,12 +74,12 @@ public: using LeftConverter = typename LeftConverterType::Type; using RightConverter = typename RightConverterType::Type; - if constexpr (std::is_same_v, LeftConverter> || std::is_same_v, RightConverter>) + if constexpr (std::is_same_v, LeftConverter> || std::is_same_v, RightConverter>) throw Exception(fmt::format("Any argument of function {} must not be Point", getName()), ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT); else { - auto first = LeftConverter(arguments[0].column->convertToFullColumnIfConst()).convert(); - auto second = RightConverter(arguments[1].column->convertToFullColumnIfConst()).convert(); + auto first = LeftConverter::convert(arguments[0].column->convertToFullColumnIfConst()); + auto second = RightConverter::convert(arguments[1].column->convertToFullColumnIfConst()); for (size_t i = 0; i < input_rows_count; i++) { diff --git a/src/Functions/polygonsEquals.cpp b/src/Functions/polygonsEquals.cpp index 7e4882d5cc2..12f4cf09fa5 100644 --- a/src/Functions/polygonsEquals.cpp +++ b/src/Functions/polygonsEquals.cpp @@ -73,12 +73,12 @@ public: using LeftConverter = typename LeftConverterType::Type; using RightConverter = typename RightConverterType::Type; - if constexpr (std::is_same_v, LeftConverter> || std::is_same_v, RightConverter>) + if constexpr (std::is_same_v, LeftConverter> || std::is_same_v, RightConverter>) throw Exception(fmt::format("Any argument of function {} must not be Point", getName()), ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT); else { - auto first = LeftConverter(arguments[0].column->convertToFullColumnIfConst()).convert(); - auto second = RightConverter(arguments[1].column->convertToFullColumnIfConst()).convert(); + auto first = LeftConverter::convert(arguments[0].column->convertToFullColumnIfConst()); + auto second = RightConverter::convert(arguments[1].column->convertToFullColumnIfConst()); for (size_t i = 0; i < input_rows_count; i++) { diff --git a/src/Functions/polygonsIntersection.cpp b/src/Functions/polygonsIntersection.cpp index 0f7a9b1f264..0de3d023044 100644 --- a/src/Functions/polygonsIntersection.cpp +++ b/src/Functions/polygonsIntersection.cpp @@ -72,12 +72,12 @@ public: using LeftConverter = typename LeftConverterType::Type; using RightConverter = typename RightConverterType::Type; - if constexpr (std::is_same_v, LeftConverter> || std::is_same_v, RightConverter>) + if constexpr (std::is_same_v, LeftConverter> || std::is_same_v, RightConverter>) throw Exception(fmt::format("Any argument of function {} must not be Point", getName()), ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT); else { - auto first = LeftConverter(arguments[0].column->convertToFullColumnIfConst()).convert(); - auto second = RightConverter(arguments[1].column->convertToFullColumnIfConst()).convert(); + auto first = LeftConverter::convert(arguments[0].column->convertToFullColumnIfConst()); + auto second = RightConverter::convert(arguments[1].column->convertToFullColumnIfConst()); /// We are not interested in some pitfalls in third-party libraries /// NOLINTNEXTLINE(clang-analyzer-core.uninitialized.Assign) diff --git a/src/Functions/polygonsSymDifference.cpp b/src/Functions/polygonsSymDifference.cpp index 4768ea93124..9ab6b79c5f5 100644 --- a/src/Functions/polygonsSymDifference.cpp +++ b/src/Functions/polygonsSymDifference.cpp @@ -71,12 +71,12 @@ public: using LeftConverter = typename LeftConverterType::Type; using RightConverter = typename RightConverterType::Type; - if constexpr (std::is_same_v, LeftConverter> || std::is_same_v, RightConverter>) + if constexpr (std::is_same_v, LeftConverter> || std::is_same_v, RightConverter>) throw Exception(fmt::format("Any argument of function {} must not be Point", getName()), ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT); else { - auto first = LeftConverter(arguments[0].column->convertToFullColumnIfConst()).convert(); - auto second = RightConverter(arguments[1].column->convertToFullColumnIfConst()).convert(); + auto first = LeftConverter::convert(arguments[0].column->convertToFullColumnIfConst()); + auto second = RightConverter::convert(arguments[1].column->convertToFullColumnIfConst()); /// NOLINTNEXTLINE(clang-analyzer-core.uninitialized.Assign) for (size_t i = 0; i < input_rows_count; i++) diff --git a/src/Functions/polygonsUnion.cpp b/src/Functions/polygonsUnion.cpp index d4d67982ee0..eab2e2e588f 100644 --- a/src/Functions/polygonsUnion.cpp +++ b/src/Functions/polygonsUnion.cpp @@ -71,12 +71,12 @@ public: using LeftConverter = typename LeftConverterType::Type; using RightConverter = typename RightConverterType::Type; - if constexpr (std::is_same_v, LeftConverter> || std::is_same_v, RightConverter>) + if constexpr (std::is_same_v, LeftConverter> || std::is_same_v, RightConverter>) throw Exception(fmt::format("Any argument of function {} must not be Point", getName()), ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT); else { - auto first = LeftConverter(arguments[0].column->convertToFullColumnIfConst()).convert(); - auto second = RightConverter(arguments[1].column->convertToFullColumnIfConst()).convert(); + auto first = LeftConverter::convert(arguments[0].column->convertToFullColumnIfConst()); + auto second = RightConverter::convert(arguments[1].column->convertToFullColumnIfConst()); /// We are not interested in some pitfalls in third-party libraries /// NOLINTNEXTLINE(clang-analyzer-core.uninitialized.Assign) diff --git a/src/Functions/polygonsWithin.cpp b/src/Functions/polygonsWithin.cpp index eabd5e683b9..68db1494a0d 100644 --- a/src/Functions/polygonsWithin.cpp +++ b/src/Functions/polygonsWithin.cpp @@ -75,12 +75,12 @@ public: using LeftConverter = typename LeftConverterType::Type; using RightConverter = typename RightConverterType::Type; - if constexpr (std::is_same_v, LeftConverter> || std::is_same_v, RightConverter>) + if constexpr (std::is_same_v, LeftConverter> || std::is_same_v, RightConverter>) throw Exception(fmt::format("Any argument of function {} must not be Point", getName()), ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT); else { - auto first = LeftConverter(arguments[0].column->convertToFullColumnIfConst()).convert(); - auto second = RightConverter(arguments[1].column->convertToFullColumnIfConst()).convert(); + auto first = LeftConverter::convert(arguments[0].column->convertToFullColumnIfConst()); + auto second = RightConverter::convert(arguments[1].column->convertToFullColumnIfConst()); /// NOLINTNEXTLINE(clang-analyzer-core.uninitialized.Assign) for (size_t i = 0; i < input_rows_count; i++) diff --git a/src/Functions/readWkt.cpp b/src/Functions/readWkt.cpp index 0e595d3d5ae..101902a00f5 100644 --- a/src/Functions/readWkt.cpp +++ b/src/Functions/readWkt.cpp @@ -16,12 +16,20 @@ namespace ErrorCodes extern const int ILLEGAL_TYPE_OF_ARGUMENT; } -template + +template class FunctionReadWkt : public IFunction { public: explicit FunctionReadWkt() = default; + static constexpr const char * name = NameHolder::name; + + String getName() const override + { + return name; + } + size_t getNumberOfArguments() const override { return 1; @@ -59,71 +67,39 @@ public: { return true; } -}; -class FunctionReadWktPoint : public FunctionReadWkt> -{ -public: - static inline const char * name = "readWktPoint"; - String getName() const override - { - return name; - } static FunctionPtr create(const Context &) { - return std::make_shared(); + return std::make_shared>(); } }; - -class FunctionReadWktRing : public FunctionReadWkt> +struct ReadWktPointNameHolder { -public: - static inline const char * name = "readWktRing"; - String getName() const override - { - return name; - } - static FunctionPtr create(const Context &) - { - return std::make_shared(); - } + static constexpr const char * name = "readWktPoint"; }; -class FunctionReadWktPolygon : public FunctionReadWkt> +struct ReadWktRingNameHolder { -public: - static inline const char * name = "readWktPolygon"; - String getName() const override - { - return name; - } - static FunctionPtr create(const Context &) - { - return std::make_shared(); - } + static constexpr const char * name = "readWktRing"; }; -class FunctionReadWktMultiPolygon : public FunctionReadWkt> +struct ReadWktPolygonNameHolder { -public: - static inline const char * name = "readWktMultiPolygon"; - String getName() const override - { - return name; - } - static FunctionPtr create(const Context &) - { - return std::make_shared(); - } + static constexpr const char * name = "readWktPolygon"; +}; + +struct ReadWktMultiPolygonNameHolder +{ + static constexpr const char * name = "readWktMultiPolygon"; }; void registerFunctionReadWkt(FunctionFactory & factory) { - factory.registerFunction(); - factory.registerFunction(); - factory.registerFunction(); - factory.registerFunction(); + factory.registerFunction, ReadWktPointNameHolder>>(); + factory.registerFunction, ReadWktRingNameHolder>>(); + factory.registerFunction, ReadWktPolygonNameHolder>>(); + factory.registerFunction, ReadWktMultiPolygonNameHolder>>(); } } diff --git a/src/Functions/svg.cpp b/src/Functions/svg.cpp index 873a42722c3..d8a16af1e1d 100644 --- a/src/Functions/svg.cpp +++ b/src/Functions/svg.cpp @@ -64,21 +64,18 @@ public: ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr & /*result_type*/, size_t input_rows_count) const override { - auto res_column = ColumnString::create(); + bool has_style = arguments.size() > 1; + ColumnPtr style; + if (has_style) + style = arguments[1].column; callOnGeometryDataType(arguments[0].type, [&] (const auto & type) { using TypeConverter = std::decay_t; using Converter = typename TypeConverter::Type; - Converter converter(arguments[0].column->convertToFullColumnIfConst()); - auto figures = converter.convert(); - - bool has_style = arguments.size() > 1; - ColumnPtr style; - if (has_style) - style = arguments[1].column; + auto figures = Converter::convert(arguments[0].column->convertToFullColumnIfConst()); for (size_t i = 0; i < input_rows_count; i++) { diff --git a/src/Functions/wkt.cpp b/src/Functions/wkt.cpp index 619c3f3aee8..1d509a7c508 100644 --- a/src/Functions/wkt.cpp +++ b/src/Functions/wkt.cpp @@ -45,8 +45,7 @@ public: using TypeConverter = std::decay_t; using Converter = typename TypeConverter::Type; - Converter converter(arguments[0].column->convertToFullColumnIfConst()); - auto figures = converter.convert(); + auto figures = Converter::convert(arguments[0].column->convertToFullColumnIfConst()); for (size_t i = 0; i < input_rows_count; i++) { diff --git a/src/Functions/ya.make b/src/Functions/ya.make index e430d72690d..3ac64828b9c 100644 --- a/src/Functions/ya.make +++ b/src/Functions/ya.make @@ -268,7 +268,6 @@ SRCS( geohashDecode.cpp geohashEncode.cpp geohashesInBox.cpp - geometryConverters.cpp getMacro.cpp getScalar.cpp getSetting.cpp diff --git a/src/IO/WriteBufferFromVector.h b/src/IO/WriteBufferFromVector.h index 1dcf2c3f327..6341a9b698b 100644 --- a/src/IO/WriteBufferFromVector.h +++ b/src/IO/WriteBufferFromVector.h @@ -45,7 +45,7 @@ private: } public: - WriteBufferFromVector(VectorType & vector_) + explicit WriteBufferFromVector(VectorType & vector_) : WriteBuffer(reinterpret_cast(vector_.data()), vector_.size()), vector(vector_) { if (vector.empty()) diff --git a/tests/queries/0_stateless/01303_polygons_equals.sql b/tests/queries/0_stateless/01303_polygons_equals.sql index 1d608ce45fa..42f1bd4693c 100644 --- a/tests/queries/0_stateless/01303_polygons_equals.sql +++ b/tests/queries/0_stateless/01303_polygons_equals.sql @@ -1,2 +1,2 @@ select polygonsEqualsCartesian([[[(0, 0),(0, 3),(1, 2.9),(2, 2.6),(2.6, 2),(2.9, 1),(3, 0),(0, 0)]]], [[[(1., 1.),(1., 4.),(4., 4.),(4., 1.),(1., 1.)]]]); -select polygonsEqualsCartesian([[[(1., 1.),(1., 4.),(4., 4.),(4., 1.)]]], [[[(1., 1.),(1., 4.),(4., 4.),(4., 1.),(1., 1.)]]]); \ No newline at end of file +select polygonsEqualsCartesian([[[(1., 1.),(1., 4.),(4., 4.),(4., 1.)]]], [[[(1., 1.),(1., 4.),(4., 4.),(4., 1.),(1., 1.)]]]); diff --git a/tests/queries/0_stateless/01306_polygons_intersection.sql b/tests/queries/0_stateless/01306_polygons_intersection.sql index fa486a138f4..fd428c3d826 100644 --- a/tests/queries/0_stateless/01306_polygons_intersection.sql +++ b/tests/queries/0_stateless/01306_polygons_intersection.sql @@ -2,4 +2,4 @@ select polygonsIntersectionCartesian([[[(0., 0.),(0., 3.),(1., 2.9),(2., 2.6),(2 select polygonsIntersectionCartesian([[[(0., 0.),(0., 3.),(1., 2.9),(2., 2.6),(2.6, 2.),(2.9, 1.),(3., 0.),(0., 0.)]]], [[[(3., 3.),(3., 4.),(4., 4.),(4., 3.),(3., 3.)]]]); select polygonsIntersectionSpherical([[[(4.346693, 50.858306), (4.367945, 50.852455), (4.366227, 50.840809), (4.344961, 50.833264), (4.338074, 50.848677), (4.346693, 50.858306)]]], [[[(25.0010, 136.9987), (17.7500, 142.5000), (11.3733, 142.5917)]]]); -select polygonsIntersectionSpherical([[[(4.3613577, 50.8651821), (4.349556, 50.8535879), (4.3602419, 50.8435626), (4.3830299, 50.8428851), (4.3904543, 50.8564867), (4.3613148, 50.8651279)]]], [[[(4.346693, 50.858306), (4.367945, 50.852455), (4.366227, 50.840809), (4.344961, 50.833264), (4.338074, 50.848677), (4.346693, 50.858306)]]]); \ No newline at end of file +select polygonsIntersectionSpherical([[[(4.3613577, 50.8651821), (4.349556, 50.8535879), (4.3602419, 50.8435626), (4.3830299, 50.8428851), (4.3904543, 50.8564867), (4.3613148, 50.8651279)]]], [[[(4.346693, 50.858306), (4.367945, 50.852455), (4.366227, 50.840809), (4.344961, 50.833264), (4.338074, 50.848677), (4.346693, 50.858306)]]]); diff --git a/tests/queries/0_stateless/01307_polygon_perimeter.sql b/tests/queries/0_stateless/01307_polygon_perimeter.sql index 2fd0c369379..18f5b385826 100644 --- a/tests/queries/0_stateless/01307_polygon_perimeter.sql +++ b/tests/queries/0_stateless/01307_polygon_perimeter.sql @@ -1 +1 @@ -select polygonPerimeterCartesian([[[(0., 0.), (0., 5.), (5., 5.), (5., 0.), (0., 0.)]]]); \ No newline at end of file +select polygonPerimeterCartesian([[[(0., 0.), (0., 5.), (5., 5.), (5., 0.), (0., 0.)]]]); diff --git a/tests/queries/0_stateless/01308_polygon_area.sql b/tests/queries/0_stateless/01308_polygon_area.sql index 4f02928b450..e3a44ad7d51 100644 --- a/tests/queries/0_stateless/01308_polygon_area.sql +++ b/tests/queries/0_stateless/01308_polygon_area.sql @@ -1,3 +1,3 @@ select polygonAreaCartesian([[[(0., 0.), (0., 5.), (5., 5.), (5., 0.)]]]); select polygonAreaSpherical([[[(4.346693, 50.858306), (4.367945, 50.852455), (4.366227, 50.840809), (4.344961, 50.833264), (4.338074, 50.848677), (4.346693, 50.858306)]]]); -SELECT polygonAreaCartesian([]); -- { serverError 36 } \ No newline at end of file +SELECT polygonAreaCartesian([]); -- { serverError 36 }