[CP][FEAT MERGE]SDO_GEOMETRY & MYSQL GIS EXPR IMPLEMENT
This commit is contained in:
@ -14,8 +14,14 @@
|
||||
#include "lib/geo/ob_geo_common.h"
|
||||
#include "lib/geo/ob_geo_utils.h"
|
||||
#include "lib/json_type/ob_json_common.h"
|
||||
#include "rpc/obmysql/ob_mysql_global.h"
|
||||
#include "src/pl/ob_pl_user_type.h"
|
||||
#include "src/pl/ob_pl_allocator.h"
|
||||
#include "src/sql/engine/expr/ob_expr_sql_udt_utils.h"
|
||||
#define private public
|
||||
#undef private
|
||||
using namespace oceanbase::pl;
|
||||
using namespace oceanbase::sql;
|
||||
|
||||
namespace oceanbase {
|
||||
namespace common {
|
||||
@ -143,6 +149,158 @@ TEST_F(TestGeoCommon, test_wkb_byte_order_util)
|
||||
}
|
||||
}
|
||||
|
||||
void double_to_number(double d, ObArenaAllocator &allocator, number::ObNumber &num)
|
||||
{
|
||||
char buf[DOUBLE_TO_STRING_CONVERSION_BUFFER_SIZE] = {0};
|
||||
uint64_t length = ob_gcvt(d, ob_gcvt_arg_type::OB_GCVT_ARG_DOUBLE,
|
||||
sizeof(buf) - 1, buf, NULL);
|
||||
ObString str(sizeof(buf), static_cast<int32_t>(length), buf);
|
||||
ObPrecision res_precision = PRECISION_UNKNOWN_YET;
|
||||
ObScale res_scale = -1;
|
||||
ASSERT_EQ(num.from_sci_opt(str.ptr(), str.length(), allocator, &res_precision, &res_scale), OB_SUCCESS);
|
||||
}
|
||||
|
||||
void build_obj_uint64(uint64_t num, ObArenaAllocator &allocator, ObObj &res) {
|
||||
number::ObNumber nmb;
|
||||
ASSERT_EQ(nmb.from(num, allocator), OB_SUCCESS);
|
||||
res.set_number(nmb);
|
||||
}
|
||||
|
||||
void build_obj_double(double num, ObArenaAllocator &allocator, ObObj &res) {
|
||||
number::ObNumber nmb;
|
||||
double_to_number(num, allocator, nmb);
|
||||
res.set_number(nmb);
|
||||
}
|
||||
|
||||
void mock_write_sdo_elem_info(ObArray<uint64_t> &elem_info, common::ObIAllocator &ctx_allocator, common::ObObj &result)
|
||||
{
|
||||
pl::ObPLVArray *elem_array = reinterpret_cast<pl::ObPLVArray *>(ctx_allocator.alloc(sizeof(pl::ObPLVArray)));
|
||||
ASSERT_EQ(elem_array != NULL, true);
|
||||
pl::ObPLCollAllocator *coll_allocator = reinterpret_cast<pl::ObPLCollAllocator *>(ctx_allocator.alloc(sizeof(pl::ObPLCollAllocator)));
|
||||
ASSERT_EQ(coll_allocator != NULL, true);
|
||||
|
||||
elem_array = new (elem_array) pl::ObPLVArray(300029);
|
||||
coll_allocator = new (coll_allocator) pl::ObPLCollAllocator(elem_array);
|
||||
elem_array->set_allocator(coll_allocator);
|
||||
ObIAllocator *allocator = coll_allocator->get_allocator();
|
||||
uint64_t elem_cnt = elem_info.size();
|
||||
ASSERT_EQ(allocator != NULL, true);
|
||||
ObObj *array_data = reinterpret_cast<ObObj *>(allocator->alloc(sizeof(ObObj) * elem_cnt));
|
||||
ASSERT_EQ(array_data != NULL, true);
|
||||
number::ObNumber elem_num;
|
||||
for (uint64_t i = 0; i < elem_cnt; ++i) {
|
||||
ASSERT_EQ(elem_num.from(elem_info[i], *allocator), OB_SUCCESS);
|
||||
array_data[i].set_number(ObNumberType, elem_num);
|
||||
}
|
||||
|
||||
ObElemDesc elem_desc;
|
||||
elem_array->set_capacity(elem_cnt);
|
||||
elem_array->set_column_count(elem_cnt);
|
||||
elem_array->set_count(elem_cnt);
|
||||
elem_array->set_data(array_data);
|
||||
elem_desc.set_pl_type(PL_VARRAY_TYPE);
|
||||
elem_desc.set_not_null(false);
|
||||
elem_desc.set_field_count(elem_cnt);
|
||||
elem_array->set_element_desc(elem_desc);
|
||||
elem_array->set_first(1);
|
||||
elem_array->set_last(elem_cnt);
|
||||
result.set_extend(reinterpret_cast<int64_t>(elem_array), elem_array->get_type());
|
||||
}
|
||||
|
||||
void mock_write_sdo_ordinates(ObArray<double> &ordinate, common::ObIAllocator &ctx_allocator, common::ObObj &result)
|
||||
{
|
||||
pl::ObPLVArray *elem_array = reinterpret_cast<pl::ObPLVArray *>(ctx_allocator.alloc(sizeof(pl::ObPLVArray)));
|
||||
ASSERT_EQ(elem_array != NULL, true);
|
||||
pl::ObPLCollAllocator *coll_allocator = reinterpret_cast<pl::ObPLCollAllocator *>(ctx_allocator.alloc(sizeof(pl::ObPLCollAllocator)));
|
||||
ASSERT_EQ(coll_allocator != NULL, true);
|
||||
|
||||
elem_array = new (elem_array) pl::ObPLVArray(300028);
|
||||
coll_allocator = new (coll_allocator) pl::ObPLCollAllocator(elem_array);
|
||||
elem_array->set_allocator(coll_allocator);
|
||||
ObIAllocator *allocator = coll_allocator->get_allocator();
|
||||
uint64_t ori_size = ordinate.size();
|
||||
ASSERT_EQ(allocator != NULL, true);
|
||||
ObObj *array_data = reinterpret_cast<ObObj *>(allocator->alloc(sizeof(ObObj) * ori_size));
|
||||
ASSERT_EQ(array_data != NULL, true);
|
||||
number::ObNumber elem_num;
|
||||
for (uint64_t i = 0; i < ori_size; ++i) {
|
||||
ASSERT_EQ(ObJsonBaseUtil::double_to_number(ordinate[i], *allocator, elem_num), OB_SUCCESS);
|
||||
array_data[i].set_number(ObNumberType, elem_num);
|
||||
}
|
||||
|
||||
ObElemDesc elem_desc;
|
||||
elem_array->set_capacity(ori_size);
|
||||
elem_array->set_column_count(ori_size);
|
||||
elem_array->set_count(ori_size);
|
||||
elem_array->set_data(array_data);
|
||||
elem_desc.set_pl_type(PL_VARRAY_TYPE);
|
||||
elem_desc.set_not_null(false);
|
||||
elem_desc.set_field_count(ori_size);
|
||||
elem_array->set_element_desc(elem_desc);
|
||||
elem_array->set_first(1);
|
||||
elem_array->set_last(ori_size);
|
||||
result.set_extend(reinterpret_cast<int64_t>(elem_array), elem_array->get_type());
|
||||
}
|
||||
|
||||
TEST_F(TestGeoCommon, sql_udt_to_wkt)
|
||||
{
|
||||
int ret = 0;
|
||||
ObArenaAllocator allocator(ObModIds::TEST);
|
||||
ObObj gtype;
|
||||
build_obj_uint64(2001, allocator, gtype);
|
||||
ObObj srid;
|
||||
build_obj_uint64(4326, allocator, srid);
|
||||
ObObj point_x;
|
||||
build_obj_double(1.23, allocator, point_x);
|
||||
ObObj point_y;
|
||||
build_obj_double(4.56, allocator, point_y);
|
||||
ObObj point_z;
|
||||
build_obj_double(7.89, allocator, point_z);
|
||||
|
||||
QualifiedMap map;
|
||||
ASSERT_EQ(map.create(7, ObModIds::TEST), OB_SUCCESS);
|
||||
ASSERT_EQ(map.set_refactored("SDO_GTYPE", >ype), OB_SUCCESS);
|
||||
ASSERT_EQ(map.set_refactored("SDO_SRID", &srid), OB_SUCCESS);
|
||||
ASSERT_EQ(map.set_refactored("SDO_POINT.X", &point_x), OB_SUCCESS);
|
||||
ASSERT_EQ(map.set_refactored("SDO_POINT.Y", &point_y), OB_SUCCESS);
|
||||
ASSERT_EQ(map.set_refactored("SDO_POINT.Z", &point_z), OB_SUCCESS);
|
||||
|
||||
ObString ewkt;
|
||||
ASSERT_EQ(ObGeoTypeUtil::sql_geo_obj_to_ewkt(map, allocator, ewkt), OB_SUCCESS);
|
||||
ASSERT_EQ(ewkt == "SRID=4326;POINT(1.23 4.56)", true) << ewkt.ptr();
|
||||
|
||||
ObObj elem_info_pl;
|
||||
ObObj elem_info_obj;
|
||||
ObArray<uint64_t> elem_info;
|
||||
ASSERT_EQ(elem_info.push_back(1), OB_SUCCESS);
|
||||
ASSERT_EQ(elem_info.push_back(1), OB_SUCCESS);
|
||||
ASSERT_EQ(elem_info.push_back(1), OB_SUCCESS);
|
||||
mock_write_sdo_elem_info(elem_info, allocator, elem_info_pl);
|
||||
ObString elem_info_str;
|
||||
ASSERT_EQ(ObSqlUdtUtils::cast_pl_varray_to_sql_varray(allocator, elem_info_str, elem_info_pl), OB_SUCCESS);
|
||||
elem_info_obj.set_sql_collection(elem_info_str.ptr(), elem_info_str.length(), 30027);
|
||||
|
||||
ObObj ordinate_pl;
|
||||
ObObj ordinate_obj;
|
||||
ObArray<double> ordinates;
|
||||
ASSERT_EQ(ordinates.push_back(9.87), OB_SUCCESS);
|
||||
ASSERT_EQ(ordinates.push_back(6.54), OB_SUCCESS);
|
||||
mock_write_sdo_ordinates(ordinates, allocator, ordinate_pl);
|
||||
ObString ordinates_str;
|
||||
ASSERT_EQ(ObSqlUdtUtils::cast_pl_varray_to_sql_varray(allocator, ordinates_str, ordinate_pl), OB_SUCCESS);
|
||||
ordinate_obj.set_sql_collection(ordinates_str.ptr(), ordinates_str.length(), 30028);
|
||||
|
||||
QualifiedMap map2;
|
||||
ASSERT_EQ(map2.create(7, ObModIds::TEST), OB_SUCCESS);
|
||||
ASSERT_EQ(map2.set_refactored("SDO_GTYPE", >ype), OB_SUCCESS);
|
||||
ASSERT_EQ(map2.set_refactored("SDO_ELEM_INFO", &elem_info_obj), OB_SUCCESS);
|
||||
ASSERT_EQ(map2.set_refactored("SDO_ORDINATES", &ordinate_obj), OB_SUCCESS);
|
||||
|
||||
ObString ewkt2;
|
||||
ASSERT_EQ(ObGeoTypeUtil::sql_geo_obj_to_ewkt(map2, allocator, ewkt2), OB_SUCCESS);
|
||||
ASSERT_EQ(ewkt2 == "SRID=NULL;POINT(9.87 6.54)", true) << ewkt2.ptr();
|
||||
}
|
||||
|
||||
} // namespace common
|
||||
} // namespace oceanbase
|
||||
|
||||
|
||||
Reference in New Issue
Block a user