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


Reply via email to