From 064915e9604f2857411521f712d4131153aed2fc Mon Sep 17 00:00:00 2001 From: Mryange <2319153948@qq.com> Date: Sun, 30 Jun 2024 08:20:50 +0800 Subject: [PATCH 1/3] opt --- be/src/vec/functions/functions_geo.cpp | 292 +++++++++++++++---------- be/src/vec/functions/functions_geo.h | 5 +- 2 files changed, 181 insertions(+), 116 deletions(-) diff --git a/be/src/vec/functions/functions_geo.cpp b/be/src/vec/functions/functions_geo.cpp index 036033db2a2dd6..6cd6da47e32bc4 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,28 @@ 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; return; } @@ -81,32 +86,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(); for (int row = 0; row < size; ++row) { auto cur_res = point.from_coord(x, right_column->operator[](row).get()); - 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(); for (int row = 0; row < size; ++row) { auto cur_res = point.from_coord(right_column->operator[](row).get(), 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(), right_column->operator[](row).get()); - loop_do(cur_res, res, point, buf); + loop_do(cur_res, res, null_map, row, point, buf); } } }; @@ -123,6 +128,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 +137,23 @@ 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 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; 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 +163,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 +172,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 +183,14 @@ struct StX { auto pt = point.decode_from(point_value.data, point_value.size); if (!pt) { - res->insert_default(); + null_map_data[row] = 1; continue; } auto x_value = point.x(); - res->insert_data(const_cast((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 +200,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 +209,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 +220,14 @@ struct StY { auto pt = point.decode_from(point_value.data, point_value.size); if (!pt) { - res->insert_default(); + null_map_data[row] = 1; continue; } auto y_value = point.y(); - res->insert_data(const_cast((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 +237,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 +248,24 @@ 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(), x_lat->operator[](row).get(), y_lng->operator[](row).get(), y_lat->operator[](row).get(), &distance)) { - res->insert_default(); + null_map_data[row] = 1; continue; } - res->insert_data(const_cast((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 +274,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 +286,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 +297,14 @@ struct StAngleSphere { x_lat->operator[](row).get(), y_lng->operator[](row).get(), y_lat->operator[](row).get(), &angle)) { - res->insert_default(); + null_map_data[row] = 1; continue; } - res->insert_data(const_cast((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 +313,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,31 +335,32 @@ struct StAngle { auto shape_value1 = p1->get_data_at(row); auto pt1 = point1.decode_from(shape_value1.data, shape_value1.size); if (!pt1) { - res->insert_default(); + null_map_data[row] = 1; continue; } auto shape_value2 = p2->get_data_at(row); auto pt2 = point2.decode_from(shape_value2.data, shape_value2.size); if (!pt2) { - res->insert_default(); + null_map_data[row] = 1; continue; } auto shape_value3 = p3->get_data_at(row); auto pt3 = point3.decode_from(shape_value3.data, shape_value3.size); if (!pt3) { - res->insert_default(); + null_map_data[row] = 1; continue; } double angle = 0; if (!GeoPoint::ComputeAngle(&point1, &point2, &point3, &angle)) { - res->insert_default(); + null_map_data[row] = 1; continue; } - res->insert_data(const_cast((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 +369,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 +380,75 @@ 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)) { - res->insert_default(); + null_map[row] = 1; return; } double angle = 0; if (!GeoPoint::ComputeAzimuth(&point1, &point2, &angle)) { - res->insert_default(); + null_map[row] = 1; return; } - res->insert_data(const_cast((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 +457,37 @@ 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 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_default(); + null_map_data[row] = 1; continue; } double area = 0; if (!GeoShape::ComputeArea(shape.get(), &area, "square_meters")) { - res->insert_default(); + null_map_data[row] = 1; continue; } - res->insert_data(const_cast((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 +496,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 shape; @@ -470,19 +514,20 @@ struct StAreaSquareKm { auto shape_value = col->get_data_at(row); shape = GeoShape::from_encoded(shape_value.data, shape_value.size); if (!shape) { - res->insert_default(); + null_map_data[row] = 1; continue; } double area = 0; if (!GeoShape::ComputeArea(shape.get(), &area, "square_km")) { - res->insert_default(); + null_map_data[row] = 1; continue; } - res->insert_data(const_cast((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 +536,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 +552,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 +566,15 @@ 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; 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 +591,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,28 +603,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>& 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::from_encoded(strs[i]->data, strs[i]->size)); if (shapes[i] == nullptr) { - res->insert_default(); + null_map[row] = 1; break; } } @@ -585,35 +640,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> 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> 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> 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 +721,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 +729,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 +739,15 @@ struct StGeoFromText { std::unique_ptr 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; 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 +775,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 +783,24 @@ 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 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; 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 +817,37 @@ 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 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; continue; } std::string binary = GeoShape::as_binary(shape.get()); if (binary.empty()) { - res->insert_data(nullptr, 0); + null_map_data[row] = 1; 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 +864,13 @@ void register_function_geo(SimpleFunctionFactory& factory) { factory.register_function>(); factory.register_function>>(); factory.register_function>>(); - factory.register_function>(); - factory.register_function>(); - factory.register_function>(); - factory.register_function>(); - factory.register_function>(); - factory.register_function>(); - factory.register_function>(); + factory.register_function>(); + factory.register_function>(); + factory.register_function>(); + factory.register_function>(); + factory.register_function>(); + factory.register_function>(); + factory.register_function>(); factory.register_function>(); factory.register_function>>(); factory.register_function>>(); @@ -815,8 +879,8 @@ void register_function_geo(SimpleFunctionFactory& factory) { factory.register_function>>(); factory.register_function>>(); factory.register_function>>(); - factory.register_function>(); - factory.register_function>(); + factory.register_function>(); + factory.register_function>(); factory.register_function>>(); factory.register_function>>(); factory.register_function>(); diff --git a/be/src/vec/functions/functions_geo.h b/be/src/vec/functions/functions_geo.h index 9c4db09e14967f..ac0358d42f59f4 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> shapes; }; -template +template class GeoFunction : public IFunction { public: static constexpr auto name = Impl::NAME; - static FunctionPtr create() { return std::make_shared>(); } + using ReturnType = typename Impl::Type; + static FunctionPtr create() { return std::make_shared>(); } 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; } From 197469204ed77f70569085ea9093a893c1fa0dc0 Mon Sep 17 00:00:00 2001 From: Mryange <2319153948@qq.com> Date: Sun, 30 Jun 2024 10:48:22 +0800 Subject: [PATCH 2/3] null str --- be/src/vec/functions/functions_geo.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/be/src/vec/functions/functions_geo.cpp b/be/src/vec/functions/functions_geo.cpp index 6cd6da47e32bc4..321ef5bdf5aac0 100644 --- a/be/src/vec/functions/functions_geo.cpp +++ b/be/src/vec/functions/functions_geo.cpp @@ -77,6 +77,7 @@ struct StPoint { int row, GeoPoint& point, std::string& buf) { if (cur_res != GEO_PARSE_OK) { null_map[row] = 1; + res->insert_default(); return; } @@ -147,6 +148,7 @@ struct StAsText { shape = GeoShape::from_encoded(shape_value.data, shape_value.size); if (shape == nullptr) { null_map_data[row] = 1; + res->insert_default(); continue; } auto wkt = shape->as_wkt(); @@ -567,6 +569,7 @@ struct StCircle { auto value = circle.init(lng_value, lat_value, radius_value); if (value != GEO_PARSE_OK) { null_map_data[row] = 1; + res->insert_default(); continue; } buf.clear(); @@ -740,6 +743,7 @@ struct StGeoFromText { if (shape == nullptr || status != GEO_PARSE_OK || (Impl::shape_type != GEO_SHAPE_ANY && shape->type() != Impl::shape_type)) { null_map_data[row] = 1; + res->insert_default(); continue; } buf.clear(); @@ -793,6 +797,7 @@ struct StGeoFromWkb { std::unique_ptr shape(GeoShape::from_wkb(value.data, value.size, &status)); if (shape == nullptr || status != GEO_PARSE_OK) { null_map_data[row] = 1; + res->insert_default(); continue; } buf.clear(); @@ -835,12 +840,14 @@ struct StAsBinary { shape = GeoShape::from_encoded(shape_value.data, shape_value.size); if (!shape) { null_map_data[row] = 1; + res->insert_default(); continue; } std::string binary = GeoShape::as_binary(shape.get()); if (binary.empty()) { null_map_data[row] = 1; + res->insert_default(); continue; } res->insert_data(binary.data(), binary.size()); From 34cfaf7c44305fec2b8e9237913b2422e5e821dd Mon Sep 17 00:00:00 2001 From: Mryange <2319153948@qq.com> Date: Sun, 30 Jun 2024 12:43:36 +0800 Subject: [PATCH 3/3] null --- be/src/vec/functions/functions_geo.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/be/src/vec/functions/functions_geo.cpp b/be/src/vec/functions/functions_geo.cpp index 321ef5bdf5aac0..b389bc1636e45f 100644 --- a/be/src/vec/functions/functions_geo.cpp +++ b/be/src/vec/functions/functions_geo.cpp @@ -186,6 +186,7 @@ struct StX { if (!pt) { null_map_data[row] = 1; + res->insert_default(); continue; } auto x_value = point.x(); @@ -223,6 +224,7 @@ struct StY { if (!pt) { null_map_data[row] = 1; + res->insert_default(); continue; } auto y_value = point.y(); @@ -261,6 +263,7 @@ struct StDistanceSphere { y_lng->operator[](row).get(), y_lat->operator[](row).get(), &distance)) { null_map_data[row] = 1; + res->insert_default(); continue; } res->insert_value(distance); @@ -300,6 +303,7 @@ struct StAngleSphere { y_lng->operator[](row).get(), y_lat->operator[](row).get(), &angle)) { null_map_data[row] = 1; + res->insert_default(); continue; } res->insert_value(angle); @@ -338,6 +342,7 @@ struct StAngle { auto pt1 = point1.decode_from(shape_value1.data, shape_value1.size); if (!pt1) { null_map_data[row] = 1; + res->insert_default(); continue; } @@ -345,18 +350,21 @@ struct StAngle { 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_value(angle); @@ -404,12 +412,14 @@ struct StAzimuth { 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_value(angle); @@ -477,12 +487,14 @@ struct StAreaSquareMeters { 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_value(area); @@ -517,12 +529,15 @@ struct StAreaSquareKm { 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_value(area); @@ -632,6 +647,7 @@ struct StContains { std::shared_ptr(GeoShape::from_encoded(strs[i]->data, strs[i]->size)); if (shapes[i] == nullptr) { null_map[row] = 1; + res->insert_default(); break; } }