From 681b0b63f1ee9d94cf3378e91be1b834deb162a6 Mon Sep 17 00:00:00 2001 From: Nikita Mikhailov Date: Sat, 20 Feb 2021 16:59:37 +0300 Subject: [PATCH] return back all functions --- src/Functions/describeGeometry.cpp | 131 -------------- src/Functions/geometryConverters.cpp | 32 ++-- src/Functions/geometryConverters.h | 91 +++++----- src/Functions/polygonArea.cpp | 10 +- src/Functions/polygonConvexHull.cpp | 151 ++++++++-------- src/Functions/polygonPerimeter.cpp | 145 ++++++++-------- src/Functions/polygonsDistance.cpp | 158 +++++++++-------- src/Functions/polygonsEquals.cpp | 155 +++++++++-------- src/Functions/polygonsIntersection.cpp | 15 +- src/Functions/polygonsSymDifference.cpp | 156 +++++++++-------- src/Functions/polygonsUnion.cpp | 162 +++++++++--------- src/Functions/polygonsWithin.cpp | 159 +++++++++-------- src/Functions/registerFunctionsGeo.cpp | 30 ++-- src/Functions/svg.cpp | 10 +- src/Functions/wkt.cpp | 10 +- .../0_stateless/01307_polygon_perimeter.sql | 2 +- 16 files changed, 669 insertions(+), 748 deletions(-) delete mode 100644 src/Functions/describeGeometry.cpp diff --git a/src/Functions/describeGeometry.cpp b/src/Functions/describeGeometry.cpp deleted file mode 100644 index 0f059d3c606..00000000000 --- a/src/Functions/describeGeometry.cpp +++ /dev/null @@ -1,131 +0,0 @@ -#include -#include -#include -#include -#include -#include - -#include -#include - -namespace DB -{ - -namespace ErrorCodes -{ - extern const int ILLEGAL_TYPE_OF_ARGUMENT; -} - -class FunctionDescribeGeometry : public IFunction -{ -public: - explicit FunctionDescribeGeometry() = default; - - size_t getNumberOfArguments() const override - { - return 1; - } - - static inline const char * name = "describeGeometry"; - - - String getName() const override - { - return name; - } - - DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override - { - if (checkAndGetDataType(arguments[0].get()) == nullptr) - { - throw Exception("First argument should be String", - ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT); - } - - return std::make_shared(); - } - - ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr & /*result_type*/, size_t input_rows_count) const override - { - const auto * column_string = checkAndGetColumn(arguments[0].column.get()); - - CartesianPoint point; - Ring ring; - Polygon polygon; - MultiPolygon multipolygon; - - auto result = ColumnUInt8::create(); - auto & result_array = result->getData(); - - result_array.reserve(input_rows_count); - - for (size_t i = 0; i < input_rows_count; i++) - { - const auto & str = column_string->getDataAt(i).toString(); - - try - { - boost::geometry::read_wkt(str, point); - result_array.emplace_back(0); - continue; - } - catch (boost::geometry::read_wkt_exception &) - { - } - - try - { - boost::geometry::read_wkt(str, ring); - result_array.emplace_back(1); - continue; - } - catch (boost::geometry::read_wkt_exception &) - { - } - - - try - { - boost::geometry::read_wkt(str, polygon); - result_array.emplace_back(2); - continue; - } - catch (boost::geometry::read_wkt_exception &) - { - } - - - try - { - boost::geometry::read_wkt(str, multipolygon); - result_array.emplace_back(3); - continue; - } - catch (boost::geometry::read_wkt_exception &) - { - } - - throw Exception("Unknown geometry format", ErrorCodes::BAD_ARGUMENTS); - } - - return result; - } - - static FunctionPtr create(const Context &) - { - return std::make_shared(); - } - - bool useDefaultImplementationForConstants() const override - { - return true; - } -}; - - -void registerFunctionDescribeGeometry(FunctionFactory & factory) -{ - factory.registerFunction(); -} - -} diff --git a/src/Functions/geometryConverters.cpp b/src/Functions/geometryConverters.cpp index 8cd023f8c58..d2050af6679 100644 --- a/src/Functions/geometryConverters.cpp +++ b/src/Functions/geometryConverters.cpp @@ -13,7 +13,7 @@ namespace ErrorCodes } template -std::vector PointFromColumnParser::parseImpl(size_t shift, size_t count) const +std::vector PointFromColumnConverter::convertImpl(size_t shift, size_t count) const { const auto * tuple = typeid_cast(col.get()); const auto & tuple_columns = tuple->getColumns(); @@ -44,7 +44,7 @@ std::vector PointFromColumnParser::parseImpl(size_t shift, size_t } template -std::vector> RingFromColumnParser::parse() const +std::vector> RingFromColumnConverter::convert() const { const IColumn::Offsets & offsets = typeid_cast(*col).getOffsets(); size_t prev_offset = 0; @@ -52,7 +52,7 @@ std::vector> RingFromColumnParser::parse() const answer.reserve(offsets.size()); for (size_t offset : offsets) { - auto tmp = point_parser.parseImpl(prev_offset, offset - prev_offset); + auto tmp = point_converter.convertImpl(prev_offset, offset - prev_offset); answer.emplace_back(tmp.begin(), tmp.end()); prev_offset = offset; } @@ -60,11 +60,11 @@ std::vector> RingFromColumnParser::parse() const } template -std::vector> PolygonFromColumnParser::parse() const +std::vector> PolygonFromColumnConverter::convert() const { const IColumn::Offsets & offsets = typeid_cast(*col).getOffsets(); std::vector> answer(offsets.size()); - auto all_rings = ring_parser.parse(); + auto all_rings = ring_converter.convert(); auto prev_offset = 0; for (size_t iter = 0; iter < offsets.size(); ++iter) @@ -82,18 +82,18 @@ std::vector> PolygonFromColumnParser::parse() const template -std::vector> MultiPolygonFromColumnParser::parse() const +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_parser.parse(); + 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])); + answer[iter].emplace_back(std::move(all_polygons[polygon_iter])); prev_offset = offsets[iter]; } @@ -101,14 +101,14 @@ std::vector> MultiPolygonFromColumnParser::parse() co } -template class PointFromColumnParser; -template class PointFromColumnParser; -template class RingFromColumnParser; -template class RingFromColumnParser; -template class PolygonFromColumnParser; -template class PolygonFromColumnParser; -template class MultiPolygonFromColumnParser; -template class MultiPolygonFromColumnParser; +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) diff --git a/src/Functions/geometryConverters.h b/src/Functions/geometryConverters.h index 6c39546bca5..a245e4c3017 100644 --- a/src/Functions/geometryConverters.h +++ b/src/Functions/geometryConverters.h @@ -60,109 +60,106 @@ using GeographicGeometry = Geometry; template -class RingFromColumnParser; +class RingFromColumnConverter; template -class PolygonFromColumnParser; +class PolygonFromColumnConverter; template -class MultiPolygonFromColumnParser; +class MultiPolygonFromColumnConverter; /** * Class which takes some boost type and returns a pair of numbers. * They are (x,y) in case of cartesian coordinated and (lon,lat) in case of geographic. */ template -class PointFromColumnParser +class PointFromColumnConverter { public: - PointFromColumnParser() = default; - explicit PointFromColumnParser(ColumnPtr col_) : col(col_) + explicit PointFromColumnConverter(ColumnPtr col_) : col(col_) { } - std::vector parse() const; + std::vector convert() const; private: - std::vector parseImpl(size_t shift, size_t count) const; + std::vector convertImpl(size_t shift, size_t count) const; - friend class RingFromColumnParser; + friend class RingFromColumnConverter; ColumnPtr col{nullptr}; }; template -class RingFromColumnParser +class RingFromColumnConverter { public: - RingFromColumnParser() = default; - - explicit RingFromColumnParser(ColumnPtr col_) + explicit RingFromColumnConverter(ColumnPtr col_) : col(col_) - , point_parser(typeid_cast(*col_).getDataPtr()) + , point_converter(typeid_cast(*col_).getDataPtr()) { } - std::vector> parse() const; + std::vector> convert() const; private: - friend class PointFromColumnParser; + friend class PointFromColumnConverter; /// To prevent use-after-free and increase column lifetime. ColumnPtr col{nullptr}; - const PointFromColumnParser point_parser{}; + const PointFromColumnConverter point_converter{}; }; template -class PolygonFromColumnParser +class PolygonFromColumnConverter { public: - PolygonFromColumnParser() = default; + PolygonFromColumnConverter() = default; - explicit PolygonFromColumnParser(ColumnPtr col_) + explicit PolygonFromColumnConverter(ColumnPtr col_) : col(col_) - , ring_parser(typeid_cast(*col_).getDataPtr()) + , ring_converter(typeid_cast(*col_).getDataPtr()) { } - std::vector> parse() const; + std::vector> convert() const; private: - friend class MultiPolygonFromColumnParser; + friend class MultiPolygonFromColumnConverter; /// To prevent use-after-free and increase column lifetime. ColumnPtr col{nullptr}; - const RingFromColumnParser ring_parser{}; + const RingFromColumnConverter ring_converter{}; }; template -class MultiPolygonFromColumnParser +class MultiPolygonFromColumnConverter { public: - MultiPolygonFromColumnParser() = default; + MultiPolygonFromColumnConverter() = default; - explicit MultiPolygonFromColumnParser(ColumnPtr col_) + explicit MultiPolygonFromColumnConverter(ColumnPtr col_) : col(col_) - , polygon_parser(typeid_cast(*col_).getDataPtr()) + , polygon_converter(typeid_cast(*col_).getDataPtr()) {} - std::vector> parse() const; + std::vector> convert() const; private: /// To prevent use-after-free and increase column lifetime. ColumnPtr col{nullptr}; - const PolygonFromColumnParser polygon_parser{}; + const PolygonFromColumnConverter polygon_converter{}; }; -extern template class PointFromColumnParser; -extern template class PointFromColumnParser; -extern template class RingFromColumnParser; -extern template class RingFromColumnParser; -extern template class PolygonFromColumnParser; -extern template class PolygonFromColumnParser; -extern template class MultiPolygonFromColumnParser; -extern template class MultiPolygonFromColumnParser; +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 Geographic or Cartesian point (a pair of numbers in both cases). @@ -207,6 +204,7 @@ private: ColumnFloat64::Container & second_container; }; +/// Serialize Point, Ring as Ring template class RingSerializer { @@ -238,6 +236,7 @@ private: ColumnUInt64::MutablePtr offsets; }; +/// Serialize Point, Ring, Polygon as Polygon template class PolygonSerializer { @@ -277,6 +276,7 @@ private: ColumnUInt64::MutablePtr offsets; }; +/// Serialize Point, Ring, Polygon, MultiPolygon as MultiPolygon template class MultiPolygonSerializer { @@ -326,7 +326,7 @@ private: template -struct ParserType +struct ConverterType { using Type = PType; }; @@ -334,12 +334,13 @@ struct ParserType template static void callOnGeometryDataType(DataTypePtr type, F && f) { + /// There is no Point type, because for most of geometry functions it is useless. if (DataTypeCustomRingSerialization::nestedDataType()->equals(*type)) - return f(ParserType>()); + return f(ConverterType>()); if (DataTypeCustomPolygonSerialization::nestedDataType()->equals(*type)) - return f(ParserType>()); + return f(ConverterType>()); if (DataTypeCustomMultiPolygonSerialization::nestedDataType()->equals(*type)) - return f(ParserType>()); + return f(ConverterType>()); throw Exception(fmt::format("Unknown geometry type {}", type->getName()), ErrorCodes::BAD_ARGUMENTS); } @@ -349,13 +350,13 @@ static void callOnTwoGeometryDataTypes(DataTypePtr left_type, DataTypePtr right_ { return callOnGeometryDataType(left_type, [&](const auto & left_types) { - using LeftParserType = std::decay_t; + using LeftConverterType = std::decay_t; return callOnGeometryDataType(right_type, [&](const auto & right_types) { - using RightParserType = std::decay_t; + using RightConverterType = std::decay_t; - return func(LeftParserType(), RightParserType()); + return func(LeftConverterType(), RightConverterType()); }); }); } diff --git a/src/Functions/polygonArea.cpp b/src/Functions/polygonArea.cpp index b21b4092419..1f2d47a3a5c 100644 --- a/src/Functions/polygonArea.cpp +++ b/src/Functions/polygonArea.cpp @@ -59,16 +59,16 @@ public: callOnGeometryDataType(arguments[0].type, [&] (const auto & type) { - using TypeParser = std::decay_t; - using Parser = typename TypeParser::Type; - Parser parser(arguments[0].column->convertToFullColumnIfConst()); - auto figures = parser.parse(); + using TypeConverter = std::decay_t; + using Converter = typename TypeConverter::Type; + Converter converter(arguments[0].column->convertToFullColumnIfConst()); + auto geometries = converter.convert(); auto & res_data = res_column->getData(); res_data.reserve(input_rows_count); for (size_t i = 0; i < input_rows_count; i++) - res_data.emplace_back(boost::geometry::area(figures[i])); + res_data.emplace_back(boost::geometry::area(geometries[i])); } ); diff --git a/src/Functions/polygonConvexHull.cpp b/src/Functions/polygonConvexHull.cpp index 6c9eb167fb1..422e46b3b15 100644 --- a/src/Functions/polygonConvexHull.cpp +++ b/src/Functions/polygonConvexHull.cpp @@ -1,89 +1,106 @@ -// #include -// #include +#include +#include -// #include -// #include -// #include +#include +#include +#include -// #include +#include -// #include -// #include -// #include -// #include -// #include -// #include +#include +#include +#include +#include +#include +#include -// #include -// #include +#include +#include -// namespace DB -// { +namespace DB +{ -// template -// class FunctionPolygonConvexHull : public IFunction -// { -// public: -// static const char * name; +namespace ErrorCodes +{ + extern const int BAD_ARGUMENTS; +} -// explicit FunctionPolygonConvexHull() = default; +template +class FunctionPolygonConvexHull : public IFunction +{ +public: + static const char * name; -// static FunctionPtr create(const Context &) -// { -// return std::make_shared(); -// } + explicit FunctionPolygonConvexHull() = default; -// String getName() const override -// { -// return name; -// } + static FunctionPtr create(const Context &) + { + return std::make_shared(); + } -// bool isVariadic() const override -// { -// return false; -// } + String getName() const override + { + return name; + } -// size_t getNumberOfArguments() const override -// { -// return 1; -// } + bool isVariadic() const override + { + return false; + } -// DataTypePtr getReturnTypeImpl(const DataTypes &) const override -// { -// return DataTypeCustomPolygonSerialization::nestedDataType(); -// } + size_t getNumberOfArguments() const override + { + return 1; + } -// ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr & /*result_type*/, size_t input_rows_count) const override -// { -// auto parser = getConverterBasedOnType(arguments[0]); -// auto figures = parseFigure(parser); + DataTypePtr getReturnTypeImpl(const DataTypes &) const override + { + return DataTypeCustomPolygonSerialization::nestedDataType(); + } -// PolygonSerializer serializer; + ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr & /*result_type*/, size_t input_rows_count) const override + { + PolygonSerializer serializer; -// for (size_t i = 0; i < input_rows_count; i++) -// { -// Polygon convex_hull{}; -// boost::geometry::convex_hull(figures[i], convex_hull); -// serializer.add(convex_hull); -// } + callOnGeometryDataType(arguments[0].type, [&] (const auto & type) + { + using TypeConverter = std::decay_t; + using Converter = typename TypeConverter::Type; -// return serializer.finalize(); -// } + if (std::is_same_v>) + throw Exception(fmt::format("The argument of function {} could not be a MultiPolygon", getName()), ErrorCodes::BAD_ARGUMENTS); + else + { + Converter converter(arguments[0].column->convertToFullColumnIfConst()); + auto geometries = converter.convert(); -// bool useDefaultImplementationForConstants() const override -// { -// return true; -// } -// }; + for (size_t i = 0; i < input_rows_count; i++) + { + Polygon convex_hull{}; + boost::geometry::convex_hull(geometries[i], convex_hull); + serializer.add(convex_hull); + } + } + } + ); + + return serializer.finalize(); + } + + bool useDefaultImplementationForConstants() const override + { + return true; + } +}; -// template <> -// const char * FunctionPolygonConvexHull::name = "polygonConvexHullCartesian"; +template <> +const char * FunctionPolygonConvexHull::name = "polygonConvexHullCartesian"; -// void registerFunctionPolygonConvexHull(FunctionFactory & factory) -// { -// factory.registerFunction>(); -// } +void registerFunctionPolygonConvexHull(FunctionFactory & factory) +{ + factory.registerFunction>(); +} -// } +} diff --git a/src/Functions/polygonPerimeter.cpp b/src/Functions/polygonPerimeter.cpp index f832d2965f9..1855ada51ed 100644 --- a/src/Functions/polygonPerimeter.cpp +++ b/src/Functions/polygonPerimeter.cpp @@ -1,94 +1,97 @@ -// #include -// #include +#include +#include -// #include -// #include -// #include +#include +#include +#include -// #include +#include -// #include -// #include -// #include -// #include -// #include -// #include +#include +#include +#include +#include +#include +#include -// #include -// #include +#include +#include -// namespace DB -// { +namespace DB +{ -// template -// class FunctionPolygonPerimeter : public IFunction -// { -// public: -// static const char * name; +template +class FunctionPolygonPerimeter : public IFunction +{ +public: + static const char * name; -// explicit FunctionPolygonPerimeter() = default; + explicit FunctionPolygonPerimeter() = default; -// static FunctionPtr create(const Context &) -// { -// return std::make_shared(); -// } + static FunctionPtr create(const Context &) + { + return std::make_shared(); + } -// String getName() const override -// { -// return name; -// } + String getName() const override + { + return name; + } -// bool isVariadic() const override -// { -// return false; -// } + bool isVariadic() const override + { + return false; + } -// size_t getNumberOfArguments() const override -// { -// return 1; -// } + size_t getNumberOfArguments() const override + { + return 1; + } -// DataTypePtr getReturnTypeImpl(const DataTypes &) const override -// { -// return std::make_shared(); -// } + DataTypePtr getReturnTypeImpl(const DataTypes &) const override + { + return std::make_shared(); + } -// ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr & /*result_type*/, size_t input_rows_count) const override -// { -// auto parser = getConverterBasedOnType(arguments[0]); -// auto figures = parseFigure(parser); + ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr & /*result_type*/, size_t input_rows_count) const override + { + auto res_column = ColumnFloat64::create(); + auto & res_data = res_column->getData(); + res_data.reserve(input_rows_count); -// auto res_column = ColumnFloat64::create(); -// auto & res_data = res_column->getData(); -// res_data.reserve(input_rows_count); + callOnGeometryDataType(arguments[0].type, [&] (const auto & type) + { + using TypeConverter = std::decay_t; + using Converter = typename TypeConverter::Type; + Converter converter(arguments[0].column->convertToFullColumnIfConst()); + auto geometries = converter.convert(); -// for (size_t i = 0; i < input_rows_count; i++) -// { -// boost::geometry::correct(figures[i]); -// res_data.emplace_back(boost::geometry::perimeter(figures[i])); -// } + for (size_t i = 0; i < input_rows_count; i++) + res_data.emplace_back(boost::geometry::perimeter(geometries[i])); + } + ); -// return res_column; -// } + return res_column; + } -// bool useDefaultImplementationForConstants() const override -// { -// return true; -// } -// }; + bool useDefaultImplementationForConstants() const override + { + return true; + } +}; -// template <> -// const char * FunctionPolygonPerimeter::name = "polygonPerimeterCartesian"; +template <> +const char * FunctionPolygonPerimeter::name = "polygonPerimeterCartesian"; -// template <> -// const char * FunctionPolygonPerimeter::name = "polygonPerimeterGeographic"; +template <> +const char * FunctionPolygonPerimeter::name = "polygonPerimeterGeographic"; -// void registerFunctionPolygonPerimeter(FunctionFactory & factory) -// { -// factory.registerFunction>(); -// factory.registerFunction>(); -// } +void registerFunctionPolygonPerimeter(FunctionFactory & factory) +{ + factory.registerFunction>(); + factory.registerFunction>(); +} -// } +} diff --git a/src/Functions/polygonsDistance.cpp b/src/Functions/polygonsDistance.cpp index 679345dc693..a5341482f2f 100644 --- a/src/Functions/polygonsDistance.cpp +++ b/src/Functions/polygonsDistance.cpp @@ -1,101 +1,107 @@ -// #include -// #include +#include +#include -// #include -// #include -// #include +#include +#include +#include -// #include +#include -// #include -// #include -// #include -// #include -// #include -// #include -// #include -// #include +#include +#include +#include +#include +#include +#include +#include +#include -// #include -// #include +#include +#include -// namespace DB -// { +namespace DB +{ -// template -// class FunctionPolygonsDistance : public IFunction -// { -// public: -// static inline const char * name; +template +class FunctionPolygonsDistance : public IFunction +{ +public: + static inline const char * name; -// explicit FunctionPolygonsDistance() = default; + explicit FunctionPolygonsDistance() = default; -// static FunctionPtr create(const Context &) -// { -// return std::make_shared(); -// } + static FunctionPtr create(const Context &) + { + return std::make_shared(); + } -// String getName() const override -// { -// return name; -// } + String getName() const override + { + return name; + } -// bool isVariadic() const override -// { -// return false; -// } + bool isVariadic() const override + { + return false; + } -// size_t getNumberOfArguments() const override -// { -// return 2; -// } + size_t getNumberOfArguments() const override + { + return 2; + } -// DataTypePtr getReturnTypeImpl(const DataTypes &) const override -// { -// return std::make_shared(); -// } + DataTypePtr getReturnTypeImpl(const DataTypes &) const override + { + return std::make_shared(); + } -// ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr & /*result_type*/, size_t input_rows_count) const override -// { -// auto first_parser = getConverterBasedOnType(arguments[0]); -// auto second_parser = getConverterBasedOnType(arguments[1]); + ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr & /*result_type*/, size_t input_rows_count) const override + { + auto res_column = ColumnFloat64::create(); + auto & res_data = res_column->getData(); + res_data.reserve(input_rows_count); -// auto first = parseFigure(first_parser); -// auto second = parseFigure(second_parser); + callOnTwoGeometryDataTypes(arguments[0].type, arguments[1].type, [&](const auto & left_type, const auto & right_type) + { + using LeftConverterType = std::decay_t; + using RightConverterType = std::decay_t; -// auto res_column = ColumnFloat64::create(); -// auto & res_data = res_column->getData(); -// res_data.reserve(input_rows_count); + using LeftConverter = typename LeftConverterType::Type; + using RightConverter = typename RightConverterType::Type; -// for (size_t i = 0; i < input_rows_count; i++) -// { -// boost::geometry::correct(first[i]); -// boost::geometry::correct(second[i]); + auto first = LeftConverter(arguments[0].column->convertToFullColumnIfConst()).convert(); + auto second = RightConverter(arguments[1].column->convertToFullColumnIfConst()).convert(); -// res_data.emplace_back(boost::geometry::distance(first[i], second[i])); -// } + for (size_t i = 0; i < input_rows_count; i++) + { + boost::geometry::correct(first[i]); + boost::geometry::correct(second[i]); -// return res_column; -// } + res_data.emplace_back(boost::geometry::distance(first[i], second[i])); + } + }); -// bool useDefaultImplementationForConstants() const override -// { -// return true; -// } -// }; + return res_column; + } -// template <> -// const char * FunctionPolygonsDistance::name = "polygonsDistanceCartesian"; + bool useDefaultImplementationForConstants() const override + { + return true; + } +}; -// template <> -// const char * FunctionPolygonsDistance::name = "polygonsDistanceGeographic"; +template <> +const char * FunctionPolygonsDistance::name = "polygonsDistanceCartesian"; + +template <> +const char * FunctionPolygonsDistance::name = "polygonsDistanceGeographic"; -// void registerFunctionPolygonsDistance(FunctionFactory & factory) -// { -// factory.registerFunction>(); -// factory.registerFunction>(); -// } +void registerFunctionPolygonsDistance(FunctionFactory & factory) +{ + factory.registerFunction>(); + factory.registerFunction>(); +} -// } +} diff --git a/src/Functions/polygonsEquals.cpp b/src/Functions/polygonsEquals.cpp index 8349e8837cd..d235e88b465 100644 --- a/src/Functions/polygonsEquals.cpp +++ b/src/Functions/polygonsEquals.cpp @@ -1,98 +1,105 @@ -// #include -// #include +#include +#include -// #include -// #include -// #include +#include +#include +#include -// #include +#include -// #include -// #include -// #include -// #include -// #include -// #include -// #include -// #include +#include +#include +#include +#include +#include +#include +#include +#include -// #include -// #include +#include +#include -// namespace DB -// { +namespace DB +{ -// template -// class FunctionPolygonsEquals : public IFunction -// { -// public: -// static const char * name; +template +class FunctionPolygonsEquals : public IFunction +{ +public: + static const char * name; -// explicit FunctionPolygonsEquals() = default; + explicit FunctionPolygonsEquals() = default; -// static FunctionPtr create(const Context &) -// { -// return std::make_shared(); -// } + static FunctionPtr create(const Context &) + { + return std::make_shared(); + } -// String getName() const override -// { -// return name; -// } + String getName() const override + { + return name; + } -// bool isVariadic() const override -// { -// return false; -// } + bool isVariadic() const override + { + return false; + } -// size_t getNumberOfArguments() const override -// { -// return 2; -// } + size_t getNumberOfArguments() const override + { + return 2; + } -// DataTypePtr getReturnTypeImpl(const DataTypes &) const override -// { -// return std::make_shared(); -// } + DataTypePtr getReturnTypeImpl(const DataTypes &) const override + { + return std::make_shared(); + } -// ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr & /*result_type*/, size_t input_rows_count) const override -// { -// auto first_parser = getConverterBasedOnType(arguments[0]); -// auto second_parser = getConverterBasedOnType(arguments[1]); + ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr & /*result_type*/, size_t input_rows_count) const override + { + auto res_column = ColumnUInt8::create(); + auto & res_data = res_column->getData(); + res_data.reserve(input_rows_count); -// auto first = parseFigure(first_parser); -// auto second = parseFigure(second_parser); + callOnTwoGeometryDataTypes(arguments[0].type, arguments[1].type, [&](const auto & left_type, const auto & right_type) + { + using LeftConverterType = std::decay_t; + using RightConverterType = std::decay_t; -// auto res_column = ColumnUInt8::create(); -// auto & res_data = res_column->getData(); -// res_data.reserve(input_rows_count); + using LeftConverter = typename LeftConverterType::Type; + using RightConverter = typename RightConverterType::Type; -// for (size_t i = 0; i < input_rows_count; i++) -// { -// boost::geometry::correct(first[i]); -// boost::geometry::correct(second[i]); + auto first = LeftConverter(arguments[0].column->convertToFullColumnIfConst()).convert(); + auto second = RightConverter(arguments[1].column->convertToFullColumnIfConst()).convert(); -// /// Main work here. -// res_data.emplace_back(boost::geometry::equals(first[i], second[i])); -// } + for (size_t i = 0; i < input_rows_count; i++) + { + boost::geometry::correct(first[i]); + boost::geometry::correct(second[i]); -// return res_column; -// } + /// Main work here. + res_data.emplace_back(boost::geometry::equals(first[i], second[i])); + } + } + ); -// bool useDefaultImplementationForConstants() const override -// { -// return true; -// } -// }; + return res_column; + } + + bool useDefaultImplementationForConstants() const override + { + return true; + } +}; -// template <> -// const char * FunctionPolygonsEquals::name = "polygonsEqualsCartesian"; +template <> +const char * FunctionPolygonsEquals::name = "polygonsEqualsCartesian"; -// void registerFunctionPolygonsEquals(FunctionFactory & factory) -// { -// factory.registerFunction>(); -// } +void registerFunctionPolygonsEquals(FunctionFactory & factory) +{ + factory.registerFunction>(); +} -// } +} diff --git a/src/Functions/polygonsIntersection.cpp b/src/Functions/polygonsIntersection.cpp index 4d6569f37a2..285255df031 100644 --- a/src/Functions/polygonsIntersection.cpp +++ b/src/Functions/polygonsIntersection.cpp @@ -59,15 +59,16 @@ public: { MultiPolygonSerializer serializer; - callOnTwoGeometryDataTypes(arguments[0].type, arguments[1].type, [&](const auto & left_type, const auto & right_type) { - using LeftParserType = std::decay_t; - using RightParserType = std::decay_t; + callOnTwoGeometryDataTypes(arguments[0].type, arguments[1].type, [&](const auto & left_type, const auto & right_type) + { + using LeftConverterType = std::decay_t; + using RightConverterType = std::decay_t; - using LeftParser = typename LeftParserType::Type; - using RightParser = typename RightParserType::Type; + using LeftConverter = typename LeftConverterType::Type; + using RightConverter = typename RightConverterType::Type; - auto first = LeftParser(arguments[0].column->convertToFullColumnIfConst()).parse(); - auto second = RightParser(arguments[1].column->convertToFullColumnIfConst()).parse(); + auto first = LeftConverter(arguments[0].column->convertToFullColumnIfConst()).convert(); + auto second = RightConverter(arguments[1].column->convertToFullColumnIfConst()).convert(); /// 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 bec6e10ba9b..20b521f7d6b 100644 --- a/src/Functions/polygonsSymDifference.cpp +++ b/src/Functions/polygonsSymDifference.cpp @@ -1,99 +1,105 @@ -// #include -// #include +#include +#include -// #include -// #include -// #include +#include +#include +#include -// #include +#include -// #include -// #include -// #include -// #include -// #include -// #include +#include +#include +#include +#include +#include +#include -// #include -// #include +#include +#include -// namespace DB -// { +namespace DB +{ -// template -// class FunctionPolygonsSymDifference : public IFunction -// { -// public: -// static const char * name; +template +class FunctionPolygonsSymDifference : public IFunction +{ +public: + static const char * name; -// explicit FunctionPolygonsSymDifference() = default; + explicit FunctionPolygonsSymDifference() = default; -// static FunctionPtr create(const Context &) -// { -// return std::make_shared(); -// } + static FunctionPtr create(const Context &) + { + return std::make_shared(); + } -// String getName() const override -// { -// return name; -// } + String getName() const override + { + return name; + } -// bool isVariadic() const override -// { -// return false; -// } + bool isVariadic() const override + { + return false; + } -// size_t getNumberOfArguments() const override -// { -// return 2; -// } + size_t getNumberOfArguments() const override + { + return 2; + } -// DataTypePtr getReturnTypeImpl(const DataTypes &) const override -// { -// return DataTypeCustomMultiPolygonSerialization::nestedDataType(); -// } + DataTypePtr getReturnTypeImpl(const DataTypes &) const override + { + return DataTypeCustomMultiPolygonSerialization::nestedDataType(); + } -// ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr & /*result_type*/, size_t input_rows_count) const override -// { -// auto first_parser = getConverterBasedOnType(arguments[0]); -// auto second_parser = getConverterBasedOnType(arguments[1]); + ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr & /*result_type*/, size_t input_rows_count) const override + { + MultiPolygonSerializer serializer; -// auto first = parseFigure(first_parser); -// auto second = parseFigure(second_parser); + callOnTwoGeometryDataTypes(arguments[0].type, arguments[1].type, [&](const auto & left_type, const auto & right_type) + { + using LeftConverterType = std::decay_t; + using RightConverterType = std::decay_t; -// MultiPolygonSerializer serializer; + using LeftConverter = typename LeftConverterType::Type; + using RightConverter = typename RightConverterType::Type; -// /// NOLINTNEXTLINE(clang-analyzer-core.uninitialized.Assign) -// for (size_t i = 0; i < input_rows_count; i++) -// { -// boost::geometry::correct(first[i]); -// boost::geometry::correct(second[i]); + auto first = LeftConverter(arguments[0].column->convertToFullColumnIfConst()).convert(); + auto second = RightConverter(arguments[1].column->convertToFullColumnIfConst()).convert(); -// MultiPolygon sym_difference{}; -// boost::geometry::sym_difference(first[i], second[i], sym_difference); + /// NOLINTNEXTLINE(clang-analyzer-core.uninitialized.Assign) + for (size_t i = 0; i < input_rows_count; i++) + { + boost::geometry::correct(first[i]); + boost::geometry::correct(second[i]); -// serializer.add(sym_difference); -// } + MultiPolygon sym_difference{}; + boost::geometry::sym_difference(first[i], second[i], sym_difference); -// return serializer.finalize(); -// } + serializer.add(sym_difference); + } + }); -// bool useDefaultImplementationForConstants() const override -// { -// return true; -// } -// }; + return serializer.finalize(); + } -// template <> -// const char * FunctionPolygonsSymDifference::name = "polygonsSymDifferenceCartesian"; + bool useDefaultImplementationForConstants() const override + { + return true; + } +}; -// template <> -// const char * FunctionPolygonsSymDifference::name = "polygonsSymDifferenceGeographic"; +template <> +const char * FunctionPolygonsSymDifference::name = "polygonsSymDifferenceCartesian"; -// void registerFunctionPolygonsSymDifference(FunctionFactory & factory) -// { -// factory.registerFunction>(); -// factory.registerFunction>(); -// } +template <> +const char * FunctionPolygonsSymDifference::name = "polygonsSymDifferenceGeographic"; -// } +void registerFunctionPolygonsSymDifference(FunctionFactory & factory) +{ + factory.registerFunction>(); + factory.registerFunction>(); +} + +} diff --git a/src/Functions/polygonsUnion.cpp b/src/Functions/polygonsUnion.cpp index 3922c4887ca..f236bf13bc3 100644 --- a/src/Functions/polygonsUnion.cpp +++ b/src/Functions/polygonsUnion.cpp @@ -1,103 +1,109 @@ -// #include -// #include +#include +#include -// #include -// #include -// #include +#include +#include +#include -// #include +#include -// #include -// #include -// #include -// #include -// #include -// #include +#include +#include +#include +#include +#include +#include -// #include -// #include +#include +#include -// namespace DB -// { +namespace DB +{ -// template -// class FunctionPolygonsUnion : public IFunction -// { -// public: -// static inline const char * name; +template +class FunctionPolygonsUnion : public IFunction +{ +public: + static inline const char * name; -// explicit FunctionPolygonsUnion() = default; + explicit FunctionPolygonsUnion() = default; -// static FunctionPtr create(const Context &) -// { -// return std::make_shared(); -// } + static FunctionPtr create(const Context &) + { + return std::make_shared(); + } -// String getName() const override -// { -// return name; -// } + String getName() const override + { + return name; + } -// bool isVariadic() const override -// { -// return false; -// } + bool isVariadic() const override + { + return false; + } -// size_t getNumberOfArguments() const override -// { -// return 2; -// } + size_t getNumberOfArguments() const override + { + return 2; + } -// DataTypePtr getReturnTypeImpl(const DataTypes &) const override -// { -// return DataTypeCustomMultiPolygonSerialization::nestedDataType(); -// } + DataTypePtr getReturnTypeImpl(const DataTypes &) const override + { + return DataTypeCustomMultiPolygonSerialization::nestedDataType(); + } -// ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr & /*result_type*/, size_t input_rows_count) const override -// { -// auto first_parser = getConverterBasedOnType(arguments[0]); -// auto second_parser = getConverterBasedOnType(arguments[1]); + ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr & /*result_type*/, size_t input_rows_count) const override + { + MultiPolygonSerializer serializer; -// auto first = parseFigure(first_parser); -// auto second = parseFigure(second_parser); + callOnTwoGeometryDataTypes(arguments[0].type, arguments[1].type, [&](const auto & left_type, const auto & right_type) + { + using LeftConverterType = std::decay_t; + using RightConverterType = std::decay_t; -// MultiPolygonSerializer serializer; + using LeftConverter = typename LeftConverterType::Type; + using RightConverter = typename RightConverterType::Type; -// /// We are not interested in some pitfalls in third-party libraries -// /// NOLINTNEXTLINE(clang-analyzer-core.uninitialized.Assign) -// for (size_t i = 0; i < input_rows_count; i++) -// { -// /// Orient the polygons correctly. -// boost::geometry::correct(first[i]); -// boost::geometry::correct(second[i]); + auto first = LeftConverter(arguments[0].column->convertToFullColumnIfConst()).convert(); + auto second = RightConverter(arguments[1].column->convertToFullColumnIfConst()).convert(); -// MultiPolygon polygons_union{}; -// /// Main work here. -// boost::geometry::union_(first[i], second[i], polygons_union); + /// We are not interested in some pitfalls in third-party libraries + /// NOLINTNEXTLINE(clang-analyzer-core.uninitialized.Assign) + for (size_t i = 0; i < input_rows_count; i++) + { + /// Orient the polygons correctly. + boost::geometry::correct(first[i]); + boost::geometry::correct(second[i]); -// serializer.add(polygons_union); -// } + MultiPolygon polygons_union{}; + /// Main work here. + boost::geometry::union_(first[i], second[i], polygons_union); -// return serializer.finalize(); -// } + serializer.add(polygons_union); + } + }); -// bool useDefaultImplementationForConstants() const override -// { -// return true; -// } -// }; + return serializer.finalize(); + } -// template <> -// const char * FunctionPolygonsUnion::name = "polygonsUnionCartesian"; + bool useDefaultImplementationForConstants() const override + { + return true; + } +}; -// template <> -// const char * FunctionPolygonsUnion::name = "polygonsUnionGeographic"; +template <> +const char * FunctionPolygonsUnion::name = "polygonsUnionCartesian"; + +template <> +const char * FunctionPolygonsUnion::name = "polygonsUnionGeographic"; -// void registerFunctionPolygonsUnion(FunctionFactory & factory) -// { -// factory.registerFunction>(); -// factory.registerFunction>(); -// } +void registerFunctionPolygonsUnion(FunctionFactory & factory) +{ + factory.registerFunction>(); + factory.registerFunction>(); +} -// } +} diff --git a/src/Functions/polygonsWithin.cpp b/src/Functions/polygonsWithin.cpp index 0b77ba45582..1e591cf0de2 100644 --- a/src/Functions/polygonsWithin.cpp +++ b/src/Functions/polygonsWithin.cpp @@ -1,101 +1,108 @@ -// #include -// #include +#include +#include -// #include -// #include -// #include +#include +#include +#include -// #include +#include -// #include -// #include -// #include -// #include -// #include -// #include -// #include -// #include +#include +#include +#include +#include +#include +#include +#include +#include -// #include -// #include +#include +#include -// namespace DB -// { +namespace DB +{ -// template -// class FunctionPolygonsWithin : public IFunction -// { -// public: -// static inline const char * name; +template +class FunctionPolygonsWithin : public IFunction +{ +public: + static inline const char * name; -// explicit FunctionPolygonsWithin() = default; + explicit FunctionPolygonsWithin() = default; -// static FunctionPtr create(const Context &) -// { -// return std::make_shared(); -// } + static FunctionPtr create(const Context &) + { + return std::make_shared(); + } -// String getName() const override -// { -// return name; -// } + String getName() const override + { + return name; + } -// bool isVariadic() const override -// { -// return false; -// } + bool isVariadic() const override + { + return false; + } -// size_t getNumberOfArguments() const override -// { -// return 2; -// } + size_t getNumberOfArguments() const override + { + return 2; + } -// DataTypePtr getReturnTypeImpl(const DataTypes &) const override -// { -// return std::make_shared(); -// } + DataTypePtr getReturnTypeImpl(const DataTypes &) const override + { + return std::make_shared(); + } -// ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr & /*result_type*/, size_t input_rows_count) const override -// { -// auto first_parser = getConverterBasedOnType(arguments[0]); -// auto second_parser = getConverterBasedOnType(arguments[1]); + ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr & /*result_type*/, size_t input_rows_count) const override + { + auto res_column = ColumnUInt8::create(); + auto & res_data = res_column->getData(); + res_data.reserve(input_rows_count); -// auto first = parseFigure(first_parser); -// auto second = parseFigure(second_parser); + callOnTwoGeometryDataTypes(arguments[0].type, arguments[1].type, [&](const auto & left_type, const auto & right_type) + { + using LeftConverterType = std::decay_t; + using RightConverterType = std::decay_t; -// auto res_column = ColumnUInt8::create(); -// auto & res_data = res_column->getData(); + using LeftConverter = typename LeftConverterType::Type; + using RightConverter = typename RightConverterType::Type; -// /// NOLINTNEXTLINE(clang-analyzer-core.uninitialized.Assign) -// for (size_t i = 0; i < input_rows_count; i++) -// { -// boost::geometry::correct(first[i]); -// boost::geometry::correct(second[i]); + auto first = LeftConverter(arguments[0].column->convertToFullColumnIfConst()).convert(); + auto second = RightConverter(arguments[1].column->convertToFullColumnIfConst()).convert(); -// res_data.emplace_back(boost::geometry::within(first[i], second[i])); -// } + /// NOLINTNEXTLINE(clang-analyzer-core.uninitialized.Assign) + for (size_t i = 0; i < input_rows_count; i++) + { + boost::geometry::correct(first[i]); + boost::geometry::correct(second[i]); -// return res_column; -// } + res_data.emplace_back(boost::geometry::within(first[i], second[i])); + } + }); -// bool useDefaultImplementationForConstants() const override -// { -// return true; -// } -// }; + return res_column; + } + + bool useDefaultImplementationForConstants() const override + { + return true; + } +}; -// template <> -// const char * FunctionPolygonsWithin::name = "polygonsWithinCartesian"; +template <> +const char * FunctionPolygonsWithin::name = "polygonsWithinCartesian"; -// template <> -// const char * FunctionPolygonsWithin::name = "polygonsWithinGeographic"; +template <> +const char * FunctionPolygonsWithin::name = "polygonsWithinGeographic"; -// void registerFunctionPolygonsWithin(FunctionFactory & factory) -// { -// factory.registerFunction>(); -// factory.registerFunction>(); -// } +void registerFunctionPolygonsWithin(FunctionFactory & factory) +{ + factory.registerFunction>(); + factory.registerFunction>(); +} -// } +} diff --git a/src/Functions/registerFunctionsGeo.cpp b/src/Functions/registerFunctionsGeo.cpp index 263f654203e..605dd4dcba0 100644 --- a/src/Functions/registerFunctionsGeo.cpp +++ b/src/Functions/registerFunctionsGeo.cpp @@ -11,20 +11,19 @@ void registerFunctionGeoDistance(FunctionFactory & factory); void registerFunctionPointInEllipses(FunctionFactory & factory); void registerFunctionPointInPolygon(FunctionFactory & factory); void registerFunctionPolygonsIntersection(FunctionFactory & factory); -// void registerFunctionPolygonsUnion(FunctionFactory & factory); +void registerFunctionPolygonsUnion(FunctionFactory & factory); void registerFunctionPolygonArea(FunctionFactory & factory); -// void registerFunctionPolygonConvexHull(FunctionFactory & factory); -// void registerFunctionPolygonsSymDifference(FunctionFactory & factory); -// void registerFunctionPolygonsEquals(FunctionFactory & factory); -// void registerFunctionPolygonsDistance(FunctionFactory & factory); -// void registerFunctionPolygonsWithin(FunctionFactory & factory); -// void registerFunctionPolygonPerimeter(FunctionFactory & factory); +void registerFunctionPolygonConvexHull(FunctionFactory & factory); +void registerFunctionPolygonsSymDifference(FunctionFactory & factory); +void registerFunctionPolygonsEquals(FunctionFactory & factory); +void registerFunctionPolygonsDistance(FunctionFactory & factory); +void registerFunctionPolygonsWithin(FunctionFactory & factory); +void registerFunctionPolygonPerimeter(FunctionFactory & factory); void registerFunctionGeohashEncode(FunctionFactory & factory); void registerFunctionGeohashDecode(FunctionFactory & factory); void registerFunctionGeohashesInBox(FunctionFactory & factory); void registerFunctionWkt(FunctionFactory & factory); void registerFunctionReadWkt(FunctionFactory & factory); -void registerFunctionDescribeGeometry(FunctionFactory & factory); void registerFunctionSvg(FunctionFactory & factory); #if USE_H3 @@ -50,20 +49,19 @@ void registerFunctionsGeo(FunctionFactory & factory) registerFunctionPointInEllipses(factory); registerFunctionPointInPolygon(factory); registerFunctionPolygonsIntersection(factory); - // registerFunctionPolygonsUnion(factory); + registerFunctionPolygonsUnion(factory); registerFunctionPolygonArea(factory); - // registerFunctionPolygonConvexHull(factory); - // registerFunctionPolygonsSymDifference(factory); - // registerFunctionPolygonsEquals(factory); - // registerFunctionPolygonsDistance(factory); - // registerFunctionPolygonsWithin(factory); - // registerFunctionPolygonPerimeter(factory); + registerFunctionPolygonConvexHull(factory); + registerFunctionPolygonsSymDifference(factory); + registerFunctionPolygonsEquals(factory); + registerFunctionPolygonsDistance(factory); + registerFunctionPolygonsWithin(factory); + registerFunctionPolygonPerimeter(factory); registerFunctionGeohashEncode(factory); registerFunctionGeohashDecode(factory); registerFunctionGeohashesInBox(factory); registerFunctionWkt(factory); registerFunctionReadWkt(factory); - registerFunctionDescribeGeometry(factory); registerFunctionSvg(factory); #if USE_H3 diff --git a/src/Functions/svg.cpp b/src/Functions/svg.cpp index 79482666222..2ad9f96ca15 100644 --- a/src/Functions/svg.cpp +++ b/src/Functions/svg.cpp @@ -69,10 +69,10 @@ public: callOnGeometryDataType(arguments[0].type, [&] (const auto & type) { - using TypeParser = std::decay_t; - using Parser = typename TypeParser::Type; - Parser parser(arguments[0].column->convertToFullColumnIfConst()); - auto figures = parser.parse(); + 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; @@ -89,7 +89,7 @@ public: } } ); - + return res_column; } diff --git a/src/Functions/wkt.cpp b/src/Functions/wkt.cpp index d088a3b5600..08aeb76dcdd 100644 --- a/src/Functions/wkt.cpp +++ b/src/Functions/wkt.cpp @@ -42,10 +42,10 @@ public: callOnGeometryDataType(arguments[0].type, [&] (const auto & type) { - using TypeParser = std::decay_t; - using Parser = typename TypeParser::Type; - Parser parser(arguments[0].column->convertToFullColumnIfConst()); - auto figures = parser.parse(); + using TypeConverter = std::decay_t; + using Converter = typename TypeConverter::Type; + Converter converter(arguments[0].column->convertToFullColumnIfConst()); + auto figures = converter.convert(); for (size_t i = 0; i < input_rows_count; i++) { @@ -56,7 +56,7 @@ public: } } ); - + return res_column; } diff --git a/tests/queries/0_stateless/01307_polygon_perimeter.sql b/tests/queries/0_stateless/01307_polygon_perimeter.sql index 1cbbf41a201..2fd0c369379 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.)]]]); \ No newline at end of file +select polygonPerimeterCartesian([[[(0., 0.), (0., 5.), (5., 5.), (5., 0.), (0., 0.)]]]); \ No newline at end of file