This is an automated email from the ASF dual-hosted git repository. lihaopeng pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/master by this push: new 444f96aa913 [opt](function)avoid virtual function calls in geo functions (#37003) 444f96aa913 is described below commit 444f96aa9136f81ccd53244e0e41769f54f0e064 Author: Mryange <59914473+mrya...@users.noreply.github.com> AuthorDate: Mon Jul 1 12:53:32 2024 +0800 [opt](function)avoid virtual function calls in geo functions (#37003) --- be/src/vec/functions/functions_geo.cpp | 285 +++++++++++++++++++++------------ be/src/vec/functions/functions_geo.h | 5 +- 2 files changed, 189 insertions(+), 101 deletions(-) diff --git a/be/src/vec/functions/functions_geo.cpp b/be/src/vec/functions/functions_geo.cpp index 036033db2a2..b389bc1636e 100644 --- a/be/src/vec/functions/functions_geo.cpp +++ b/be/src/vec/functions/functions_geo.cpp @@ -26,6 +26,7 @@ #include "geo/geo_common.h" #include "geo/geo_types.h" #include "vec/columns/column.h" +#include "vec/columns/column_nullable.h" #include "vec/columns/columns_number.h" #include "vec/common/string_ref.h" #include "vec/core/block.h" @@ -33,6 +34,7 @@ #include "vec/core/field.h" #include "vec/data_types/data_type_nullable.h" #include "vec/data_types/data_type_number.h" +#include "vec/data_types/data_type_string.h" #include "vec/functions/simple_function_factory.h" namespace doris::vectorized { @@ -41,6 +43,7 @@ struct StPoint { static constexpr auto NEED_CONTEXT = false; static constexpr auto NAME = "st_point"; static const size_t NUM_ARGS = 2; + using Type = DataTypeString; static Status execute(Block& block, const ColumnNumbers& arguments, size_t result) { DCHECK_EQ(arguments.size(), 2); auto return_type = block.get_data_type(result); @@ -52,26 +55,29 @@ struct StPoint { const auto size = std::max(left_column->size(), right_column->size()); - MutableColumnPtr res = return_type->create_column(); - + auto res = ColumnString::create(); + auto null_map = ColumnUInt8::create(size, 0); + auto& null_map_data = null_map->get_data(); GeoPoint point; std::string buf; if (left_const) { - const_vector(left_column, right_column, res, size, point, buf); + const_vector(left_column, right_column, res, null_map_data, size, point, buf); } else if (right_const) { - vector_const(left_column, right_column, res, size, point, buf); + vector_const(left_column, right_column, res, null_map_data, size, point, buf); } else { - vector_vector(left_column, right_column, res, size, point, buf); + vector_vector(left_column, right_column, res, null_map_data, size, point, buf); } - block.replace_by_position(result, std::move(res)); + block.replace_by_position(result, + ColumnNullable::create(std::move(res), std::move(null_map))); return Status::OK(); } - static void loop_do(GeoParseStatus& cur_res, MutableColumnPtr& res, GeoPoint& point, - std::string& buf) { + static void loop_do(GeoParseStatus& cur_res, ColumnString::MutablePtr& res, NullMap& null_map, + int row, GeoPoint& point, std::string& buf) { if (cur_res != GEO_PARSE_OK) { - res->insert_data(nullptr, 0); + null_map[row] = 1; + res->insert_default(); return; } @@ -81,32 +87,32 @@ struct StPoint { } static void const_vector(const ColumnPtr& left_column, const ColumnPtr& right_column, - MutableColumnPtr& res, const size_t size, GeoPoint& point, - std::string& buf) { + ColumnString::MutablePtr& res, NullMap& null_map, const size_t size, + GeoPoint& point, std::string& buf) { double x = left_column->operator[](0).get<Float64>(); for (int row = 0; row < size; ++row) { auto cur_res = point.from_coord(x, right_column->operator[](row).get<Float64>()); - loop_do(cur_res, res, point, buf); + loop_do(cur_res, res, null_map, row, point, buf); } } static void vector_const(const ColumnPtr& left_column, const ColumnPtr& right_column, - MutableColumnPtr& res, const size_t size, GeoPoint& point, - std::string& buf) { + ColumnString::MutablePtr& res, NullMap& null_map, const size_t size, + GeoPoint& point, std::string& buf) { double y = right_column->operator[](0).get<Float64>(); for (int row = 0; row < size; ++row) { auto cur_res = point.from_coord(right_column->operator[](row).get<Float64>(), y); - loop_do(cur_res, res, point, buf); + loop_do(cur_res, res, null_map, row, point, buf); } } static void vector_vector(const ColumnPtr& left_column, const ColumnPtr& right_column, - MutableColumnPtr& res, const size_t size, GeoPoint& point, - std::string& buf) { + ColumnString::MutablePtr& res, NullMap& null_map, const size_t size, + GeoPoint& point, std::string& buf) { for (int row = 0; row < size; ++row) { auto cur_res = point.from_coord(left_column->operator[](row).get<Float64>(), right_column->operator[](row).get<Float64>()); - loop_do(cur_res, res, point, buf); + loop_do(cur_res, res, null_map, row, point, buf); } } }; @@ -123,6 +129,7 @@ struct StAsText { static constexpr auto NEED_CONTEXT = false; static constexpr auto NAME = FunctionName::NAME; static const size_t NUM_ARGS = 1; + using Type = DataTypeString; static Status execute(Block& block, const ColumnNumbers& arguments, size_t result) { DCHECK_EQ(arguments.size(), 1); auto return_type = block.get_data_type(result); @@ -131,20 +138,24 @@ struct StAsText { auto size = input->size(); - MutableColumnPtr res = return_type->create_column(); + auto res = ColumnString::create(); + auto null_map = ColumnUInt8::create(size, 0); + auto& null_map_data = null_map->get_data(); std::unique_ptr<GeoShape> shape; for (int row = 0; row < size; ++row) { auto shape_value = input->get_data_at(row); shape = GeoShape::from_encoded(shape_value.data, shape_value.size); if (shape == nullptr) { - res->insert_data(nullptr, 0); + null_map_data[row] = 1; + res->insert_default(); continue; } auto wkt = shape->as_wkt(); res->insert_data(wkt.data(), wkt.size()); } - block.replace_by_position(result, std::move(res)); + block.replace_by_position(result, + ColumnNullable::create(std::move(res), std::move(null_map))); return Status::OK(); } @@ -154,6 +165,7 @@ struct StX { static constexpr auto NEED_CONTEXT = false; static constexpr auto NAME = "st_x"; static const size_t NUM_ARGS = 1; + using Type = DataTypeFloat64; static Status execute(Block& block, const ColumnNumbers& arguments, size_t result) { DCHECK_EQ(arguments.size(), 1); auto return_type = block.get_data_type(result); @@ -162,7 +174,10 @@ struct StX { auto size = input->size(); - MutableColumnPtr res = return_type->create_column(); + auto res = ColumnFloat64::create(); + auto null_map = ColumnUInt8::create(size, 0); + auto& null_map_data = null_map->get_data(); + res->reserve(size); GeoPoint point; for (int row = 0; row < size; ++row) { @@ -170,13 +185,15 @@ struct StX { auto pt = point.decode_from(point_value.data, point_value.size); if (!pt) { + null_map_data[row] = 1; res->insert_default(); continue; } auto x_value = point.x(); - res->insert_data(const_cast<const char*>((char*)(&x_value)), 0); + res->insert_value(x_value); } - block.replace_by_position(result, std::move(res)); + block.replace_by_position(result, + ColumnNullable::create(std::move(res), std::move(null_map))); return Status::OK(); } @@ -186,6 +203,7 @@ struct StY { static constexpr auto NEED_CONTEXT = false; static constexpr auto NAME = "st_y"; static const size_t NUM_ARGS = 1; + using Type = DataTypeFloat64; static Status execute(Block& block, const ColumnNumbers& arguments, size_t result) { DCHECK_EQ(arguments.size(), 1); auto return_type = block.get_data_type(result); @@ -194,7 +212,10 @@ struct StY { auto size = input->size(); - MutableColumnPtr res = return_type->create_column(); + auto res = ColumnFloat64::create(); + res->reserve(size); + auto null_map = ColumnUInt8::create(size, 0); + auto& null_map_data = null_map->get_data(); GeoPoint point; for (int row = 0; row < size; ++row) { @@ -202,13 +223,15 @@ struct StY { auto pt = point.decode_from(point_value.data, point_value.size); if (!pt) { + null_map_data[row] = 1; res->insert_default(); continue; } auto y_value = point.y(); - res->insert_data(const_cast<const char*>((char*)(&y_value)), 0); + res->insert_value(y_value); } - block.replace_by_position(result, std::move(res)); + block.replace_by_position(result, + ColumnNullable::create(std::move(res), std::move(null_map))); return Status::OK(); } @@ -218,6 +241,7 @@ struct StDistanceSphere { static constexpr auto NEED_CONTEXT = false; static constexpr auto NAME = "st_distance_sphere"; static const size_t NUM_ARGS = 4; + using Type = DataTypeFloat64; static Status execute(Block& block, const ColumnNumbers& arguments, size_t result) { DCHECK_EQ(arguments.size(), 4); auto return_type = block.get_data_type(result); @@ -228,22 +252,25 @@ struct StDistanceSphere { auto y_lat = block.get_by_position(arguments[3]).column->convert_to_full_column_if_const(); const auto size = x_lng->size(); - - MutableColumnPtr res = return_type->create_column(); - + auto res = ColumnFloat64::create(); + res->reserve(size); + auto null_map = ColumnUInt8::create(size, 0); + auto& null_map_data = null_map->get_data(); for (int row = 0; row < size; ++row) { double distance = 0; if (!GeoPoint::ComputeDistance(x_lng->operator[](row).get<Float64>(), x_lat->operator[](row).get<Float64>(), y_lng->operator[](row).get<Float64>(), y_lat->operator[](row).get<Float64>(), &distance)) { + null_map_data[row] = 1; res->insert_default(); continue; } - res->insert_data(const_cast<const char*>((char*)&distance), 0); + res->insert_value(distance); } - block.replace_by_position(result, std::move(res)); + block.replace_by_position(result, + ColumnNullable::create(std::move(res), std::move(null_map))); return Status::OK(); } }; @@ -252,6 +279,7 @@ struct StAngleSphere { static constexpr auto NEED_CONTEXT = false; static constexpr auto NAME = "st_angle_sphere"; static const size_t NUM_ARGS = 4; + using Type = DataTypeFloat64; static Status execute(Block& block, const ColumnNumbers& arguments, size_t result) { DCHECK_EQ(arguments.size(), 4); auto return_type = block.get_data_type(result); @@ -263,7 +291,10 @@ struct StAngleSphere { const auto size = x_lng->size(); - MutableColumnPtr res = return_type->create_column(); + auto res = ColumnFloat64::create(); + res->reserve(size); + auto null_map = ColumnUInt8::create(size, 0); + auto& null_map_data = null_map->get_data(); for (int row = 0; row < size; ++row) { double angle = 0; @@ -271,13 +302,15 @@ struct StAngleSphere { x_lat->operator[](row).get<Float64>(), y_lng->operator[](row).get<Float64>(), y_lat->operator[](row).get<Float64>(), &angle)) { + null_map_data[row] = 1; res->insert_default(); continue; } - res->insert_data(const_cast<const char*>((char*)&angle), 0); + res->insert_value(angle); } - block.replace_by_position(result, std::move(res)); + block.replace_by_position(result, + ColumnNullable::create(std::move(res), std::move(null_map))); return Status::OK(); } }; @@ -286,15 +319,19 @@ struct StAngle { static constexpr auto NEED_CONTEXT = false; static constexpr auto NAME = "st_angle"; static const size_t NUM_ARGS = 3; + using Type = DataTypeFloat64; static Status execute(Block& block, const ColumnNumbers& arguments, size_t result) { DCHECK_EQ(arguments.size(), 3); auto return_type = block.get_data_type(result); - MutableColumnPtr res = return_type->create_column(); auto p1 = block.get_by_position(arguments[0]).column->convert_to_full_column_if_const(); auto p2 = block.get_by_position(arguments[1]).column->convert_to_full_column_if_const(); auto p3 = block.get_by_position(arguments[2]).column->convert_to_full_column_if_const(); const auto size = p1->size(); + auto res = ColumnFloat64::create(); + res->reserve(size); + auto null_map = ColumnUInt8::create(size, 0); + auto& null_map_data = null_map->get_data(); GeoPoint point1; GeoPoint point2; @@ -304,6 +341,7 @@ struct StAngle { auto shape_value1 = p1->get_data_at(row); auto pt1 = point1.decode_from(shape_value1.data, shape_value1.size); if (!pt1) { + null_map_data[row] = 1; res->insert_default(); continue; } @@ -311,24 +349,28 @@ struct StAngle { auto shape_value2 = p2->get_data_at(row); auto pt2 = point2.decode_from(shape_value2.data, shape_value2.size); if (!pt2) { + null_map_data[row] = 1; res->insert_default(); continue; } auto shape_value3 = p3->get_data_at(row); auto pt3 = point3.decode_from(shape_value3.data, shape_value3.size); if (!pt3) { + null_map_data[row] = 1; res->insert_default(); continue; } double angle = 0; if (!GeoPoint::ComputeAngle(&point1, &point2, &point3, &angle)) { + null_map_data[row] = 1; res->insert_default(); continue; } - res->insert_data(const_cast<const char*>((char*)&angle), 0); + res->insert_value(angle); } - block.replace_by_position(result, std::move(res)); + block.replace_by_position(result, + ColumnNullable::create(std::move(res), std::move(null_map))); return Status::OK(); } }; @@ -337,10 +379,10 @@ struct StAzimuth { static constexpr auto NEED_CONTEXT = false; static constexpr auto NAME = "st_azimuth"; static const size_t NUM_ARGS = 2; + using Type = DataTypeFloat64; static Status execute(Block& block, const ColumnNumbers& arguments, size_t result) { DCHECK_EQ(arguments.size(), 2); auto return_type = block.get_data_type(result); - MutableColumnPtr res = return_type->create_column(); const auto& [left_column, left_const] = unpack_if_const(block.get_by_position(arguments[0]).column); @@ -348,71 +390,77 @@ struct StAzimuth { unpack_if_const(block.get_by_position(arguments[1]).column); const auto size = std::max(left_column->size(), right_column->size()); - + auto res = ColumnFloat64::create(); + res->reserve(size); + auto null_map = ColumnUInt8::create(size, 0); + auto& null_map_data = null_map->get_data(); GeoPoint point1; GeoPoint point2; if (left_const) { - const_vector(left_column, right_column, res, size, point1, point2); + const_vector(left_column, right_column, res, null_map_data, size, point1, point2); } else if (right_const) { - vector_const(left_column, right_column, res, size, point1, point2); + vector_const(left_column, right_column, res, null_map_data, size, point1, point2); } else { - vector_vector(left_column, right_column, res, size, point1, point2); + vector_vector(left_column, right_column, res, null_map_data, size, point1, point2); } - block.replace_by_position(result, std::move(res)); + block.replace_by_position(result, + ColumnNullable::create(std::move(res), std::move(null_map))); return Status::OK(); } static void loop_do(bool& pt1, bool& pt2, GeoPoint& point1, GeoPoint& point2, - MutableColumnPtr& res) { + ColumnFloat64::MutablePtr& res, NullMap& null_map, int row) { if (!(pt1 && pt2)) { + null_map[row] = 1; res->insert_default(); return; } double angle = 0; if (!GeoPoint::ComputeAzimuth(&point1, &point2, &angle)) { + null_map[row] = 1; res->insert_default(); return; } - res->insert_data(const_cast<const char*>((char*)&angle), 0); + res->insert_value(angle); } static void const_vector(const ColumnPtr& left_column, const ColumnPtr& right_column, - MutableColumnPtr& res, size_t size, GeoPoint& point1, - GeoPoint& point2) { + ColumnFloat64::MutablePtr& res, NullMap& null_map, size_t size, + GeoPoint& point1, GeoPoint& point2) { auto shape_value1 = left_column->get_data_at(0); auto pt1 = point1.decode_from(shape_value1.data, shape_value1.size); for (int row = 0; row < size; ++row) { auto shape_value2 = right_column->get_data_at(row); auto pt2 = point2.decode_from(shape_value2.data, shape_value2.size); - loop_do(pt1, pt2, point1, point2, res); + loop_do(pt1, pt2, point1, point2, res, null_map, row); } } static void vector_const(const ColumnPtr& left_column, const ColumnPtr& right_column, - MutableColumnPtr& res, size_t size, GeoPoint& point1, - GeoPoint& point2) { + ColumnFloat64::MutablePtr& res, NullMap& null_map, size_t size, + GeoPoint& point1, GeoPoint& point2) { auto shape_value2 = right_column->get_data_at(0); auto pt2 = point2.decode_from(shape_value2.data, shape_value2.size); for (int row = 0; row < size; ++row) { auto shape_value1 = left_column->get_data_at(row); auto pt1 = point1.decode_from(shape_value1.data, shape_value1.size); - loop_do(pt1, pt2, point1, point2, res); + loop_do(pt1, pt2, point1, point2, res, null_map, row); } } static void vector_vector(const ColumnPtr& left_column, const ColumnPtr& right_column, - MutableColumnPtr& res, size_t size, GeoPoint& point1, - GeoPoint& point2) { + ColumnFloat64::MutablePtr& res, NullMap& null_map, size_t size, + GeoPoint& point1, GeoPoint& point2) { for (int row = 0; row < size; ++row) { auto shape_value1 = left_column->get_data_at(row); auto pt1 = point1.decode_from(shape_value1.data, shape_value1.size); auto shape_value2 = right_column->get_data_at(row); auto pt2 = point2.decode_from(shape_value2.data, shape_value2.size); - loop_do(pt1, pt2, point1, point2, res); + loop_do(pt1, pt2, point1, point2, res, null_map, row); } } }; @@ -421,33 +469,39 @@ struct StAreaSquareMeters { static constexpr auto NEED_CONTEXT = false; static constexpr auto NAME = "st_area_square_meters"; static const size_t NUM_ARGS = 1; + using Type = DataTypeFloat64; static Status execute(Block& block, const ColumnNumbers& arguments, size_t result) { DCHECK_EQ(arguments.size(), 1); auto return_type = block.get_data_type(result); - MutableColumnPtr res = return_type->create_column(); auto col = block.get_by_position(arguments[0]).column->convert_to_full_column_if_const(); const auto size = col->size(); - + auto res = ColumnFloat64::create(); + res->reserve(size); + auto null_map = ColumnUInt8::create(size, 0); + auto& null_map_data = null_map->get_data(); std::unique_ptr<GeoShape> shape; for (int row = 0; row < size; ++row) { auto shape_value = col->get_data_at(row); shape = GeoShape::from_encoded(shape_value.data, shape_value.size); if (!shape) { + null_map_data[row] = 1; res->insert_default(); continue; } double area = 0; if (!GeoShape::ComputeArea(shape.get(), &area, "square_meters")) { + null_map_data[row] = 1; res->insert_default(); continue; } - res->insert_data(const_cast<const char*>((char*)&area), 0); + res->insert_value(area); } - block.replace_by_position(result, std::move(res)); + block.replace_by_position(result, + ColumnNullable::create(std::move(res), std::move(null_map))); return Status::OK(); } }; @@ -456,13 +510,17 @@ struct StAreaSquareKm { static constexpr auto NEED_CONTEXT = false; static constexpr auto NAME = "st_area_square_km"; static const size_t NUM_ARGS = 1; + using Type = DataTypeFloat64; static Status execute(Block& block, const ColumnNumbers& arguments, size_t result) { DCHECK_EQ(arguments.size(), 1); auto return_type = block.get_data_type(result); - MutableColumnPtr res = return_type->create_column(); auto col = block.get_by_position(arguments[0]).column->convert_to_full_column_if_const(); const auto size = col->size(); + auto res = ColumnFloat64::create(); + res->reserve(size); + auto null_map = ColumnUInt8::create(size, 0); + auto& null_map_data = null_map->get_data(); std::unique_ptr<GeoShape> shape; @@ -470,19 +528,23 @@ struct StAreaSquareKm { auto shape_value = col->get_data_at(row); shape = GeoShape::from_encoded(shape_value.data, shape_value.size); if (!shape) { + null_map_data[row] = 1; res->insert_default(); continue; } double area = 0; if (!GeoShape::ComputeArea(shape.get(), &area, "square_km")) { + null_map_data[row] = 1; res->insert_default(); + ; continue; } - res->insert_data(const_cast<const char*>((char*)&area), 0); + res->insert_value(area); } - block.replace_by_position(result, std::move(res)); + block.replace_by_position(result, + ColumnNullable::create(std::move(res), std::move(null_map))); return Status::OK(); } }; @@ -491,6 +553,7 @@ struct StCircle { static constexpr auto NEED_CONTEXT = true; static constexpr auto NAME = "st_circle"; static const size_t NUM_ARGS = 3; + using Type = DataTypeString; static Status execute(FunctionContext* context, Block& block, const ColumnNumbers& arguments, size_t result) { DCHECK_EQ(arguments.size(), 3); @@ -506,7 +569,10 @@ struct StCircle { const auto size = center_lng->size(); - MutableColumnPtr res = return_type->create_column(); + auto res = ColumnString::create(); + + auto null_map = ColumnUInt8::create(size, 0); + auto& null_map_data = null_map->get_data(); GeoCircle circle; std::string buf; @@ -517,14 +583,16 @@ struct StCircle { auto value = circle.init(lng_value, lat_value, radius_value); if (value != GEO_PARSE_OK) { - res->insert_data(nullptr, 0); + null_map_data[row] = 1; + res->insert_default(); continue; } buf.clear(); circle.encode_to(&buf); res->insert_data(buf.data(), buf.size()); } - block.replace_by_position(result, std::move(res)); + block.replace_by_position(result, + ColumnNullable::create(std::move(res), std::move(null_map))); return Status::OK(); } @@ -541,6 +609,7 @@ struct StContains { static constexpr auto NEED_CONTEXT = true; static constexpr auto NAME = "st_contains"; static const size_t NUM_ARGS = 2; + using Type = DataTypeUInt8; static Status execute(FunctionContext* context, Block& block, const ColumnNumbers& arguments, size_t result) { DCHECK_EQ(arguments.size(), 2); @@ -552,27 +621,32 @@ struct StContains { const auto size = std::max(left_column->size(), right_column->size()); - MutableColumnPtr res = return_type->create_column(); + auto res = ColumnUInt8::create(); + res->reserve(size); + auto null_map = ColumnUInt8::create(size, 0); + auto& null_map_data = null_map->get_data(); if (left_const) { - const_vector(left_column, right_column, res, size); + const_vector(left_column, right_column, res, null_map_data, size); } else if (right_const) { - vector_const(left_column, right_column, res, size); + vector_const(left_column, right_column, res, null_map_data, size); } else { - vector_vector(left_column, right_column, res, size); + vector_vector(left_column, right_column, res, null_map_data, size); } - block.replace_by_position(result, std::move(res)); + block.replace_by_position(result, + ColumnNullable::create(std::move(res), std::move(null_map))); return Status::OK(); } static void loop_do(StringRef& lhs_value, StringRef& rhs_value, std::vector<std::shared_ptr<GeoShape>>& shapes, int& i, - MutableColumnPtr& res) { + ColumnUInt8::MutablePtr& res, NullMap& null_map, int row) { StringRef* strs[2] = {&lhs_value, &rhs_value}; for (i = 0; i < 2; ++i) { shapes[i] = std::shared_ptr<GeoShape>(GeoShape::from_encoded(strs[i]->data, strs[i]->size)); if (shapes[i] == nullptr) { + null_map[row] = 1; res->insert_default(); break; } @@ -585,35 +659,35 @@ struct StContains { } static void const_vector(const ColumnPtr& left_column, const ColumnPtr& right_column, - MutableColumnPtr& res, const size_t size) { + ColumnUInt8::MutablePtr& res, NullMap& null_map, const size_t size) { int i; auto lhs_value = left_column->get_data_at(0); std::vector<std::shared_ptr<GeoShape>> shapes = {nullptr, nullptr}; for (int row = 0; row < size; ++row) { auto rhs_value = right_column->get_data_at(row); - loop_do(lhs_value, rhs_value, shapes, i, res); + loop_do(lhs_value, rhs_value, shapes, i, res, null_map, row); } } static void vector_const(const ColumnPtr& left_column, const ColumnPtr& right_column, - MutableColumnPtr& res, const size_t size) { + ColumnUInt8::MutablePtr& res, NullMap& null_map, const size_t size) { int i; auto rhs_value = right_column->get_data_at(0); std::vector<std::shared_ptr<GeoShape>> shapes = {nullptr, nullptr}; for (int row = 0; row < size; ++row) { auto lhs_value = left_column->get_data_at(row); - loop_do(lhs_value, rhs_value, shapes, i, res); + loop_do(lhs_value, rhs_value, shapes, i, res, null_map, row); } } static void vector_vector(const ColumnPtr& left_column, const ColumnPtr& right_column, - MutableColumnPtr& res, const size_t size) { + ColumnUInt8::MutablePtr& res, NullMap& null_map, const size_t size) { int i; std::vector<std::shared_ptr<GeoShape>> shapes = {nullptr, nullptr}; for (int row = 0; row < size; ++row) { auto lhs_value = left_column->get_data_at(row); auto rhs_value = right_column->get_data_at(row); - loop_do(lhs_value, rhs_value, shapes, i, res); + loop_do(lhs_value, rhs_value, shapes, i, res, null_map, row); } } @@ -666,6 +740,7 @@ struct StGeoFromText { static constexpr auto NEED_CONTEXT = true; static constexpr auto NAME = Impl::NAME; static const size_t NUM_ARGS = 1; + using Type = DataTypeString; static Status execute(FunctionContext* context, Block& block, const ColumnNumbers& arguments, size_t result) { DCHECK_EQ(arguments.size(), 1); @@ -673,8 +748,9 @@ struct StGeoFromText { auto& geo = block.get_by_position(arguments[0]).column; const auto size = geo->size(); - MutableColumnPtr res = return_type->create_column(); - + auto res = ColumnString::create(); + auto null_map = ColumnUInt8::create(size, 0); + auto& null_map_data = null_map->get_data(); GeoParseStatus status; std::string buf; for (int row = 0; row < size; ++row) { @@ -682,14 +758,16 @@ struct StGeoFromText { std::unique_ptr<GeoShape> shape(GeoShape::from_wkt(value.data, value.size, &status)); if (shape == nullptr || status != GEO_PARSE_OK || (Impl::shape_type != GEO_SHAPE_ANY && shape->type() != Impl::shape_type)) { - res->insert_data(nullptr, 0); + null_map_data[row] = 1; + res->insert_default(); continue; } buf.clear(); shape->encode_to(&buf); res->insert_data(buf.data(), buf.size()); } - block.replace_by_position(result, std::move(res)); + block.replace_by_position(result, + ColumnNullable::create(std::move(res), std::move(null_map))); return Status::OK(); } @@ -717,6 +795,7 @@ struct StGeoFromWkb { static constexpr auto NEED_CONTEXT = true; static constexpr auto NAME = Impl::NAME; static const size_t NUM_ARGS = 1; + using Type = DataTypeString; static Status execute(FunctionContext* context, Block& block, const ColumnNumbers& arguments, size_t result) { DCHECK_EQ(arguments.size(), 1); @@ -724,22 +803,25 @@ struct StGeoFromWkb { auto& geo = block.get_by_position(arguments[0]).column; const auto size = geo->size(); - MutableColumnPtr res = return_type->create_column(); - + auto res = ColumnString::create(); + auto null_map = ColumnUInt8::create(size, 0); + auto& null_map_data = null_map->get_data(); GeoParseStatus status; std::string buf; for (int row = 0; row < size; ++row) { auto value = geo->get_data_at(row); std::unique_ptr<GeoShape> shape(GeoShape::from_wkb(value.data, value.size, &status)); if (shape == nullptr || status != GEO_PARSE_OK) { - res->insert_data(nullptr, 0); + null_map_data[row] = 1; + res->insert_default(); continue; } buf.clear(); shape->encode_to(&buf); res->insert_data(buf.data(), buf.size()); } - block.replace_by_position(result, std::move(res)); + block.replace_by_position(result, + ColumnNullable::create(std::move(res), std::move(null_map))); return Status::OK(); } @@ -756,34 +838,39 @@ struct StAsBinary { static constexpr auto NEED_CONTEXT = true; static constexpr auto NAME = "st_asbinary"; static const size_t NUM_ARGS = 1; + using Type = DataTypeString; static Status execute(FunctionContext* context, Block& block, const ColumnNumbers& arguments, size_t result) { DCHECK_EQ(arguments.size(), 1); auto return_type = block.get_data_type(result); - MutableColumnPtr res = return_type->create_column(); + auto res = ColumnString::create(); auto col = block.get_by_position(arguments[0]).column; const auto size = col->size(); - + auto null_map = ColumnUInt8::create(size, 0); + auto& null_map_data = null_map->get_data(); std::unique_ptr<GeoShape> shape; for (int row = 0; row < size; ++row) { auto shape_value = col->get_data_at(row); shape = GeoShape::from_encoded(shape_value.data, shape_value.size); if (!shape) { - res->insert_data(nullptr, 0); + null_map_data[row] = 1; + res->insert_default(); continue; } std::string binary = GeoShape::as_binary(shape.get()); if (binary.empty()) { - res->insert_data(nullptr, 0); + null_map_data[row] = 1; + res->insert_default(); continue; } res->insert_data(binary.data(), binary.size()); } - block.replace_by_position(result, std::move(res)); + block.replace_by_position(result, + ColumnNullable::create(std::move(res), std::move(null_map))); return Status::OK(); } @@ -800,13 +887,13 @@ void register_function_geo(SimpleFunctionFactory& factory) { factory.register_function<GeoFunction<StPoint>>(); factory.register_function<GeoFunction<StAsText<StAsWktName>>>(); factory.register_function<GeoFunction<StAsText<StAsTextName>>>(); - factory.register_function<GeoFunction<StX, DataTypeFloat64>>(); - factory.register_function<GeoFunction<StY, DataTypeFloat64>>(); - factory.register_function<GeoFunction<StDistanceSphere, DataTypeFloat64>>(); - factory.register_function<GeoFunction<StAngleSphere, DataTypeFloat64>>(); - factory.register_function<GeoFunction<StAngle, DataTypeFloat64>>(); - factory.register_function<GeoFunction<StAzimuth, DataTypeFloat64>>(); - factory.register_function<GeoFunction<StContains, DataTypeUInt8>>(); + factory.register_function<GeoFunction<StX>>(); + factory.register_function<GeoFunction<StY>>(); + factory.register_function<GeoFunction<StDistanceSphere>>(); + factory.register_function<GeoFunction<StAngleSphere>>(); + factory.register_function<GeoFunction<StAngle>>(); + factory.register_function<GeoFunction<StAzimuth>>(); + factory.register_function<GeoFunction<StContains>>(); factory.register_function<GeoFunction<StCircle>>(); factory.register_function<GeoFunction<StGeoFromText<StGeometryFromText>>>(); factory.register_function<GeoFunction<StGeoFromText<StGeomFromText>>>(); @@ -815,8 +902,8 @@ void register_function_geo(SimpleFunctionFactory& factory) { factory.register_function<GeoFunction<StGeoFromText<StPolygon>>>(); factory.register_function<GeoFunction<StGeoFromText<StPolygonFromText>>>(); factory.register_function<GeoFunction<StGeoFromText<StPolyFromText>>>(); - factory.register_function<GeoFunction<StAreaSquareMeters, DataTypeFloat64>>(); - factory.register_function<GeoFunction<StAreaSquareKm, DataTypeFloat64>>(); + factory.register_function<GeoFunction<StAreaSquareMeters>>(); + factory.register_function<GeoFunction<StAreaSquareKm>>(); factory.register_function<GeoFunction<StGeoFromWkb<StGeometryFromWKB>>>(); factory.register_function<GeoFunction<StGeoFromWkb<StGeomFromWKB>>>(); factory.register_function<GeoFunction<StAsBinary>>(); diff --git a/be/src/vec/functions/functions_geo.h b/be/src/vec/functions/functions_geo.h index 9c4db09e149..ac0358d42f5 100644 --- a/be/src/vec/functions/functions_geo.h +++ b/be/src/vec/functions/functions_geo.h @@ -56,11 +56,12 @@ struct StContainsState { std::vector<std::shared_ptr<GeoShape>> shapes; }; -template <typename Impl, typename ReturnType = DataTypeString> +template <typename Impl> class GeoFunction : public IFunction { public: static constexpr auto name = Impl::NAME; - static FunctionPtr create() { return std::make_shared<GeoFunction<Impl, ReturnType>>(); } + using ReturnType = typename Impl::Type; + static FunctionPtr create() { return std::make_shared<GeoFunction<Impl>>(); } String get_name() const override { return name; } size_t get_number_of_arguments() const override { return Impl::NUM_ARGS; } bool is_variadic() const override { return false; } --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org For additional commands, e-mail: commits-h...@doris.apache.org