fix gis version

This commit is contained in:
obdev 2023-11-07 09:10:25 +00:00 committed by ob-robot
parent c39a62ab29
commit 47f0f086a6
5 changed files with 87 additions and 27 deletions

View File

@ -650,6 +650,23 @@ int ObGeoTypeUtil::get_bo_from_wkb(const ObString &wkb, ObGeoWkbByteOrder &bo)
return ret;
}
int ObGeoTypeUtil::add_geo_version(ObIAllocator &allocator, const ObString &src, ObString &res_wkb)
{
int ret = OB_SUCCESS;
uint64_t res_size = src.length() + WKB_VERSION_SIZE;
char *res_buf = reinterpret_cast<char *>(allocator.alloc(res_size));
if (OB_ISNULL(res_buf)) {
ret = OB_ALLOCATE_MEMORY_FAILED;
LOG_WARN("failed to alloc memory", K(ret), K(res_size));
} else {
MEMCPY(res_buf, src.ptr(), WKB_GEO_SRID_SIZE);
*(res_buf + WKB_GEO_SRID_SIZE) = ENCODE_GEO_VERSION(GEO_VESION_1);
MEMCPY(res_buf + WKB_OFFSET, src.ptr() + WKB_GEO_SRID_SIZE, src.length() - WKB_GEO_SRID_SIZE);
res_wkb.assign_ptr(res_buf, res_size);
}
return ret;
}
int ObGeoTypeUtil::to_wkb(ObIAllocator &allocator,
ObGeometry &geo,
const ObSrsItem *srs_item,

View File

@ -119,6 +119,7 @@ public:
ObS2Cellids &cellids,
ObString &mbr_val);
static int get_wkb_from_swkb(const ObString &swkb, ObString &wkb, uint32_t &offset);
static int add_geo_version(ObIAllocator &allocator, const ObString &src, ObString &res_wkb);
private:
template<typename PT, typename LN, typename PY, typename MPT, typename MLN, typename MPY, typename GC>
static int create_geo_bin_by_type(ObIAllocator &allocator,

View File

@ -1223,7 +1223,14 @@ int ObMySQLUtil::geometry_cell_str(char *buf, const int64_t len, const ObString
ret = OB_SIZE_OVERFLOW;
}
} else {
length = val.length() - WKB_VERSION_SIZE;
uint8_t version = (*(val.ptr() + WKB_GEO_SRID_SIZE));
uint8_t offset = WKB_GEO_SRID_SIZE;
if (IS_GEO_VERSION(version)) {
// version exist
length = val.length() - WKB_VERSION_SIZE;
offset += WKB_VERSION_SIZE;
}
if (OB_LIKELY(length < len - pos)) {
int64_t pos_bk = pos;
if (OB_FAIL(ObMySQLUtil::store_length(buf, len, length, pos))) {
@ -1232,7 +1239,7 @@ int ObMySQLUtil::geometry_cell_str(char *buf, const int64_t len, const ObString
if (OB_LIKELY(length <= len - pos)) {
MEMCPY(buf + pos, val.ptr(), WKB_GEO_SRID_SIZE); // srid
pos += WKB_GEO_SRID_SIZE;
MEMCPY(buf + pos, val.ptr() + WKB_OFFSET, length - WKB_GEO_SRID_SIZE);
MEMCPY(buf + pos, val.ptr() + offset, length - WKB_GEO_SRID_SIZE);
pos += (length - WKB_GEO_SRID_SIZE);
} else {
pos = pos_bk;

View File

@ -6322,8 +6322,13 @@ static int string_geometry(const ObObjType expect_type, ObObjCastParams &params,
} else if (OB_FAIL(common_build_geometry(temp_allocator, in_str, geo, srs, cast_name))) {
LOG_WARN("fail to parse geometry", K(ret), K(in_str), K(dst_geo_type));
} else if (ObGeoType::GEOMETRY == dst_geo_type) {
out.set_string(expect_type, in_str.ptr(), in_str.length());
SET_RES_ACCURACY_STRING(expect_type, DEFAULT_PRECISION_FOR_STRING, in_str.length());
ObString res_wkb;
if (OB_FAIL(ObGeoTypeUtil::add_geo_version(temp_allocator, in_str, res_wkb))) {
LOG_WARN("fail to add version", K(ret), K(dst_geo_type));
} else {
out.set_string(expect_type, res_wkb.ptr(), res_wkb.length());
SET_RES_ACCURACY_STRING(expect_type, DEFAULT_PRECISION_FOR_STRING, res_wkb.length());
}
} else if (OB_FAIL(geometry_geometry(expect_type, params, in, out, cast_mode))) {
LOG_WARN("fail to cast geometry", K(ret), K(dst_geo_type));
}
@ -9089,14 +9094,21 @@ static int geom_copy_string(ObObjCastParams &params,
{
int ret = OB_SUCCESS;
char *buf = NULL;
int64_t len = src.length() - WKB_VERSION_SIZE;
if (OB_LIKELY(len > 0)) {
int64_t len = src.length();
uint8_t offset = WKB_GEO_SRID_SIZE;
if (OB_LIKELY(len > WKB_OFFSET)) {
uint8_t version = (*(src.ptr() + WKB_GEO_SRID_SIZE));
if (IS_GEO_VERSION(version)) {
// version exist
len -= WKB_VERSION_SIZE;
offset += WKB_VERSION_SIZE;
}
if (is_lob_storage(expect_type)) {
bool has_lob_header = (!IS_CLUSTER_VERSION_BEFORE_4_1_0_0 && (expect_type != ObTinyTextType));
sql::ObTextStringObObjResult str_result(expect_type, &params, &obj, has_lob_header);
if (OB_FAIL(str_result.init(len))) {
} else if (OB_FAIL(str_result.append(src.ptr(), WKB_GEO_SRID_SIZE))) {
} else if (OB_FAIL(str_result.append(src.ptr() + WKB_OFFSET, len - WKB_GEO_SRID_SIZE))) {
} else if (OB_FAIL(str_result.append(src.ptr() + offset, len - WKB_GEO_SRID_SIZE))) {
} else {
str_result.set_result();
}
@ -9105,7 +9117,7 @@ static int geom_copy_string(ObObjCastParams &params,
ret = OB_ALLOCATE_MEMORY_FAILED;
} else {
MEMMOVE(buf, src.ptr(), WKB_GEO_SRID_SIZE);
MEMMOVE(buf + WKB_GEO_SRID_SIZE, src.ptr() + WKB_OFFSET, len - WKB_GEO_SRID_SIZE);
MEMMOVE(buf + WKB_GEO_SRID_SIZE, src.ptr() + offset, len - WKB_GEO_SRID_SIZE);
if (ob_is_raw(expect_type)) {
obj.set_raw(buf, static_cast<int32_t>(len));
} else {

View File

@ -526,15 +526,23 @@ static int common_json_bin(const ObExpr &expr, ObEvalCtx &ctx, ObDatum &res_datu
return ret;
}
static int common_gis_wkb(const ObExpr &expr, ObEvalCtx &ctx, ObDatum &res_datum, ObString &wkb)
static int common_gis_wkb(const ObExpr &expr, ObEvalCtx &ctx, ObDatum &res_datum, ObString &wkb, bool skip_ver = false)
{
int ret = OB_SUCCESS;
ObTextStringDatumResult text_result(ObGeometryType, &expr, &ctx, &res_datum);
if (OB_FAIL(text_result.init(wkb.length()))) {
uint32_t len = skip_ver ? wkb.length() - WKB_VERSION_SIZE : wkb.length();
if (OB_FAIL(text_result.init(len))) {
LOG_WARN("Lob: init lob result failed");
} else if (skip_ver) {
if (OB_FAIL(text_result.append(wkb.ptr(), WKB_GEO_SRID_SIZE))) {
LOG_WARN("failed to append realdata", K(ret), K(wkb), K(text_result));
} else if (OB_FAIL(text_result.append(wkb.ptr() + WKB_OFFSET, len - WKB_GEO_SRID_SIZE))) {
LOG_WARN("failed to append realdata", K(ret), K(wkb), K(text_result));
}
} else if (OB_FAIL(text_result.append(wkb.ptr(), wkb.length()))) {
LOG_WARN("failed to append realdata", K(ret), K(wkb), K(text_result));
} else {
}
if (OB_SUCC(ret)) {
text_result.set_result();
}
return ret;
@ -4017,7 +4025,10 @@ CAST_FUNC_NAME(string, geometry)
} else if (OB_FAIL(ObGeoExprUtils::build_geometry(temp_allocator, in_str, geo, srs, cast_name))) {
LOG_WARN("fail to parse geometry", K(ret), K(in_str), K(dst_geo_type));
} else if (ObGeoType::GEOMETRY == dst_geo_type || ObGeoType::GEOTYPEMAX == dst_geo_type) {
if (OB_FAIL(common_gis_wkb(expr, ctx, res_datum, in_str))){
ObString res_wkb;
if (OB_FAIL(ObGeoTypeUtil::add_geo_version(temp_allocator, in_str, res_wkb))) {
LOG_WARN("fail to add version", K(ret), K(dst_geo_type));
} else if (OB_FAIL(common_gis_wkb(expr, ctx, res_datum, res_wkb))) {
LOG_WARN("fail to copy string", K(ret), K(dst_geo_type));
}
} else if (OB_FAIL(geometry_geometry(expr, ctx, res_datum))) {
@ -8576,26 +8587,38 @@ static int geom_copy_string(const ObExpr &expr,
{
int ret = OB_SUCCESS;
char *out_ptr = NULL;
int64_t len = src.length() - WKB_VERSION_SIZE;
if (expr.obj_meta_.is_lob_storage()) {
if (OB_FAIL(common_gis_wkb(expr, ctx, res_datum, src))) {
LOG_WARN("fail to pack gis lob res", K(ret));
int64_t len = src.length();
if (OB_LIKELY(len > WKB_OFFSET)) {
uint8_t offset = WKB_GEO_SRID_SIZE;
uint8_t version = (*(src.ptr() + WKB_GEO_SRID_SIZE));
if (IS_GEO_VERSION(version)) {
// version exist
len -= WKB_VERSION_SIZE;
offset += WKB_VERSION_SIZE;
}
} else {
if (expr.res_buf_len_ < len) {
if (OB_ISNULL(out_ptr = expr.get_str_res_mem(ctx, len))) {
ret = OB_ALLOCATE_MEMORY_FAILED;
LOG_WARN("allocate memory failed", K(ret));
if (expr.obj_meta_.is_lob_storage()) {
if (OB_FAIL(common_gis_wkb(expr, ctx, res_datum, src, IS_GEO_VERSION(version)))) {
LOG_WARN("fail to pack gis lob res", K(ret));
}
} else {
out_ptr = const_cast<char*>(res_datum.ptr_);
}
if (expr.res_buf_len_ < len) {
if (OB_ISNULL(out_ptr = expr.get_str_res_mem(ctx, len))) {
ret = OB_ALLOCATE_MEMORY_FAILED;
LOG_WARN("allocate memory failed", K(ret));
}
} else {
out_ptr = const_cast<char*>(res_datum.ptr_);
}
if (OB_SUCC(ret)) {
MEMMOVE(out_ptr, src.ptr(), WKB_GEO_SRID_SIZE);
MEMMOVE(out_ptr + WKB_GEO_SRID_SIZE, src.ptr() + WKB_OFFSET, len - WKB_GEO_SRID_SIZE);
res_datum.set_string(out_ptr, len);
if (OB_SUCC(ret)) {
MEMMOVE(out_ptr, src.ptr(), WKB_GEO_SRID_SIZE);
MEMMOVE(out_ptr + WKB_GEO_SRID_SIZE, src.ptr() + offset, len - WKB_GEO_SRID_SIZE);
res_datum.set_string(out_ptr, len);
}
}
} else {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("invalid obj len", K(ret), K(len));
}
return ret;
}