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 <[email protected]>
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: [email protected]
For additional commands, e-mail: [email protected]