[CP] [FEAT MERGE] JSON/XML/GIS MEM OPTIMIZATION AND NEW XML/GIS EXPR
This commit is contained in:
parent
ba5bcd80ac
commit
a8a00b05fc
6
deps/oblib/src/common/object/ob_obj_funcs.h
vendored
6
deps/oblib/src/common/object/ob_obj_funcs.h
vendored
@ -1784,7 +1784,7 @@ inline int obj_print_sql<ObJsonType>(const ObObj &obj, char *buffer, int64_t len
|
||||
} else if (str.empty()) { // nothing to print;
|
||||
} else if (OB_FAIL(ObJsonBaseFactory::get_json_base(&tmp_allocator, str, in_type, in_type, j_base, parse_flag))) {
|
||||
COMMON_LOG(WARN, "fail to get json base", K(ret), K(in_type));
|
||||
} else if (OB_FAIL(j_base->print(jbuf, false))) { // json binary to string
|
||||
} else if (OB_FAIL(j_base->print(jbuf, false, str.length()))) { // json binary to string
|
||||
COMMON_LOG(WARN, "fail to convert json to string", K(ret), K(obj));
|
||||
} else if (OB_FAIL(databuff_printf(buffer, length, pos, "'"))) {
|
||||
COMMON_LOG(WARN, "fail to print \"'\"", K(ret), K(length), K(pos));
|
||||
@ -1821,7 +1821,7 @@ inline int obj_print_plain_str<ObJsonType>(const ObObj &obj, char *buffer, int64
|
||||
} else if (str.empty()) { // nothing to print;
|
||||
} else if (OB_FAIL(ObJsonBaseFactory::get_json_base(&tmp_allocator, str, in_type, in_type, j_base, parse_flag))) {
|
||||
COMMON_LOG(WARN, "fail to get json base", K(ret), K(in_type));
|
||||
} else if (OB_FAIL(j_base->print(jbuf, false))) { // json binary to string
|
||||
} else if (OB_FAIL(j_base->print(jbuf, false, str.length()))) { // json binary to string
|
||||
COMMON_LOG(WARN, "fail to convert json to string", K(ret), K(obj));
|
||||
} else if (params.use_memcpy_) {
|
||||
ret = databuff_memcpy(buffer, length, pos, jbuf.length(), jbuf.ptr());
|
||||
@ -1849,7 +1849,7 @@ inline int obj_print_json<ObJsonType>(const ObObj &obj, char *buf, int64_t buf_l
|
||||
} else if (str.empty()) { // nothing to print;
|
||||
} else if (OB_FAIL(ObJsonBaseFactory::get_json_base(&tmp_allocator, str, in_type, in_type, j_base, parse_flag))) {
|
||||
COMMON_LOG(WARN, "fail to get json base", K(ret), K(in_type));
|
||||
} else if (OB_FAIL(j_base->print(jbuf, false))) { // json binary to string
|
||||
} else if (OB_FAIL(j_base->print(jbuf, false, str.length()))) { // json binary to string
|
||||
COMMON_LOG(WARN, "fail to convert json to string", K(ret), K(obj));
|
||||
} else if (OB_FAIL(databuff_printf(buf, buf_len, pos, "%.*s",
|
||||
static_cast<int>(MIN(jbuf.length(), buf_len - pos)),
|
||||
|
2
deps/oblib/src/lib/CMakeLists.txt
vendored
2
deps/oblib/src/lib/CMakeLists.txt
vendored
@ -93,6 +93,7 @@ ob_set_subtarget(oblib_lib geo
|
||||
geo/ob_sdo_geo_func_to_wkb.cpp
|
||||
geo/ob_wkb_to_sdo_geo_visitor.cpp
|
||||
geo/ob_wkb_to_json_visitor.cpp
|
||||
geo/ob_wkb_to_json_bin_visitor.cpp
|
||||
geo/ob_wkb_byte_order_visitor.cpp
|
||||
geo/ob_geo_3d.cpp
|
||||
geo/ob_sdo_geo_object.cpp
|
||||
@ -109,6 +110,7 @@ ob_set_subtarget(oblib_lib geo
|
||||
geo/ob_geo_simplify_visitor.cpp
|
||||
geo/ob_geo_box_clip_visitor.cpp
|
||||
geo/ob_geo_func_dissolve_polygon.cpp
|
||||
geo/ob_geo_close_ring_visitor.cpp
|
||||
geo/ob_geo_cache.cpp
|
||||
geo/ob_geo_vertex_collect_visitor.cpp
|
||||
geo/ob_geo_segment_collect_visitor.cpp
|
||||
|
2
deps/oblib/src/lib/allocator/page_arena.h
vendored
2
deps/oblib/src/lib/allocator/page_arena.h
vendored
@ -98,6 +98,7 @@ struct ModulePageAllocator: public ObIAllocator
|
||||
void set_tenant_id(uint64_t tenant_id) {attr_.tenant_id_ = tenant_id;};
|
||||
void set_ctx_id(int64_t ctx_id) { attr_.ctx_id_ = ctx_id; }
|
||||
void set_attr(const lib::ObMemAttr &attr) { attr_ = attr; }
|
||||
uint64_t get_tenant_id() { return attr_.tenant_id_; }
|
||||
lib::ObLabel get_label() const { return attr_.label_; }
|
||||
void *alloc(const int64_t sz)
|
||||
{
|
||||
@ -525,6 +526,7 @@ public: // API
|
||||
|
||||
void set_label(const lib::ObLabel &label) { page_allocator_.set_label(label); }
|
||||
lib::ObLabel get_label() const { return page_allocator_.get_label(); }
|
||||
uint64_t get_tenant_id() { return page_allocator_.get_tenant_id(); }
|
||||
void set_tenant_id(uint64_t tenant_id) { page_allocator_.set_tenant_id(tenant_id); }
|
||||
void set_ctx_id(int64_t ctx_id) { page_allocator_.set_ctx_id(ctx_id); }
|
||||
void set_attr(const lib::ObMemAttr &attr) { page_allocator_.set_attr(attr); }
|
||||
|
9
deps/oblib/src/lib/geo/ob_geo.h
vendored
9
deps/oblib/src/lib/geo/ob_geo.h
vendored
@ -23,10 +23,8 @@ class ObIGeoVisitor;
|
||||
class ObGeometry {
|
||||
public:
|
||||
// constructor
|
||||
ObGeometry(uint32_t srid = 0, ObIAllocator *allocator = NULL)
|
||||
ObGeometry(uint32_t srid = 0)
|
||||
: srid_(srid),
|
||||
zoom_in_value_(0),
|
||||
allocator_(allocator),
|
||||
version_(ENCODE_GEO_VERSION(GEO_VESION_1)) {}
|
||||
virtual ~ObGeometry() = default;
|
||||
ObGeometry(const ObGeometry& g) = default;
|
||||
@ -47,14 +45,11 @@ public:
|
||||
// srid
|
||||
uint32_t get_srid() const { return srid_; }
|
||||
void set_srid(uint32_t srid) { srid_ = srid; }
|
||||
uint32_t get_zoom_in_value() const { return zoom_in_value_; }
|
||||
void set_zoom_in_value(uint32_t value) { zoom_in_value_ = value; }
|
||||
// version
|
||||
uint8_t get_version() { return version_; }
|
||||
VIRTUAL_TO_STRING_KV(K_(srid));
|
||||
protected:
|
||||
uint32_t srid_;
|
||||
uint32_t zoom_in_value_;
|
||||
ObIAllocator* allocator_; // for write mode?
|
||||
uint8_t version_;
|
||||
};
|
||||
|
||||
|
47
deps/oblib/src/lib/geo/ob_geo_3d.cpp
vendored
47
deps/oblib/src/lib/geo/ob_geo_3d.cpp
vendored
@ -83,7 +83,7 @@ int ObGeometry3D::to_2d_geo(ObIAllocator &allocator, ObGeometry *&res, uint32_t
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
bool is_geog = (crs_ == ObGeoCRS::Geographic) ? true : false;
|
||||
if (OB_FAIL(ObGeoTypeUtil::create_geo_by_type(*allocator_, geo_type, is_geog, true, res, srid))) {
|
||||
if (OB_FAIL(ObGeoTypeUtil::create_geo_by_type(allocator, geo_type, is_geog, true, res, srid_))) {
|
||||
LOG_WARN("fail to create 2d geo obj", K(ret), K(geo_type), K(is_geog));
|
||||
} else {
|
||||
res->set_data(wkb_2d);
|
||||
@ -127,10 +127,10 @@ int ObGeometry3D::read_nums_value(ObGeoWkbByteOrder bo, uint32_t &nums)
|
||||
int ObGeometry3D::to_wkt(ObIAllocator &allocator, ObString &wkt, uint32_t srid/* = 0*/, int64_t maxdecimaldigits/* = -1*/, bool output_srid0/* = false*/)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObStringBuffer *buf = NULL;
|
||||
ObGeoStringBuffer *buf = NULL;
|
||||
ObGeo3DToWktVisitor visitor(maxdecimaldigits);
|
||||
set_pos(0);
|
||||
if (OB_ISNULL(buf = OB_NEWx(ObStringBuffer, &allocator, (&allocator)))) {
|
||||
if (OB_ISNULL(buf = OB_NEWx(ObGeoStringBuffer, &allocator, (&allocator)))) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
LOG_WARN("fail to allocate buffer", K(ret));
|
||||
} else if (srid != 0 || output_srid0) {
|
||||
@ -443,7 +443,7 @@ int ObGeometry3D::create_elevation_extent(ObGeoElevationExtent &extent)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObGeometry3D::normalize(const ObSrsItem *srs, uint32_t &zoom_in_value)
|
||||
int ObGeometry3D::normalize(const ObSrsItem *srs)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObGeo3DNormalizeVisitor visitor(srs);
|
||||
@ -453,8 +453,6 @@ int ObGeometry3D::normalize(const ObSrsItem *srs, uint32_t &zoom_in_value)
|
||||
} else if (!is_end()) {
|
||||
ret = OB_ERR_GIS_INVALID_DATA;
|
||||
LOG_WARN("has extra buffer in wkb", K(ret), K(cur_pos_), K(length()));
|
||||
} else {
|
||||
zoom_in_value = visitor.get_zoom_in_value();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@ -715,9 +713,12 @@ int ObGeo3DTo2DVisitor::visit_header(ObGeoWkbByteOrder bo, ObGeoType geo_type, b
|
||||
int ObGeo3DTo2DVisitor::append_nums(uint32_t nums)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
uint64_t reserve_len = WKB_GEO_ELEMENT_NUM_SIZE + nums * WKB_GEO_DOUBLE_STORED_SIZE;
|
||||
if (OB_ISNULL(wkb_buf_)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("wkb_buf_ is NULL", K(ret));
|
||||
} else if (OB_FAIL(wkb_buf_->reserve(reserve_len))) {
|
||||
LOG_WARN("fail to resverse buffer", K(ret));
|
||||
} else if (OB_FAIL(wkb_buf_->append(nums))) {
|
||||
LOG_WARN("fail to append nums value", K(ret));
|
||||
}
|
||||
@ -840,7 +841,8 @@ int ObGeo3DToWktVisitor::visit_pointz_inner(double x, double y, double z)
|
||||
uint64_t len_y = 0;
|
||||
uint64_t len_z = 0;
|
||||
char *buff_ptr = NULL;
|
||||
if (OB_FAIL(wkt_buf_->reserve(3 * double_buff_size + 2))) {
|
||||
uint32_t reserve_len = 3 * double_buff_size + 2;
|
||||
if (wkt_buf_->remain() < reserve_len && OB_FAIL(wkt_buf_->reserve(reserve_len))) {
|
||||
LOG_WARN("fail to reserve buffer", K(ret));
|
||||
} else if (FALSE_IT(buff_ptr = wkt_buf_->ptr() + wkt_buf_->length())) {
|
||||
} else if (OB_FAIL(ObGeoToWktVisitor::convert_double_to_str(buff_ptr, double_buff_size, x, has_scale_, scale_, is_oracle_mode_, len_x))) {
|
||||
@ -1508,48 +1510,21 @@ int ObGeo3DNormalizeVisitor::visit_pointz_start(ObGeometry3D *geo, bool is_inner
|
||||
ObGeoWkbByteOrder bo = geo->byteorder();
|
||||
double x = ObGeoWkbByteOrderUtil::read<double>(ptr + cur_pos, bo);
|
||||
double y = ObGeoWkbByteOrderUtil::read<double>(ptr + cur_pos + WKB_GEO_DOUBLE_STORED_SIZE, bo);
|
||||
double z = ObGeoWkbByteOrderUtil::read<double>(ptr + cur_pos + 2 * WKB_GEO_DOUBLE_STORED_SIZE, bo);
|
||||
double nx = 1.0;
|
||||
double ny = 1.0;
|
||||
double nz = 1.0;
|
||||
if (no_srs_) {
|
||||
nx = x * M_PI / 180.0;
|
||||
ny = y * M_PI / 180.0;
|
||||
nz = z * M_PI / 180.0;
|
||||
} else {
|
||||
if (OB_FAIL(srs_->latitude_convert_to_radians(y, ny))) {
|
||||
LOG_WARN("normalize y failed", K(ret));
|
||||
} else if (OB_FAIL(srs_->longtitude_convert_to_radians(x, nx))) {
|
||||
LOG_WARN("normalize x failed", K(ret));
|
||||
} else {
|
||||
uint32_t count = 0;
|
||||
double nx_tmp = nx;
|
||||
double ny_tmp = ny;
|
||||
double nz_tmp = nz;
|
||||
while (nx_tmp != 0.0 && std::fabs(nx_tmp) < ZOOM_IN_THRESHOLD) {
|
||||
nx_tmp *= 10;
|
||||
count++;
|
||||
}
|
||||
zoom_in_value_ = count > zoom_in_value_ ? count : zoom_in_value_;
|
||||
count = 0;
|
||||
while (ny_tmp != 0.0 && std::fabs(ny_tmp) < ZOOM_IN_THRESHOLD) {
|
||||
ny_tmp *= 10;
|
||||
count++;
|
||||
}
|
||||
zoom_in_value_ = count > zoom_in_value_ ? count : zoom_in_value_;
|
||||
count = 0;
|
||||
while (nz_tmp != 0.0 && std::fabs(nz_tmp) < ZOOM_IN_THRESHOLD) {
|
||||
nz_tmp *= 10;
|
||||
count++;
|
||||
}
|
||||
zoom_in_value_ = count > zoom_in_value_ ? count : zoom_in_value_;
|
||||
ObGeoWkbByteOrderUtil::write<double>(ptr + cur_pos, nx, bo);
|
||||
ObGeoWkbByteOrderUtil::write<double>(ptr + cur_pos + WKB_GEO_DOUBLE_STORED_SIZE, ny, bo);
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
ObGeoWkbByteOrderUtil::write<double>(ptr + cur_pos, nx, bo);
|
||||
ObGeoWkbByteOrderUtil::write<double>(ptr + cur_pos + WKB_GEO_DOUBLE_STORED_SIZE, ny, bo);
|
||||
ObGeoWkbByteOrderUtil::write<double>(ptr + cur_pos + WKB_GEO_DOUBLE_STORED_SIZE * 2, nz, bo);
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
|
15
deps/oblib/src/lib/geo/ob_geo_3d.h
vendored
15
deps/oblib/src/lib/geo/ob_geo_3d.h
vendored
@ -33,8 +33,8 @@ enum ObLineType {
|
||||
class ObGeometry3D: public ObGeometry
|
||||
{
|
||||
public:
|
||||
ObGeometry3D(uint32_t srid = 0, ObIAllocator *allocator = NULL)
|
||||
: ObGeometry(srid, allocator), cur_pos_(0) {}
|
||||
ObGeometry3D(uint32_t srid = 0)
|
||||
: ObGeometry(srid), cur_pos_(0) {}
|
||||
virtual ~ObGeometry3D() = default;
|
||||
ObGeometry3D(const ObGeometry3D& g) = default;
|
||||
ObGeometry3D& operator=(const ObGeometry3D& g) = default;
|
||||
@ -63,7 +63,7 @@ public:
|
||||
int to_sdo_geometry(ObSdoGeoObject &sdo_geo);
|
||||
int to_geo_json(ObIAllocator *allocator, common::ObString &geo_json);
|
||||
int create_elevation_extent(ObGeoElevationExtent &extent);
|
||||
int normalize(const ObSrsItem *srs, uint32_t &zoom_in_value);
|
||||
int normalize(const ObSrsItem *srs);
|
||||
int check_empty(bool &is_empty);
|
||||
int correct_lon_lat(const ObSrsItem *srs);
|
||||
private:
|
||||
@ -146,7 +146,7 @@ class ObGeo3DToWktVisitor : public ObGeo3DVisitor
|
||||
{
|
||||
public:
|
||||
ObGeo3DToWktVisitor(int64_t maxdecimaldigits = -1);
|
||||
void set_wkt_buf(ObStringBuffer *wkt_buf) { wkt_buf_ = wkt_buf; }
|
||||
void set_wkt_buf(ObGeoStringBuffer *wkt_buf) { wkt_buf_ = wkt_buf; }
|
||||
virtual int visit_header(ObGeoWkbByteOrder bo, ObGeoType geo_type, bool is_sub_type = false);
|
||||
// pointz
|
||||
virtual int visit_pointz_start(ObGeometry3D *geo, bool is_inner);
|
||||
@ -173,7 +173,7 @@ private:
|
||||
int append_comma();
|
||||
int append_paren(bool is_left);
|
||||
private:
|
||||
ObStringBuffer *wkt_buf_;
|
||||
ObGeoStringBuffer *wkt_buf_;
|
||||
bool is_oracle_mode_;
|
||||
bool is_mpt_visit_;
|
||||
bool has_scale_;
|
||||
@ -287,14 +287,11 @@ class ObGeo3DNormalizeVisitor : public ObGeo3DVisitor
|
||||
{
|
||||
public:
|
||||
explicit ObGeo3DNormalizeVisitor(const ObSrsItem *srs, bool no_srs = false)
|
||||
: srs_(srs), no_srs_(no_srs), zoom_in_value_(0) {}
|
||||
: srs_(srs), no_srs_(no_srs){}
|
||||
virtual int visit_pointz_start(ObGeometry3D *geo, bool is_inner = false);
|
||||
uint32_t get_zoom_in_value() { return zoom_in_value_; }
|
||||
private:
|
||||
static constexpr double ZOOM_IN_THRESHOLD = 0.00000001;
|
||||
const ObSrsItem *srs_;
|
||||
bool no_srs_; // for st_transform, only proj4text is given
|
||||
uint32_t zoom_in_value_;
|
||||
DISALLOW_COPY_AND_ASSIGN(ObGeo3DNormalizeVisitor);
|
||||
};
|
||||
|
||||
|
49
deps/oblib/src/lib/geo/ob_geo_bin.cpp
vendored
49
deps/oblib/src/lib/geo/ob_geo_bin.cpp
vendored
@ -13,7 +13,6 @@
|
||||
|
||||
#define USING_LOG_PREFIX LIB
|
||||
#include "ob_geo_bin.h"
|
||||
|
||||
namespace oceanbase {
|
||||
namespace common {
|
||||
|
||||
@ -178,13 +177,21 @@ ObWkbGeomInnerPoint::ObWkbGeomInnerPoint(const ObWkbGeomInnerPoint& p)
|
||||
bool ObWkbGeomInnerPoint::equals(const ObWkbGeomInnerPoint& p) const
|
||||
{
|
||||
bool bret = false;
|
||||
if ((fabs(this->get<0>() - p.get<0>()) <= 1e-12) &&
|
||||
(fabs(this->get<1>() - p.get<1>()) <= 1e-12)) {
|
||||
if ((fabs(this->get<0>() - p.get<0>()) <= OB_GEO_TOLERANCE) &&
|
||||
(fabs(this->get<1>() - p.get<1>()) <= OB_GEO_TOLERANCE)) {
|
||||
bret = true;
|
||||
}
|
||||
return bret;
|
||||
}
|
||||
|
||||
bool ObWkbGeomInnerPoint::operator==(const ObWkbGeomInnerPoint& p) const {
|
||||
return (fabs(x_ - p.get<0>()) <= OB_GEO_TOLERANCE) && (fabs(y_ - p.get<1>()) <= OB_GEO_TOLERANCE);
|
||||
}
|
||||
|
||||
bool ObWkbGeomInnerPoint::operator!=(const ObWkbGeomInnerPoint& p) const {
|
||||
return !((fabs(x_ - p.get<0>()) <= OB_GEO_TOLERANCE) && (fabs(y_ - p.get<1>()) <= OB_GEO_TOLERANCE));
|
||||
}
|
||||
|
||||
// Cartesian linestring
|
||||
uint32_t ObWkbGeomLineString::size() const
|
||||
{
|
||||
@ -203,7 +210,7 @@ ObWkbGeomLineString::size_type ObWkbGeomLineString::length() const
|
||||
|
||||
// iter adaptor
|
||||
void ObWkbGeomLineString::get_sub_addr(const_pointer last_addr, index_type last_idx, index_type cur_idx,
|
||||
ObWkbIterOffsetArray* offsets, pointer& data)
|
||||
ObWkbIterOffsetArray*& offsets, pointer& data)
|
||||
{
|
||||
UNUSED(last_addr);
|
||||
UNUSED(last_idx);
|
||||
@ -230,7 +237,7 @@ ObWkbGeomLinearRing::size_type ObWkbGeomLinearRing::length(ObGeoWkbByteOrder bo
|
||||
|
||||
// iter adaptor
|
||||
void ObWkbGeomLinearRing::get_sub_addr(const_pointer last_addr, index_type last_idx, index_type cur_idx,
|
||||
ObWkbIterOffsetArray* offsets, pointer& data)
|
||||
ObWkbIterOffsetArray*& offsets, pointer& data)
|
||||
{
|
||||
UNUSED(last_addr);
|
||||
UNUSED(last_idx);
|
||||
@ -259,7 +266,7 @@ ObWkbGeomPolygonInnerRings::size_type ObWkbGeomPolygonInnerRings::length() const
|
||||
|
||||
// iter adaptor
|
||||
void ObWkbGeomPolygonInnerRings::get_sub_addr(const_pointer last_addr, index_type last_idx, index_type cur_idx,
|
||||
ObWkbIterOffsetArray* offsets, pointer& data)
|
||||
ObWkbIterOffsetArray *&offsets, pointer& data)
|
||||
{
|
||||
ObWkbUtils::get_sub_addr_common(*this, last_addr, last_idx, cur_idx, offsets, data);
|
||||
}
|
||||
@ -328,7 +335,7 @@ ObWkbGeomMultiPoint::size_type ObWkbGeomMultiPoint::length() const
|
||||
|
||||
// iter adaptor
|
||||
void ObWkbGeomMultiPoint::get_sub_addr(const_pointer last_addr, index_type last_idx, index_type cur_idx,
|
||||
ObWkbIterOffsetArray* offsets, pointer& data)
|
||||
ObWkbIterOffsetArray*& offsets, pointer& data)
|
||||
{
|
||||
UNUSED(last_addr);
|
||||
UNUSED(last_idx);
|
||||
@ -360,7 +367,7 @@ ObWkbGeomMultiLineString::size_type ObWkbGeomMultiLineString::length() const
|
||||
|
||||
// iter adaptor
|
||||
void ObWkbGeomMultiLineString::get_sub_addr(const_pointer last_addr, index_type last_idx, index_type cur_idx,
|
||||
ObWkbIterOffsetArray* offsets, pointer& data)
|
||||
ObWkbIterOffsetArray*& offsets, pointer& data)
|
||||
{
|
||||
ObWkbUtils::get_sub_addr_common(*this, last_addr, last_idx, cur_idx, offsets, data);
|
||||
}
|
||||
@ -384,7 +391,7 @@ ObWkbGeomMultiPolygon::size_type ObWkbGeomMultiPolygon::length() const
|
||||
|
||||
// iter adaptor
|
||||
void ObWkbGeomMultiPolygon::get_sub_addr(const_pointer last_addr, index_type last_idx, index_type cur_idx,
|
||||
ObWkbIterOffsetArray* offsets, pointer& data)
|
||||
ObWkbIterOffsetArray*& offsets, pointer& data)
|
||||
{
|
||||
ObWkbUtils::get_sub_addr_common(*this, last_addr, last_idx, cur_idx, offsets, data);
|
||||
}
|
||||
@ -408,7 +415,7 @@ ObWkbGeomCollection::size_type ObWkbGeomCollection::length() const
|
||||
|
||||
// iter adaptor
|
||||
void ObWkbGeomCollection::get_sub_addr(const_pointer last_addr, index_type last_idx, index_type cur_idx,
|
||||
ObWkbIterOffsetArray* offsets, pointer& data)
|
||||
ObWkbIterOffsetArray*& offsets, pointer& data)
|
||||
{
|
||||
ObWkbUtils::get_sub_addr_common(*this, last_addr, last_idx, cur_idx, offsets, data);
|
||||
}
|
||||
@ -595,6 +602,14 @@ ObWkbGeogInnerPoint& ObWkbGeogInnerPoint::operator=(const ObWkbGeogInnerPoint& p
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool ObWkbGeogInnerPoint::operator==(const ObWkbGeogInnerPoint& p) const {
|
||||
return (fabs(x_ - p.get<0>()) <= OB_GEO_TOLERANCE) && (fabs(y_ - p.get<1>()) <= OB_GEO_TOLERANCE);
|
||||
}
|
||||
|
||||
bool ObWkbGeogInnerPoint::operator!=(const ObWkbGeogInnerPoint& p) const {
|
||||
return !((fabs(x_ - p.get<0>()) <= OB_GEO_TOLERANCE) && (fabs(y_ - p.get<1>()) <= OB_GEO_TOLERANCE));
|
||||
}
|
||||
|
||||
// Geograph linestring
|
||||
uint32_t ObWkbGeogLineString::size() const
|
||||
{
|
||||
@ -613,7 +628,7 @@ ObWkbGeogLineString::size_type ObWkbGeogLineString::length() const
|
||||
|
||||
// iter adaptor
|
||||
void ObWkbGeogLineString::get_sub_addr(const_pointer last_addr, index_type last_idx, index_type cur_idx,
|
||||
ObWkbIterOffsetArray* offsets, pointer& data)
|
||||
ObWkbIterOffsetArray*& offsets, pointer& data)
|
||||
{
|
||||
UNUSED(last_addr);
|
||||
UNUSED(last_idx);
|
||||
@ -640,7 +655,7 @@ ObWkbGeogLinearRing::size_type ObWkbGeogLinearRing::length(ObGeoWkbByteOrder bo
|
||||
|
||||
// iter adaptor
|
||||
void ObWkbGeogLinearRing::get_sub_addr(const_pointer last_addr, index_type last_idx, index_type cur_idx,
|
||||
ObWkbIterOffsetArray* offsets, pointer& data)
|
||||
ObWkbIterOffsetArray*& offsets, pointer& data)
|
||||
{
|
||||
UNUSED(last_addr);
|
||||
UNUSED(last_idx);
|
||||
@ -669,7 +684,7 @@ ObWkbGeogPolygonInnerRings::size_type ObWkbGeogPolygonInnerRings::length() const
|
||||
|
||||
// iter adaptor
|
||||
void ObWkbGeogPolygonInnerRings::get_sub_addr(const_pointer last_addr, index_type last_idx, index_type cur_idx,
|
||||
ObWkbIterOffsetArray* offsets, pointer& data)
|
||||
ObWkbIterOffsetArray*& offsets, pointer& data)
|
||||
{
|
||||
ObWkbUtils::get_sub_addr_common(*this, last_addr, last_idx, cur_idx, offsets, data);
|
||||
}
|
||||
@ -738,7 +753,7 @@ ObWkbGeogMultiPoint::size_type ObWkbGeogMultiPoint::length() const
|
||||
|
||||
// iter adaptor
|
||||
void ObWkbGeogMultiPoint::get_sub_addr(const_pointer last_addr, index_type last_idx, index_type cur_idx,
|
||||
ObWkbIterOffsetArray* offsets, pointer& data)
|
||||
ObWkbIterOffsetArray*& offsets, pointer& data)
|
||||
{
|
||||
UNUSED(last_addr);
|
||||
UNUSED(last_idx);
|
||||
@ -770,7 +785,7 @@ ObWkbGeogMultiLineString::size_type ObWkbGeogMultiLineString::length() const
|
||||
|
||||
// iter adaptor
|
||||
void ObWkbGeogMultiLineString::get_sub_addr(const_pointer last_addr, index_type last_idx, index_type cur_idx,
|
||||
ObWkbIterOffsetArray* offsets, pointer& data)
|
||||
ObWkbIterOffsetArray*& offsets, pointer& data)
|
||||
{
|
||||
ObWkbUtils::get_sub_addr_common(*this, last_addr, last_idx, cur_idx, offsets, data);
|
||||
}
|
||||
@ -793,7 +808,7 @@ ObWkbGeogMultiPolygon::size_type ObWkbGeogMultiPolygon::length() const
|
||||
|
||||
// iter adaptor
|
||||
void ObWkbGeogMultiPolygon::get_sub_addr(const_pointer last_addr, index_type last_idx, index_type cur_idx,
|
||||
ObWkbIterOffsetArray* offsets, pointer& data)
|
||||
ObWkbIterOffsetArray*& offsets, pointer& data)
|
||||
{
|
||||
ObWkbUtils::get_sub_addr_common(*this, last_addr, last_idx, cur_idx, offsets, data);
|
||||
}
|
||||
@ -817,7 +832,7 @@ ObWkbGeogCollection::size_type ObWkbGeogCollection::length() const
|
||||
|
||||
// iter adaptor
|
||||
void ObWkbGeogCollection::get_sub_addr(const_pointer last_addr, index_type last_idx, index_type cur_idx,
|
||||
ObWkbIterOffsetArray* offsets, pointer& data)
|
||||
ObWkbIterOffsetArray*& offsets, pointer& data)
|
||||
{
|
||||
ObWkbUtils::get_sub_addr_common(*this, last_addr, last_idx, cur_idx, offsets, data);
|
||||
}
|
||||
|
34
deps/oblib/src/lib/geo/ob_geo_bin.h
vendored
34
deps/oblib/src/lib/geo/ob_geo_bin.h
vendored
@ -47,6 +47,8 @@ static const uint32_t WKB_POINT_DATA_SIZE = WKB_GEO_DOUBLE_STORED_SIZE + WKB_GEO
|
||||
static const uint32_t WKB_DATA_OFFSET = WKB_OFFSET + WKB_GEO_BO_SIZE;
|
||||
// skip [srid][bo][type] only used for inner points
|
||||
static const uint32_t WKB_INNER_POINT = WKB_DATA_OFFSET + WKB_GEO_TYPE_SIZE;
|
||||
|
||||
static constexpr double OB_GEO_TOLERANCE = 5e-14;
|
||||
// Cartesian
|
||||
// [bo][type][X][Y]
|
||||
#pragma pack(1)
|
||||
@ -95,6 +97,8 @@ public:
|
||||
ObWkbGeomInnerPoint& operator=(const ObWkbGeomInnerPoint& p);
|
||||
ObWkbGeomInnerPoint& operator=(const ObWkbGeomInnerPoint& p) const;
|
||||
bool equals(const ObWkbGeomInnerPoint& p) const;
|
||||
bool operator==(const ObWkbGeomInnerPoint& p) const;
|
||||
bool operator!=(const ObWkbGeomInnerPoint& p) const;
|
||||
// TODO
|
||||
int64_t to_string(char *buffer, const int64_t length) const{
|
||||
UNUSED(buffer);
|
||||
@ -133,7 +137,7 @@ public:
|
||||
index_type iter_idx_max() const { return size(); }
|
||||
index_type iter_idx_min() const { return 0; }
|
||||
void get_sub_addr(const_pointer last_addr, index_type last_idx, index_type cur_idx,
|
||||
ObWkbIterOffsetArray* offsets, pointer& data);
|
||||
ObWkbIterOffsetArray*& offsets, pointer& data);
|
||||
iterator begin() { return iterator(iter_idx_min(), this); }
|
||||
const_iterator begin() const { return const_iterator(iter_idx_min(), this); }
|
||||
iterator end() { return iterator(iter_idx_max(), this); }
|
||||
@ -168,7 +172,7 @@ public:
|
||||
index_type iter_idx_max(ObGeoWkbByteOrder bo = ObGeoWkbByteOrder::LittleEndian) const { return size(bo); }
|
||||
index_type iter_idx_min() const { return 0; }
|
||||
void get_sub_addr(const_pointer last_addr, index_type last_idx, index_type cur_idx,
|
||||
ObWkbIterOffsetArray* offsets, pointer& data);
|
||||
ObWkbIterOffsetArray*& offsets, pointer& data);
|
||||
// iter adapt
|
||||
iterator begin() { return iterator(iter_idx_min(), this); }
|
||||
const_iterator begin() const { return const_iterator(iter_idx_min(), this); }
|
||||
@ -220,7 +224,7 @@ public:
|
||||
uint32_t data_offset() const { return WKB_COMMON_WKB_HEADER_LEN; }
|
||||
index_type et(index_type curidx) const { return curidx; }
|
||||
void get_sub_addr(const_pointer last_addr, index_type last_idx, index_type cur_idx,
|
||||
ObWkbIterOffsetArray* offsets, pointer& data);
|
||||
ObWkbIterOffsetArray*& offsets, pointer& data);
|
||||
size_type get_sub_size(const_pointer data) const { return data->length(static_cast<ObGeoWkbByteOrder>(bo_)); };
|
||||
iterator begin() { return iterator(iter_idx_min(), this); } // for move over exterior
|
||||
const_iterator begin() const { return const_iterator(iter_idx_min(), this); } // for move over exterior
|
||||
@ -277,7 +281,7 @@ public:
|
||||
index_type iter_idx_max() const { return size(); }
|
||||
index_type iter_idx_min() const { return 0; }
|
||||
void get_sub_addr(const_pointer last_addr, index_type last_idx, index_type cur_idx,
|
||||
ObWkbIterOffsetArray* offsets, pointer& data);
|
||||
ObWkbIterOffsetArray*& offsets, pointer& data);
|
||||
iterator begin() { return iterator(iter_idx_min(), this); }
|
||||
const_iterator begin() const { return const_iterator(iter_idx_min(), this); }
|
||||
iterator end() { return iterator(iter_idx_max(), this); }
|
||||
@ -317,7 +321,7 @@ public:
|
||||
uint32_t data_offset() const { return WKB_COMMON_WKB_HEADER_LEN; }
|
||||
index_type et(index_type curidx) const { return curidx; }
|
||||
void get_sub_addr(const_pointer last_addr, index_type last_idx, index_type cur_idx,
|
||||
ObWkbIterOffsetArray* offsets, pointer& data);
|
||||
ObWkbIterOffsetArray*& offsets, pointer& data);
|
||||
size_type get_sub_size(const_pointer data) const { return data->length(); };
|
||||
iterator begin() { return iterator(iter_idx_min(), this); }
|
||||
const_iterator begin() const { return const_iterator(iter_idx_min(), this); }
|
||||
@ -358,7 +362,7 @@ public:
|
||||
uint32_t data_offset() const { return WKB_COMMON_WKB_HEADER_LEN; }
|
||||
index_type et(index_type curidx) const { return curidx; }
|
||||
void get_sub_addr(const_pointer last_addr, index_type last_idx, index_type cur_idx,
|
||||
ObWkbIterOffsetArray* offsets, pointer& data);
|
||||
ObWkbIterOffsetArray*& offsets, pointer& data);
|
||||
size_type get_sub_size(const_pointer data) const { return data->length(); };
|
||||
iterator begin() { return iterator(iter_idx_min(), this); }
|
||||
const_iterator begin() const { return const_iterator(iter_idx_min(), this); }
|
||||
@ -402,7 +406,7 @@ public:
|
||||
uint32_t data_offset() const { return WKB_COMMON_WKB_HEADER_LEN; }
|
||||
index_type et(index_type curidx) const { return curidx; }
|
||||
void get_sub_addr(const_pointer last_addr, index_type last_idx, index_type cur_idx,
|
||||
ObWkbIterOffsetArray* offsets, pointer& data);
|
||||
ObWkbIterOffsetArray*& offsets, pointer& data);
|
||||
// sub obj interface
|
||||
size_type get_sub_size(const_pointer data) const;
|
||||
ObGeoType get_sub_type(const_pointer data) const;
|
||||
@ -464,6 +468,8 @@ public:
|
||||
template<std::size_t K>
|
||||
void set(double d, ObGeoWkbByteOrder bo = ObGeoWkbByteOrder::LittleEndian);
|
||||
ObWkbGeogInnerPoint& operator=(const ObWkbGeogInnerPoint& p);
|
||||
bool operator==(const ObWkbGeogInnerPoint& p) const;
|
||||
bool operator!=(const ObWkbGeogInnerPoint& p) const;
|
||||
// TODO
|
||||
int64_t to_string(char *buffer, const int64_t length) const{
|
||||
UNUSED(buffer);
|
||||
@ -502,7 +508,7 @@ public:
|
||||
index_type iter_idx_max() const { return size(); }
|
||||
index_type iter_idx_min() const { return 0; }
|
||||
void get_sub_addr(const_pointer last_addr, index_type last_idx, index_type cur_idx,
|
||||
ObWkbIterOffsetArray* offsets, pointer& data);
|
||||
ObWkbIterOffsetArray*& offsets, pointer& data);
|
||||
iterator begin() { return iterator(iter_idx_min(), this); }
|
||||
const_iterator begin() const { return const_iterator(iter_idx_min(), this); }
|
||||
iterator end() { return iterator(iter_idx_max(), this); }
|
||||
@ -537,7 +543,7 @@ public:
|
||||
index_type iter_idx_max(ObGeoWkbByteOrder bo = ObGeoWkbByteOrder::LittleEndian) const { return size(bo); }
|
||||
index_type iter_idx_min() const { return 0; }
|
||||
void get_sub_addr(const_pointer last_addr, index_type last_idx, index_type cur_idx,
|
||||
ObWkbIterOffsetArray* offsets, pointer& data);
|
||||
ObWkbIterOffsetArray*& offsets, pointer& data);
|
||||
// iter adapt
|
||||
iterator begin() { return iterator(iter_idx_min(), this); }
|
||||
const_iterator begin() const { return const_iterator(iter_idx_min(), this); }
|
||||
@ -586,7 +592,7 @@ public:
|
||||
uint32_t data_offset() const { return WKB_COMMON_WKB_HEADER_LEN; }
|
||||
index_type et(index_type curidx) const { return curidx; }
|
||||
void get_sub_addr(const_pointer last_addr, index_type last_idx, index_type cur_idx,
|
||||
ObWkbIterOffsetArray* offsets, pointer& data);
|
||||
ObWkbIterOffsetArray*& offsets, pointer& data);
|
||||
size_type get_sub_size(const_pointer data) const { return data->length(static_cast<ObGeoWkbByteOrder>(bo_)); };
|
||||
// iter interface
|
||||
iterator begin() { return iterator(iter_idx_min(), this); }
|
||||
@ -645,7 +651,7 @@ public:
|
||||
index_type iter_idx_max() const { return size(); }
|
||||
index_type iter_idx_min() const { return 0; }
|
||||
void get_sub_addr(const_pointer last_addr, index_type last_idx, index_type cur_idx,
|
||||
ObWkbIterOffsetArray* offsets, pointer& data);
|
||||
ObWkbIterOffsetArray*& offsets, pointer& data);
|
||||
iterator begin() { return iterator(iter_idx_min(), this); }
|
||||
const_iterator begin() const { return const_iterator(iter_idx_min(), this); }
|
||||
iterator end() { return iterator(iter_idx_max(), this); }
|
||||
@ -685,7 +691,7 @@ public:
|
||||
uint32_t data_offset() const { return WKB_COMMON_WKB_HEADER_LEN; }
|
||||
index_type et(index_type curidx) const { return curidx; }
|
||||
void get_sub_addr(const_pointer last_addr, index_type last_idx, index_type cur_idx,
|
||||
ObWkbIterOffsetArray* offsets, pointer& data);
|
||||
ObWkbIterOffsetArray*& offsets, pointer& data);
|
||||
size_type get_sub_size(const_pointer data) const { return data->length(); };
|
||||
iterator begin() { return iterator(iter_idx_min(), this); }
|
||||
const_iterator begin() const { return const_iterator(iter_idx_min(), this); }
|
||||
@ -726,7 +732,7 @@ public:
|
||||
uint32_t data_offset() const { return WKB_COMMON_WKB_HEADER_LEN; }
|
||||
index_type et(index_type curidx) const { return curidx; }
|
||||
void get_sub_addr(const_pointer last_addr, index_type last_idx, index_type cur_idx,
|
||||
ObWkbIterOffsetArray* offsets, pointer& data);
|
||||
ObWkbIterOffsetArray*& offsets, pointer& data);
|
||||
size_type get_sub_size(const_pointer data) const { return data->length(); };
|
||||
iterator begin() { return iterator(iter_idx_min(), this); }
|
||||
const_iterator begin() const { return const_iterator(iter_idx_min(), this); }
|
||||
@ -770,7 +776,7 @@ public:
|
||||
uint32_t data_offset() const { return WKB_COMMON_WKB_HEADER_LEN; }
|
||||
index_type et(index_type curidx) const { return curidx; }
|
||||
void get_sub_addr(const_pointer last_addr, index_type last_idx, index_type cur_idx,
|
||||
ObWkbIterOffsetArray* offsets, pointer& data);
|
||||
ObWkbIterOffsetArray*& offsets, pointer& data);
|
||||
size_type get_sub_size(const_pointer data) const;
|
||||
ObGeoType get_sub_type(const_pointer data) const;
|
||||
// iter interface
|
||||
|
11
deps/oblib/src/lib/geo/ob_geo_bin_iter.h
vendored
11
deps/oblib/src/lib/geo/ob_geo_bin_iter.h
vendored
@ -21,7 +21,7 @@
|
||||
namespace oceanbase {
|
||||
namespace common {
|
||||
|
||||
typedef common::ObSEArray<uint64_t, 64> ObWkbIterOffsetArray;
|
||||
typedef common::ObArray<uint64_t> ObWkbIterOffsetArray;
|
||||
|
||||
template<typename T, typename O>
|
||||
class ObWkbConstIterator
|
||||
@ -45,7 +45,7 @@ public:
|
||||
ObWkbConstIterator(index_type idx, const owner_t* owner);
|
||||
ObWkbConstIterator(self& iter, bool do_array_assign = true);
|
||||
ObWkbConstIterator(const self& iter, bool do_array_assign = true);
|
||||
~ObWkbConstIterator() {}
|
||||
~ObWkbConstIterator();
|
||||
// compare iter interface
|
||||
bool operator==(const self& iter) const { return (idx_ == iter.idx_); }
|
||||
bool operator!=(const self& iter) const { return (idx_ != iter.idx_); }
|
||||
@ -85,12 +85,9 @@ protected:
|
||||
};
|
||||
protected:
|
||||
index_type idx_;
|
||||
index_type idx_min_;
|
||||
index_type idx_max_;
|
||||
owner_t* owner_;
|
||||
// should not use pointer to save diff_info_ since iterator can not return error code
|
||||
DiffInfo diff_info_;
|
||||
DiffInfo* diff_info_ptr_;
|
||||
ObWkbIterOffsetArray offsets_;
|
||||
ObWkbIterOffsetArray* offsets_ptr_;
|
||||
};
|
||||
|
||||
@ -167,7 +164,7 @@ public:
|
||||
typename T::const_pointer last_addr,
|
||||
typename T::index_type last_idx,
|
||||
typename T::index_type cur_idx,
|
||||
ObWkbIterOffsetArray* offsets,
|
||||
ObWkbIterOffsetArray*& offsets,
|
||||
typename T::pointer& data);
|
||||
};
|
||||
|
||||
|
97
deps/oblib/src/lib/geo/ob_geo_bin_iter.ipp
vendored
97
deps/oblib/src/lib/geo/ob_geo_bin_iter.ipp
vendored
@ -13,6 +13,7 @@
|
||||
|
||||
#include "ob_geo.h"
|
||||
#include "lib/container/ob_vector.h"
|
||||
#include "share/rc/ob_tenant_base.h"
|
||||
|
||||
namespace oceanbase {
|
||||
namespace common {
|
||||
@ -20,13 +21,13 @@ namespace common {
|
||||
template<typename T, typename O>
|
||||
ObWkbConstIterator<T, O>::ObWkbConstIterator()
|
||||
: idx_(-1), owner_(NULL), diff_info_(),
|
||||
diff_info_ptr_(&diff_info_), offsets_(), offsets_ptr_(&offsets_)
|
||||
{}
|
||||
offsets_ptr_(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
template<typename T, typename O>
|
||||
ObWkbConstIterator<T, O>::ObWkbConstIterator(index_type idx, const owner_t* owner)
|
||||
: idx_(idx), diff_info_(), diff_info_ptr_(&diff_info_),
|
||||
offsets_(), offsets_ptr_(&offsets_)
|
||||
: idx_(idx), diff_info_(), offsets_ptr_(nullptr)
|
||||
{
|
||||
owner_ = const_cast<owner_t*>(owner);
|
||||
}
|
||||
@ -36,10 +37,20 @@ template<typename T, typename O>
|
||||
ObWkbConstIterator<T, O>::ObWkbConstIterator(self& iter, bool do_array_assign)
|
||||
: idx_(iter.idx_),
|
||||
owner_(iter.owner_), diff_info_(iter.diff_info_),
|
||||
diff_info_ptr_(&diff_info_), offsets_(), offsets_ptr_(&offsets_)
|
||||
offsets_ptr_(nullptr)
|
||||
{
|
||||
if (do_array_assign) {
|
||||
offsets_.assign(iter.offsets_);
|
||||
int ret = OB_SUCCESS; // for log
|
||||
if (iter.offsets_ptr_ != nullptr && do_array_assign) {
|
||||
// If the tenant ID can be obtained, use tenant memory
|
||||
ObMemAttr mem_attr(OB_SERVER_TENANT_ID, "GeoWkbIter");
|
||||
if (nullptr != MTL_CTX()) {
|
||||
mem_attr.tenant_id_ = MTL_ID();
|
||||
}
|
||||
void *buf = ob_malloc(sizeof(ObWkbIterOffsetArray), mem_attr);
|
||||
if (nullptr == buf || nullptr == (offsets_ptr_ = new(buf) ObWkbIterOffsetArray(*iter.offsets_ptr_))) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
COMMON_LOG(WARN, "allocate memory for hashmap failed", K(ret));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -48,13 +59,29 @@ template<typename T, typename O>
|
||||
ObWkbConstIterator<T, O>::ObWkbConstIterator(const self& iter, bool do_array_assign)
|
||||
: idx_(iter.idx_),
|
||||
owner_(iter.owner_), diff_info_(iter.diff_info_),
|
||||
diff_info_ptr_(&diff_info_), offsets_(), offsets_ptr_(&offsets_)
|
||||
offsets_ptr_(nullptr)
|
||||
{
|
||||
if (do_array_assign) {
|
||||
offsets_.assign(iter.offsets_);
|
||||
int ret = OB_SUCCESS; // for log
|
||||
if (iter.offsets_ptr_ != nullptr && do_array_assign) {
|
||||
// If the tenant ID can be obtained, use tenant memory
|
||||
ObMemAttr mem_attr(OB_SERVER_TENANT_ID, "GeoWkbIter");
|
||||
if (nullptr != MTL_CTX()) {
|
||||
mem_attr.tenant_id_ = MTL_ID();
|
||||
}
|
||||
void *buf = ob_malloc(sizeof(ObWkbIterOffsetArray), mem_attr);
|
||||
if (nullptr == buf || nullptr == (offsets_ptr_ = new(buf) ObWkbIterOffsetArray(*iter.offsets_ptr_))) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
COMMON_LOG(WARN, "allocate memory for hashmap failed", K(ret));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T, typename O>
|
||||
ObWkbConstIterator<T, O>::~ObWkbConstIterator()
|
||||
{
|
||||
OB_DELETE(ObWkbIterOffsetArray, "GeoWkbIter", offsets_ptr_);
|
||||
}
|
||||
|
||||
// shift iter interface
|
||||
template<typename T, typename O>
|
||||
typename ObWkbConstIterator<T, O>::self& ObWkbConstIterator<T, O>::operator++()
|
||||
@ -93,10 +120,24 @@ const typename ObWkbConstIterator<T, O>::self& ObWkbConstIterator<T, O>::operato
|
||||
idx_ = iter.idx_;
|
||||
owner_ = iter.owner_;
|
||||
diff_info_ = iter.diff_info_;
|
||||
// if fail to allocate memory, return the original iterator.
|
||||
// offsets_ is used for cache iter, won't affect correctness.
|
||||
if (OB_FAIL(offsets_.assign(iter.offsets_))) {
|
||||
COMMON_LOG(WARN, "fail to allocate memory", K(ret), K(iter.offsets_.count()));
|
||||
if (iter.offsets_ptr_ == nullptr) {
|
||||
OB_DELETE(ObWkbIterOffsetArray, "GeoWkbIter", offsets_ptr_);
|
||||
} else {
|
||||
if (iter.offsets_ptr_ != nullptr) {
|
||||
*iter.offsets_ptr_ = *iter.offsets_ptr_;
|
||||
} else {
|
||||
int ret = OB_SUCCESS; // for log
|
||||
// If the tenant ID can be obtained, use tenant memory
|
||||
ObMemAttr mem_attr(OB_SERVER_TENANT_ID, "GeoWkbIter");
|
||||
if (nullptr != MTL_CTX()) {
|
||||
mem_attr.tenant_id_ = MTL_ID();
|
||||
}
|
||||
void *buf = ob_malloc(sizeof(ObWkbIterOffsetArray), mem_attr);
|
||||
if (nullptr == buf || nullptr == (offsets_ptr_ = new(buf) ObWkbIterOffsetArray(*iter.offsets_ptr_))) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
COMMON_LOG(WARN, "allocate memory for hashmap failed", K(ret), KP(iter.offsets_ptr_));
|
||||
}
|
||||
}
|
||||
}
|
||||
return iter;
|
||||
}
|
||||
@ -160,7 +201,6 @@ typename ObWkbConstIterator<T, O>::reference ObWkbConstIterator<T, O>::operator[
|
||||
{
|
||||
self iter(*this, false);
|
||||
this->move(iter, diff, false);
|
||||
iter.diff_info_ptr_ = this->diff_info_ptr_;
|
||||
iter.offsets_ptr_ = this->offsets_ptr_;
|
||||
this->update_val(iter);
|
||||
return *(diff_info_.last_addr_);
|
||||
@ -187,12 +227,12 @@ template<typename T, typename O>
|
||||
void ObWkbConstIterator<T, O>::update_val(self& iter) const
|
||||
{
|
||||
pointer data = NULL;
|
||||
iter.owner_->get_sub_addr(iter.diff_info_ptr_->last_addr_,
|
||||
iter.diff_info_ptr_->last_idx_,
|
||||
iter.owner_->get_sub_addr(iter.diff_info_.last_addr_,
|
||||
iter.diff_info_.last_idx_,
|
||||
iter.idx_, iter.offsets_ptr_, data);
|
||||
// update info
|
||||
iter.diff_info_ptr_->last_addr_ = data;
|
||||
iter.diff_info_ptr_->last_idx_ = iter.idx_;
|
||||
iter.diff_info_.last_addr_ = data;
|
||||
iter.diff_info_.last_idx_ = iter.idx_;
|
||||
}
|
||||
|
||||
|
||||
@ -291,7 +331,6 @@ typename ObWkbIterator<T, O>::reference ObWkbIterator<T, O>::operator[](differen
|
||||
{
|
||||
self iter(*this, false);
|
||||
this->move(iter, diff, false);
|
||||
iter.diff_info_ptr_ = this->diff_info_ptr_;
|
||||
iter.offsets_ptr_ = this->offsets_ptr_;
|
||||
this->update_val(iter);
|
||||
return *(this->diff_info_.last_addr_);
|
||||
@ -314,12 +353,26 @@ void ObWkbUtils::get_sub_addr_common(const T& obj,
|
||||
typename T::const_pointer last_addr,
|
||||
typename T::index_type last_idx,
|
||||
typename T::index_type cur_idx,
|
||||
ObWkbIterOffsetArray* offsets,
|
||||
ObWkbIterOffsetArray *&offsets,
|
||||
typename T::pointer& data)
|
||||
{
|
||||
// init or reverse offset, search from head
|
||||
INIT_SUCC(ret);
|
||||
bool enable_offset_info = (offsets != NULL);
|
||||
bool enable_offset_info = true;
|
||||
if (offsets == nullptr) {
|
||||
// If the tenant ID can be obtained, use tenant memory
|
||||
ObMemAttr mem_attr(OB_SERVER_TENANT_ID, "GeoWkbIter");
|
||||
if (nullptr != MTL_CTX()) {
|
||||
mem_attr.tenant_id_ = MTL_ID();
|
||||
}
|
||||
void *buf = ob_malloc(sizeof(ObWkbIterOffsetArray), mem_attr);
|
||||
if (nullptr == buf || nullptr == (offsets = new(buf) ObWkbIterOffsetArray())) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
// allocate memory failed, can't maintain ObWkbIterOffsetArray
|
||||
enable_offset_info = false;
|
||||
COMMON_LOG(WARN, "allocate memory for hashmap failed", K(ret));
|
||||
}
|
||||
}
|
||||
bool need_do_scan = false;
|
||||
char* scan_ptr = nullptr;
|
||||
uint32_t offset = 0;
|
||||
|
@ -171,8 +171,7 @@ int ObGeoBoxClipVisitor::visit(ObCartesianMultipoint *geo)
|
||||
allocator_,
|
||||
mpt[i].get<0>(),
|
||||
mpt[i].get<1>(),
|
||||
geo->get_srid(),
|
||||
allocator_);
|
||||
geo->get_srid());
|
||||
if (OB_ISNULL(pt)) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
LOG_WARN("fail to alloc memory for geometry", K(ret));
|
||||
@ -398,7 +397,7 @@ int ObGeoBoxClipVisitor::line_visit(
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (OB_ISNULL(mls)) {
|
||||
mls = OB_NEWx(ObCartesianMultilinestring, allocator_);
|
||||
mls = OB_NEWx(ObCartesianMultilinestring, allocator_, line.get_srid(), *allocator_);
|
||||
if (OB_ISNULL(mls)) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
LOG_WARN("fail to alloc memory for geometry", K(ret));
|
||||
@ -768,7 +767,7 @@ int ObGeoBoxClipVisitor::make_polygons(
|
||||
} else {
|
||||
for (uint32_t j = 0; OB_SUCC(ret) && j < new_mpy.size(); ++j) {
|
||||
bool is_covered_by = false;
|
||||
ObGeoEvalCtx gis_context(allocator_);
|
||||
ObGeoEvalCtx gis_context(*mem_ctx_);
|
||||
ObCartesianLineString *tmp_line = reinterpret_cast<ObCartesianLineString *>(&ext_ring);
|
||||
if (OB_FAIL(gis_context.append_geo_arg(tmp_line))
|
||||
|| OB_FAIL(gis_context.append_geo_arg(&new_mpy[j]))) {
|
||||
@ -865,7 +864,7 @@ int ObGeoBoxClipVisitor::visit_polygon_inner_ring(
|
||||
double xmid = xmin_ + (xmax_ - xmin_) / 2;
|
||||
double ymid = ymin_ + (ymax_ - ymin_) / 2;
|
||||
ObCartesianPoint pt(xmid, ymid);
|
||||
ObGeoEvalCtx gis_context(allocator_);
|
||||
ObGeoEvalCtx gis_context(*mem_ctx_);
|
||||
if (OB_FAIL(gis_context.append_geo_arg(&pt))
|
||||
|| OB_FAIL(gis_context.append_geo_arg(&tmp_py))) {
|
||||
LOG_WARN("build gis context failed", K(ret), K(gis_context.get_geo_count()));
|
||||
@ -908,7 +907,7 @@ int ObGeoBoxClipVisitor::visit_polygon_ext_ring(const ObCartesianLinearring &ext
|
||||
double xmid = xmin_ + (xmax_ - xmin_) / 2;
|
||||
double ymid = ymin_ + (ymax_ - ymin_) / 2;
|
||||
ObCartesianPoint pt(xmid, ymid);
|
||||
ObGeoEvalCtx gis_context(allocator_);
|
||||
ObGeoEvalCtx gis_context(*mem_ctx_);
|
||||
if (OB_FAIL(gis_context.append_geo_arg(&pt)) || OB_FAIL(gis_context.append_geo_arg(&tmp_py))) {
|
||||
LOG_WARN("build gis context failed", K(ret), K(gis_context.get_geo_count()));
|
||||
} else if (OB_FAIL(ObGeoFunc<ObGeoFuncType::Within>::gis_func::eval(
|
||||
|
@ -38,14 +38,16 @@ enum ObBoxPosition {
|
||||
class ObGeoBoxClipVisitor : public ObEmptyGeoVisitor
|
||||
{
|
||||
public:
|
||||
explicit ObGeoBoxClipVisitor(const ObGeogBox &box, ObIAllocator &allocator)
|
||||
explicit ObGeoBoxClipVisitor(const ObGeogBox &box, lib::MemoryContext &mem_ctx)
|
||||
: xmin_(box.xmin),
|
||||
ymin_(box.ymin),
|
||||
xmax_(box.xmax),
|
||||
ymax_(box.ymax),
|
||||
res_geo_(nullptr),
|
||||
allocator_(&allocator)
|
||||
{}
|
||||
allocator_(&mem_ctx->get_arena_allocator()),
|
||||
mem_ctx_(&mem_ctx)
|
||||
{
|
||||
}
|
||||
virtual ~ObGeoBoxClipVisitor()
|
||||
{}
|
||||
|
||||
@ -141,6 +143,7 @@ private:
|
||||
ObCartesianGeometrycollection *res_geo_;
|
||||
ObIAllocator *allocator_;
|
||||
bool keep_polygon_;
|
||||
lib::MemoryContext *mem_ctx_;
|
||||
DISALLOW_COPY_AND_ASSIGN(ObGeoBoxClipVisitor);
|
||||
};
|
||||
|
||||
|
@ -584,7 +584,7 @@ int ObCachedGeoPolygon::check_valid(ObGeoEvalCtx& gis_context)
|
||||
int ret = OB_SUCCESS;
|
||||
if (!check_valid_) {
|
||||
bool invalid_for_cache = false;
|
||||
if (OB_FAIL(ObGeoTypeUtil::polygon_check_self_intersections(*(gis_context.get_allocator()), *origin_geo_, srs_, invalid_for_cache))) {
|
||||
if (OB_FAIL(ObGeoTypeUtil::polygon_check_self_intersections(gis_context.get_mem_ctx(), *origin_geo_, srs_, invalid_for_cache))) {
|
||||
LOG_WARN("cached polygon fail to check valid", K(ret));
|
||||
} else {
|
||||
check_valid_ = true;
|
||||
|
47
deps/oblib/src/lib/geo/ob_geo_close_ring_visitor.cpp
vendored
Normal file
47
deps/oblib/src/lib/geo/ob_geo_close_ring_visitor.cpp
vendored
Normal file
@ -0,0 +1,47 @@
|
||||
/**
|
||||
* Copyright (c) 2021 OceanBase
|
||||
* OceanBase CE is licensed under Mulan PubL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PubL v2.
|
||||
* You may obtain a copy of Mulan PubL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPubL-2.0
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PubL v2 for more details.
|
||||
*/
|
||||
|
||||
#define USING_LOG_PREFIX LIB
|
||||
#include "ob_geo_close_ring_visitor.h"
|
||||
|
||||
|
||||
namespace oceanbase {
|
||||
namespace common {
|
||||
|
||||
template<typename PolyTree>
|
||||
int ObGeoCloseRingVisitor::visit_poly(PolyTree *geo)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (geo->front() != geo->back()) {
|
||||
if (OB_FAIL(geo->push_back(geo->front()))) {
|
||||
LOG_WARN("fail to push back point", K(ret));
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret) && geo->size() < 4) {
|
||||
ret = OB_ERR_GIS_INVALID_DATA;
|
||||
LOG_WARN("invalid geometry polygon", K(ret), K(geo->size()));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObGeoCloseRingVisitor::visit(ObGeographLinearring *geo)
|
||||
{
|
||||
return visit_poly(geo);
|
||||
}
|
||||
|
||||
int ObGeoCloseRingVisitor::visit(ObCartesianLinearring *geo)
|
||||
{
|
||||
return visit_poly(geo);
|
||||
}
|
||||
|
||||
} // namespace common
|
||||
} // namespace oceanbase
|
52
deps/oblib/src/lib/geo/ob_geo_close_ring_visitor.h
vendored
Normal file
52
deps/oblib/src/lib/geo/ob_geo_close_ring_visitor.h
vendored
Normal file
@ -0,0 +1,52 @@
|
||||
/**
|
||||
* Copyright (c) 2021 OceanBase
|
||||
* OceanBase CE is licensed under Mulan PubL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PubL v2.
|
||||
* You may obtain a copy of Mulan PubL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPubL-2.0
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PubL v2 for more details.
|
||||
*/
|
||||
|
||||
#ifndef OCEANBASE_LIB_GEO_OB_GEO_CLOSE_RING_VISITOR_
|
||||
#define OCEANBASE_LIB_GEO_OB_GEO_CLOSE_RING_VISITOR_
|
||||
#include "lib/geo/ob_geo_visitor.h"
|
||||
#include "lib/geo/ob_srs_info.h"
|
||||
|
||||
namespace oceanbase
|
||||
{
|
||||
namespace common
|
||||
{
|
||||
|
||||
class ObGeoCloseRingVisitor : public ObEmptyGeoVisitor
|
||||
{
|
||||
public:
|
||||
// need_convert: Configure whether conversion is required when srs type is GEOGRAPHIC_SRS.
|
||||
explicit ObGeoCloseRingVisitor() {}
|
||||
virtual ~ObGeoCloseRingVisitor() {}
|
||||
bool prepare(ObGeometry *geo) override { return geo != nullptr; }
|
||||
|
||||
// tree
|
||||
int visit(ObPolygon *geo) { UNUSED(geo); return OB_SUCCESS; }
|
||||
|
||||
int visit(ObGeometrycollection *geo) { UNUSED(geo); return OB_SUCCESS; }
|
||||
|
||||
int visit(ObGeographLinearring *geo) override;
|
||||
int visit(ObCartesianLinearring *geo) override;
|
||||
|
||||
int visit(ObMultipolygon *geo) { UNUSED(geo); return OB_SUCCESS; }
|
||||
|
||||
bool is_end(ObLinearring *geo) override { UNUSED(geo); return true; }
|
||||
|
||||
private:
|
||||
template<typename PolyTree>
|
||||
int visit_poly(PolyTree *geo);
|
||||
DISALLOW_COPY_AND_ASSIGN(ObGeoCloseRingVisitor);
|
||||
};
|
||||
|
||||
} // namespace common
|
||||
} // namespace oceanbase
|
||||
|
||||
#endif
|
4
deps/oblib/src/lib/geo/ob_geo_common.cpp
vendored
4
deps/oblib/src/lib/geo/ob_geo_common.cpp
vendored
@ -133,12 +133,12 @@ int ObWkbBuffer::append(const char *str)
|
||||
|
||||
int ObWkbBuffer::append(const char *str, const uint64_t len)
|
||||
{
|
||||
return buf_.append(str, len);
|
||||
return buf_.append(str, len, 0);
|
||||
}
|
||||
|
||||
int ObWkbBuffer::append(const ObString &str)
|
||||
{
|
||||
return buf_.append(str);
|
||||
return buf_.append(str, 0);
|
||||
}
|
||||
|
||||
int ObWkbBuffer::write(uint64_t pos, uint32_t val)
|
||||
|
24
deps/oblib/src/lib/geo/ob_geo_dispatcher.h
vendored
24
deps/oblib/src/lib/geo/ob_geo_dispatcher.h
vendored
@ -50,6 +50,8 @@ protected:
|
||||
const common::ObGeometry *g2,
|
||||
const ObGeoEvalCtx &context,
|
||||
RetType &result);
|
||||
|
||||
static inline int eval_geo_func_inner(const common::ObGeoEvalCtx &gis_context, RetType &result);
|
||||
};
|
||||
|
||||
template <typename RetType, typename Functype>
|
||||
@ -207,6 +209,7 @@ int ObIGeoDispatcher<RetType, Functype>::eval_wkb_binary(const common::ObGeometr
|
||||
INIT_SUCC(ret);
|
||||
if (g1->crs() != g2->crs()) {
|
||||
ret = OB_ERR_GIS_DIFFERENT_SRIDS;
|
||||
OB_LOG(WARN, "invalid different srids", K(ret), K(g1->crs()), K(g2->crs()));
|
||||
} else {
|
||||
switch (g1->crs()) {
|
||||
case common::ObGeoCRS::Cartesian:
|
||||
@ -635,6 +638,7 @@ int ObIGeoDispatcher<RetType, Functype>::eval_tree_binary(const common::ObGeomet
|
||||
INIT_SUCC(ret);
|
||||
if (g1->crs() != g2->crs()) {
|
||||
ret = OB_ERR_GIS_DIFFERENT_SRIDS;
|
||||
OB_LOG(WARN, "invalid different srids", K(ret), K(g1->crs()), K(g2->crs()));
|
||||
} else {
|
||||
switch (g1->crs()) {
|
||||
case common::ObGeoCRS::Cartesian:
|
||||
@ -1055,6 +1059,25 @@ int ObIGeoDispatcher<RetType, Functype>::eval_tree_binary(const common::ObGeomet
|
||||
template <typename RetType, typename Functype>
|
||||
int ObIGeoDispatcher<RetType, Functype>::eval_geo_func(
|
||||
const common::ObGeoEvalCtx &gis_context, RetType &result)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
lib::MemoryContext mem_ctx = gis_context.get_mem_ctx();
|
||||
WITH_CONTEXT(mem_ctx) {
|
||||
if (CURRENT_CONTEXT->attr_.label_ != "GISModule" || CURRENT_CONTEXT->attr_.use_500()) {
|
||||
// only warning, not return error
|
||||
OB_LOG(WARN, "should not use other label expect GISModule",
|
||||
K(ret), K(CURRENT_CONTEXT->attr_), K(CURRENT_CONTEXT->attr_.use_500()), K(lbt()));
|
||||
}
|
||||
ret = eval_geo_func_inner(gis_context, result);
|
||||
} else {
|
||||
OB_LOG(WARN, "fail to do with context", K(ret));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <typename RetType, typename Functype>
|
||||
int ObIGeoDispatcher<RetType, Functype>::eval_geo_func_inner(
|
||||
const common::ObGeoEvalCtx &gis_context, RetType &result)
|
||||
{
|
||||
INIT_SUCC(ret);
|
||||
try {
|
||||
@ -1079,6 +1102,7 @@ int ObIGeoDispatcher<RetType, Functype>::eval_geo_func(
|
||||
ret = OB_ERR_NULL_VALUE; // error log at end of func
|
||||
} else if (g1->crs() != g2->crs()) {
|
||||
ret = OB_ERR_GIS_DIFFERENT_SRIDS;
|
||||
OB_LOG(WARN, "invalid different srids", K(ret), K(g1->crs()), K(g2->crs()));
|
||||
} else if (g1->crs() == common::ObGeoCRS::Geographic && OB_ISNULL(gis_context.get_srs())) {
|
||||
ret = OB_ERR_NULL_VALUE;
|
||||
} else if (g1->is_tree()) {
|
||||
|
@ -125,15 +125,16 @@ void ObGeoElevationExtent::calculate_z()
|
||||
is_z_calculated_ = true;
|
||||
}
|
||||
|
||||
ObGeoElevationVisitor::ObGeoElevationVisitor(ObIAllocator &allocator, const common::ObSrsItem *srs)
|
||||
ObGeoElevationVisitor::ObGeoElevationVisitor(lib::MemoryContext &mem_ctx, const common::ObSrsItem *srs)
|
||||
: extent_(nullptr),
|
||||
is_inited_(false),
|
||||
allocator_(&allocator),
|
||||
buffer_(allocator),
|
||||
allocator_(&mem_ctx->get_arena_allocator()),
|
||||
buffer_(*allocator_),
|
||||
srs_(srs),
|
||||
type_3D_(ObGeoType::GEO3DTYPEMAX),
|
||||
crs_(ObGeoCRS::Cartesian),
|
||||
srid_(0)
|
||||
srid_(0),
|
||||
mem_ctx_(&mem_ctx)
|
||||
{
|
||||
if (OB_NOT_NULL(srs_)) {
|
||||
crs_ = (srs_->srs_type() == ObSrsType::PROJECTED_SRS) ? ObGeoCRS::Cartesian
|
||||
@ -156,7 +157,7 @@ int ObGeoElevationVisitor::add_geometry(
|
||||
LOG_WARN("fail to check is geometry empty", K(ret));
|
||||
} else if (!is_geo_empty) {
|
||||
ObGeometry *geo_2D = nullptr;
|
||||
ObGeoEvalCtx geo_ctx(allocator_, srs_);
|
||||
ObGeoEvalCtx geo_ctx(*mem_ctx_, srs_);
|
||||
geo_ctx.set_is_called_in_pg_expr(true);
|
||||
ObGeogBox *box = nullptr;
|
||||
if (OB_FAIL(geo_3D.to_2d_geo(tmp_allocator, geo_2D))) {
|
||||
|
@ -66,7 +66,7 @@ private:
|
||||
class ObGeoElevationVisitor : public ObEmptyGeoVisitor
|
||||
{
|
||||
public:
|
||||
explicit ObGeoElevationVisitor(ObIAllocator &allocator, const common::ObSrsItem *srs);
|
||||
explicit ObGeoElevationVisitor(lib::MemoryContext &mem_ctx, const common::ObSrsItem *srs);
|
||||
virtual ~ObGeoElevationVisitor()
|
||||
{ if (OB_NOT_NULL(extent_))
|
||||
{ extent_->~ObGeoElevationExtent(); }
|
||||
@ -154,7 +154,7 @@ private:
|
||||
ObGeoType type_3D_;
|
||||
ObGeoCRS crs_;
|
||||
uint32_t srid_;
|
||||
|
||||
lib::MemoryContext *mem_ctx_;
|
||||
DISALLOW_COPY_AND_ASSIGN(ObGeoElevationVisitor);
|
||||
};
|
||||
|
||||
|
376
deps/oblib/src/lib/geo/ob_geo_func_buffer.cpp
vendored
376
deps/oblib/src/lib/geo/ob_geo_func_buffer.cpp
vendored
@ -61,13 +61,6 @@ private:
|
||||
static bool apply_bg_equal(ObGeographPolygon &geo1,
|
||||
ObGeographPolygon &geo2,
|
||||
const ObSrsItem *srs);
|
||||
template<typename MultiPointType, typename MultiLineType, typename MultiPolygonType>
|
||||
static int apply_bg_remove_duplicate_geo(ObIAllocator &allocator,
|
||||
const ObSrsItem *srs,
|
||||
ObGeometry *&geo);
|
||||
static int remove_duplicate_geo(ObIAllocator &allocator,
|
||||
const ObSrsItem *srs,
|
||||
ObGeometry *&geo);
|
||||
template <typename GeoTreeType>
|
||||
static int unwrap_geo_tree_inner(ObGeometry *geo_in,
|
||||
ObGeometry *&geo_out);
|
||||
@ -231,10 +224,10 @@ private:
|
||||
ObCartesianMultipolygon *mpt_res = NULL;
|
||||
ObCartesianMultipolygon *ml_res = NULL;
|
||||
ObCartesianMultipolygon *mpo_res = NULL;
|
||||
ObCartesianMultipolygon *geo_res = NULL;
|
||||
ObGeometry *dedup_pt_ptr = NULL;
|
||||
ObGeometry *dedup_ml_ptr = NULL;
|
||||
ObGeometry *dedup_mpo_ptr = NULL;
|
||||
ObArenaAllocator tmp_allocator;
|
||||
|
||||
ObCartesianGeometrycollection *geo_tree = NULL;
|
||||
common::ObIAllocator *allocator = context.get_allocator();
|
||||
@ -247,135 +240,106 @@ private:
|
||||
} else if ((srid != 0) && OB_ISNULL(srs)) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("invalid strategy for cartisan collection with null srs", K(srid), K(ret));
|
||||
} else if (OB_FAIL(ObGeoFuncUtils::ob_gc_prepare<ObCartesianGeometrycollection>(context, const_cast<ObGeometry *>(g), mpt, ml, mpo))) {
|
||||
LOG_WARN("fail to do gc prepare", K(ret));
|
||||
} else if (OB_ISNULL(mpt) || OB_ISNULL(ml) || OB_ISNULL(mpo)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("unexpected null geometry collection union", K(ret), KP(mpt), KP(ml), KP(mpo));
|
||||
} else if (OB_ISNULL(strategy = context.get_val_arg(0)->strategy_)) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
} else if (strategy->distance_val_ < 0 && !(mpt->empty() && ml->empty())) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("negative distance is only permitted for geometry collection with only (multi)polygon", K(ret));
|
||||
} else if (OB_NOT_NULL(mpt)
|
||||
&& (dedup_pt_ptr = reinterpret_cast<ObGeometry *>(mpt))
|
||||
&& OB_FAIL(ObGeoTypeUtil::remove_duplicate_geo(dedup_pt_ptr, context.get_mem_ctx(), srs, false))) {
|
||||
LOG_WARN("failed to deduplicate points", K(ret));
|
||||
} else if (OB_NOT_NULL(ml) && (dedup_ml_ptr = reinterpret_cast<ObGeometry *>(ml))
|
||||
&& OB_FAIL(ObGeoTypeUtil::remove_duplicate_geo(dedup_ml_ptr, context.get_mem_ctx(), srs, false))) {
|
||||
LOG_WARN("failed to deduplicate lines", K(ret));
|
||||
} else if (OB_NOT_NULL(mpo) && (dedup_mpo_ptr = reinterpret_cast<ObGeometry *>(mpo))
|
||||
&& OB_FAIL(ObGeoTypeUtil::remove_duplicate_geo(dedup_mpo_ptr, context.get_mem_ctx(), srs, false))) {
|
||||
LOG_WARN("failed to deduplicate polygons", K(ret));
|
||||
} else if (OB_ISNULL(mpt_res = OB_NEWx(ObCartesianMultipolygon, &tmp_allocator, srid, tmp_allocator))) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
LOG_WARN("failed to allocate memory", K(ret));
|
||||
} else if (OB_ISNULL(ml_res = OB_NEWx(ObCartesianMultipolygon, &tmp_allocator, srid, tmp_allocator))) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
LOG_WARN("failed to allocate memory", K(ret));
|
||||
} else if (OB_ISNULL(mpo_res = OB_NEWx(ObCartesianMultipolygon, &tmp_allocator, srid, tmp_allocator))) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
LOG_WARN("failed to allocate memory", K(ret));
|
||||
} else {
|
||||
ObGeoToTreeVisitor visitor(allocator);
|
||||
if (is_tree == false) {
|
||||
ObIWkbGeomCollection *i_geo =
|
||||
const_cast<ObIWkbGeomCollection *>(reinterpret_cast<const ObIWkbGeomCollection *>(g));
|
||||
if (OB_FAIL(i_geo->do_visit(visitor))) {
|
||||
LOG_WARN("failed to do geo to tree visit", K(ret));
|
||||
} else {
|
||||
geo_tree = static_cast<ObCartesianGeometrycollection *>(visitor.get_geometry());
|
||||
mpt = reinterpret_cast<ObCartesianMultipoint *>(dedup_pt_ptr);
|
||||
ml = reinterpret_cast<ObCartesianMultilinestring *>(dedup_ml_ptr);
|
||||
mpo = reinterpret_cast<ObCartesianMultipolygon *>(dedup_mpo_ptr);
|
||||
|
||||
// param 1, 2
|
||||
bg::strategy::buffer::distance_symmetric<double> distance_s(strategy->distance_val_);
|
||||
bg::strategy::buffer::side_straight side_s;
|
||||
// param 3
|
||||
bg::strategy::buffer::join_round join_round_s(strategy->join_round_val_);
|
||||
bg::strategy::buffer::join_miter join_miter_s(strategy->join_miter_val_);
|
||||
// param 4
|
||||
bg::strategy::buffer::end_round end_round_s(strategy->end_round_val_);
|
||||
bg::strategy::buffer::end_flat end_flat_s;
|
||||
// param 5
|
||||
bg::strategy::buffer::point_circle point_circle_s(strategy->point_circle_val_);
|
||||
bg::strategy::buffer::point_square point_square_s;
|
||||
|
||||
switch (ObGeoBufferStrategyStateType(strategy->state_num_)) {
|
||||
case ObGeoBufferStrategyStateType::JR_ER_PC: {
|
||||
bg::buffer(*mpt, *mpt_res, distance_s, side_s, join_round_s, end_round_s, point_circle_s);
|
||||
bg::buffer(*ml, *ml_res, distance_s, side_s, join_round_s, end_round_s, point_circle_s);
|
||||
bg::buffer(*mpo, *mpo_res, distance_s, side_s, join_round_s, end_round_s, point_circle_s);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
geo_tree =
|
||||
const_cast<ObCartesianGeometrycollection *>(reinterpret_cast<const ObCartesianGeometrycollection *>(g));
|
||||
}
|
||||
|
||||
if (OB_FAIL(ret)) {
|
||||
// do nothing
|
||||
} else if (OB_ISNULL(geo_tree)) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("failed to convert to geo tree", K(ret), KP(geo_res));
|
||||
} else if (OB_ISNULL((geo_res = OB_NEWx(ObCartesianMultipolygon , allocator, srid, *allocator)))) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
LOG_WARN("failed to allocate memory", K(ret), KP(geo_res));
|
||||
} else if (OB_FAIL(ObGeoFuncUtils::ob_geo_gc_split(*allocator, *geo_tree, mpt, ml, mpo))) {
|
||||
LOG_WARN("failed to do geometry collection split", K(ret));
|
||||
} else if (OB_ISNULL(mpt) || OB_ISNULL(ml) || OB_ISNULL(mpo)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("unexpected null geometry collection split", K(ret), KP(mpt), KP(ml), KP(mpo));
|
||||
} else if (OB_FAIL(ObGeoFuncUtils::ob_geo_gc_union(*allocator, *srs, mpt, ml, mpo))) {
|
||||
LOG_WARN("failed to do geometry collection union", K(ret));
|
||||
} else if (OB_ISNULL(mpt) || OB_ISNULL(ml) || OB_ISNULL(mpo)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("unexpected null geometry collection union", K(ret), KP(mpt), KP(ml), KP(mpo));
|
||||
} else if (OB_ISNULL(strategy = context.get_val_arg(0)->strategy_)) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
} else if (strategy->distance_val_ < 0 && !(mpt->empty() && ml->empty())) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("negative distance is only permitted for geometry collection with only (multi)polygon", K(ret));
|
||||
} else if (OB_NOT_NULL(mpt)
|
||||
&& (dedup_pt_ptr = reinterpret_cast<ObGeometry *>(mpt))
|
||||
&& OB_FAIL(remove_duplicate_geo(*allocator, srs, dedup_pt_ptr))) {
|
||||
LOG_WARN("failed to deduplicate points", K(ret));
|
||||
} else if (OB_NOT_NULL(ml) && (dedup_ml_ptr = reinterpret_cast<ObGeometry *>(ml))
|
||||
&& OB_FAIL(remove_duplicate_geo(*allocator, srs, dedup_ml_ptr))) {
|
||||
LOG_WARN("failed to deduplicate lines", K(ret));
|
||||
} else if (OB_NOT_NULL(mpo) && (dedup_mpo_ptr = reinterpret_cast<ObGeometry *>(mpo))
|
||||
&& OB_FAIL(remove_duplicate_geo(*allocator, srs, dedup_mpo_ptr))) {
|
||||
LOG_WARN("failed to deduplicate polygons", K(ret));
|
||||
} else if (OB_ISNULL(mpt_res = OB_NEWx(ObCartesianMultipolygon, allocator, srid, *allocator))) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
LOG_WARN("failed to allocate memory", K(ret));
|
||||
} else if (OB_ISNULL(ml_res = OB_NEWx(ObCartesianMultipolygon, allocator, srid, *allocator))) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
LOG_WARN("failed to allocate memory", K(ret));
|
||||
} else if (OB_ISNULL(mpo_res = OB_NEWx(ObCartesianMultipolygon, allocator, srid, *allocator))) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
LOG_WARN("failed to allocate memory", K(ret));
|
||||
} else {
|
||||
mpt = reinterpret_cast<ObCartesianMultipoint *>(dedup_pt_ptr);
|
||||
ml = reinterpret_cast<ObCartesianMultilinestring *>(dedup_ml_ptr);
|
||||
mpo = reinterpret_cast<ObCartesianMultipolygon *>(dedup_mpo_ptr);
|
||||
|
||||
// param 1, 2
|
||||
bg::strategy::buffer::distance_symmetric<double> distance_s(strategy->distance_val_);
|
||||
bg::strategy::buffer::side_straight side_s;
|
||||
// param 3
|
||||
bg::strategy::buffer::join_round join_round_s(strategy->join_round_val_);
|
||||
bg::strategy::buffer::join_miter join_miter_s(strategy->join_miter_val_);
|
||||
// param 4
|
||||
bg::strategy::buffer::end_round end_round_s(strategy->end_round_val_);
|
||||
bg::strategy::buffer::end_flat end_flat_s;
|
||||
// param 5
|
||||
bg::strategy::buffer::point_circle point_circle_s(strategy->point_circle_val_);
|
||||
bg::strategy::buffer::point_square point_square_s;
|
||||
|
||||
switch (ObGeoBufferStrategyStateType(strategy->state_num_)) {
|
||||
case ObGeoBufferStrategyStateType::JR_ER_PC: {
|
||||
bg::buffer(*mpt, *mpt_res, distance_s, side_s, join_round_s, end_round_s, point_circle_s);
|
||||
bg::buffer(*ml, *ml_res, distance_s, side_s, join_round_s, end_round_s, point_circle_s);
|
||||
bg::buffer(*mpo, *mpo_res, distance_s, side_s, join_round_s, end_round_s, point_circle_s);
|
||||
break;
|
||||
}
|
||||
case ObGeoBufferStrategyStateType::JR_ER_PS: {
|
||||
bg::buffer(*mpt, *mpt_res, distance_s, side_s, join_round_s, end_round_s, point_square_s);
|
||||
bg::buffer(*ml, *ml_res, distance_s, side_s, join_round_s, end_round_s, point_square_s);
|
||||
bg::buffer(*mpo, *mpo_res, distance_s, side_s, join_round_s, end_round_s, point_square_s);
|
||||
break;
|
||||
}
|
||||
case ObGeoBufferStrategyStateType::JR_EF_PC: {
|
||||
bg::buffer(*mpt, *mpt_res, distance_s, side_s, join_round_s, end_flat_s, point_circle_s);
|
||||
bg::buffer(*ml, *ml_res, distance_s, side_s, join_round_s, end_flat_s, point_circle_s);
|
||||
bg::buffer(*mpo, *mpo_res, distance_s, side_s, join_round_s, end_flat_s, point_circle_s);
|
||||
break;
|
||||
}
|
||||
case ObGeoBufferStrategyStateType::JR_EF_PS: {
|
||||
bg::buffer(*mpt, *mpt_res, distance_s, side_s, join_round_s, end_flat_s, point_square_s);
|
||||
bg::buffer(*ml, *ml_res, distance_s, side_s, join_round_s, end_flat_s, point_square_s);
|
||||
bg::buffer(*mpo, *mpo_res, distance_s, side_s, join_round_s, end_flat_s, point_square_s);
|
||||
break;
|
||||
}
|
||||
case ObGeoBufferStrategyStateType::JM_ER_PC: {
|
||||
bg::buffer(*mpt, *mpt_res, distance_s, side_s, join_miter_s, end_round_s, point_circle_s);
|
||||
bg::buffer(*ml, *ml_res, distance_s, side_s, join_miter_s, end_round_s, point_circle_s);
|
||||
bg::buffer(*mpo, *mpo_res, distance_s, side_s, join_miter_s, end_round_s, point_circle_s);
|
||||
break;
|
||||
}
|
||||
case ObGeoBufferStrategyStateType::JM_ER_PS: {
|
||||
bg::buffer(*mpt, *mpt_res, distance_s, side_s, join_miter_s, end_round_s, point_square_s);
|
||||
bg::buffer(*ml, *ml_res, distance_s, side_s, join_miter_s, end_round_s, point_square_s);
|
||||
bg::buffer(*mpo, *mpo_res, distance_s, side_s, join_miter_s, end_round_s, point_square_s);
|
||||
break;
|
||||
}
|
||||
case ObGeoBufferStrategyStateType::JM_EF_PC: {
|
||||
bg::buffer(*mpt, *mpt_res, distance_s, side_s, join_miter_s, end_flat_s, point_circle_s);
|
||||
bg::buffer(*ml, *ml_res, distance_s, side_s, join_miter_s, end_flat_s, point_circle_s);
|
||||
bg::buffer(*mpo, *mpo_res, distance_s, side_s, join_miter_s, end_flat_s, point_circle_s);
|
||||
break;
|
||||
}
|
||||
case ObGeoBufferStrategyStateType::JM_EF_PS: {
|
||||
bg::buffer(*mpt, *mpt_res, distance_s, side_s, join_miter_s, end_flat_s, point_square_s);
|
||||
bg::buffer(*ml, *ml_res, distance_s, side_s, join_miter_s, end_flat_s, point_square_s);
|
||||
bg::buffer(*mpo, *mpo_res, distance_s, side_s, join_miter_s, end_flat_s, point_square_s);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("error strategy state number", K(ret), K(strategy->state_num_));
|
||||
break;
|
||||
}
|
||||
case ObGeoBufferStrategyStateType::JR_ER_PS: {
|
||||
bg::buffer(*mpt, *mpt_res, distance_s, side_s, join_round_s, end_round_s, point_square_s);
|
||||
bg::buffer(*ml, *ml_res, distance_s, side_s, join_round_s, end_round_s, point_square_s);
|
||||
bg::buffer(*mpo, *mpo_res, distance_s, side_s, join_round_s, end_round_s, point_square_s);
|
||||
break;
|
||||
}
|
||||
case ObGeoBufferStrategyStateType::JR_EF_PC: {
|
||||
bg::buffer(*mpt, *mpt_res, distance_s, side_s, join_round_s, end_flat_s, point_circle_s);
|
||||
bg::buffer(*ml, *ml_res, distance_s, side_s, join_round_s, end_flat_s, point_circle_s);
|
||||
bg::buffer(*mpo, *mpo_res, distance_s, side_s, join_round_s, end_flat_s, point_circle_s);
|
||||
break;
|
||||
}
|
||||
case ObGeoBufferStrategyStateType::JR_EF_PS: {
|
||||
bg::buffer(*mpt, *mpt_res, distance_s, side_s, join_round_s, end_flat_s, point_square_s);
|
||||
bg::buffer(*ml, *ml_res, distance_s, side_s, join_round_s, end_flat_s, point_square_s);
|
||||
bg::buffer(*mpo, *mpo_res, distance_s, side_s, join_round_s, end_flat_s, point_square_s);
|
||||
break;
|
||||
}
|
||||
case ObGeoBufferStrategyStateType::JM_ER_PC: {
|
||||
bg::buffer(*mpt, *mpt_res, distance_s, side_s, join_miter_s, end_round_s, point_circle_s);
|
||||
bg::buffer(*ml, *ml_res, distance_s, side_s, join_miter_s, end_round_s, point_circle_s);
|
||||
bg::buffer(*mpo, *mpo_res, distance_s, side_s, join_miter_s, end_round_s, point_circle_s);
|
||||
break;
|
||||
}
|
||||
case ObGeoBufferStrategyStateType::JM_ER_PS: {
|
||||
bg::buffer(*mpt, *mpt_res, distance_s, side_s, join_miter_s, end_round_s, point_square_s);
|
||||
bg::buffer(*ml, *ml_res, distance_s, side_s, join_miter_s, end_round_s, point_square_s);
|
||||
bg::buffer(*mpo, *mpo_res, distance_s, side_s, join_miter_s, end_round_s, point_square_s);
|
||||
break;
|
||||
}
|
||||
case ObGeoBufferStrategyStateType::JM_EF_PC: {
|
||||
bg::buffer(*mpt, *mpt_res, distance_s, side_s, join_miter_s, end_flat_s, point_circle_s);
|
||||
bg::buffer(*ml, *ml_res, distance_s, side_s, join_miter_s, end_flat_s, point_circle_s);
|
||||
bg::buffer(*mpo, *mpo_res, distance_s, side_s, join_miter_s, end_flat_s, point_circle_s);
|
||||
break;
|
||||
}
|
||||
case ObGeoBufferStrategyStateType::JM_EF_PS: {
|
||||
bg::buffer(*mpt, *mpt_res, distance_s, side_s, join_miter_s, end_flat_s, point_square_s);
|
||||
bg::buffer(*ml, *ml_res, distance_s, side_s, join_miter_s, end_flat_s, point_square_s);
|
||||
bg::buffer(*mpo, *mpo_res, distance_s, side_s, join_miter_s, end_flat_s, point_square_s);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("error strategy state number", K(ret), K(strategy->state_num_));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -389,13 +353,13 @@ private:
|
||||
}
|
||||
} else {
|
||||
ObGeometry *temp_geo = NULL;
|
||||
ObGeoEvalCtx union_context_mpt_ml(allocator, srs);
|
||||
ObGeoEvalCtx union_context_mpt_ml(context.get_mem_ctx(), srs);
|
||||
union_context_mpt_ml.append_geo_arg(mpt_res);
|
||||
union_context_mpt_ml.append_geo_arg(ml_res);
|
||||
if (OB_FAIL(ObGeoFuncUnion::eval(union_context_mpt_ml, temp_geo))) {
|
||||
LOG_WARN("union buffer result of multipoints and multistringline failed", K(ret));
|
||||
} else {
|
||||
ObGeoEvalCtx union_context_mpt_ml_mpo(allocator, srs);
|
||||
ObGeoEvalCtx union_context_mpt_ml_mpo(context.get_mem_ctx(), srs);
|
||||
union_context_mpt_ml_mpo.append_geo_arg(temp_geo);
|
||||
union_context_mpt_ml_mpo.append_geo_arg(mpo_res);
|
||||
if (OB_FAIL(ObGeoFuncUnion::eval(union_context_mpt_ml_mpo, temp_geo))) {
|
||||
@ -428,8 +392,8 @@ private:
|
||||
ObGeoBufferStrategy *strategy = context.get_val_arg(0)->strategy_;
|
||||
// Notice: transfrom context use dest srs
|
||||
common::ObIAllocator *allocator = context.get_allocator();
|
||||
ObGeoEvalCtx transfrom_proj_context(allocator, strategy->srs_proj_);
|
||||
ObGeoEvalCtx transfrom_wgs84_context(allocator, strategy->srs_wgs84_);
|
||||
ObGeoEvalCtx transfrom_proj_context(context.get_mem_ctx(), strategy->srs_proj_);
|
||||
ObGeoEvalCtx transfrom_wgs84_context(context.get_mem_ctx(), strategy->srs_wgs84_);
|
||||
ObGeometry *projected_geo = NULL;
|
||||
ObGeometry *projected_result = NULL;
|
||||
ObGeometry *projected_bin = NULL;
|
||||
@ -772,140 +736,6 @@ bool ObGeoFuncBufferImpl::apply_bg_equal(ObGeographPolygon &geo1,
|
||||
return bg::equals(geo1, geo2, line_strategy);
|
||||
}
|
||||
|
||||
template<typename MultiPointType, typename MultiLineType, typename MultiPolygonType>
|
||||
int ObGeoFuncBufferImpl::apply_bg_remove_duplicate_geo(ObIAllocator &allocator,
|
||||
const ObSrsItem *srs,
|
||||
ObGeometry *&geo)
|
||||
{
|
||||
INIT_SUCC(ret);
|
||||
switch (geo->type()) {
|
||||
case ObGeoType::POINT :
|
||||
case ObGeoType::LINESTRING :
|
||||
case ObGeoType::POLYGON :
|
||||
break;
|
||||
case ObGeoType::MULTIPOINT : {
|
||||
MultiPointType *mp = OB_NEWx(MultiPointType, (&allocator));
|
||||
if (OB_ISNULL(mp)) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
LOG_WARN("failed to allocate memory for multipoint", K(ret));
|
||||
} else {
|
||||
bool is_equal = false;
|
||||
MultiPointType *g = static_cast<MultiPointType *>(geo);
|
||||
FOREACH_X(item, (*g), OB_SUCC(ret)) {
|
||||
FOREACH(point, *mp) {
|
||||
is_equal = ObGeoFuncBufferImpl::apply_bg_equal(*item, *point, srs);
|
||||
if (is_equal) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!is_equal) {
|
||||
if(OB_FAIL(mp->push_back(*item))) {
|
||||
LOG_WARN("failed to add point to multipoint", K(ret));
|
||||
}
|
||||
}
|
||||
}
|
||||
geo = mp;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ObGeoType::MULTILINESTRING : {
|
||||
MultiLineType *ml = OB_NEWx(MultiLineType, (&allocator));
|
||||
if (OB_ISNULL(ml)) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
LOG_WARN("failed to allocate memory for multiline", K(ret));
|
||||
} else {
|
||||
bool is_equal = false;
|
||||
MultiLineType *g = static_cast<MultiLineType *>(geo);
|
||||
FOREACH_X(item, (*g), OB_SUCC(ret)) {
|
||||
FOREACH(line, *ml) {
|
||||
is_equal = ObGeoFuncBufferImpl::apply_bg_equal(*item, *line, srs);
|
||||
if (is_equal) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!is_equal) {
|
||||
if(OB_FAIL(ml->push_back(*item))) {
|
||||
LOG_WARN("failed to add line to multiline", K(ret));
|
||||
}
|
||||
}
|
||||
}
|
||||
geo = ml;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ObGeoType::MULTIPOLYGON : {
|
||||
MultiPolygonType *mpoly = OB_NEWx(MultiPolygonType, (&allocator));
|
||||
if (OB_ISNULL(mpoly)) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
LOG_WARN("failed to allocate memory for multipolygon", K(ret));
|
||||
} else {
|
||||
bool is_equal = false;
|
||||
MultiPolygonType *g = static_cast<MultiPolygonType *>(geo);
|
||||
FOREACH_X(item, *g, OB_SUCC(ret)) {
|
||||
FOREACH(poly, *mpoly) {
|
||||
is_equal = ObGeoFuncBufferImpl::apply_bg_equal(*item, *poly, srs);
|
||||
if (is_equal) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!is_equal) {
|
||||
if(OB_FAIL(mpoly->push_back(*item))) {
|
||||
LOG_WARN("failed to add polygon to multipolygon", K(ret));
|
||||
}
|
||||
}
|
||||
}
|
||||
geo = mpoly;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default : {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("invalid geo type", K(ret), K(geo->type()), K(geo->crs()));
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObGeoFuncBufferImpl::remove_duplicate_geo(ObIAllocator &allocator,
|
||||
const ObSrsItem *srs,
|
||||
ObGeometry *&geo)
|
||||
{
|
||||
INIT_SUCC(ret);
|
||||
if (geo == NULL) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("input geo is null", K(ret));
|
||||
} else if ((srs == NULL || srs->srs_type() != ObSrsType::GEOGRAPHIC_SRS)
|
||||
&& geo->crs() == ObGeoCRS::Geographic) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("invalid srs type", K(ret), KP(srs), K(geo->crs()));
|
||||
} else {
|
||||
switch (geo->crs()) {
|
||||
case ObGeoCRS::Geographic : {
|
||||
ret = apply_bg_remove_duplicate_geo<ObGeographMultipoint,
|
||||
ObGeographMultilinestring, ObGeographMultipolygon>(allocator, srs, geo);
|
||||
if (OB_FAIL(ret)) {
|
||||
LOG_WARN("failed to remove duplicate geo", K(ret), K(geo->crs()));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ObGeoCRS::Cartesian : {
|
||||
ret = apply_bg_remove_duplicate_geo<ObCartesianMultipoint,
|
||||
ObCartesianMultilinestring, ObCartesianMultipolygon>(allocator, srs, geo);
|
||||
if (OB_FAIL(ret)) {
|
||||
LOG_WARN("failed to remove duplicate geo", K(ret), K(geo->crs()));
|
||||
}
|
||||
break;
|
||||
}
|
||||
default : {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("invalid geo type", K(ret), K(srs->srs_type()), K(geo->crs()));
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <typename GeoTreeType>
|
||||
int ObGeoFuncBufferImpl::unwrap_geo_tree_inner(ObGeometry *geo_in,
|
||||
ObGeometry *&geo_out)
|
||||
|
@ -51,7 +51,7 @@ private:
|
||||
ObCartesianMultilinestring *ml = nullptr;
|
||||
ObCartesianMultipolygon *mpo = nullptr;
|
||||
ObIAllocator *allocator = context.get_allocator();
|
||||
ObCartesianPoint *res_geo = OB_NEWx(ObCartesianPoint, allocator, 0, 0, g->get_srid(), allocator);
|
||||
ObCartesianPoint *res_geo = OB_NEWx(ObCartesianPoint, allocator, 0, 0, g->get_srid());
|
||||
ObGeoToTreeVisitor tree_visitor(allocator);
|
||||
if (OB_ISNULL(res_geo)) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
@ -85,7 +85,7 @@ private:
|
||||
static int centroid_default(const ObGeometry *g, const ObGeoEvalCtx &context, ObGeometry *&result)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObCartesianPoint *res_geo = OB_NEWx(ObCartesianPoint, context.get_allocator(), 0, 0, g->get_srid(), context.get_allocator());
|
||||
ObCartesianPoint *res_geo = OB_NEWx(ObCartesianPoint, context.get_allocator(), 0, 0, g->get_srid());
|
||||
if (OB_ISNULL(res_geo)) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
LOG_WARN("fail to alloc memory for result grometry", K(ret));
|
||||
|
13
deps/oblib/src/lib/geo/ob_geo_func_common.h
vendored
13
deps/oblib/src/lib/geo/ob_geo_func_common.h
vendored
@ -50,11 +50,12 @@ union ObGeoNormalVal {
|
||||
class ObGeoEvalCtx
|
||||
{
|
||||
public:
|
||||
ObGeoEvalCtx() : allocator_(NULL), srs_(NULL), g_arg_c_(0), v_arg_c_(0), is_called_in_pg_expr_(false){};
|
||||
ObGeoEvalCtx(common::ObIAllocator * allocator) :
|
||||
allocator_(allocator), srs_(NULL), g_arg_c_(0), v_arg_c_(0), is_called_in_pg_expr_(false) {};
|
||||
ObGeoEvalCtx(common::ObIAllocator * allocator, const common::ObSrsItem *srs_item) :
|
||||
allocator_(allocator), srs_(srs_item), g_arg_c_(0), v_arg_c_(0), is_called_in_pg_expr_(false) {};
|
||||
ObGeoEvalCtx(lib::MemoryContext &mem_ctx) :
|
||||
allocator_(&mem_ctx->get_arena_allocator()), srs_(NULL), g_arg_c_(0), v_arg_c_(0),
|
||||
is_called_in_pg_expr_(false), mem_ctx_(mem_ctx) {};
|
||||
ObGeoEvalCtx(lib::MemoryContext &mem_ctx, const common::ObSrsItem *srs_item) :
|
||||
allocator_(&mem_ctx->get_arena_allocator()), srs_(srs_item), g_arg_c_(0), v_arg_c_(0),
|
||||
is_called_in_pg_expr_(false), mem_ctx_(mem_ctx) {};
|
||||
~ObGeoEvalCtx() = default;
|
||||
|
||||
inline int append_geo_arg(const common::ObGeometry *g)
|
||||
@ -156,6 +157,7 @@ public:
|
||||
|
||||
inline void set_is_called_in_pg_expr(bool in) { is_called_in_pg_expr_ = in; }
|
||||
inline bool get_is_called_in_pg_expr() const { return is_called_in_pg_expr_; }
|
||||
inline lib::MemoryContext &get_mem_ctx() const { return mem_ctx_; }
|
||||
|
||||
// interfaces for unittest only
|
||||
inline void ut_set_geo_count(int count)
|
||||
@ -180,6 +182,7 @@ private:
|
||||
const common::ObGeometry *gis_args_[MAX_ARG_COUNT]; // geo arguments
|
||||
ObGeoNormalVal val_args_[MAX_ARG_COUNT]; // other arguments
|
||||
bool is_called_in_pg_expr_; // distinguish pg/mysql expr call
|
||||
lib::MemoryContext &mem_ctx_;
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(ObGeoEvalCtx);
|
||||
|
@ -162,10 +162,11 @@ OB_GEO_CART_BINARY_FUNC_BEGIN(ObGeoFuncCoveredByImpl, ObWkbGeomPoint, ObWkbGeomC
|
||||
break;
|
||||
}
|
||||
case ObGeoType::POLYGON : {
|
||||
ObArenaAllocator tmp_alloc;
|
||||
const ObWkbGeomPolygon *polygon = reinterpret_cast<const ObWkbGeomPolygon*>(sub_ptr);
|
||||
ObString tmp(polygon->length(), reinterpret_cast<const char*>(sub_ptr));
|
||||
ObString pol_data;
|
||||
if (OB_FAIL(ob_write_string(*context.get_allocator(), tmp, pol_data))) {
|
||||
if (OB_FAIL(ob_write_string(tmp_alloc, tmp, pol_data))) {
|
||||
LOG_WARN("failed to copy polygon geo", K(ret));
|
||||
} else {
|
||||
ObWkbGeomPolygon *poly_copy = reinterpret_cast<ObWkbGeomPolygon*>(pol_data.ptr());
|
||||
@ -175,10 +176,11 @@ OB_GEO_CART_BINARY_FUNC_BEGIN(ObGeoFuncCoveredByImpl, ObWkbGeomPoint, ObWkbGeomC
|
||||
break;
|
||||
}
|
||||
case ObGeoType::MULTIPOLYGON : {
|
||||
ObArenaAllocator tmp_alloc;
|
||||
const ObWkbGeomMultiPolygon *multi_poly = reinterpret_cast<const ObWkbGeomMultiPolygon*>(sub_ptr);
|
||||
ObString tmp(multi_poly->length(), reinterpret_cast<const char*>(sub_ptr));
|
||||
ObString multipol_data;
|
||||
if (OB_FAIL(ob_write_string(*context.get_allocator(), tmp, multipol_data))) {
|
||||
if (OB_FAIL(ob_write_string(tmp_alloc, tmp, multipol_data))) {
|
||||
LOG_WARN("failed to copy multi_poly geo", K(ret));
|
||||
} else {
|
||||
ObWkbGeomMultiPolygon *multipoly_copy = reinterpret_cast<ObWkbGeomMultiPolygon*>(multipol_data.ptr());
|
||||
@ -655,10 +657,11 @@ OB_GEO_GEOG_BINARY_FUNC_BEGIN(ObGeoFuncCoveredByImpl, ObWkbGeogPoint, ObWkbGeogC
|
||||
}
|
||||
|
||||
case ObGeoType::POLYGON : {
|
||||
ObArenaAllocator tmp_alloc;
|
||||
const ObWkbGeogPolygon *polygon = reinterpret_cast<const ObWkbGeogPolygon*>(sub_ptr);
|
||||
ObString tmp(polygon->length(), reinterpret_cast<const char*>(sub_ptr));
|
||||
ObString pol_data;
|
||||
if (OB_FAIL(ob_write_string(*context.get_allocator(), tmp, pol_data))) {
|
||||
if (OB_FAIL(ob_write_string(tmp_alloc, tmp, pol_data))) {
|
||||
LOG_WARN("failed to copy polygon geo", K(ret));
|
||||
} else {
|
||||
ObWkbGeogPolygon *poly_copy = reinterpret_cast<ObWkbGeogPolygon*>(pol_data.ptr());
|
||||
@ -674,10 +677,11 @@ OB_GEO_GEOG_BINARY_FUNC_BEGIN(ObGeoFuncCoveredByImpl, ObWkbGeogPoint, ObWkbGeogC
|
||||
break;
|
||||
}
|
||||
case ObGeoType::MULTIPOLYGON : {
|
||||
ObArenaAllocator tmp_alloc;
|
||||
const ObWkbGeogMultiPolygon *multi_poly = reinterpret_cast<const ObWkbGeogMultiPolygon*>(sub_ptr);
|
||||
ObString tmp(multi_poly->length(), reinterpret_cast<const char*>(sub_ptr));
|
||||
ObString multipol_data;
|
||||
if (OB_FAIL(ob_write_string(*context.get_allocator(), tmp, multipol_data))) {
|
||||
if (OB_FAIL(ob_write_string(tmp_alloc, tmp, multipol_data))) {
|
||||
LOG_WARN("failed to copy multi_poly geo", K(ret));
|
||||
} else {
|
||||
ObWkbGeogMultiPolygon *multipoly_copy = reinterpret_cast<ObWkbGeogMultiPolygon*>(multipol_data.ptr());
|
||||
@ -1273,7 +1277,7 @@ OB_GEO_GEOG_BINARY_FUNC_BEGIN(ObGeoFuncCoveredByImpl, ObWkbGeogCollection, ObWkb
|
||||
OB_GEO_CART_TREE_FUNC_BEGIN(ObGeoFuncCoveredByImpl, ObCartesianLineString, ObCartesianPolygon, bool)
|
||||
{
|
||||
UNUSED(context);
|
||||
const ObCartesianPoint *geo1 = reinterpret_cast<const ObCartesianPoint *>(g1);
|
||||
const ObCartesianLineString *geo1 = reinterpret_cast<const ObCartesianLineString *>(g1);
|
||||
const ObCartesianPolygon *geo2 = reinterpret_cast<const ObCartesianPolygon *>(g2);
|
||||
result = boost::geometry::covered_by(*geo1, *geo2);
|
||||
return OB_SUCCESS;
|
||||
|
@ -194,7 +194,7 @@ private:
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObGeometry *last_res = res;
|
||||
ObGeoEvalCtx diff_ctx(context.get_allocator(), context.get_srs());
|
||||
ObGeoEvalCtx diff_ctx(context.get_mem_ctx(), context.get_srs());
|
||||
if (OB_FAIL(diff_ctx.append_geo_arg(g1)) || OB_FAIL(diff_ctx.append_geo_arg(g2))) {
|
||||
LOG_WARN("failed to append geo to ctx", K(ret));
|
||||
} else if (OB_FAIL(ObGeoFunc<ObGeoFuncType::Difference>::geo_func::eval(diff_ctx, res))) {
|
||||
@ -357,7 +357,7 @@ private:
|
||||
LOG_WARN("unexpected null geometry collection split", K(ret));
|
||||
} else if (!mpy1->empty()) {
|
||||
result.is_null = true;
|
||||
} else if (OB_FAIL(ObGeoFuncUtils::ob_geo_gc_union(*allocator, *srs, mpt1, mls1, mpy1))) {
|
||||
} else if (OB_FAIL(ObGeoFuncUtils::ob_geo_gc_union(context.get_mem_ctx(), *srs, mpt1, mls1, mpy1))) {
|
||||
LOG_WARN("failed to do gc union", K(ret));
|
||||
} else if (OB_ISNULL(mpt1) || OB_ISNULL(mls1) || OB_ISNULL(mpy1)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
@ -381,7 +381,7 @@ private:
|
||||
} else if (OB_ISNULL(mpt2) || OB_ISNULL(mls2) || OB_ISNULL(mpy2)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("unexpected null geometry collection split", K(ret));
|
||||
} else if (OB_FAIL(ObGeoFuncUtils::ob_geo_gc_union(*allocator, *srs, mpt2, mls2, mpy2))) {
|
||||
} else if (OB_FAIL(ObGeoFuncUtils::ob_geo_gc_union(context.get_mem_ctx(), *srs, mpt2, mls2, mpy2))) {
|
||||
LOG_WARN("failed to do gc union", K(ret));
|
||||
} else if (OB_ISNULL(mpt2) || OB_ISNULL(mls2) || OB_ISNULL(mpy2)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
@ -407,7 +407,7 @@ private:
|
||||
static int make_collection(const ObGeometry *g, ObIAllocator *allocator, const ObGeometry *&geo)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
GcBinType *gc_bin = OB_NEWx(GcBinType, allocator);
|
||||
GcBinType *gc_bin = OB_NEWx(GcBinType, allocator, g->get_srid());
|
||||
ObWkbBuffer buffer(*allocator);
|
||||
if (OB_ISNULL(gc_bin)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
|
@ -178,7 +178,7 @@ private:
|
||||
{
|
||||
INIT_SUCC(ret);
|
||||
|
||||
CollType *res = OB_NEWx(CollType, context.get_allocator());
|
||||
CollType *res = OB_NEWx(CollType, context.get_allocator(), g1->get_srid(), *context.get_allocator());
|
||||
MptType *mpt = NULL;
|
||||
MlsType *mls = NULL;
|
||||
MpyType *mpy = NULL;
|
||||
@ -198,7 +198,7 @@ private:
|
||||
} else if (OB_ISNULL(mpt) || OB_ISNULL(mls) || OB_ISNULL(mpy)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("unexpected null geometry collection split", K(ret), KP(mpt), KP(mls), KP(mpy));
|
||||
} else if (OB_FAIL(ObGeoFuncUtils::ob_geo_gc_union(*context.get_allocator(), *context.get_srs(), mpt, mls, mpy))) {
|
||||
} else if (OB_FAIL(ObGeoFuncUtils::ob_geo_gc_union(context.get_mem_ctx(), *context.get_srs(), mpt, mls, mpy))) {
|
||||
LOG_WARN("failed to do geometry collection union", K(ret));
|
||||
} else if (OB_ISNULL(mpt) || OB_ISNULL(mls) || OB_ISNULL(mpy)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
@ -254,7 +254,8 @@ private:
|
||||
MptType *mpt_res_tree = reinterpret_cast<MptType *>(mpt_res);
|
||||
typename MptType::iterator iter = mpt_res_tree->begin();
|
||||
for (; OB_SUCC(ret) && iter != mpt_res_tree->end(); iter++) {
|
||||
typename CollType::sub_pt_type *pt = OB_NEWx(typename CollType::sub_pt_type, context.get_allocator());
|
||||
typename CollType::sub_pt_type *pt = OB_NEWx(
|
||||
typename CollType::sub_pt_type, context.get_allocator(), mpt_res_tree->get_srid());
|
||||
if (OB_ISNULL(pt)) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
LOG_WARN("fail to alloc memotry for point", K(ret));
|
||||
@ -379,8 +380,7 @@ private:
|
||||
allocator,
|
||||
pt.template get<0>(),
|
||||
pt.template get<1>(),
|
||||
g1->get_srid(),
|
||||
allocator);
|
||||
g1->get_srid());
|
||||
if (OB_ISNULL(pt_tree)) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
LOG_WARN("fail to allocate memory", K(ret));
|
||||
@ -479,7 +479,7 @@ private:
|
||||
LOG_WARN("fail to do eval", K(ret));
|
||||
} else if (FALSE_IT(iter++)) {
|
||||
} else if (iter != geo2->end()) {
|
||||
if (OB_FAIL((ObGeoFuncUtils::simplify_multi_geo<GcTreeType>(result, *allocator)))) {
|
||||
if (OB_FAIL((ObGeoTypeUtil::simplify_multi_geo<GcTreeType>(result, *allocator)))) {
|
||||
// should not do simplify in difference functor, it may affect
|
||||
// ObGeoFuncUtils::ob_geo_gc_union
|
||||
LOG_WARN("fail to simplify result", K(ret));
|
||||
|
@ -49,15 +49,16 @@ static int eval_dissolve_polygon(
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
LOG_WARN("fail to create go by type", K(ret), K(res));
|
||||
} else if (is_self_intersects) {
|
||||
ObArenaAllocator tmp_alloc;
|
||||
MPY *left_part =
|
||||
OB_NEWx(MPY, context.get_allocator(), g1->get_srid(), *context.get_allocator());
|
||||
OB_NEWx(MPY, &tmp_alloc, g1->get_srid(), tmp_alloc);
|
||||
MPY *right_part =
|
||||
OB_NEWx(MPY, context.get_allocator(), g1->get_srid(), *context.get_allocator());
|
||||
if (OB_ISNULL(res) || OB_ISNULL(left_part) || OB_ISNULL(right_part)) {
|
||||
OB_NEWx(MPY, &tmp_alloc, g1->get_srid(), tmp_alloc);
|
||||
if (OB_ISNULL(left_part) || OB_ISNULL(right_part)) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
LOG_WARN("fail to create go by type", K(ret), K(res), K(left_part), K(right_part));
|
||||
} else {
|
||||
GeometryType *g1_rev = OB_NEWx(GeometryType, context.get_allocator(), *geo1);
|
||||
GeometryType *g1_rev = OB_NEWx(GeometryType, &tmp_alloc, *geo1);
|
||||
if (OB_ISNULL(g1_rev)) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
LOG_WARN("fail to create go by type", K(ret));
|
||||
@ -67,13 +68,24 @@ static int eval_dissolve_polygon(
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ObArenaAllocator tmp_alloc;
|
||||
bg::intersection(*geo1, *geo1, *res);
|
||||
if (res->is_empty() && !geo1->is_empty()) {
|
||||
bg::reverse(*geo1);
|
||||
bg::intersection(*geo1, *geo1, *res);
|
||||
GeometryType *g1_rev = OB_NEWx(GeometryType, &tmp_alloc, *geo1);
|
||||
if (OB_ISNULL(g1_rev)) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
LOG_WARN("fail to create go by type", K(ret));
|
||||
} else {
|
||||
bg::reverse(*g1_rev);
|
||||
bg::intersection(*g1_rev, *g1_rev, *res);
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
bg::correct(*res);
|
||||
}
|
||||
}
|
||||
if (res->size() == 1) {
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (res->size() == 1) {
|
||||
result = &res->front();
|
||||
} else {
|
||||
result = res;
|
||||
@ -108,11 +120,12 @@ static int eval_dissolve_multipolygon(
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
LOG_WARN("fail to create go by type", K(ret), K(res));
|
||||
} else if (is_self_intersects) {
|
||||
MPY *left_part =
|
||||
OB_NEWx(MPY, context.get_allocator(), g1->get_srid(), *context.get_allocator());
|
||||
ObArenaAllocator tmp_alloc;
|
||||
MPY *left_part =
|
||||
OB_NEWx(MPY, &tmp_alloc, g1->get_srid(), tmp_alloc);
|
||||
MPY *right_part =
|
||||
OB_NEWx(MPY, context.get_allocator(), g1->get_srid(), *context.get_allocator());
|
||||
if (OB_ISNULL(res) || OB_ISNULL(left_part) || OB_ISNULL(right_part)) {
|
||||
OB_NEWx(MPY, &tmp_alloc, g1->get_srid(), tmp_alloc);
|
||||
if (OB_ISNULL(left_part) || OB_ISNULL(right_part)) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
LOG_WARN("fail to create go by type", K(ret), K(res), K(left_part), K(right_part));
|
||||
} else {
|
||||
@ -127,6 +140,7 @@ static int eval_dissolve_multipolygon(
|
||||
bg::reverse(*geo1);
|
||||
bg::intersection(*geo1, *geo1, *res);
|
||||
}
|
||||
bg::correct(*res);
|
||||
}
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (res->size() == 1) {
|
||||
|
@ -30,7 +30,7 @@ int eval_intersects_by_disjoint(const ObGeometry *g1, const ObGeometry *g2, cons
|
||||
INIT_SUCC(ret);
|
||||
result = false;
|
||||
// Notice:should not use geoemtry from context, they are the original inputs, maybe changed
|
||||
ObGeoEvalCtx disjoint_context(context.get_allocator(), context.get_srs());
|
||||
ObGeoEvalCtx disjoint_context(context.get_mem_ctx(), context.get_srs());
|
||||
disjoint_context.append_geo_arg(g1);
|
||||
disjoint_context.append_geo_arg(g2);
|
||||
if (OB_SUCC(ObGeoFuncDisjoint::eval(disjoint_context, result))) {
|
||||
|
149
deps/oblib/src/lib/geo/ob_geo_func_symdifference.cpp
vendored
149
deps/oblib/src/lib/geo/ob_geo_func_symdifference.cpp
vendored
@ -63,9 +63,9 @@ static int apply_bg_symdifference_pt_pt(
|
||||
if (OB_FAIL(get_specific_geos(g1, g2, context, geo1, geo2, res))) {
|
||||
LOG_WARN("fail to get specific geometry", K(ret));
|
||||
} else {
|
||||
ObIAllocator *allocator = context.get_allocator();
|
||||
GeometryRes *union_res = OB_NEWx(GeometryRes, allocator, g1->get_srid(), *allocator);
|
||||
GeometryRes *intersection_res = OB_NEWx(GeometryRes, allocator, g1->get_srid(), *allocator);
|
||||
ObArenaAllocator tmp_alloc;
|
||||
GeometryRes *union_res = OB_NEWx(GeometryRes, &tmp_alloc, g1->get_srid(), tmp_alloc);
|
||||
GeometryRes *intersection_res = OB_NEWx(GeometryRes, &tmp_alloc, g1->get_srid(), tmp_alloc);
|
||||
if (OB_ISNULL(union_res) || OB_ISNULL(intersection_res)) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
LOG_WARN("failed to create geometry", K(ret), K(union_res), K(intersection_res));
|
||||
@ -102,8 +102,7 @@ static int push_disjoint_point(PtBinType &geo1, GeoType &geo2, const ObGeoEvalCt
|
||||
allocator,
|
||||
geo1.template get<0>(),
|
||||
geo1.template get<1>(),
|
||||
0,
|
||||
allocator);
|
||||
res.get_srid());
|
||||
if (OB_ISNULL(pt)) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
LOG_WARN("fail to allocate memory for geometry", K(ret));
|
||||
@ -288,7 +287,7 @@ static int simplify_and_push_geometry(
|
||||
ObIAllocator &allocator, ObGeometry *push_geo, GcTreeType &geo_coll)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (OB_FAIL((ObGeoFuncUtils::simplify_multi_geo<GcTreeType>(push_geo, allocator)))) {
|
||||
if (OB_FAIL((ObGeoTypeUtil::simplify_multi_geo<GcTreeType>(push_geo, allocator)))) {
|
||||
LOG_WARN("fail to simplify result", K(ret));
|
||||
} else if (OB_FAIL(geo_coll.push_back(*push_geo))) {
|
||||
LOG_WARN("fail to push back geometry", K(ret));
|
||||
@ -321,8 +320,9 @@ static int apply_bg_symdifference_pt_coll(const ObGeometry *g1, const ObGeometry
|
||||
LOG_WARN("fail to do symdifference between pointlike and pointlike type", K(ret));
|
||||
} else {
|
||||
uint32_t srid = g1->get_srid();
|
||||
ObArenaAllocator tmp_alloc;
|
||||
typename GcTreeType::sub_mpt_type *mls_res =
|
||||
OB_NEWx(typename GcTreeType::sub_mpt_type, allocator, srid, *allocator);
|
||||
OB_NEWx(typename GcTreeType::sub_mpt_type, &tmp_alloc, srid, tmp_alloc);
|
||||
typename GcTreeType::sub_mpt_type *mpy_res =
|
||||
OB_NEWx(typename GcTreeType::sub_mpt_type, allocator, srid, *allocator);
|
||||
GcTreeType *res = OB_NEWx(GcTreeType, allocator, srid, *allocator);
|
||||
@ -391,9 +391,10 @@ static int apply_bg_symdifference_line_coll(const ObGeometry *g1, const ObGeomet
|
||||
LOG_WARN("fail to convert geometry to tree", K(ret));
|
||||
} else if (FALSE_IT(g1_tree = tree_visitor.get_geometry())) {
|
||||
} else {
|
||||
ObArenaAllocator tmp_alloc;
|
||||
uint32_t srid = g1->get_srid();
|
||||
typename GcTreeType::sub_ml_type *mls_res =
|
||||
OB_NEWx(typename GcTreeType::sub_ml_type, allocator, srid, *allocator);
|
||||
OB_NEWx(typename GcTreeType::sub_ml_type, &tmp_alloc, srid, tmp_alloc);
|
||||
GcTreeType *res = OB_NEWx(GcTreeType, allocator, srid, *allocator);
|
||||
typename GcTreeType::sub_ml_type *mls_diff_res =
|
||||
OB_NEWx(typename GcTreeType::sub_ml_type, allocator, srid, *allocator);
|
||||
@ -447,7 +448,7 @@ static int apply_bg_symdifference_line_coll(const ObGeometry *g1, const ObGeomet
|
||||
return ret;
|
||||
}
|
||||
|
||||
template<typename PolyTreeType, typename GcTreeType>
|
||||
template<typename PolyTreeType, typename GcTreeType, typename GeomType>
|
||||
static int apply_bg_symdifference_poly_coll(const ObGeometry *g1, const ObGeometry *g2,
|
||||
const ObGeoEvalCtx &context, ObBGStrategyType strategy, ObGeometry *&result)
|
||||
{
|
||||
@ -460,64 +461,58 @@ static int apply_bg_symdifference_poly_coll(const ObGeometry *g1, const ObGeomet
|
||||
LOG_WARN("fail to apply symdifference collection common", K(ret));
|
||||
} else if (OB_ISNULL(result)) {
|
||||
ObIAllocator *allocator = context.get_allocator();
|
||||
ObGeometry *g1_tree = nullptr;
|
||||
ObGeoToTreeVisitor tree_visitor(allocator);
|
||||
if (OB_FAIL(const_cast<ObGeometry *>(g1)->do_visit(tree_visitor))) {
|
||||
LOG_WARN("fail to convert geometry to tree", K(ret));
|
||||
} else if (FALSE_IT(g1_tree = tree_visitor.get_geometry())) {
|
||||
const GeomType *g1_bin = reinterpret_cast<const GeomType *>(g1->val());
|
||||
uint32_t srid = g1->get_srid();
|
||||
typename GcTreeType::sub_ml_type *mls_res =
|
||||
OB_NEWx(typename GcTreeType::sub_ml_type, allocator, srid, *allocator);
|
||||
GcTreeType *res = OB_NEWx(GcTreeType, allocator, srid, *allocator);
|
||||
typename GcTreeType::sub_mp_type *mpy_res =
|
||||
OB_NEWx(typename GcTreeType::sub_mp_type, allocator, srid, *allocator);
|
||||
typename GcTreeType::sub_mpt_type *mpt_res =
|
||||
OB_NEWx(typename GcTreeType::sub_mpt_type, allocator, srid, *allocator);
|
||||
if (OB_ISNULL(mpt_res) || OB_ISNULL(mls_res) || OB_ISNULL(res) || OB_ISNULL(mpy_res)) {
|
||||
ret = OB_ERR_GIS_INVALID_DATA;
|
||||
LOG_WARN("wrong geometry type or create geometry failed",
|
||||
K(ret),
|
||||
K(mpt_res),
|
||||
K(mls_res),
|
||||
K(res),
|
||||
K(mpy_res));
|
||||
} else if (strategy == ObBGStrategyType::DEFAULT_NONE) {
|
||||
bg::sym_difference(*g1_bin, *mpy, *mpy_res);
|
||||
bg::difference(*mls, *g1_bin, *mls_res);
|
||||
bg::difference(*mpt, *g1_bin, *mpt_res);
|
||||
} else if (OB_ISNULL(context.get_srs())) {
|
||||
ret = OB_ERR_NULL_VALUE;
|
||||
LOG_WARN("invalid null srs", K(ret));
|
||||
} else {
|
||||
uint32_t srid = g1->get_srid();
|
||||
typename GcTreeType::sub_ml_type *mls_res =
|
||||
OB_NEWx(typename GcTreeType::sub_ml_type, allocator, srid, *allocator);
|
||||
GcTreeType *res = OB_NEWx(GcTreeType, allocator, srid, *allocator);
|
||||
typename GcTreeType::sub_mp_type *mpy_res =
|
||||
OB_NEWx(typename GcTreeType::sub_mp_type, allocator, srid, *allocator);
|
||||
typename GcTreeType::sub_mpt_type *mpt_res =
|
||||
OB_NEWx(typename GcTreeType::sub_mpt_type, allocator, srid, *allocator);
|
||||
if (OB_ISNULL(mpt_res) || OB_ISNULL(mls_res) || OB_ISNULL(res) || OB_ISNULL(mpy_res)) {
|
||||
ret = OB_ERR_GIS_INVALID_DATA;
|
||||
LOG_WARN("wrong geometry type or create geometry failed",
|
||||
K(ret),
|
||||
K(mpt_res),
|
||||
K(mls_res),
|
||||
K(res),
|
||||
K(mpy_res));
|
||||
} else if (strategy == ObBGStrategyType::DEFAULT_NONE) {
|
||||
bg::sym_difference(*reinterpret_cast<PolyTreeType *>(g1_tree), *mpy, *mpy_res);
|
||||
bg::difference(*mls, *reinterpret_cast<PolyTreeType *>(g1_tree), *mls_res);
|
||||
bg::difference(*mpt, *reinterpret_cast<PolyTreeType *>(g1_tree), *mpt_res);
|
||||
} else if (OB_ISNULL(context.get_srs())) {
|
||||
ret = OB_ERR_NULL_VALUE;
|
||||
LOG_WARN("invalid null srs", K(ret));
|
||||
} else {
|
||||
const ObSrsItem *srs = context.get_srs();
|
||||
boost::geometry::srs::spheroid<double> geog_sphere(
|
||||
srs->semi_major_axis(), srs->semi_minor_axis());
|
||||
ObLlLaAaStrategy line_strategy(geog_sphere);
|
||||
ObPlPaStrategy point_strategy(geog_sphere);
|
||||
bg::sym_difference(
|
||||
*reinterpret_cast<PolyTreeType *>(g1_tree), *mpy, *mpy_res, line_strategy);
|
||||
bg::difference(*mls, *reinterpret_cast<PolyTreeType *>(g1_tree), *mls_res, line_strategy);
|
||||
bg::difference(*mpt, *reinterpret_cast<PolyTreeType *>(g1_tree), *mpt_res, point_strategy);
|
||||
}
|
||||
if (OB_SUCC(ret) && !mpy_res->is_empty()
|
||||
&& OB_FAIL(simplify_and_push_geometry(
|
||||
*allocator, reinterpret_cast<ObGeometry *>(mpy_res), *res))) {
|
||||
LOG_WARN("fail to push back geometry", K(ret));
|
||||
}
|
||||
if (OB_SUCC(ret) && !mls_res->is_empty()
|
||||
&& OB_FAIL(simplify_and_push_geometry(
|
||||
*allocator, reinterpret_cast<ObGeometry *>(mls_res), *res))) {
|
||||
LOG_WARN("fail to push back geometry", K(ret));
|
||||
}
|
||||
if (OB_SUCC(ret) && !mpt_res->is_empty()
|
||||
&& OB_FAIL(simplify_and_push_geometry(
|
||||
*allocator, reinterpret_cast<ObGeometry *>(mpt_res), *res))) {
|
||||
LOG_WARN("fail to push back geometry", K(ret));
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
result = res;
|
||||
}
|
||||
const ObSrsItem *srs = context.get_srs();
|
||||
boost::geometry::srs::spheroid<double> geog_sphere(
|
||||
srs->semi_major_axis(), srs->semi_minor_axis());
|
||||
ObLlLaAaStrategy line_strategy(geog_sphere);
|
||||
ObPlPaStrategy point_strategy(geog_sphere);
|
||||
bg::sym_difference(
|
||||
*g1_bin, *mpy, *mpy_res, line_strategy);
|
||||
bg::difference(*mls, *g1_bin, *mls_res, line_strategy);
|
||||
bg::difference(*mpt, *g1_bin, *mpt_res, point_strategy);
|
||||
}
|
||||
if (OB_SUCC(ret) && !mpy_res->is_empty()
|
||||
&& OB_FAIL(simplify_and_push_geometry(
|
||||
*allocator, reinterpret_cast<ObGeometry *>(mpy_res), *res))) {
|
||||
LOG_WARN("fail to push back geometry", K(ret));
|
||||
}
|
||||
if (OB_SUCC(ret) && !mls_res->is_empty()
|
||||
&& OB_FAIL(simplify_and_push_geometry(
|
||||
*allocator, reinterpret_cast<ObGeometry *>(mls_res), *res))) {
|
||||
LOG_WARN("fail to push back geometry", K(ret));
|
||||
}
|
||||
if (OB_SUCC(ret) && !mpt_res->is_empty()
|
||||
&& OB_FAIL(simplify_and_push_geometry(
|
||||
*allocator, reinterpret_cast<ObGeometry *>(mpt_res), *res))) {
|
||||
LOG_WARN("fail to push back geometry", K(ret));
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
result = res;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
@ -613,19 +608,19 @@ private:
|
||||
LOG_WARN("fail to convert geometry tree to bin", K(ret));
|
||||
} else if (OB_FAIL(eval_wkb_binary(mpy_bin, g2, context, mpy_res))) {
|
||||
LOG_WARN("fail to eval wkb binary", K(ret));
|
||||
} else if (OB_FAIL(!mpy_res->is_empty() && (ObGeoFuncUtils::simplify_multi_geo<GcTreeType>(mpy_res, *allocator)))) {
|
||||
} else if (OB_FAIL(!mpy_res->is_empty() && (ObGeoTypeUtil::simplify_multi_geo<GcTreeType>(mpy_res, *allocator)))) {
|
||||
LOG_WARN("fail to simplify result", K(ret));
|
||||
} else if (OB_FAIL(ObGeoTypeUtil::tree_to_bin(*allocator, mpy_res, mpy_res_bin, srs))) {
|
||||
LOG_WARN("fail to convert geometry tree to bin", K(ret));
|
||||
} else if (OB_FAIL(eval_wkb_binary(mls_bin, mpy_res_bin, context, mls_res))) {
|
||||
LOG_WARN("fail to eval wkb binary", K(ret));
|
||||
} else if (OB_FAIL(!mls_res->is_empty() && (ObGeoFuncUtils::simplify_multi_geo<GcTreeType>(mls_res, *allocator)))) {
|
||||
} else if (OB_FAIL(!mls_res->is_empty() && (ObGeoTypeUtil::simplify_multi_geo<GcTreeType>(mls_res, *allocator)))) {
|
||||
LOG_WARN("fail to simplify result", K(ret));
|
||||
} else if (OB_FAIL(ObGeoTypeUtil::tree_to_bin(*allocator, mls_res, mls_res_bin, srs))) {
|
||||
LOG_WARN("fail to convert geometry tree to bin", K(ret));
|
||||
} else if (OB_FAIL(eval_wkb_binary(mpt_bin, mls_res_bin, context, result))) {
|
||||
LOG_WARN("fail to eval wkb binary", K(ret));
|
||||
} else if (OB_FAIL(!result->is_empty() && (ObGeoFuncUtils::simplify_multi_geo<GcTreeType>(result, *allocator)))) {
|
||||
} else if (OB_FAIL(!result->is_empty() && (ObGeoTypeUtil::simplify_multi_geo<GcTreeType>(result, *allocator)))) {
|
||||
LOG_WARN("fail to simplify result", K(ret));
|
||||
}
|
||||
}
|
||||
@ -813,7 +808,7 @@ OB_GEO_FUNC_END;
|
||||
OB_GEO_CART_BINARY_FUNC_BEGIN(
|
||||
ObGeoFuncSymDifferenceImpl, ObWkbGeomPolygon, ObWkbGeomCollection, ObGeometry *)
|
||||
{
|
||||
return apply_bg_symdifference_poly_coll<ObCartesianPolygon, ObCartesianGeometrycollection>(
|
||||
return apply_bg_symdifference_poly_coll<ObCartesianPolygon, ObCartesianGeometrycollection, ObWkbGeomPolygon>(
|
||||
g1, g2, context, ObBGStrategyType::DEFAULT_NONE, result);
|
||||
}
|
||||
OB_GEO_FUNC_END;
|
||||
@ -1000,7 +995,7 @@ OB_GEO_FUNC_END;
|
||||
OB_GEO_CART_BINARY_FUNC_BEGIN(
|
||||
ObGeoFuncSymDifferenceImpl, ObWkbGeomMultiPolygon, ObWkbGeomCollection, ObGeometry *)
|
||||
{
|
||||
return apply_bg_symdifference_poly_coll<ObCartesianMultipolygon, ObCartesianGeometrycollection>(
|
||||
return apply_bg_symdifference_poly_coll<ObCartesianMultipolygon, ObCartesianGeometrycollection, ObWkbGeomMultiPolygon>(
|
||||
g1, g2, context, ObBGStrategyType::DEFAULT_NONE, result);
|
||||
}
|
||||
OB_GEO_FUNC_END;
|
||||
@ -1025,7 +1020,7 @@ OB_GEO_FUNC_END;
|
||||
OB_GEO_CART_BINARY_FUNC_BEGIN(
|
||||
ObGeoFuncSymDifferenceImpl, ObWkbGeomCollection, ObWkbGeomPolygon, ObGeometry *)
|
||||
{
|
||||
return apply_bg_symdifference_poly_coll<ObCartesianPolygon, ObCartesianGeometrycollection>(
|
||||
return apply_bg_symdifference_poly_coll<ObCartesianPolygon, ObCartesianGeometrycollection, ObWkbGeomPolygon>(
|
||||
g2, g1, context, ObBGStrategyType::DEFAULT_NONE, result);
|
||||
}
|
||||
OB_GEO_FUNC_END;
|
||||
@ -1049,7 +1044,7 @@ OB_GEO_FUNC_END;
|
||||
OB_GEO_CART_BINARY_FUNC_BEGIN(
|
||||
ObGeoFuncSymDifferenceImpl, ObWkbGeomCollection, ObWkbGeomMultiPolygon, ObGeometry *)
|
||||
{
|
||||
return apply_bg_symdifference_poly_coll<ObCartesianMultipolygon, ObCartesianGeometrycollection>(
|
||||
return apply_bg_symdifference_poly_coll<ObCartesianMultipolygon, ObCartesianGeometrycollection, ObWkbGeomMultiPolygon>(
|
||||
g2, g1, context, ObBGStrategyType::DEFAULT_NONE, result);
|
||||
}
|
||||
OB_GEO_FUNC_END;
|
||||
@ -1246,7 +1241,7 @@ OB_GEO_FUNC_END;
|
||||
OB_GEO_GEOG_BINARY_FUNC_BEGIN(
|
||||
ObGeoFuncSymDifferenceImpl, ObWkbGeogPolygon, ObWkbGeogCollection, ObGeometry *)
|
||||
{
|
||||
return apply_bg_symdifference_poly_coll<ObGeographPolygon, ObGeographGeometrycollection>(
|
||||
return apply_bg_symdifference_poly_coll<ObGeographPolygon, ObGeographGeometrycollection, ObWkbGeogPolygon>(
|
||||
g1, g2, context, ObBGStrategyType::LL_LA_AA_STRATEGY, result);
|
||||
}
|
||||
OB_GEO_FUNC_END;
|
||||
@ -1438,7 +1433,7 @@ OB_GEO_FUNC_END;
|
||||
OB_GEO_GEOG_BINARY_FUNC_BEGIN(
|
||||
ObGeoFuncSymDifferenceImpl, ObWkbGeogMultiPolygon, ObWkbGeogCollection, ObGeometry *)
|
||||
{
|
||||
return apply_bg_symdifference_poly_coll<ObGeographMultipolygon, ObGeographGeometrycollection>(
|
||||
return apply_bg_symdifference_poly_coll<ObGeographMultipolygon, ObGeographGeometrycollection, ObWkbGeogMultiPolygon>(
|
||||
g1, g2, context, ObBGStrategyType::LL_LA_AA_STRATEGY, result);
|
||||
}
|
||||
OB_GEO_FUNC_END;
|
||||
@ -1463,7 +1458,7 @@ OB_GEO_FUNC_END;
|
||||
OB_GEO_GEOG_BINARY_FUNC_BEGIN(
|
||||
ObGeoFuncSymDifferenceImpl, ObWkbGeogCollection, ObWkbGeogPolygon, ObGeometry *)
|
||||
{
|
||||
return apply_bg_symdifference_poly_coll<ObGeographPolygon, ObGeographGeometrycollection>(
|
||||
return apply_bg_symdifference_poly_coll<ObGeographPolygon, ObGeographGeometrycollection, ObWkbGeogPolygon>(
|
||||
g2, g1, context, ObBGStrategyType::LL_LA_AA_STRATEGY, result);
|
||||
}
|
||||
OB_GEO_FUNC_END;
|
||||
@ -1488,7 +1483,7 @@ OB_GEO_FUNC_END;
|
||||
OB_GEO_GEOG_BINARY_FUNC_BEGIN(
|
||||
ObGeoFuncSymDifferenceImpl, ObWkbGeogCollection, ObWkbGeogMultiPolygon, ObGeometry *)
|
||||
{
|
||||
return apply_bg_symdifference_poly_coll<ObGeographMultipolygon, ObGeographGeometrycollection>(
|
||||
return apply_bg_symdifference_poly_coll<ObGeographMultipolygon, ObGeographGeometrycollection, ObWkbGeogMultiPolygon>(
|
||||
g2, g1, context, ObBGStrategyType::LL_LA_AA_STRATEGY, result);
|
||||
}
|
||||
OB_GEO_FUNC_END;
|
||||
|
@ -605,7 +605,7 @@ private:
|
||||
*context.get_allocator(), mpt1, mpt_bin, context.get_srs()))) {
|
||||
LOG_WARN("failed to convert geo tree to binary", K(ret));
|
||||
} else {
|
||||
ObGeoEvalCtx intersects_context(context.get_allocator(), context.get_srs());
|
||||
ObGeoEvalCtx intersects_context(context.get_mem_ctx(), context.get_srs());
|
||||
intersects_context.append_geo_arg(mpt_bin);
|
||||
intersects_context.append_geo_arg(g2);
|
||||
if (OB_FAIL(ObGeoFuncIntersects::eval(intersects_context, point_intersects))) {
|
||||
@ -617,7 +617,7 @@ private:
|
||||
}
|
||||
|
||||
if (point_intersects || OB_FAIL(ret)) {
|
||||
} else if (OB_FAIL(ObGeoFuncUtils::ob_geo_gc_union(*allocator, *context.get_srs(), mpt1, mls1, mpy1))) {
|
||||
} else if (OB_FAIL(ObGeoFuncUtils::ob_geo_gc_union(context.get_mem_ctx(), *context.get_srs(), mpt1, mls1, mpy1))) {
|
||||
LOG_WARN("fail to do gc union", K(ret));
|
||||
} else {
|
||||
// Check that at least one part of g1 touches at least one part of g2.
|
||||
@ -676,7 +676,7 @@ private:
|
||||
*context.get_allocator(), mpt1, mpt_bin, context.get_srs()))) {
|
||||
LOG_WARN("failed to convert geo tree to binary", K(ret));
|
||||
} else {
|
||||
ObGeoEvalCtx intersects_context(context.get_allocator(), context.get_srs());
|
||||
ObGeoEvalCtx intersects_context(context.get_mem_ctx(), context.get_srs());
|
||||
intersects_context.append_geo_arg(mpt_bin);
|
||||
intersects_context.append_geo_arg(g2);
|
||||
if (OB_FAIL(ObGeoFuncIntersects::eval(intersects_context, point_intersects))) {
|
||||
@ -688,7 +688,7 @@ private:
|
||||
}
|
||||
|
||||
if (point_intersects || OB_FAIL(ret)) {
|
||||
} else if (OB_FAIL(ObGeoFuncUtils::ob_geo_gc_union(*allocator, *context.get_srs(), mpt1, mls1, mpy1))) {
|
||||
} else if (OB_FAIL(ObGeoFuncUtils::ob_geo_gc_union(context.get_mem_ctx(), *context.get_srs(), mpt1, mls1, mpy1))) {
|
||||
LOG_WARN("fail to do gc union", K(ret));
|
||||
} else {
|
||||
// Check that at least one part of g1 touches at least one part of g2.
|
||||
|
@ -51,7 +51,7 @@ private:
|
||||
lib::ObMallocHookAttrGuard malloc_guard(last_mem_attr);
|
||||
const PtInType *src_geo = reinterpret_cast<const PtInType *>(g->val());
|
||||
PtResType *dest_geo = NULL;
|
||||
if (OB_ISNULL(dest_geo = OB_NEWx(PtResType, (context.get_allocator())))) {
|
||||
if (OB_ISNULL(dest_geo = OB_NEWx(PtResType, (context.get_allocator()), g->get_srid(), context.get_allocator()))) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
LOG_WARN("failed to allocate memory", K(ret));
|
||||
} else {
|
||||
@ -77,7 +77,7 @@ private:
|
||||
if (OB_ISNULL(alloc)) {
|
||||
ret = OB_ERR_NULL_VALUE;
|
||||
LOG_WARN("unexpected null allocator for transform functor", K(ret));
|
||||
} else if (OB_ISNULL(dest_geo = OB_NEWx(GeometryResType, alloc))) {
|
||||
} else if (OB_ISNULL(dest_geo = OB_NEWx(GeometryResType, alloc, g->get_srid(), *alloc))) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
LOG_WARN("fail to create geo by type", K(ret));
|
||||
} else {
|
||||
|
9
deps/oblib/src/lib/geo/ob_geo_func_union.cpp
vendored
9
deps/oblib/src/lib/geo/ob_geo_func_union.cpp
vendored
@ -245,7 +245,7 @@ static int push_back_innerpoint(const ObWkbGeomInnerPoint &innerpoint, const ObG
|
||||
ObCartesianGeometrycollection &res)
|
||||
{
|
||||
INIT_SUCC(ret);
|
||||
ObCartesianPoint *point = OB_NEWx(ObCartesianPoint, context.get_allocator());
|
||||
ObCartesianPoint *point = OB_NEWx(ObCartesianPoint, context.get_allocator(), res.get_srid());
|
||||
if (OB_ISNULL(point)) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
LOG_WARN("fail to create cartesian point", K(ret));
|
||||
@ -263,7 +263,7 @@ static int push_back_innerpoint(const ObWkbGeogInnerPoint &innerpoint, const ObG
|
||||
ObGeographGeometrycollection &res)
|
||||
{
|
||||
INIT_SUCC(ret);
|
||||
ObGeographPoint *point = OB_NEWx(ObGeographPoint, context.get_allocator());
|
||||
ObGeographPoint *point = OB_NEWx(ObGeographPoint, context.get_allocator(), res.get_srid());
|
||||
if (OB_ISNULL(point)) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
LOG_WARN("fail to create geograph point", K(ret));
|
||||
@ -494,7 +494,7 @@ public:
|
||||
LOG_WARN("fail to push back geometry", K(ret));
|
||||
} else if (OB_FAIL(ObGeoFuncUtils::ob_geo_gc_split(*allocator, *geo_coll, mpt, mls, mpy))) {
|
||||
LOG_WARN("failed to do gc split", K(ret));
|
||||
} else if (OB_FAIL(ObGeoFuncUtils::ob_geo_gc_union(*allocator, *context.get_srs(), mpt, mls, mpy))) {
|
||||
} else if (OB_FAIL(ObGeoFuncUtils::ob_geo_gc_union(context.get_mem_ctx(), *context.get_srs(), mpt, mls, mpy))) {
|
||||
LOG_WARN("failed to do gc union", K(ret));
|
||||
} else {
|
||||
for (int i = 0; OB_SUCC(ret) && i < mpy->size(); ++i) {
|
||||
@ -515,8 +515,7 @@ public:
|
||||
allocator,
|
||||
pt.template get<0>(),
|
||||
pt.template get<1>(),
|
||||
srid,
|
||||
allocator);
|
||||
srid);
|
||||
if (OB_ISNULL(pt_tree)) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
LOG_WARN("fail to allocate memory", K(ret));
|
||||
|
316
deps/oblib/src/lib/geo/ob_geo_func_utils.h
vendored
316
deps/oblib/src/lib/geo/ob_geo_func_utils.h
vendored
@ -18,6 +18,7 @@
|
||||
#include "lib/utility/ob_hang_fatal_error.h"
|
||||
#include "lib/geo/ob_geo_to_tree_visitor.h"
|
||||
#include "common/ob_smart_call.h"
|
||||
#include "share/rc/ob_tenant_base.h"
|
||||
|
||||
namespace oceanbase
|
||||
{
|
||||
@ -36,7 +37,7 @@ public:
|
||||
virtual ~ObGeoFuncUtils() = default;
|
||||
|
||||
template<typename MultiPointType, typename MultiLineType, typename MultiPolygonType>
|
||||
static int ob_geo_gc_union(common::ObIAllocator &allocator,
|
||||
static int ob_geo_gc_union(lib::MemoryContext &mem_ctx,
|
||||
const common::ObSrsItem &srs,
|
||||
MultiPointType *&mps,
|
||||
MultiLineType *&mls,
|
||||
@ -57,12 +58,6 @@ public:
|
||||
typename GcTreeType::sub_mp_type *&multi_poly);
|
||||
|
||||
static int apply_bg_to_tree(const ObGeometry *g1, const ObGeoEvalCtx &context, ObGeometry *&result);
|
||||
template<typename GcTreeType>
|
||||
static int remove_duplicate_multi_geo(ObGeometry *&geo, common::ObIAllocator &allocator, const ObSrsItem *srs);
|
||||
template<typename GcTreeType>
|
||||
static int simplify_geo_collection(ObGeometry *&geo, common::ObIAllocator &allocator, const ObSrsItem *srs);
|
||||
template<typename GcType>
|
||||
static int simplify_multi_geo(ObGeometry *&geo, common::ObIAllocator &allocator);
|
||||
|
||||
private:
|
||||
template<typename GcTreeType>
|
||||
@ -70,12 +65,10 @@ private:
|
||||
typename GcTreeType::sub_mpt_type &mpt,
|
||||
typename GcTreeType::sub_ml_type &ml,
|
||||
typename GcTreeType::sub_mp_type &mpo);
|
||||
template<typename MpType>
|
||||
static int is_in_geometry(const ObGeometry &geo, const MpType &multi_geo, const ObSrsItem *srs, bool &res);
|
||||
};
|
||||
|
||||
template<typename MultiPointType, typename MultiLineType, typename MultiPolygonType>
|
||||
int ObGeoFuncUtils::ob_geo_gc_union(ObIAllocator &allocator,
|
||||
int ObGeoFuncUtils::ob_geo_gc_union(lib::MemoryContext &mem_ctx,
|
||||
const ObSrsItem &srs,
|
||||
MultiPointType *&mps,
|
||||
MultiLineType *&mls,
|
||||
@ -83,11 +76,12 @@ int ObGeoFuncUtils::ob_geo_gc_union(ObIAllocator &allocator,
|
||||
{
|
||||
INIT_SUCC(ret);
|
||||
ObGeometry *func_result = NULL;
|
||||
ObIAllocator &allocator = mem_ctx->get_arena_allocator();
|
||||
if (!mps->is_tree() || !mls->is_tree() || !mpols->is_tree()) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
OB_LOG(WARN, "invalid geometry type, must be geotree", K(ret));
|
||||
} else {
|
||||
MultiPolygonType *mpols_res = OB_NEWx(MultiPolygonType, (&allocator));
|
||||
MultiPolygonType *mpols_res = OB_NEWx(MultiPolygonType, (&allocator), mpols->get_srid(), allocator);
|
||||
if (OB_ISNULL(mpols_res)) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
} else {
|
||||
@ -100,7 +94,7 @@ int ObGeoFuncUtils::ob_geo_gc_union(ObIAllocator &allocator,
|
||||
boost::geometry::correct(*pol, area_strategy);
|
||||
}
|
||||
|
||||
ObGeoEvalCtx gis_context(&allocator, &srs);
|
||||
ObGeoEvalCtx gis_context(mem_ctx, &srs);
|
||||
if (OB_FAIL(gis_context.append_geo_arg(&(*pol)))
|
||||
|| OB_FAIL(gis_context.append_geo_arg(&(*mpols_res)))) {
|
||||
OB_LOG(WARN, "failed to append geo to ctx", K(ret));
|
||||
@ -123,7 +117,7 @@ int ObGeoFuncUtils::ob_geo_gc_union(ObIAllocator &allocator,
|
||||
}
|
||||
|
||||
if (OB_SUCC(ret)) {
|
||||
ObGeoEvalCtx line_diff_context(&allocator, &srs);
|
||||
ObGeoEvalCtx line_diff_context(mem_ctx, &srs);
|
||||
if (OB_FAIL(line_diff_context.append_geo_arg(mls))
|
||||
|| OB_FAIL(line_diff_context.append_geo_arg(mpols))) {
|
||||
OB_LOG(WARN, "failed to append geo to ctx", K(ret));
|
||||
@ -138,7 +132,7 @@ int ObGeoFuncUtils::ob_geo_gc_union(ObIAllocator &allocator,
|
||||
}
|
||||
|
||||
for (uint8_t i = 0; i < 2 && OB_SUCC(ret); i++) {
|
||||
ObGeoEvalCtx point_diff_context(&allocator, &srs);
|
||||
ObGeoEvalCtx point_diff_context(mem_ctx, &srs);
|
||||
ObGeometry *tmp_geo = NULL;
|
||||
if (i == 0) {
|
||||
tmp_geo = mls;
|
||||
@ -214,23 +208,30 @@ int ObGeoFuncUtils::ob_gc_prepare(const ObGeoEvalCtx &context,
|
||||
ObIAllocator *allocator = context.get_allocator();
|
||||
const ObSrsItem *srs = context.get_srs();
|
||||
const GcTreeType *gc_tree = nullptr;
|
||||
ObArenaAllocator tmp_alloc;
|
||||
if (gc->is_tree()) {
|
||||
gc_tree = static_cast<const GcTreeType *>(gc);
|
||||
} else {
|
||||
ObGeoToTreeVisitor tree_visitor(allocator);
|
||||
ObGeoToTreeVisitor tree_visitor(&tmp_alloc);
|
||||
if (OB_FAIL(gc->do_visit(tree_visitor))) {
|
||||
OB_LOG(WARN, "failed to transform gc to tree", K(ret));
|
||||
} else {
|
||||
gc_tree = static_cast<const GcTreeType *>(tree_visitor.get_geometry());
|
||||
}
|
||||
}
|
||||
// ob_geo_gc_union will rewrite multi_line/multi_poly if success
|
||||
// so mls/mpy can be temporary
|
||||
multi_line = OB_NEWx(typename GcTreeType::sub_ml_type, &tmp_alloc, gc->get_srid(), tmp_alloc);
|
||||
multi_poly = OB_NEWx(typename GcTreeType::sub_mp_type, &tmp_alloc, gc->get_srid(), tmp_alloc);
|
||||
multi_point = OB_NEWx(typename GcTreeType::sub_mpt_type, allocator, gc->get_srid(), *allocator);
|
||||
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (OB_FAIL(ObGeoFuncUtils::ob_geo_gc_split(*allocator,
|
||||
*gc_tree,
|
||||
multi_point, multi_line, multi_poly))) {
|
||||
OB_LOG(WARN, "failed to do gc split", K(ret));
|
||||
} else if (OB_FAIL(ObGeoFuncUtils::ob_geo_gc_union(*allocator, *srs, multi_point,
|
||||
} else if (OB_ISNULL(multi_point)) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
OB_LOG(WARN, "failed to allocate memory", K(ret));
|
||||
} else if (OB_FAIL(ObGeoFuncUtils::ob_geo_gc_split_inner(*gc_tree, *multi_point, *multi_line, *multi_poly))) {
|
||||
OB_LOG(WARN, "failed to falatten geometrycollection", K(ret));
|
||||
} else if (OB_FAIL(ObGeoFuncUtils::ob_geo_gc_union(context.get_mem_ctx(), *srs, multi_point,
|
||||
multi_line, multi_poly))) {
|
||||
OB_LOG(WARN, "failed to do gc union", K(ret));
|
||||
} else { /* do nothing */ }
|
||||
@ -320,281 +321,6 @@ int ObGeoFuncUtils::ob_geo_gc_split_inner(const GcTreeType &gc,
|
||||
return ret;
|
||||
}
|
||||
|
||||
template<typename MpType>
|
||||
int ObGeoFuncUtils::is_in_geometry(const ObGeometry &geo, const MpType &multi_geo, const ObSrsItem *srs, bool &res)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObArenaAllocator temp_allocator;
|
||||
for (int32_t j = 0; j < multi_geo.size() && OB_SUCC(ret) && !res; j++) {
|
||||
ObGeoEvalCtx gis_context(&temp_allocator, srs);
|
||||
if (OB_FAIL(gis_context.append_geo_arg(&geo)) || OB_FAIL(gis_context.append_geo_arg(&multi_geo[j]))) {
|
||||
OB_LOG(WARN, "build gis context failed", K(ret), K(gis_context.get_geo_count()));
|
||||
} else if (OB_FAIL(ObGeoFunc<ObGeoFuncType::Equals>::geo_func::eval(gis_context, res))) {
|
||||
OB_LOG(WARN, "eval st intersection failed", K(ret));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
template<typename GcType>
|
||||
int ObGeoFuncUtils::simplify_multi_geo(ObGeometry *&geo, common::ObIAllocator &allocator)
|
||||
{
|
||||
// e.g. MULTILINESTRING((0 0, 1 1)) -> LINESTRING(0 0, 1 1)
|
||||
int ret= OB_SUCCESS;
|
||||
switch (geo->type()) {
|
||||
case ObGeoType::MULTILINESTRING: {
|
||||
typename GcType::sub_ml_type *mp = reinterpret_cast<typename GcType::sub_ml_type *>(geo);
|
||||
if (OB_ISNULL(mp)) {
|
||||
ret = OB_ERR_GIS_INVALID_DATA;
|
||||
OB_LOG(WARN, "invalid null pointer", K(ret));
|
||||
} else if (mp->size() == 1) {
|
||||
geo = &(mp->front());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ObGeoType::MULTIPOINT: {
|
||||
typename GcType::sub_mpt_type *mpt = reinterpret_cast<typename GcType::sub_mpt_type *>(geo);
|
||||
if (OB_ISNULL(mpt)) {
|
||||
ret = OB_ERR_GIS_INVALID_DATA;
|
||||
OB_LOG(WARN, "invalid null pointer", K(ret));
|
||||
} else if (mpt->size() == 1) {
|
||||
typename GcType::sub_pt_type *p = OB_NEWx(typename GcType::sub_pt_type, &allocator);
|
||||
if (OB_ISNULL(p)) {
|
||||
ret = OB_ERR_GIS_INVALID_DATA;
|
||||
OB_LOG(WARN, "invalid null pointer", K(ret));
|
||||
} else {
|
||||
p->set_data(mpt->front());
|
||||
geo = p;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ObGeoType::MULTIPOLYGON: {
|
||||
typename GcType::sub_mp_type *mp = reinterpret_cast<typename GcType::sub_mp_type *>(geo);
|
||||
if (OB_ISNULL(mp)) {
|
||||
ret = OB_ERR_GIS_INVALID_DATA;
|
||||
OB_LOG(WARN, "invalid null pointer", K(ret));
|
||||
} else if (mp->size() == 1) {
|
||||
geo = &(mp->front());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ObGeoType::GEOMETRYCOLLECTION: {
|
||||
GcType *mp = reinterpret_cast<GcType *>(geo);
|
||||
if (OB_ISNULL(mp)) {
|
||||
ret = OB_ERR_GIS_INVALID_DATA;
|
||||
OB_LOG(WARN, "invalid null pointer", K(ret));
|
||||
} else if (mp->size() == 1) {
|
||||
geo = &(mp->front());
|
||||
if (OB_FAIL((simplify_multi_geo<GcType>(geo, allocator)))) {
|
||||
OB_LOG(WARN, "fail to simplify geometry", K(ret));
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
break; // do nothing
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
// for geo tree
|
||||
template<typename GcTreeType>
|
||||
int ObGeoFuncUtils::simplify_geo_collection(ObGeometry *&geo, common::ObIAllocator &allocator, const ObSrsItem *srs)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (geo->type() != ObGeoType::GEOMETRYCOLLECTION) {
|
||||
// do nothing
|
||||
} else {
|
||||
GcTreeType *&geo_coll = reinterpret_cast<GcTreeType *&>(geo);
|
||||
ObGeoType front_type;
|
||||
bool need_simplify = true;
|
||||
if (geo_coll->size() < 2) {
|
||||
need_simplify = false;
|
||||
} else {
|
||||
front_type = geo_coll->front().type();
|
||||
for (uint32_t i = 1; need_simplify && i < geo_coll->size(); ++i) {
|
||||
if (((*geo_coll)[i]).type() != front_type) {
|
||||
need_simplify = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (need_simplify) {
|
||||
switch(front_type) {
|
||||
case ObGeoType::POINT: {
|
||||
typename GcTreeType::sub_mpt_type *res_geo = OB_NEWx(typename GcTreeType::sub_mpt_type, &allocator, geo->get_srid(), allocator);
|
||||
if (OB_ISNULL(res_geo)) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
OB_LOG(WARN, "fail to alloc memory", K(ret));
|
||||
}
|
||||
for (uint32_t i = 0; OB_SUCC(ret) && i < geo_coll->size(); ++i) {
|
||||
typename GcTreeType::sub_pt_type &geo_point = reinterpret_cast<typename GcTreeType::sub_pt_type &>((*geo_coll)[i]);
|
||||
if (OB_FAIL(res_geo->push_back(geo_point))) {
|
||||
OB_LOG(WARN, "failed to add point to multipoint", K(ret));
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
geo = res_geo;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ObGeoType::LINESTRING: {
|
||||
typename GcTreeType::sub_ml_type *res_geo = OB_NEWx(typename GcTreeType::sub_ml_type, &allocator, geo->get_srid(), allocator);
|
||||
if (OB_ISNULL(res_geo)) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
OB_LOG(WARN, "fail to alloc memory", K(ret));
|
||||
}
|
||||
for (uint32_t i = 0; OB_SUCC(ret) && i < geo_coll->size(); ++i) {
|
||||
if (OB_FAIL(res_geo->push_back((*geo_coll)[i]))) {
|
||||
OB_LOG(WARN, "failed to add linestring to multilinestring", K(ret));
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
geo = res_geo;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ObGeoType::POLYGON: {
|
||||
typename GcTreeType::sub_mp_type *res_geo = OB_NEWx(typename GcTreeType::sub_mp_type, &allocator, geo->get_srid(), allocator);
|
||||
if (OB_ISNULL(res_geo)) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
OB_LOG(WARN, "fail to alloc memory", K(ret));
|
||||
}
|
||||
for (uint32_t i = 0; OB_SUCC(ret) && i < geo_coll->size(); ++i) {
|
||||
if (OB_FAIL(res_geo->push_back((*geo_coll)[i]))) {
|
||||
OB_LOG(WARN, "failed to add polygon to multipolygon", K(ret));
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
geo = res_geo;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
// do nothing
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
// for geo tree
|
||||
template<typename GcTreeType>
|
||||
int ObGeoFuncUtils::remove_duplicate_multi_geo(ObGeometry *&geo, common::ObIAllocator &allocator, const ObSrsItem *srs)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObArenaAllocator temp_allocator;
|
||||
switch (geo->type()) {
|
||||
case ObGeoType::POINT:
|
||||
case ObGeoType::LINESTRING:
|
||||
case ObGeoType::POLYGON: {
|
||||
break;
|
||||
}
|
||||
case ObGeoType::MULTIPOINT: {
|
||||
typename GcTreeType::sub_mpt_type *res_geo = OB_NEWx(typename GcTreeType::sub_mpt_type, &allocator, geo->get_srid(), allocator);
|
||||
typename GcTreeType::sub_mpt_type &sp_geo = reinterpret_cast<typename GcTreeType::sub_mpt_type &>(*geo);
|
||||
if (OB_ISNULL(res_geo)) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
OB_LOG(WARN, "failt to allocate memory for geometry", K(ret), K(geo->type()));
|
||||
}
|
||||
for (int32_t i = 0; i < sp_geo.size() && OB_SUCC(ret); i++) {
|
||||
bool in_res_geo = false;
|
||||
for (int32_t j = 0; j < res_geo->size() && OB_SUCC(ret) && !in_res_geo; j++) {
|
||||
if ((sp_geo[i].template get<0>() == (*res_geo)[j].template get<0>())
|
||||
&& (sp_geo[i].template get<1>() == (*res_geo)[j].template get<1>())) {
|
||||
in_res_geo = true;
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret) && !in_res_geo) {
|
||||
typename GcTreeType::sub_pt_type pt(sp_geo[i].template get<0>(), sp_geo[i].template get<1>());
|
||||
if (OB_FAIL(res_geo->push_back(pt))) {
|
||||
OB_LOG(WARN, "fail to push back geometry", K(ret));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
geo = res_geo;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ObGeoType::MULTILINESTRING: {
|
||||
typename GcTreeType::sub_ml_type *res_geo = OB_NEWx(typename GcTreeType::sub_ml_type, &allocator, geo->get_srid(), allocator);
|
||||
typename GcTreeType::sub_ml_type &sp_geo = reinterpret_cast<typename GcTreeType::sub_ml_type &>(*geo);
|
||||
if (OB_ISNULL(res_geo)) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
OB_LOG(WARN, "failt to allocate memory for geometry", K(ret), K(geo->type()));
|
||||
}
|
||||
for (int32_t i = 0; i < sp_geo.size() && OB_SUCC(ret); i++) {
|
||||
bool in_res_geo = false;
|
||||
if (OB_FAIL(is_in_geometry(sp_geo[i], *res_geo, srs, in_res_geo))) {
|
||||
OB_LOG(WARN, "fail to check is in geometry", K(ret));
|
||||
} else if (!in_res_geo && res_geo->push_back(sp_geo[i])) {
|
||||
OB_LOG(WARN, "fail to push back geometry", K(ret));
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
geo = res_geo;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ObGeoType::MULTIPOLYGON: {
|
||||
typename GcTreeType::sub_mp_type *res_geo = OB_NEWx(typename GcTreeType::sub_mp_type, &allocator, geo->get_srid(), allocator);
|
||||
typename GcTreeType::sub_mp_type &sp_geo = reinterpret_cast<typename GcTreeType::sub_mp_type &>(*geo);
|
||||
if (OB_ISNULL(res_geo)) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
OB_LOG(WARN, "failt to allocate memory for geometry", K(ret), K(geo->type()));
|
||||
}
|
||||
for (int32_t i = 0; i < sp_geo.size() && OB_SUCC(ret); i++) {
|
||||
bool in_res_geo = false;
|
||||
if (OB_FAIL(is_in_geometry(sp_geo[i], *res_geo, srs, in_res_geo))) {
|
||||
OB_LOG(WARN, "fail to check is in geometry", K(ret));
|
||||
} else if (!in_res_geo && res_geo->push_back(sp_geo[i])) {
|
||||
OB_LOG(WARN, "fail to push back geometry", K(ret));
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
geo = res_geo;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ObGeoType::GEOMETRYCOLLECTION: {
|
||||
GcTreeType *res_geo = OB_NEWx(GcTreeType, &allocator, geo->get_srid(), allocator);
|
||||
GcTreeType *&sp_geo = reinterpret_cast<GcTreeType *&>(geo);
|
||||
if (OB_ISNULL(res_geo)) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
OB_LOG(WARN, "failt to allocate memory for geometry", K(ret), K(geo->type()));
|
||||
}
|
||||
for (int32_t i = 0; i < sp_geo->size() && OB_SUCC(ret); i++) {
|
||||
bool in_res_geo = false;
|
||||
ObGeometry *cur_geo = &(*sp_geo)[i];
|
||||
if (OB_FAIL(remove_duplicate_multi_geo<GcTreeType>(cur_geo, allocator, srs))) {
|
||||
OB_LOG(WARN, "fail to remove dupilicate multi geometry", K(ret));
|
||||
} else if (OB_FAIL(is_in_geometry(*cur_geo, *res_geo, srs, in_res_geo))) {
|
||||
OB_LOG(WARN, "fail to check is in geometry", K(ret));
|
||||
} else if (!in_res_geo && res_geo->push_back(*cur_geo)) {
|
||||
OB_LOG(WARN, "fail to push back geometry", K(ret));
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
geo = res_geo;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
ret = OB_NOT_SUPPORTED;
|
||||
OB_LOG(WARN, "geometry type not supported", K(ret), K(geo->type()));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (OB_SUCC(ret) && OB_FAIL((simplify_multi_geo<GcTreeType>(geo, allocator)))) {
|
||||
OB_LOG(WARN, "fail to simplify result", K(ret));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
} // sql
|
||||
} // oceanbase
|
||||
#endif // OCEANBASE_LIB_OB_GEO_FUNC_UTILS_H_
|
26
deps/oblib/src/lib/geo/ob_geo_func_within.cpp
vendored
26
deps/oblib/src/lib/geo/ob_geo_func_within.cpp
vendored
@ -28,7 +28,7 @@ namespace common
|
||||
namespace bg = boost::geometry;
|
||||
|
||||
static int do_multi_difference(const ObSrsItem &srs,
|
||||
ObIAllocator &allocator,
|
||||
const ObGeoEvalCtx &context,
|
||||
ObGeometry *geo,
|
||||
ObGeometry *mpt,
|
||||
ObGeometry *ml,
|
||||
@ -38,9 +38,9 @@ static int do_multi_difference(const ObSrsItem &srs,
|
||||
INIT_SUCC(ret);
|
||||
ObGeometry *res_geo1 = NULL;
|
||||
ObGeometry *res_geo2 = NULL;
|
||||
ObGeoEvalCtx gis_context1(&allocator, &srs);
|
||||
ObGeoEvalCtx gis_context2(&allocator, &srs);
|
||||
ObGeoEvalCtx gis_context3(&allocator, &srs);
|
||||
ObGeoEvalCtx gis_context1(context.get_mem_ctx(), &srs);
|
||||
ObGeoEvalCtx gis_context2(context.get_mem_ctx(), &srs);
|
||||
ObGeoEvalCtx gis_context3(context.get_mem_ctx(), &srs);
|
||||
if (OB_NOT_NULL(mpt)) {
|
||||
if (OB_FAIL(gis_context1.append_geo_arg(reinterpret_cast<ObGeometry *>(geo))) || OB_FAIL(gis_context1.append_geo_arg(mpt))) {
|
||||
LOG_WARN("build gis context failed", K(ret), K(gis_context1.get_geo_count()));
|
||||
@ -280,7 +280,7 @@ static int ob_caculate_ml_within_gc(const ObGeometry *g1, const ObGeometry *g2,
|
||||
ObGeometry *i_geo1 = const_cast<ObGeometry *>(g1);
|
||||
if (OB_FAIL(i_geo1->do_visit(visitor))) {
|
||||
LOG_WARN("failed to do geo2 to_tree visit", K(ret));
|
||||
} else if (OB_FAIL(do_multi_difference(*srs, *allocator, visitor.get_geometry(),
|
||||
} else if (OB_FAIL(do_multi_difference(*srs, context, visitor.get_geometry(),
|
||||
NULL,
|
||||
reinterpret_cast<ObGeometry *>(multi_line),
|
||||
reinterpret_cast<ObGeometry *>(multi_poly),
|
||||
@ -324,7 +324,7 @@ static int ob_caculate_ml_within_gc_geog(const ObGeometry *g1, const ObGeometry
|
||||
ObGeometry *i_geo1 = const_cast<ObGeometry *>(g1);
|
||||
if (OB_FAIL(i_geo1->do_visit(visitor))) {
|
||||
LOG_WARN("failed to do geo2 to_tree visit", K(ret));
|
||||
} else if (OB_FAIL(do_multi_difference(*srs, *allocator, visitor.get_geometry(),
|
||||
} else if (OB_FAIL(do_multi_difference(*srs, context, visitor.get_geometry(),
|
||||
NULL,
|
||||
reinterpret_cast<ObGeometry *>(multi_line),
|
||||
reinterpret_cast<ObGeometry *>(multi_poly),
|
||||
@ -532,7 +532,7 @@ private:
|
||||
IPointType i_point;
|
||||
i_point.set_data(data);
|
||||
|
||||
ObGeoEvalCtx intersects_context(context.get_allocator(), context.get_srs());
|
||||
ObGeoEvalCtx intersects_context(context.get_mem_ctx(), context.get_srs());
|
||||
intersects_context.append_geo_arg(&i_point);
|
||||
intersects_context.append_geo_arg(g2);
|
||||
if (!within) {
|
||||
@ -983,7 +983,7 @@ OB_GEO_CART_BINARY_FUNC_BEGIN(ObGeoFuncWithinImpl, ObWkbGeomCollection, ObWkbGeo
|
||||
const ObSrsItem *srs = context.get_srs();
|
||||
ObIAllocator *allocator = context.get_allocator();
|
||||
ObGeometry *res_geo3 = NULL;
|
||||
if (OB_FAIL(do_multi_difference(*srs, *allocator, reinterpret_cast<ObGeometry *>(g1_multi_point),
|
||||
if (OB_FAIL(do_multi_difference(*srs, context, reinterpret_cast<ObGeometry *>(g1_multi_point),
|
||||
reinterpret_cast<ObGeometry *>(g2_multi_point),
|
||||
reinterpret_cast<ObGeometry *>(g2_multi_line),
|
||||
reinterpret_cast<ObGeometry *>(g2_multi_poly),
|
||||
@ -993,7 +993,7 @@ OB_GEO_CART_BINARY_FUNC_BEGIN(ObGeoFuncWithinImpl, ObWkbGeomCollection, ObWkbGeo
|
||||
result = false;
|
||||
} else {
|
||||
ObGeometry *res_geo5 = NULL;
|
||||
if (OB_FAIL(do_multi_difference(*srs, *allocator, reinterpret_cast<ObGeometry *>(g1_multi_line),
|
||||
if (OB_FAIL(do_multi_difference(*srs, context, reinterpret_cast<ObGeometry *>(g1_multi_line),
|
||||
NULL,
|
||||
reinterpret_cast<ObGeometry *>(g2_multi_line),
|
||||
reinterpret_cast<ObGeometry *>(g2_multi_poly),
|
||||
@ -1003,7 +1003,7 @@ OB_GEO_CART_BINARY_FUNC_BEGIN(ObGeoFuncWithinImpl, ObWkbGeomCollection, ObWkbGeo
|
||||
result = false;
|
||||
} else {
|
||||
ObGeometry *res_geo6 = NULL;
|
||||
if (OB_FAIL(do_multi_difference(*srs, *allocator, reinterpret_cast<ObGeometry *>(g1_multi_poly),
|
||||
if (OB_FAIL(do_multi_difference(*srs, context, reinterpret_cast<ObGeometry *>(g1_multi_poly),
|
||||
NULL,
|
||||
NULL,
|
||||
reinterpret_cast<ObGeometry *>(g2_multi_poly),
|
||||
@ -1635,7 +1635,7 @@ OB_GEO_GEOG_BINARY_FUNC_BEGIN(ObGeoFuncWithinImpl, ObWkbGeogCollection, ObWkbGeo
|
||||
ObIAllocator *allocator = context.get_allocator();
|
||||
|
||||
ObGeometry *res_geo3 = NULL;
|
||||
if (OB_FAIL(do_multi_difference(*srs, *allocator, reinterpret_cast<ObGeometry *>(g1_multi_point),
|
||||
if (OB_FAIL(do_multi_difference(*srs, context, reinterpret_cast<ObGeometry *>(g1_multi_point),
|
||||
reinterpret_cast<ObGeometry *>(g2_multi_point),
|
||||
reinterpret_cast<ObGeometry *>(g2_multi_line),
|
||||
reinterpret_cast<ObGeometry *>(g2_multi_poly),
|
||||
@ -1645,7 +1645,7 @@ OB_GEO_GEOG_BINARY_FUNC_BEGIN(ObGeoFuncWithinImpl, ObWkbGeogCollection, ObWkbGeo
|
||||
result = false;
|
||||
} else {
|
||||
ObGeometry *res_geo5 = NULL;
|
||||
if (OB_FAIL(do_multi_difference(*srs, *allocator, reinterpret_cast<ObGeometry *>(g1_multi_line),
|
||||
if (OB_FAIL(do_multi_difference(*srs, context, reinterpret_cast<ObGeometry *>(g1_multi_line),
|
||||
NULL,
|
||||
reinterpret_cast<ObGeometry *>(g2_multi_line),
|
||||
reinterpret_cast<ObGeometry *>(g2_multi_poly),
|
||||
@ -1655,7 +1655,7 @@ OB_GEO_GEOG_BINARY_FUNC_BEGIN(ObGeoFuncWithinImpl, ObWkbGeogCollection, ObWkbGeo
|
||||
result = false;
|
||||
} else {
|
||||
ObGeometry * res_geo6 = NULL;
|
||||
if (OB_FAIL(do_multi_difference(*srs, *allocator, reinterpret_cast<ObGeometry *>(g1_multi_poly),
|
||||
if (OB_FAIL(do_multi_difference(*srs, context, reinterpret_cast<ObGeometry *>(g1_multi_poly),
|
||||
NULL,
|
||||
NULL,
|
||||
reinterpret_cast<ObGeometry *>(g2_multi_poly),
|
||||
|
12
deps/oblib/src/lib/geo/ob_geo_ibin.cpp
vendored
12
deps/oblib/src/lib/geo/ob_geo_ibin.cpp
vendored
@ -94,11 +94,11 @@ bool ObIWkbGeomPolygon::is_empty_inner() const
|
||||
return (poly->exterior_ring().size(static_cast<ObGeoWkbByteOrder>(poly->get_bo())) == 0) && (poly->inner_rings().size() == 0);
|
||||
}
|
||||
|
||||
int ObIWkbGeomCollection::get_sub(uint32_t idx, ObGeometry*& geo) const
|
||||
int ObIWkbGeomCollection::get_sub(ObIAllocator *allocator, uint32_t idx, ObGeometry*& geo) const
|
||||
{
|
||||
INIT_SUCC(ret);
|
||||
ObWkbGeomCollection* g = reinterpret_cast<ObWkbGeomCollection*>(const_cast<char*>(val()));
|
||||
if (OB_ISNULL(this->allocator_)) {
|
||||
if (OB_ISNULL(allocator)) {
|
||||
ret = OB_ERR_NULL_VALUE;
|
||||
LOG_WARN("Null allocator.", K(ret));
|
||||
} else if (idx >= g->size()) {
|
||||
@ -112,7 +112,7 @@ int ObIWkbGeomCollection::get_sub(uint32_t idx, ObGeometry*& geo) const
|
||||
// TODO use create_obj_by_type
|
||||
switch (g->get_sub_type(ptr)) {
|
||||
case ObGeoType::POINT: {
|
||||
geo = OB_NEWx(ObIWkbGeomPoint, this->allocator_);
|
||||
geo = OB_NEWx(ObIWkbGeomPoint, allocator, srid_);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
@ -194,11 +194,11 @@ bool ObIWkbGeogPolygon::is_empty_inner() const
|
||||
return bret;
|
||||
}
|
||||
|
||||
int ObIWkbGeogCollection::get_sub(uint32_t idx, ObGeometry*& geo) const
|
||||
int ObIWkbGeogCollection::get_sub(ObIAllocator *allocator, uint32_t idx, ObGeometry*& geo) const
|
||||
{
|
||||
INIT_SUCC(ret);
|
||||
ObWkbGeogCollection* g = reinterpret_cast<ObWkbGeogCollection*>(const_cast<char*>(val()));
|
||||
if (OB_ISNULL(this->allocator_)) {
|
||||
if (OB_ISNULL(allocator)) {
|
||||
ret = OB_ERR_NULL_VALUE;
|
||||
LOG_WARN("Null allocator.", K(ret));
|
||||
} else if (idx >= g->size()) {
|
||||
@ -212,7 +212,7 @@ int ObIWkbGeogCollection::get_sub(uint32_t idx, ObGeometry*& geo) const
|
||||
// TODO use create_obj_by_type
|
||||
switch (g->get_sub_type(ptr)) {
|
||||
case ObGeoType::POINT: {
|
||||
geo = OB_NEWx(ObIWkbGeomPoint, this->allocator_);
|
||||
geo = OB_NEWx(ObIWkbGeomPoint, allocator, srid_);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
|
78
deps/oblib/src/lib/geo/ob_geo_ibin.h
vendored
78
deps/oblib/src/lib/geo/ob_geo_ibin.h
vendored
@ -26,8 +26,8 @@ class ObIGeoVisitor;
|
||||
class ObIWkbGeometry : public ObGeometry
|
||||
{
|
||||
public:
|
||||
ObIWkbGeometry(uint32_t srid = 0, ObIAllocator *allocator = NULL)
|
||||
: ObGeometry(srid, allocator) {}
|
||||
ObIWkbGeometry(uint32_t srid = 0)
|
||||
: ObGeometry(srid) {}
|
||||
~ObIWkbGeometry() = default;
|
||||
ObIWkbGeometry(const ObIWkbGeometry& g) = default;
|
||||
ObIWkbGeometry& operator=(const ObIWkbGeometry& g) = default;
|
||||
@ -53,8 +53,8 @@ protected:
|
||||
class ObIWkbPoint : public ObIWkbGeometry
|
||||
{
|
||||
public:
|
||||
ObIWkbPoint(uint32_t srid = 0, ObIAllocator *allocator = NULL)
|
||||
: ObIWkbGeometry(srid, allocator) {}
|
||||
ObIWkbPoint(uint32_t srid = 0)
|
||||
: ObIWkbGeometry(srid) {}
|
||||
~ObIWkbPoint() = default;
|
||||
// point interface
|
||||
virtual double x() const = 0;
|
||||
@ -80,8 +80,8 @@ public:
|
||||
typedef ObWkbGeomPoint value_type;
|
||||
public:
|
||||
// constructor
|
||||
ObIWkbGeomPoint(uint32_t srid = 0, ObIAllocator *allocator = NULL)
|
||||
: ObIWkbPoint(srid, allocator) {}
|
||||
ObIWkbGeomPoint(uint32_t srid = 0)
|
||||
: ObIWkbPoint(srid) {}
|
||||
~ObIWkbGeomPoint() = default;
|
||||
ObIWkbGeomPoint(const ObIWkbGeomPoint& g) = default;
|
||||
ObIWkbGeomPoint& operator=(const ObIWkbGeomPoint& g) = default;
|
||||
@ -101,8 +101,8 @@ public:
|
||||
typedef ObWkbGeomLineString value_type;
|
||||
public:
|
||||
// constructor
|
||||
ObIWkbGeomLineString(uint32_t srid = 0, ObIAllocator *allocator = NULL)
|
||||
: ObIWkbGeometry(srid, allocator) {}
|
||||
ObIWkbGeomLineString(uint32_t srid = 0)
|
||||
: ObIWkbGeometry(srid) {}
|
||||
~ObIWkbGeomLineString() = default;
|
||||
ObIWkbGeomLineString(const ObIWkbGeomLineString& g) = default;
|
||||
ObIWkbGeomLineString& operator=(const ObIWkbGeomLineString& g) = default;
|
||||
@ -124,8 +124,8 @@ public:
|
||||
typedef ObWkbGeomPolygon value_type;
|
||||
public:
|
||||
// constructor
|
||||
ObIWkbGeomPolygon(uint32_t srid = 0, ObIAllocator *allocator = NULL)
|
||||
: ObIWkbGeometry(srid, allocator) {}
|
||||
ObIWkbGeomPolygon(uint32_t srid = 0)
|
||||
: ObIWkbGeometry(srid) {}
|
||||
~ObIWkbGeomPolygon() = default;
|
||||
ObIWkbGeomPolygon(const ObIWkbGeomPolygon& g) = default;
|
||||
ObIWkbGeomPolygon& operator=(const ObIWkbGeomPolygon& g) = default;
|
||||
@ -144,8 +144,8 @@ private:
|
||||
class ObIWkbGeomMultiPoint : public ObIWkbGeometry {
|
||||
public:
|
||||
// constructor
|
||||
ObIWkbGeomMultiPoint(uint32_t srid = 0, ObIAllocator *allocator = NULL)
|
||||
: ObIWkbGeometry(srid, allocator) {}
|
||||
ObIWkbGeomMultiPoint(uint32_t srid = 0)
|
||||
: ObIWkbGeometry(srid) {}
|
||||
~ObIWkbGeomMultiPoint() = default;
|
||||
ObIWkbGeomMultiPoint(const ObIWkbGeomMultiPoint& g) = default;
|
||||
ObIWkbGeomMultiPoint& operator=(const ObIWkbGeomMultiPoint& g) = default;
|
||||
@ -164,8 +164,8 @@ public:
|
||||
class ObIWkbGeomMultiLineString : public ObIWkbGeometry {
|
||||
public:
|
||||
// constructor
|
||||
ObIWkbGeomMultiLineString(uint32_t srid = 0, ObIAllocator *allocator = NULL)
|
||||
: ObIWkbGeometry(srid, allocator) {}
|
||||
ObIWkbGeomMultiLineString(uint32_t srid = 0)
|
||||
: ObIWkbGeometry(srid) {}
|
||||
~ObIWkbGeomMultiLineString() = default;
|
||||
ObIWkbGeomMultiLineString(const ObIWkbGeomMultiLineString& g) = default;
|
||||
ObIWkbGeomMultiLineString& operator=(const ObIWkbGeomMultiLineString& g) = default;
|
||||
@ -188,8 +188,8 @@ public:
|
||||
|
||||
public:
|
||||
// constructor
|
||||
ObIWkbGeomLinearRing(uint32_t srid = 0, ObIAllocator *allocator = NULL)
|
||||
: ObIWkbGeometry(srid, allocator) {}
|
||||
ObIWkbGeomLinearRing(uint32_t srid = 0)
|
||||
: ObIWkbGeometry(srid) {}
|
||||
~ObIWkbGeomLinearRing() = default;
|
||||
ObIWkbGeomLinearRing(const ObIWkbGeomLinearRing& g) = default;
|
||||
ObIWkbGeomLinearRing& operator=(const ObIWkbGeomLinearRing& g) = default;
|
||||
@ -209,8 +209,8 @@ private:
|
||||
class ObIWkbGeomMultiPolygon : public ObIWkbGeometry {
|
||||
public:
|
||||
// constructor
|
||||
ObIWkbGeomMultiPolygon(uint32_t srid = 0, ObIAllocator *allocator = NULL)
|
||||
: ObIWkbGeometry(srid, allocator) {}
|
||||
ObIWkbGeomMultiPolygon(uint32_t srid = 0)
|
||||
: ObIWkbGeometry(srid) {}
|
||||
~ObIWkbGeomMultiPolygon() = default;
|
||||
ObIWkbGeomMultiPolygon(const ObIWkbGeomMultiPolygon& g) = default;
|
||||
ObIWkbGeomMultiPolygon& operator=(const ObIWkbGeomMultiPolygon& g) = default;
|
||||
@ -233,8 +233,8 @@ private:
|
||||
class ObIWkbGeomCollection : public ObIWkbGeometry {
|
||||
public:
|
||||
// constructor
|
||||
ObIWkbGeomCollection(uint32_t srid = 0, ObIAllocator *allocator = NULL)
|
||||
: ObIWkbGeometry(srid, allocator) {}
|
||||
ObIWkbGeomCollection(uint32_t srid = 0)
|
||||
: ObIWkbGeometry(srid) {}
|
||||
~ObIWkbGeomCollection() = default;
|
||||
ObIWkbGeomCollection(const ObIWkbGeomCollection& g) = default;
|
||||
ObIWkbGeomCollection& operator=(const ObIWkbGeomCollection& g) = default;
|
||||
@ -242,7 +242,8 @@ public:
|
||||
ObGeoType type() const override { return ObGeoType::GEOMETRYCOLLECTION; }
|
||||
ObGeoCRS crs() const override { return ObGeoCRS::Cartesian; }
|
||||
// iter interface
|
||||
int get_sub(uint32_t idx, ObGeometry*& geo) const;
|
||||
// no use currently
|
||||
int get_sub(ObIAllocator *allocator, uint32_t idx, ObGeometry*& geo) const;
|
||||
int do_visit(ObIGeoVisitor &visitor);
|
||||
uint32_t size() const
|
||||
{ return reinterpret_cast<const ObWkbGeomCollection*>(val())->size(); }
|
||||
@ -265,8 +266,8 @@ public:
|
||||
typedef ObWkbGeogPoint value_type;
|
||||
public:
|
||||
// constructor
|
||||
ObIWkbGeogPoint(uint32_t srid = 0, ObIAllocator *allocator = NULL)
|
||||
: ObIWkbPoint(srid, allocator) {}
|
||||
ObIWkbGeogPoint(uint32_t srid = 0)
|
||||
: ObIWkbPoint(srid) {}
|
||||
~ObIWkbGeogPoint() = default;
|
||||
ObIWkbGeogPoint(const ObIWkbGeogPoint& g) = default;
|
||||
ObIWkbGeogPoint& operator=(const ObIWkbGeogPoint& g) = default;
|
||||
@ -286,8 +287,8 @@ public:
|
||||
typedef ObWkbGeogLineString value_type;
|
||||
public:
|
||||
// constructor
|
||||
ObIWkbGeogLineString(uint32_t srid = 0, ObIAllocator *allocator = NULL)
|
||||
: ObIWkbGeometry(srid, allocator) {}
|
||||
ObIWkbGeogLineString(uint32_t srid = 0)
|
||||
: ObIWkbGeometry(srid) {}
|
||||
~ObIWkbGeogLineString() = default;
|
||||
ObIWkbGeogLineString(const ObIWkbGeogLineString& g) = default;
|
||||
ObIWkbGeogLineString& operator=(const ObIWkbGeogLineString& g) = default;
|
||||
@ -311,8 +312,8 @@ public:
|
||||
|
||||
public:
|
||||
// constructor
|
||||
ObIWkbGeogLinearRing(uint32_t srid = 0, ObIAllocator *allocator = NULL)
|
||||
: ObIWkbGeometry(srid, allocator) {}
|
||||
ObIWkbGeogLinearRing(uint32_t srid = 0)
|
||||
: ObIWkbGeometry(srid) {}
|
||||
~ObIWkbGeogLinearRing() = default;
|
||||
ObIWkbGeogLinearRing(const ObIWkbGeogLinearRing& g) = default;
|
||||
ObIWkbGeogLinearRing& operator=(const ObIWkbGeogLinearRing& g) = default;
|
||||
@ -334,8 +335,8 @@ public:
|
||||
typedef ObWkbGeogPolygon value_type;
|
||||
public:
|
||||
// constructor
|
||||
ObIWkbGeogPolygon(uint32_t srid = 0, ObIAllocator *allocator = NULL)
|
||||
: ObIWkbGeometry(srid, allocator) {}
|
||||
ObIWkbGeogPolygon(uint32_t srid = 0)
|
||||
: ObIWkbGeometry(srid) {}
|
||||
~ObIWkbGeogPolygon() = default;
|
||||
ObIWkbGeogPolygon(const ObIWkbGeogPolygon& g) = default;
|
||||
ObIWkbGeogPolygon& operator=(const ObIWkbGeogPolygon& g) = default;
|
||||
@ -354,8 +355,8 @@ private:
|
||||
class ObIWkbGeogMultiPoint : public ObIWkbGeometry {
|
||||
public:
|
||||
// constructor
|
||||
ObIWkbGeogMultiPoint(uint32_t srid = 0, ObIAllocator *allocator = NULL)
|
||||
: ObIWkbGeometry(srid, allocator) {}
|
||||
ObIWkbGeogMultiPoint(uint32_t srid = 0)
|
||||
: ObIWkbGeometry(srid) {}
|
||||
~ObIWkbGeogMultiPoint() = default;
|
||||
ObIWkbGeogMultiPoint(const ObIWkbGeogMultiPoint& g) = default;
|
||||
ObIWkbGeogMultiPoint& operator=(const ObIWkbGeogMultiPoint& g) = default;
|
||||
@ -375,8 +376,8 @@ private:
|
||||
class ObIWkbGeogMultiLineString : public ObIWkbGeometry {
|
||||
public:
|
||||
// constructor
|
||||
ObIWkbGeogMultiLineString(uint32_t srid = 0, ObIAllocator *allocator = NULL)
|
||||
: ObIWkbGeometry(srid, allocator) {}
|
||||
ObIWkbGeogMultiLineString(uint32_t srid = 0)
|
||||
: ObIWkbGeometry(srid) {}
|
||||
~ObIWkbGeogMultiLineString() = default;
|
||||
ObIWkbGeogMultiLineString(const ObIWkbGeogMultiLineString& g) = default;
|
||||
ObIWkbGeogMultiLineString& operator=(const ObIWkbGeogMultiLineString& g) = default;
|
||||
@ -396,8 +397,8 @@ private:
|
||||
class ObIWkbGeogMultiPolygon : public ObIWkbGeometry {
|
||||
public:
|
||||
// constructor
|
||||
ObIWkbGeogMultiPolygon(uint32_t srid = 0, ObIAllocator *allocator = NULL)
|
||||
: ObIWkbGeometry(srid, allocator) {}
|
||||
ObIWkbGeogMultiPolygon(uint32_t srid = 0)
|
||||
: ObIWkbGeometry(srid) {}
|
||||
~ObIWkbGeogMultiPolygon() = default;
|
||||
ObIWkbGeogMultiPolygon(const ObIWkbGeogMultiPolygon& g) = default;
|
||||
ObIWkbGeogMultiPolygon& operator=(const ObIWkbGeogMultiPolygon& g) = default;
|
||||
@ -417,8 +418,8 @@ private:
|
||||
class ObIWkbGeogCollection : public ObIWkbGeometry {
|
||||
public:
|
||||
// constructor
|
||||
ObIWkbGeogCollection(uint32_t srid = 0, ObIAllocator *allocator = NULL)
|
||||
: ObIWkbGeometry(srid, allocator) {}
|
||||
ObIWkbGeogCollection(uint32_t srid = 0)
|
||||
: ObIWkbGeometry(srid) {}
|
||||
~ObIWkbGeogCollection() = default;
|
||||
ObIWkbGeogCollection(const ObIWkbGeogCollection& g) = default;
|
||||
ObIWkbGeogCollection& operator=(const ObIWkbGeogCollection& g) = default;
|
||||
@ -426,7 +427,8 @@ public:
|
||||
ObGeoType type() const override { return ObGeoType::GEOMETRYCOLLECTION; }
|
||||
ObGeoCRS crs() const override { return ObGeoCRS::Geographic; }
|
||||
// iter interface
|
||||
int get_sub(uint32_t idx, ObGeometry*& geo) const;
|
||||
// no use currently
|
||||
int get_sub(ObIAllocator *allocator, uint32_t idx, ObGeometry*& geo) const;
|
||||
int do_visit(ObIGeoVisitor &visitor);
|
||||
uint32_t size() const
|
||||
{ return reinterpret_cast<const ObWkbGeogCollection*>(val())->size(); }
|
||||
|
@ -26,7 +26,7 @@ int ObGeoInteriorPointVisitor::init(ObGeometry *geo)
|
||||
if (OB_FAIL(ObGeoTypeUtil::check_empty(geo, is_geo_empty_))) {
|
||||
LOG_WARN("fail to check geometry is empty", K(ret));
|
||||
} else {
|
||||
ObGeoEvalCtx centroid_context(allocator_);
|
||||
ObGeoEvalCtx centroid_context(mem_ctx_);
|
||||
ObGeometry *res_geo = nullptr;
|
||||
if (OB_FAIL(centroid_context.append_geo_arg(geo))) {
|
||||
LOG_WARN("build geo gis context failed", K(ret));
|
||||
@ -61,7 +61,7 @@ int ObGeoInteriorPointVisitor::assign_interior_point(double x, double y)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (OB_ISNULL(interior_point_)) {
|
||||
if (OB_ISNULL(interior_point_ = OB_NEWx(ObCartesianPoint, allocator_, x, y, srid_, allocator_))) {
|
||||
if (OB_ISNULL(interior_point_ = OB_NEWx(ObCartesianPoint, allocator_, x, y, srid_))) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
LOG_WARN("fail to alloc memory for collection", K(ret));
|
||||
}
|
||||
@ -77,7 +77,7 @@ int ObGeoInteriorPointVisitor::assign_interior_endpoint(double x, double y)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (OB_ISNULL(interior_endpoint_)) {
|
||||
if (OB_ISNULL(interior_endpoint_ = OB_NEWx(ObCartesianPoint, allocator_, x, y, srid_, allocator_))) {
|
||||
if (OB_ISNULL(interior_endpoint_ = OB_NEWx(ObCartesianPoint, allocator_, x, y, srid_))) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
LOG_WARN("fail to alloc memory for collection", K(ret));
|
||||
}
|
||||
@ -237,7 +237,7 @@ int ObGeoInteriorPointVisitor::inner_calculate_interior_y(
|
||||
int ObGeoInteriorPointVisitor::calculate_interior_y(ObIWkbGeomPolygon *geo, double &interior_y)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObGeoEvalCtx box_ctx(allocator_);
|
||||
ObGeoEvalCtx box_ctx(mem_ctx_);
|
||||
ObGeogBox *gbox = nullptr;
|
||||
const ObWkbGeomPolygon *polygon = reinterpret_cast<const ObWkbGeomPolygon *>(geo->val());
|
||||
ObWkbGeomLinearRing::iterator iter = polygon->exterior_ring().begin();
|
||||
@ -423,7 +423,7 @@ int ObGeoInteriorPointVisitor::visit(ObIWkbGeomCollection *geo)
|
||||
if (OB_FAIL(ObGeoTypeUtil::get_coll_dimension(geo, dimension_))) {
|
||||
LOG_WARN("fail to calculate collection dimension_", K(ret));
|
||||
} else if (dimension_ == 0 || dimension_ == 1) {
|
||||
ObGeoEvalCtx centroid_context(allocator_);
|
||||
ObGeoEvalCtx centroid_context(mem_ctx_);
|
||||
ObGeometry *res_geo = nullptr;
|
||||
if (OB_FAIL(centroid_context.append_geo_arg(geo))) {
|
||||
LOG_WARN("build geo gis context failed", K(ret));
|
||||
|
@ -22,8 +22,8 @@ namespace common
|
||||
class ObGeoInteriorPointVisitor : public ObEmptyGeoVisitor
|
||||
{
|
||||
public:
|
||||
explicit ObGeoInteriorPointVisitor(ObIAllocator *allocator)
|
||||
: allocator_(allocator),
|
||||
explicit ObGeoInteriorPointVisitor(lib::MemoryContext &mem_ctx)
|
||||
: allocator_(&mem_ctx->get_arena_allocator()),
|
||||
interior_point_(nullptr),
|
||||
min_dist_(DBL_MAX),
|
||||
interior_endpoint_(nullptr),
|
||||
@ -34,7 +34,8 @@ public:
|
||||
max_width_(-1),
|
||||
is_geo_empty_(true),
|
||||
is_inited_(false),
|
||||
dimension_(-1)
|
||||
dimension_(-1),
|
||||
mem_ctx_(mem_ctx)
|
||||
{}
|
||||
~ObGeoInteriorPointVisitor()
|
||||
{}
|
||||
@ -142,6 +143,7 @@ private:
|
||||
bool is_geo_empty_;
|
||||
bool is_inited_;
|
||||
int8_t dimension_; // for collection
|
||||
lib::MemoryContext &mem_ctx_;
|
||||
DISALLOW_COPY_AND_ASSIGN(ObGeoInteriorPointVisitor);
|
||||
};
|
||||
|
||||
|
2
deps/oblib/src/lib/geo/ob_geo_mvt.cpp
vendored
2
deps/oblib/src/lib/geo/ob_geo_mvt.cpp
vendored
@ -80,7 +80,7 @@ int mvt_agg_result::generate_feature(ObObj *tmp_obj, uint32_t obj_cnt)
|
||||
LOG_WARN("Lob: init lob str iter failed ", K(ret), K(str_iter));
|
||||
} else if (OB_FAIL(str_iter.get_full_data(str))) {
|
||||
LOG_WARN("Lob: str iter get full data failed ", K(ret), K(str_iter));
|
||||
} else if (OB_FAIL(ObGeoTypeUtil::construct_geometry(*temp_allocator_, str, NULL, geo, true))) {
|
||||
} else if (OB_FAIL(ObGeoTypeUtil::construct_geometry(*temp_allocator_, str, NULL, geo, true, !str_iter.is_outrow_lob()))) {
|
||||
LOG_WARN("failed to construct geometry", K(ret));
|
||||
} else if (ObGeoTypeUtil::is_3d_geo_type(geo->type())
|
||||
&& OB_FAIL(ObGeoTypeUtil::convert_geometry_3D_to_2D(NULL, allocator_, geo, ObGeoBuildFlag::GEO_ALL_DISABLE, geo))) {
|
||||
|
@ -43,21 +43,6 @@ int ObGeoNormalizeVisitor::normalize(ObIWkbPoint *geo)
|
||||
LOG_WARN("normalize y failed", K(ret));
|
||||
} else if (OB_FAIL(srs_->longtitude_convert_to_radians(geo->x(), nx))) {
|
||||
LOG_WARN("normalize x failed", K(ret));
|
||||
} else {
|
||||
uint32_t count = 0;
|
||||
double nx_tmp = nx;
|
||||
double ny_tmp = ny;
|
||||
while (nx_tmp != 0.0 && std::fabs(nx_tmp) < ZOOM_IN_THRESHOLD) {
|
||||
nx_tmp *= 10;
|
||||
count++;
|
||||
}
|
||||
zoom_in_value_ = count > zoom_in_value_ ? count : zoom_in_value_;
|
||||
count = 0;
|
||||
while (ny_tmp != 0.0 && std::fabs(ny_tmp) < ZOOM_IN_THRESHOLD) {
|
||||
ny_tmp *= 10;
|
||||
count++;
|
||||
}
|
||||
zoom_in_value_ = count > zoom_in_value_ ? count : zoom_in_value_;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -22,22 +22,19 @@ class ObGeoNormalizeVisitor : public ObEmptyGeoVisitor
|
||||
{
|
||||
public:
|
||||
ObGeoNormalizeVisitor(const ObSrsItem *srs, bool no_srs = false)
|
||||
: srs_(srs), no_srs_(no_srs), zoom_in_value_(0) {}
|
||||
: srs_(srs), no_srs_(no_srs) {}
|
||||
virtual ~ObGeoNormalizeVisitor() {}
|
||||
bool prepare(ObGeometry *geo);
|
||||
int visit(ObIWkbGeogPoint *geo);
|
||||
int visit(ObIWkbGeomPoint *geo);
|
||||
int visit(ObIWkbGeometry *geo) { UNUSED(geo); return OB_SUCCESS; }
|
||||
uint32_t get_zoom_in_value() { return zoom_in_value_; }
|
||||
|
||||
private:
|
||||
int normalize(ObIWkbPoint *geo);
|
||||
|
||||
private:
|
||||
static constexpr double ZOOM_IN_THRESHOLD = 0.00000001;
|
||||
const ObSrsItem *srs_;
|
||||
bool no_srs_; // for st_transform, only proj4text is given
|
||||
uint32_t zoom_in_value_;
|
||||
DISALLOW_COPY_AND_ASSIGN(ObGeoNormalizeVisitor);
|
||||
};
|
||||
|
||||
|
@ -61,7 +61,9 @@ int ObGeoToTreeVisitor::create_geo_tree_collection(T_IBIN *i_geo)
|
||||
LOG_WARN("failed to alloc tree geog geo string", K(ret));
|
||||
} else {
|
||||
geo = new(geo)T(i_geo->get_srid(), *allocator_);
|
||||
if (OB_FAIL(update_root_and_parent(geo))) {
|
||||
if (OB_FAIL(geo->reserve(i_geo->size()))) {
|
||||
LOG_WARN("fail to reserve size", K(ret), K(i_geo->size()));
|
||||
} else if (OB_FAIL(update_root_and_parent(geo))) {
|
||||
LOG_WARN("failed to update parent", K(ret));
|
||||
} else if (OB_FAIL(parent_.push_back(geo))) {
|
||||
LOG_WARN("failed to set self to parent", K(ret));
|
||||
@ -80,6 +82,9 @@ int ObGeoToTreeVisitor::create_geo_multi_point(T_TREE *&geo, T_IBIN *geo_ibin)
|
||||
LOG_WARN("geo value is null", K(ret));
|
||||
} else {
|
||||
geo = new(geo)T_TREE(geo_ibin->get_srid(), *allocator_);
|
||||
if (OB_FAIL(geo->reserve(geo_bin->size()))) {
|
||||
LOG_WARN("fail to reserve size", K(ret), K(geo_bin->size()));
|
||||
}
|
||||
typename T_BIN::iterator iter = geo_bin->begin();
|
||||
for ( ; iter != geo_bin->end() && OB_SUCC(ret); iter++) {
|
||||
T_POINT p(iter->template get<0>(), iter->template get<1>());
|
||||
@ -190,6 +195,11 @@ int ObGeoToTreeVisitor::polygon_visit(p_ibin_type *geo)
|
||||
// construct and add tree exterior ring
|
||||
L_TYPE& tree_ext_ring = polygon->exterior_ring();
|
||||
const L_BIN_TYPE &ext_ring = polygon_bin->exterior_ring();
|
||||
if (OB_FAIL(polygon->reserve(polygon_bin->size()))) {
|
||||
LOG_WARN("fail to reserve size", K(ret), K(polygon_bin->size()));
|
||||
} else if (OB_FAIL(tree_ext_ring.reserve(ext_ring.size()))) {
|
||||
LOG_WARN("fail to reserve size", K(ret), K(ext_ring.size()));
|
||||
}
|
||||
typename L_BIN_TYPE::iterator iter = ext_ring.begin();
|
||||
for ( ; iter != ext_ring.end() && OB_SUCC(ret); iter++) {
|
||||
POINT_TYPE p(iter->template get<0>(), iter->template get<1>());
|
||||
@ -202,19 +212,18 @@ int ObGeoToTreeVisitor::polygon_visit(p_ibin_type *geo)
|
||||
const RINGS_TYPE& inner_rings = polygon_bin->inner_rings();
|
||||
typename RINGS_TYPE::iterator iter = inner_rings.begin();
|
||||
for (; iter != inner_rings.end() && OB_SUCC(ret); iter++) {
|
||||
L_TYPE *tree_linearring = NULL;
|
||||
if (OB_FAIL(alloc_geo_tree_obj(tree_linearring))) {
|
||||
LOG_WARN("failed to alloc tree linearring", K(ret));
|
||||
L_TYPE tree_linearring(geo->get_srid(), *allocator_);
|
||||
if (OB_FAIL(tree_linearring.reserve(iter->size()))) {
|
||||
LOG_WARN("fail to reserve size", K(ret), K(iter->size()));
|
||||
} else {
|
||||
tree_linearring = new(tree_linearring)L_TYPE(geo->get_srid(), *allocator_);
|
||||
typename L_BIN_TYPE::iterator point_iter = iter->begin();
|
||||
for ( ; point_iter != iter->end() && OB_SUCC(ret); point_iter++) {
|
||||
POINT_TYPE p(point_iter->template get<0>(), point_iter->template get<1>());
|
||||
if (OB_FAIL(tree_linearring->push_back(p))) {
|
||||
if (OB_FAIL(tree_linearring.push_back(p))) {
|
||||
LOG_WARN("failed to push point to ring", K(ret));
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret) && OB_FAIL(polygon->push_back(*tree_linearring))) {
|
||||
if (OB_SUCC(ret) && OB_FAIL(polygon->push_back(tree_linearring))) {
|
||||
LOG_WARN("failed to push ring to polygon", K(ret));
|
||||
}
|
||||
}
|
||||
|
22
deps/oblib/src/lib/geo/ob_geo_to_tree_visitor.h
vendored
22
deps/oblib/src/lib/geo/ob_geo_to_tree_visitor.h
vendored
@ -24,10 +24,7 @@ class ObGeoToTreeVisitor : public ObEmptyGeoVisitor
|
||||
public:
|
||||
ObGeoToTreeVisitor(ObIAllocator *allocator)
|
||||
: allocator_(allocator), root_(NULL),
|
||||
page_allocator_(*allocator, common::ObModIds::OB_MODULE_PAGE_ALLOCATOR),
|
||||
mode_arena_(DEFAULT_PAGE_SIZE_GEO, page_allocator_),
|
||||
parent_(&mode_arena_, common::ObModIds::OB_MODULE_PAGE_ALLOCATOR) {}
|
||||
virtual ~ObGeoToTreeVisitor() { parent_.clear(); }
|
||||
parent_(GEOM_PAGE_SIZE_GEO, ModulePageAllocator(*allocator, "GISModule")) {}
|
||||
ObGeometry *get_geometry() const { return root_; }
|
||||
template<typename T>
|
||||
int alloc_geo_tree_obj(T *&obj);
|
||||
@ -71,21 +68,18 @@ public:
|
||||
bool is_end(ObIWkbGeogPolygon *geo) override { UNUSED(geo); return true; }
|
||||
bool is_end(ObIWkbGeomPolygon *geo) override { UNUSED(geo); return true; }
|
||||
|
||||
int finish(ObIWkbGeogMultiLineString *geo) override { UNUSED(geo); return parent_.remove(parent_.last()); }
|
||||
int finish(ObIWkbGeomMultiLineString *geo) override { UNUSED(geo); return parent_.remove(parent_.last()); }
|
||||
int finish(ObIWkbGeogMultiPolygon *geo) override { UNUSED(geo); return parent_.remove(parent_.last()); }
|
||||
int finish(ObIWkbGeomMultiPolygon *geo) override { UNUSED(geo); return parent_.remove(parent_.last()); }
|
||||
int finish(ObIWkbGeogCollection *geo) override { UNUSED(geo); return parent_.remove(parent_.last()); }
|
||||
int finish(ObIWkbGeomCollection *geo) override { UNUSED(geo); return parent_.remove(parent_.last()); }
|
||||
int finish(ObIWkbGeogMultiLineString *geo) override { UNUSED(geo); parent_.pop_back(); return OB_SUCCESS; }
|
||||
int finish(ObIWkbGeomMultiLineString *geo) override { UNUSED(geo); parent_.pop_back(); return OB_SUCCESS; }
|
||||
int finish(ObIWkbGeogMultiPolygon *geo) override { UNUSED(geo); parent_.pop_back(); return OB_SUCCESS; }
|
||||
int finish(ObIWkbGeomMultiPolygon *geo) override { UNUSED(geo); parent_.pop_back(); return OB_SUCCESS; }
|
||||
int finish(ObIWkbGeogCollection *geo) override { UNUSED(geo); parent_.pop_back(); return OB_SUCCESS; }
|
||||
int finish(ObIWkbGeomCollection *geo) override { UNUSED(geo); parent_.pop_back(); return OB_SUCCESS; }
|
||||
|
||||
|
||||
private:
|
||||
typedef PageArena<ObGeometrycollection *, ModulePageAllocator> ObCGeoModuleArena;
|
||||
ObIAllocator *allocator_;
|
||||
ObGeometry *root_;
|
||||
ModulePageAllocator page_allocator_;
|
||||
ObCGeoModuleArena mode_arena_;
|
||||
ObVector<ObGeometrycollection *, ObCGeoModuleArena> parent_;
|
||||
ObArray<ObGeometrycollection *> parent_;
|
||||
DISALLOW_COPY_AND_ASSIGN(ObGeoToTreeVisitor);
|
||||
};
|
||||
|
||||
|
77
deps/oblib/src/lib/geo/ob_geo_to_wkt_visitor.cpp
vendored
77
deps/oblib/src/lib/geo/ob_geo_to_wkt_visitor.cpp
vendored
@ -19,6 +19,7 @@
|
||||
#include "lib/charset/ob_dtoa.h"
|
||||
#include "lib/utility/ob_fast_convert.h"
|
||||
#include "lib/geo/ob_geo_utils.h"
|
||||
#include "rpc/obmysql/ob_mysql_global.h"
|
||||
|
||||
|
||||
namespace oceanbase {
|
||||
@ -156,8 +157,12 @@ int ObGeoToWktVisitor::appendInnerPoint(double x, double y)
|
||||
int16_t scale = static_cast<int16_t>(scale_);
|
||||
uint64_t len_x = 0;
|
||||
uint64_t len_y = 0;
|
||||
char *buf_ptr = buffer_.ptr() + buffer_.length();
|
||||
if (OB_FAIL(convert_double_to_str(buf_ptr, buffer_.remain(), x, has_scale_, scale, is_oracle_mode_, len_x))) {
|
||||
char *buf_ptr = nullptr;
|
||||
uint64_t reserve_len = MAX_DIGITS_IN_DOUBLE * 2;
|
||||
if (buffer_.remain() < reserve_len && OB_FAIL(buffer_.reserve(reserve_len))) {
|
||||
LOG_WARN("fail to reserve memory for buffer_", K(ret), K(reserve_len));
|
||||
} else if (FALSE_IT(buf_ptr = buffer_.ptr() + buffer_.length())) {
|
||||
} else if (OB_FAIL(convert_double_to_str(buf_ptr, buffer_.remain(), x, has_scale_, scale, is_oracle_mode_, len_x))) {
|
||||
LOG_WARN("fail to append x to buffer", K(ret), K(x));
|
||||
} else if (OB_FAIL(buffer_.set_length(buffer_.length() + len_x))) {
|
||||
LOG_WARN("fail to set buffer len", K(ret), K(buffer_.length()), K(len_x));
|
||||
@ -176,13 +181,15 @@ template<typename T_IBIN>
|
||||
int ObGeoToWktVisitor::appendPoint(T_IBIN *geo)
|
||||
{
|
||||
INIT_SUCC(ret);
|
||||
const char *type_name = ObGeoTypeUtil::get_geo_name_by_type(geo->type());
|
||||
uint64_t reserve_len = MAX_DIGITS_IN_DOUBLE * 2 + 3;
|
||||
uint64_t reserve_len = PREPARE_DIGITS_IN_DOUBLE * 2 + 4; // two points + "(" ")" ","
|
||||
if (in_multi_visit_) {
|
||||
reserve_len += strlen("POINT");
|
||||
}
|
||||
// [type_name][(][x][ ][y][)]
|
||||
if (OB_FAIL(buffer_.reserve(reserve_len))) {
|
||||
LOG_WARN("fail to reserve memory for buffer_", K(ret), K(reserve_len));
|
||||
} else if (!in_multi_visit_ && OB_FAIL(appendTypeNameWithMode(geo))) {
|
||||
LOG_WARN("fail to append buffer_", K(ret), K(in_multi_visit_), K(type_name));
|
||||
LOG_WARN("fail to append buffer_", K(ret), K(in_multi_visit_));
|
||||
} else if (OB_FAIL(buffer_.append("("))) {
|
||||
LOG_WARN("fail to append buffer_", K(ret));
|
||||
} else if (OB_FAIL(appendInnerPoint(geo->x(), geo->y()))) {
|
||||
@ -200,14 +207,15 @@ int ObGeoToWktVisitor::appendLine(T_IBIN *geo)
|
||||
{
|
||||
INIT_SUCC(ret);
|
||||
uint64_t size = geo->size();
|
||||
uint64_t reserve_len = (MAX_DIGITS_IN_DOUBLE * 2 + 1) * size;
|
||||
const char *type_name = ObGeoTypeUtil::get_geo_name_by_type(geo->type());
|
||||
reserve_len += in_multi_visit_ ? 0 : 2;
|
||||
uint64_t reserve_len = 2 + (PREPARE_DIGITS_IN_DOUBLE + 1) * size;
|
||||
if (in_multi_visit_) {
|
||||
reserve_len += strlen("LINESTRING");
|
||||
}
|
||||
// [type_name][(][x1][ ][y1][,][x2][ ][y2][)]
|
||||
if (OB_FAIL(buffer_.reserve(reserve_len))) {
|
||||
LOG_WARN("fail to reserve memory for buffer_", K(ret), K(reserve_len));
|
||||
} else if (!in_multi_visit_ && OB_FAIL(appendTypeNameWithMode(geo))) {
|
||||
LOG_WARN("fail to append buffer_", K(ret), K(in_multi_visit_), K(type_name));
|
||||
LOG_WARN("fail to append buffer_", K(ret), K(in_multi_visit_));
|
||||
} else if (OB_FAIL(buffer_.append("("))) {
|
||||
LOG_WARN("fail to append buffer_", K(ret));
|
||||
} else {
|
||||
@ -232,13 +240,39 @@ int ObGeoToWktVisitor::appendLine(T_IBIN *geo)
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Assume that each number has a length of PREPARE_DIGITS_IN_DOUBLE
|
||||
// to estimate polygon wkt lenth, not true length
|
||||
template<typename T_IBIN, typename T_BIN,
|
||||
typename T_BIN_RING, typename T_BIN_INNER_RING>
|
||||
int ObGeoToWktVisitor::estimate_polygon_len(T_IBIN *geo)
|
||||
{
|
||||
T_BIN& poly = *(T_BIN *)(geo->val());
|
||||
uint32_t ring_sz = poly.size();
|
||||
int reserve_len = ring_sz * 3; // "()," = 3
|
||||
uint32_t point_num = 0;
|
||||
if (in_multi_visit_) {
|
||||
reserve_len += strlen("POLYGON");
|
||||
}
|
||||
if (ring_sz > 0) {
|
||||
T_BIN_RING& exterior = poly.exterior_ring();
|
||||
point_num += exterior.size();
|
||||
T_BIN_INNER_RING& inner_rings = poly.inner_rings();
|
||||
typename T_BIN_INNER_RING::iterator iterInnerRing = inner_rings.begin();
|
||||
for (; iterInnerRing != inner_rings.end(); ++iterInnerRing) {
|
||||
point_num += inner_rings.size();
|
||||
}
|
||||
reserve_len += point_num * (PREPARE_DIGITS_IN_DOUBLE + 1);
|
||||
}
|
||||
return reserve_len;
|
||||
}
|
||||
|
||||
template<typename T_IBIN, typename T_BIN,
|
||||
typename T_BIN_RING, typename T_BIN_INNER_RING>
|
||||
int ObGeoToWktVisitor::appendPolygon(T_IBIN *geo)
|
||||
{
|
||||
INIT_SUCC(ret);
|
||||
const char *type_name = ObGeoTypeUtil::get_geo_name_by_type(geo->type());
|
||||
uint64_t reserve_len = 2;
|
||||
uint64_t reserve_len = estimate_polygon_len<T_IBIN, T_BIN, T_BIN_RING, T_BIN_INNER_RING>(geo);
|
||||
// [type_name][(][(][x1][ ][y1][,][x2][ ][y2][,][x3][ ][y3][)][)]
|
||||
if (geo->length() < WKB_COMMON_WKB_HEADER_LEN) {
|
||||
ret = OB_ERR_GIS_INVALID_DATA;
|
||||
@ -256,9 +290,7 @@ int ObGeoToWktVisitor::appendPolygon(T_IBIN *geo)
|
||||
if (poly.size() != 0) {
|
||||
typename T_BIN_RING::iterator iter = exterior.begin();
|
||||
// [(][x1][ ][y1][,][x2][ ][y2][,][x3][ ][y3][)]
|
||||
if (OB_FAIL(buffer_.reserve(reserve_len))) {
|
||||
LOG_WARN("fail to reserve memory for buffer_", K(ret), K(reserve_len));
|
||||
} else if (OB_FAIL(buffer_.append("("))) {
|
||||
if (OB_FAIL(buffer_.append("("))) {
|
||||
LOG_WARN("fail to append buffer_", K(ret));
|
||||
}
|
||||
for (; OB_SUCC(ret) && iter != exterior.end(); ++iter) {
|
||||
@ -281,11 +313,8 @@ int ObGeoToWktVisitor::appendPolygon(T_IBIN *geo)
|
||||
typename T_BIN_INNER_RING::iterator iterInnerRing = inner_rings.begin();
|
||||
for (; OB_SUCC(ret) && iterInnerRing != inner_rings.end(); ++iterInnerRing) {
|
||||
uint32_t size = iterInnerRing->size();
|
||||
uint64_t ring_len = 1 + (MAX_DIGITS_IN_DOUBLE * 2 + 1) * size + 1;
|
||||
typename T_BIN_RING::iterator iter = (*iterInnerRing).begin();
|
||||
if (OB_FAIL(buffer_.reserve(ring_len))) {
|
||||
LOG_WARN("fail to reserve memory for buffer_", K(ret), K(reserve_len));
|
||||
} else if (OB_FAIL(buffer_.append("("))) {
|
||||
if (OB_FAIL(buffer_.append("("))) {
|
||||
LOG_WARN("fail to append buffer_", K(ret));
|
||||
}
|
||||
for (; OB_SUCC(ret) && iter != (*iterInnerRing).end(); ++iter) {
|
||||
@ -322,7 +351,7 @@ int ObGeoToWktVisitor::appendMultiPrefix(T_IBIN *geo)
|
||||
{
|
||||
INIT_SUCC(ret);
|
||||
const char *type_name = ObGeoTypeUtil::get_geo_name_by_type(geo->type());
|
||||
uint64_t reserve_len = 2;
|
||||
uint64_t reserve_len = 2 + strlen(type_name);
|
||||
// [type_name][(][x][ ][y][)]
|
||||
if (OB_FAIL(buffer_.reserve(reserve_len))) {
|
||||
LOG_WARN("fail to reserve memory for buffer_", K(ret), K(reserve_len));
|
||||
@ -644,7 +673,7 @@ int ObGeoToWktVisitor::init(uint32_t srid, int64_t maxdecimaldigits, bool output
|
||||
LOG_WARN("fail to append buffer_", K(ret));
|
||||
} else if (srid == UINT32_MAX && OB_FAIL(buffer_.append("NULL"))) {
|
||||
LOG_WARN("fail to append buffer_", K(ret));
|
||||
} else if (srid != UINT32_MAX && OB_FAIL(buffer_.append(ffi.ptr(), ffi.length()))) {
|
||||
} else if (srid != UINT32_MAX && OB_FAIL(buffer_.append(ffi.ptr(), ffi.length(), 0))) {
|
||||
LOG_WARN("fail to append buffer_", K(ret), K(ffi.length()));
|
||||
} else if (OB_FAIL(buffer_.append(";"))) {
|
||||
LOG_WARN("fail to append buffer_", K(ret));
|
||||
@ -665,9 +694,7 @@ int ObGeoToWktVisitor::appendCommaWithMode() {
|
||||
// oracle [,][ ]
|
||||
// mysql [,]
|
||||
uint64_t reserve_len = is_oracle_mode_ ? 2 : 1;
|
||||
if (OB_FAIL(buffer_.reserve(reserve_len))) {
|
||||
LOG_WARN("fail to reserve memory for buffer_", K(ret), K(reserve_len));
|
||||
} else if (OB_FAIL(buffer_.append(","))) {
|
||||
if (OB_FAIL(buffer_.append(","))) {
|
||||
LOG_WARN("fail to append buffer_", K(ret), K(is_oracle_mode_));
|
||||
} else if (is_oracle_mode_ && OB_FAIL(buffer_.append(" "))) {
|
||||
LOG_WARN("fail to append buffer_", K(ret), K(is_oracle_mode_));
|
||||
@ -682,12 +709,8 @@ int ObGeoToWktVisitor::appendTypeNameWithMode(T_IBIN *geo) {
|
||||
// oracle [typename][ ]
|
||||
// mysql [typename]
|
||||
const char *type_name = ObGeoTypeUtil::get_geo_name_by_type(geo->type());
|
||||
uint64_t reserve_len = strlen(type_name);
|
||||
reserve_len += is_oracle_mode_ ? 1 : 0;
|
||||
|
||||
if (OB_FAIL(buffer_.reserve(reserve_len))) {
|
||||
LOG_WARN("fail to reserve memory for buffer_", K(ret), K(reserve_len));
|
||||
} else if (OB_FAIL(buffer_.append(type_name))) {
|
||||
if (OB_FAIL(buffer_.append(type_name))) {
|
||||
LOG_WARN("fail to append buffer_", K(ret), K(type_name));
|
||||
} else if (is_oracle_mode_ && OB_FAIL(buffer_.append(" "))) {
|
||||
LOG_WARN("fail to append buffer_", K(ret), K(is_oracle_mode_));
|
||||
|
@ -24,6 +24,7 @@ class ObGeoToWktVisitor : public ObEmptyGeoVisitor
|
||||
{
|
||||
public:
|
||||
static const int MAX_DIGITS_IN_DOUBLE = 25;
|
||||
static const int PREPARE_DIGITS_IN_DOUBLE = 15;
|
||||
explicit ObGeoToWktVisitor(ObIAllocator *allocator)
|
||||
: buffer_(allocator),
|
||||
has_scale_(false),
|
||||
@ -97,6 +98,10 @@ private:
|
||||
template<typename T_IBIN>
|
||||
int appendTypeNameWithMode(T_IBIN *geo);
|
||||
|
||||
template<typename T_IBIN, typename T_BIN,
|
||||
typename T_BIN_RING, typename T_BIN_INNER_RING>
|
||||
int estimate_polygon_len(T_IBIN *geo);
|
||||
|
||||
public:
|
||||
static int convert_double_to_str(char* buff, uint64_t buff_size, double val, bool has_scale,
|
||||
int16_t scale, bool is_oracle_mode, uint64_t &out_len);
|
||||
|
64
deps/oblib/src/lib/geo/ob_geo_tree.cpp
vendored
64
deps/oblib/src/lib/geo/ob_geo_tree.cpp
vendored
@ -80,6 +80,12 @@ int ObCartesianPolygon::push_back(const ObLinearring &ring)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObCartesianPolygon::reserve(int64_t capacity)
|
||||
{
|
||||
int ret = capacity > 0 ? inner_rings_.reserve(capacity - 1) : OB_SUCCESS;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObGeographPolygon::push_back(const ObLinearring &ring)
|
||||
{
|
||||
INIT_SUCC(ret);
|
||||
@ -93,6 +99,12 @@ int ObGeographPolygon::push_back(const ObLinearring &ring)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObGeographPolygon::reserve(int64_t capacity)
|
||||
{
|
||||
int ret = capacity > 0 ? inner_rings_.reserve(capacity - 1) : OB_SUCCESS;
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <typename GeometryT,
|
||||
typename CartesianT,
|
||||
typename GeographT>
|
||||
@ -370,6 +382,58 @@ void ObCartesianBox::set_box(double min_x, double min_y, double max_x, double ma
|
||||
max_p_.set<1>(max_y);
|
||||
}
|
||||
|
||||
int ObCartesianGeometrycollection::set(uint32_t index, ObGeometry *geo)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (index >= geoms_.size()) {
|
||||
ret = OB_ERR_ARGUMENT_OUT_OF_RANGE;
|
||||
LOG_WARN("index is out of range", K(ret), K(index), K(geoms_.size()));
|
||||
} else {
|
||||
geoms_[index] = geo;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObGeographGeometrycollection::set(uint32_t index, ObGeometry *geo)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (index >= geoms_.size()) {
|
||||
ret = OB_ERR_ARGUMENT_OUT_OF_RANGE;
|
||||
LOG_WARN("index is out of range", K(ret), K(index), K(geoms_.size()));
|
||||
} else {
|
||||
geoms_[index] = geo;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObCartesianGeometrycollection::resize(int64_t size) {
|
||||
int ret = OB_SUCCESS;
|
||||
if (size > geoms_.size()) {
|
||||
if (OB_FAIL(geoms_.prepare_allocate(size))) {
|
||||
OB_LOG(WARN, "failed to resize ObGeomVector", K(ret), K(size));
|
||||
}
|
||||
} else {
|
||||
while (size != geoms_.size()) {
|
||||
geoms_.pop_back();
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObGeographGeometrycollection::resize(int64_t size) {
|
||||
int ret = OB_SUCCESS;
|
||||
if (size > geoms_.size()) {
|
||||
if (OB_FAIL(geoms_.prepare_allocate(size))) {
|
||||
OB_LOG(WARN, "failed to resize ObGeomVector", K(ret), K(size));
|
||||
}
|
||||
} else {
|
||||
while (size != geoms_.size()) {
|
||||
geoms_.pop_back();
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool ObCartesianBox::Contains(ObCartesianBox &other)
|
||||
{
|
||||
double this_min_x = min_corner().get<0>();
|
||||
|
256
deps/oblib/src/lib/geo/ob_geo_tree.h
vendored
256
deps/oblib/src/lib/geo/ob_geo_tree.h
vendored
@ -21,13 +21,18 @@
|
||||
|
||||
namespace oceanbase {
|
||||
namespace common {
|
||||
static const int64_t DEFAULT_PAGE_SIZE_GEO = 8192;
|
||||
static const int64_t POINT_PAGE_SIZE_GEO = 512; // 32 point
|
||||
static const int64_t LINE_PAGE_SIZE_GEO = 1024; // 8 line
|
||||
static const int64_t POLY_PAGE_SIZE_GEO = 2048; // 8 poly
|
||||
static const int64_t GEOM_PAGE_SIZE_GEO = 512; // 128 geometry *
|
||||
|
||||
class ObIGeoVisitor;
|
||||
|
||||
template <typename T>
|
||||
class ObGeomConstIterator : public array::Iterator<common::ObArray<T, ModulePageAllocator, true>, T>
|
||||
class ObGeomConstIterator : public array::Iterator<common::ObArray<T, ModulePageAllocator, false>, T>
|
||||
{
|
||||
typedef array::Iterator<common::ObArray<T, ModulePageAllocator, true>, T> base_t;
|
||||
typedef array::Iterator<common::ObArray<T, ModulePageAllocator, false>, T> base_t;
|
||||
typedef ObGeomConstIterator<T> self_t;
|
||||
public:
|
||||
typedef typename std::random_access_iterator_tag iterator_category;
|
||||
@ -128,7 +133,7 @@ class ObGeomVector
|
||||
public:
|
||||
typedef T value_type;
|
||||
typedef ObGeomConstIterator<T> const_iterator;
|
||||
typedef typename ObArray<T, ModulePageAllocator, true>::iterator iterator;
|
||||
typedef typename ObArray<T, ModulePageAllocator, false>::iterator iterator;
|
||||
typedef int64_t size_type;
|
||||
typedef const T *const_pointer;
|
||||
typedef const T &const_reference;
|
||||
@ -137,8 +142,8 @@ public:
|
||||
typedef int64_t difference_type;
|
||||
|
||||
public:
|
||||
ObGeomVector(ModulePageAllocator &page_allocator)
|
||||
: vec_(OB_MALLOC_NORMAL_BLOCK_SIZE, page_allocator) {}
|
||||
ObGeomVector(const ModulePageAllocator &page_allocator, int64_t block_size = DEFAULT_PAGE_SIZE_GEO)
|
||||
: vec_(block_size, page_allocator) {}
|
||||
ObGeomVector(const ObGeomVector<T> &v) = default;
|
||||
ObGeomVector<T> &operator=(const ObGeomVector<T> &rhs) = default;
|
||||
~ObGeomVector() {};
|
||||
@ -147,18 +152,20 @@ public:
|
||||
size_type size() const { return vec_.size(); }
|
||||
bool empty() const { return vec_.size() == 0;}
|
||||
void pop_front() { vec_.remove(0); }
|
||||
void resize(int32_t size) {
|
||||
int resize(int64_t size) {
|
||||
int ret = OB_SUCCESS;
|
||||
if (size > vec_.size()) {
|
||||
if (OB_FAIL(vec_.prepare_allocate(size))) {
|
||||
OB_LOG(WARN, "failed to resize ObGeomVector", K(ret));
|
||||
OB_LOG(WARN, "failed to resize ObGeomVector", K(ret), K(size));
|
||||
}
|
||||
} else {
|
||||
while (size != vec_.size()) {
|
||||
vec_.pop_back();
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
int reserve(int64_t capacity) { return vec_.reserve(capacity); }
|
||||
void clear() { vec_.reuse(); }
|
||||
value_type &back() { return *(vec_.end()-1); }
|
||||
const value_type &back() const { return *(vec_.end()-1); };
|
||||
@ -168,14 +175,14 @@ public:
|
||||
const value_type &operator[](int64_t i) const { return vec_[i]; }
|
||||
// iterator
|
||||
iterator begin() { return vec_.begin(); }
|
||||
const_iterator begin() const { return const_iterator(&*(const_cast<common::ObArray<T, ModulePageAllocator, true> *>(&vec_))->begin()); }
|
||||
const_iterator begin() const { return const_iterator(&*(const_cast<common::ObArray<T, ModulePageAllocator, false> *>(&vec_))->begin()); }
|
||||
iterator end() { return vec_.end(); }
|
||||
const_iterator end() const { return const_iterator(&*(const_cast<common::ObArray<T, ModulePageAllocator, true> *>(&vec_))->end()); }
|
||||
// ObArray<T, ModulePageAllocator, true>& get_vec_() const { return vec_; }
|
||||
const_iterator end() const { return const_iterator(&*(const_cast<common::ObArray<T, ModulePageAllocator, false> *>(&vec_))->end()); }
|
||||
// ObArray<T, ModulePageAllocator, false>& get_vec_() const { return vec_; }
|
||||
int remove(int64_t idx) { return vec_.remove(idx); }
|
||||
|
||||
private:
|
||||
common::ObArray<T, ModulePageAllocator, true> vec_;
|
||||
common::ObArray<T, ModulePageAllocator, false> vec_;
|
||||
};
|
||||
|
||||
// ObPoint is an abstract class
|
||||
@ -183,8 +190,8 @@ class ObPoint : public ObGeometry
|
||||
{
|
||||
public:
|
||||
// constructor
|
||||
ObPoint(uint32_t srid = 0, ObIAllocator *allocator = NULL) :
|
||||
ObGeometry(srid, allocator) {};
|
||||
ObPoint(uint32_t srid = 0) :
|
||||
ObGeometry(srid) {};
|
||||
~ObPoint() {};
|
||||
ObPoint(const ObPoint&) = default;
|
||||
ObPoint &operator=(const ObPoint&) = default;
|
||||
@ -210,12 +217,12 @@ public:
|
||||
class ObCartesianPoint : public ObPoint
|
||||
{
|
||||
public:
|
||||
// constructor
|
||||
ObCartesianPoint(uint32_t srid = 0, ObIAllocator *allocator = NULL) : ObPoint(srid, allocator) {
|
||||
// constructor, allocator is not used, just for compatible with other tree constructors
|
||||
ObCartesianPoint(uint32_t srid = 0, ObIAllocator *allocator = NULL) : ObPoint(srid) {
|
||||
point_.set<0>(std::nan(""));
|
||||
point_.set<1>(std::nan(""));
|
||||
};
|
||||
ObCartesianPoint(double x, double y, uint32_t srid = 0, ObIAllocator *allocator = NULL) : ObPoint(srid, allocator) {
|
||||
ObCartesianPoint(double x, double y, uint32_t srid = 0) : ObPoint(srid) {
|
||||
point_.set<0>(x);
|
||||
point_.set<1>(y);
|
||||
};
|
||||
@ -245,11 +252,11 @@ class ObGeographPoint : public ObPoint
|
||||
{
|
||||
public:
|
||||
// constructor
|
||||
ObGeographPoint(uint32_t srid = 0, ObIAllocator *allocator = NULL) : ObPoint(srid, allocator) {
|
||||
ObGeographPoint(uint32_t srid = 0, ObIAllocator *allocator = NULL) : ObPoint(srid) {
|
||||
point_.set<0>(std::nan(""));
|
||||
point_.set<1>(std::nan(""));
|
||||
};
|
||||
ObGeographPoint(double x, double y, uint32_t srid = 0, ObIAllocator *allocator = NULL) : ObPoint(srid, allocator) {
|
||||
ObGeographPoint(double x, double y, uint32_t srid = 0) : ObPoint(srid) {
|
||||
point_.set<0>(x);
|
||||
point_.set<1>(y);
|
||||
};
|
||||
@ -281,16 +288,16 @@ class ObCurve : public ObGeometry
|
||||
public:
|
||||
// do nothing
|
||||
// constructor
|
||||
ObCurve(uint32_t srid = 0, ObIAllocator *allocator = NULL) :
|
||||
ObGeometry(srid, allocator){};
|
||||
ObCurve(uint32_t srid = 0) :
|
||||
ObGeometry(srid){};
|
||||
~ObCurve() {};
|
||||
};
|
||||
|
||||
class ObLineString : public ObCurve
|
||||
{
|
||||
public:
|
||||
ObLineString(uint32_t srid = 0, ObIAllocator *allocator = NULL)
|
||||
: ObCurve(srid, allocator)
|
||||
ObLineString(uint32_t srid = 0)
|
||||
: ObCurve(srid)
|
||||
{}
|
||||
|
||||
~ObLineString() {}
|
||||
@ -309,7 +316,7 @@ public:
|
||||
ObIAllocator &allocator, ObLineString*& output);
|
||||
};
|
||||
|
||||
static const int64_t DEFAULT_PAGE_SIZE_GEO = 8192;
|
||||
|
||||
class ObCartesianLineString : public ObLineString
|
||||
{
|
||||
public:
|
||||
@ -319,14 +326,12 @@ public:
|
||||
typedef ObGeomVector<ObWkbGeomInnerPoint>::const_iterator const_iterator;
|
||||
public:
|
||||
ObCartesianLineString(uint32_t srid, ObIAllocator &allocator)
|
||||
: ObLineString(srid, &allocator),
|
||||
page_allocator_(allocator, common::ObModIds::OB_MODULE_PAGE_ALLOCATOR),
|
||||
points_(page_allocator_) {}
|
||||
: ObLineString(srid),
|
||||
points_(ModulePageAllocator(allocator, "GISModule"), POINT_PAGE_SIZE_GEO) {}
|
||||
|
||||
ObCartesianLineString()
|
||||
: ObLineString(0, NULL),
|
||||
page_allocator_(),
|
||||
points_(page_allocator_) {}
|
||||
: ObLineString(0),
|
||||
points_(ModulePageAllocator(CURRENT_CONTEXT->get_arena_allocator(), "GISModule"), POINT_PAGE_SIZE_GEO) {}
|
||||
|
||||
ObCartesianLineString(const ObCartesianLineString&) = default;
|
||||
ObCartesianLineString &operator=(const ObCartesianLineString&) = default;
|
||||
@ -341,7 +346,7 @@ public:
|
||||
int push_back(const ObWkbGeomInnerPoint& point) { return points_.push_back(point); }
|
||||
int64_t size() const override { return points_.size(); }
|
||||
void pop_front() override { points_.pop_front(); }
|
||||
void resize(int32_t size) { points_.resize(size); }
|
||||
int resize(int64_t size) { return points_.resize(size); }
|
||||
void clear() override { points_.clear(); }
|
||||
ObWkbGeomInnerPoint &back() { return points_.back(); }
|
||||
const ObWkbGeomInnerPoint &back() const { return points_.back(); }
|
||||
@ -357,11 +362,11 @@ public:
|
||||
const_iterator end() const { return points_.end(); }
|
||||
const ObGeomVector<ObWkbGeomInnerPoint> &get_points() const {return points_;}
|
||||
ObGeomVector<ObWkbGeomInnerPoint> &get_points() {return points_;}
|
||||
int reserve(int64_t capacity) { return points_.reserve(capacity); }
|
||||
TO_STRING_KV("type", "ObCartesianLineString",
|
||||
"size", size());
|
||||
|
||||
private:
|
||||
ModulePageAllocator page_allocator_;
|
||||
ObGeomVector<ObWkbGeomInnerPoint> points_;
|
||||
};
|
||||
|
||||
@ -373,14 +378,12 @@ public:
|
||||
typedef ObGeomVector<ObWkbGeogInnerPoint>::const_iterator const_iterator;
|
||||
public:
|
||||
ObGeographLineString(uint32_t srid, ObIAllocator &allocator)
|
||||
: ObLineString(srid, &allocator),
|
||||
page_allocator_(allocator, common::ObModIds::OB_MODULE_PAGE_ALLOCATOR),
|
||||
points_(page_allocator_) {}
|
||||
: ObLineString(srid),
|
||||
points_(ModulePageAllocator(allocator, "GISModule"), POINT_PAGE_SIZE_GEO) {}
|
||||
|
||||
ObGeographLineString()
|
||||
: ObLineString(0, NULL),
|
||||
page_allocator_(),
|
||||
points_(page_allocator_) {}
|
||||
: ObLineString(0),
|
||||
points_(ModulePageAllocator(CURRENT_CONTEXT->get_arena_allocator(), "GISModule"), POINT_PAGE_SIZE_GEO) {}
|
||||
|
||||
ObGeographLineString(const ObGeographLineString&) = default;
|
||||
ObGeographLineString &operator=(const ObGeographLineString&) = default;
|
||||
@ -394,7 +397,7 @@ public:
|
||||
int push_back(const ObWkbGeogInnerPoint& point) { return points_.push_back(point); }
|
||||
int64_t size() const override { return points_.size(); }
|
||||
void pop_front() override { points_.pop_front(); }
|
||||
void resize(int32_t size) { points_.resize(size); }
|
||||
int resize(int64_t size) { return points_.resize(size); }
|
||||
void clear() override { points_.clear(); }
|
||||
ObWkbGeogInnerPoint &back() { return points_.back(); }
|
||||
const ObWkbGeogInnerPoint &back() const { return points_.back(); }
|
||||
@ -411,11 +414,11 @@ public:
|
||||
const_iterator end() const { return points_.end(); }
|
||||
const ObGeomVector<ObWkbGeogInnerPoint> &get_points() const {return points_;}
|
||||
ObGeomVector<ObWkbGeogInnerPoint> &get_points() {return points_;}
|
||||
int reserve(int64_t capacity) { return points_.reserve(capacity); }
|
||||
TO_STRING_KV("type", "ObGeographLineString",
|
||||
"size", size());
|
||||
|
||||
private:
|
||||
ModulePageAllocator page_allocator_;
|
||||
ObGeomVector<ObWkbGeogInnerPoint> points_;
|
||||
};
|
||||
|
||||
@ -448,7 +451,7 @@ public:
|
||||
bool is_empty() const override { return ObCartesianLineString::is_empty(); }
|
||||
bool empty() const { return ObCartesianLineString::empty(); }
|
||||
void pop_front() override { ObCartesianLineString::pop_front(); }
|
||||
void resize(int32_t size) { ObCartesianLineString::resize(size); }
|
||||
int resize(int64_t size) { return ObCartesianLineString::resize(size); }
|
||||
void clear() override { ObCartesianLineString::clear(); }
|
||||
ObWkbGeomInnerPoint &back() { return ObCartesianLineString::back(); }
|
||||
const ObWkbGeomInnerPoint &back() const { return ObCartesianLineString::back(); };
|
||||
@ -456,6 +459,8 @@ public:
|
||||
const ObWkbGeomInnerPoint &front() const { return ObCartesianLineString::front(); }
|
||||
ObWkbGeomInnerPoint &operator[](int32_t i) { return ObCartesianLineString::operator[](i); }
|
||||
const ObWkbGeomInnerPoint &operator[](int32_t i) const { return ObCartesianLineString::operator[](i); }
|
||||
TO_STRING_KV("type", "ObCartesianLinearring",
|
||||
"size", size());
|
||||
};
|
||||
|
||||
class ObGeographLinearring : public ObGeographLineString, public ObLinearring
|
||||
@ -479,7 +484,7 @@ public:
|
||||
bool is_empty() const override { return ObGeographLineString::is_empty(); }
|
||||
bool empty() const { return ObGeographLineString::empty(); }
|
||||
void pop_front() override { ObGeographLineString::pop_front(); }
|
||||
void resize(int32_t size) { ObGeographLineString::resize(size); }
|
||||
int resize(int64_t size) { return ObGeographLineString::resize(size); }
|
||||
void clear() override { ObGeographLineString::clear(); }
|
||||
ObWkbGeogInnerPoint &back() { return ObGeographLineString::back(); }
|
||||
const ObWkbGeogInnerPoint &back() const { return ObGeographLineString::back(); };
|
||||
@ -487,6 +492,8 @@ public:
|
||||
const ObWkbGeogInnerPoint &front() const { return ObGeographLineString::front(); }
|
||||
ObWkbGeogInnerPoint &operator[](int32_t i) { return ObGeographLineString::operator[](i); }
|
||||
const ObWkbGeogInnerPoint &operator[](int32_t i) const { return ObGeographLineString::operator[](i); }
|
||||
TO_STRING_KV("type", "ObGeographLineString",
|
||||
"size", size());
|
||||
};
|
||||
|
||||
class ObSurface : public ObGeometry
|
||||
@ -494,8 +501,8 @@ class ObSurface : public ObGeometry
|
||||
public:
|
||||
// do nothing
|
||||
// constructor
|
||||
ObSurface(uint32_t srid = 0, ObIAllocator *allocator = NULL) :
|
||||
ObGeometry(srid, allocator){};
|
||||
ObSurface(uint32_t srid = 0) :
|
||||
ObGeometry(srid){};
|
||||
~ObSurface() {};
|
||||
};
|
||||
|
||||
@ -503,8 +510,8 @@ class ObPolygon : public ObSurface
|
||||
{
|
||||
public:
|
||||
// contructor
|
||||
ObPolygon(uint32_t srid = 0, ObIAllocator *allocator = NULL)
|
||||
: ObSurface(srid, allocator)
|
||||
ObPolygon(uint32_t srid = 0)
|
||||
: ObSurface(srid)
|
||||
{}
|
||||
~ObPolygon() {}
|
||||
ObGeoType type() const override { return ObGeoType::POLYGON; }
|
||||
@ -537,16 +544,14 @@ class ObCartesianPolygon : public ObPolygon
|
||||
public:
|
||||
// constructor
|
||||
ObCartesianPolygon(uint32_t srid, ObIAllocator &allocator)
|
||||
: ObPolygon(srid, &allocator),
|
||||
page_allocator_(allocator, common::ObModIds::OB_MODULE_PAGE_ALLOCATOR),
|
||||
: ObPolygon(srid),
|
||||
exterior_(srid, allocator),
|
||||
inner_rings_(page_allocator_) {}
|
||||
inner_rings_(ModulePageAllocator(allocator, "GISModule"), LINE_PAGE_SIZE_GEO) {}
|
||||
|
||||
ObCartesianPolygon()
|
||||
: ObPolygon(),
|
||||
page_allocator_(),
|
||||
exterior_(),
|
||||
inner_rings_(page_allocator_) {}
|
||||
inner_rings_(ModulePageAllocator(CURRENT_CONTEXT->get_arena_allocator(), "GISModule"), LINE_PAGE_SIZE_GEO) {}
|
||||
ObCartesianPolygon(const ObCartesianPolygon &v) = default;
|
||||
ObCartesianPolygon &operator=(const ObCartesianPolygon &rhs) = default;
|
||||
~ObCartesianPolygon() {};
|
||||
@ -567,11 +572,11 @@ public:
|
||||
ObCartesianLinearring &cartesian_exterior_ring() const { return const_cast<ObCartesianLinearring &>(exterior_); }
|
||||
ObGeomVector<ObCartesianLinearring> &interior_rings() { return inner_rings_; }
|
||||
ObGeomVector<ObCartesianLinearring> const &const_interior_rings() const { return inner_rings_; }
|
||||
int reserve(int64_t capacity);
|
||||
TO_STRING_KV("type", "ObCartesianPolygon",
|
||||
"size", size());
|
||||
|
||||
private:
|
||||
ModulePageAllocator page_allocator_;
|
||||
ObCartesianLinearring exterior_;
|
||||
ObGeomVector<ObCartesianLinearring> inner_rings_;
|
||||
};
|
||||
@ -581,16 +586,14 @@ class ObGeographPolygon : public ObPolygon
|
||||
public:
|
||||
// constructor
|
||||
ObGeographPolygon(uint32_t srid, ObIAllocator &allocator)
|
||||
: ObPolygon(srid, &allocator),
|
||||
page_allocator_(allocator, common::ObModIds::OB_MODULE_PAGE_ALLOCATOR),
|
||||
: ObPolygon(srid),
|
||||
exterior_(srid, allocator),
|
||||
inner_rings_(page_allocator_) {}
|
||||
inner_rings_(ModulePageAllocator(allocator, "GISModule"), LINE_PAGE_SIZE_GEO) {}
|
||||
|
||||
ObGeographPolygon()
|
||||
: ObPolygon(0, NULL),
|
||||
page_allocator_(),
|
||||
: ObPolygon(0),
|
||||
exterior_(),
|
||||
inner_rings_(page_allocator_) {}
|
||||
inner_rings_(ModulePageAllocator(CURRENT_CONTEXT->get_arena_allocator(), "GISModule"), LINE_PAGE_SIZE_GEO) {}
|
||||
ObGeographPolygon(const ObGeographPolygon &v) = default;
|
||||
ObGeographPolygon &operator=(const ObGeographPolygon &rhs) = default;
|
||||
~ObGeographPolygon() {};
|
||||
@ -612,11 +615,11 @@ public:
|
||||
ObGeographLinearring &geographic_exterior_ring() const { return const_cast<ObGeographLinearring &>(exterior_); }
|
||||
ObGeomVector<ObGeographLinearring> &interior_rings() { return inner_rings_; }
|
||||
ObGeomVector<ObGeographLinearring> const &const_interior_rings() const { return inner_rings_; }
|
||||
int reserve(int64_t capacity);
|
||||
TO_STRING_KV("type", "ObGeographPolygon",
|
||||
"size", size());
|
||||
|
||||
private:
|
||||
ModulePageAllocator page_allocator_;
|
||||
ObGeographLinearring exterior_;
|
||||
ObGeomVector<ObGeographLinearring> inner_rings_;
|
||||
};
|
||||
@ -625,14 +628,12 @@ class ObGeometrycollection : public ObGeometry
|
||||
{
|
||||
public:
|
||||
// constructor
|
||||
ObGeometrycollection(uint32_t srid, ObIAllocator &allocator)
|
||||
: ObGeometry(srid, &allocator),
|
||||
page_allocator_(allocator, common::ObModIds::OB_MODULE_PAGE_ALLOCATOR)
|
||||
ObGeometrycollection(uint32_t srid)
|
||||
: ObGeometry(srid)
|
||||
{}
|
||||
|
||||
ObGeometrycollection()
|
||||
: ObGeometry(0, NULL),
|
||||
page_allocator_()
|
||||
: ObGeometry(0)
|
||||
{}
|
||||
~ObGeometrycollection() {};
|
||||
|
||||
@ -643,20 +644,18 @@ public:
|
||||
virtual void pop_front() = 0;
|
||||
virtual bool empty() const = 0;
|
||||
virtual uint64_t size() const = 0;
|
||||
virtual void resize(int32_t count) = 0;
|
||||
virtual int resize(int64_t count) = 0;
|
||||
virtual void clear() = 0;
|
||||
virtual int push_back(const ObGeometry &g) = 0;
|
||||
static int create_collection(ObGeoCRS crs, uint32_t srid,
|
||||
ObIAllocator &allocator, ObGeometrycollection*& output);
|
||||
protected:
|
||||
ModulePageAllocator page_allocator_;
|
||||
};
|
||||
|
||||
class ObMultipoint : public ObGeometrycollection
|
||||
{
|
||||
public:
|
||||
ObMultipoint(uint32_t srid, ObIAllocator &allocator) :
|
||||
ObGeometrycollection(srid, allocator){};
|
||||
ObMultipoint(uint32_t srid) :
|
||||
ObGeometrycollection(srid){};
|
||||
|
||||
ObMultipoint() :
|
||||
ObGeometrycollection(){};
|
||||
@ -678,12 +677,12 @@ public:
|
||||
|
||||
public:
|
||||
ObCartesianMultipoint(uint32_t srid, ObIAllocator &allocator)
|
||||
: ObMultipoint(srid, allocator),
|
||||
points_(page_allocator_) {}
|
||||
: ObMultipoint(srid),
|
||||
points_(ModulePageAllocator(allocator, "GISModule"), POINT_PAGE_SIZE_GEO) {}
|
||||
|
||||
ObCartesianMultipoint()
|
||||
: ObMultipoint(),
|
||||
points_(page_allocator_) {}
|
||||
points_(ModulePageAllocator(), POINT_PAGE_SIZE_GEO) {}
|
||||
|
||||
~ObCartesianMultipoint() {}
|
||||
|
||||
@ -701,7 +700,7 @@ public:
|
||||
return true;
|
||||
}
|
||||
uint64_t size() const override { return points_.size(); }
|
||||
void resize(int32_t size) { points_.resize(size); }
|
||||
int resize(int64_t size) { return points_.resize(size); }
|
||||
void clear() override { points_.clear(); }
|
||||
ObWkbGeomInnerPoint &front() { return points_.front(); }
|
||||
const ObWkbGeomInnerPoint &front() const { return points_.front(); }
|
||||
@ -715,6 +714,7 @@ public:
|
||||
const_iterator begin() const { return points_.begin(); }
|
||||
iterator end() { return points_.end(); }
|
||||
const_iterator end() const { return points_.end(); }
|
||||
int reserve(int64_t capacity) { return points_.reserve(capacity); }
|
||||
TO_STRING_KV("type", "ObCartesianMultipoint",
|
||||
"size", size());
|
||||
|
||||
@ -732,12 +732,12 @@ public:
|
||||
|
||||
public:
|
||||
ObGeographMultipoint(uint32_t srid, ObIAllocator &allocator)
|
||||
: ObMultipoint(srid, allocator),
|
||||
points_(page_allocator_) {}
|
||||
: ObMultipoint(srid),
|
||||
points_(ModulePageAllocator(allocator, "GISModule"), POINT_PAGE_SIZE_GEO) {}
|
||||
|
||||
ObGeographMultipoint()
|
||||
: ObMultipoint(),
|
||||
points_(page_allocator_) {}
|
||||
points_(ModulePageAllocator(), POINT_PAGE_SIZE_GEO) {}
|
||||
~ObGeographMultipoint() {}
|
||||
|
||||
ObGeoCRS crs() const override { return ObGeoCRS::Geographic; }
|
||||
@ -754,7 +754,7 @@ public:
|
||||
return true;
|
||||
}
|
||||
uint64_t size() const override { return points_.size(); }
|
||||
void resize(int32_t size) { points_.resize(size); }
|
||||
int resize(int64_t size) { return points_.resize(size); }
|
||||
void clear() override { points_.clear(); }
|
||||
ObWkbGeogInnerPoint &front() { return points_.front(); }
|
||||
const ObWkbGeogInnerPoint &front() const { return points_.front(); }
|
||||
@ -768,6 +768,7 @@ public:
|
||||
const_iterator begin() const { return points_.begin(); }
|
||||
iterator end() { return points_.end(); }
|
||||
const_iterator end() const { return points_.end(); }
|
||||
int reserve(int64_t capacity) { return points_.reserve(capacity); }
|
||||
TO_STRING_KV("type", "ObGeographMultipoint",
|
||||
"size", size());
|
||||
|
||||
@ -781,8 +782,8 @@ class ObMulticurve : public ObGeometrycollection
|
||||
public:
|
||||
// do nothing
|
||||
// constructor
|
||||
ObMulticurve(uint32_t srid, ObIAllocator &allocator) :
|
||||
ObGeometrycollection(srid, allocator){};
|
||||
ObMulticurve(uint32_t srid) :
|
||||
ObGeometrycollection(srid){};
|
||||
ObMulticurve() :
|
||||
ObGeometrycollection(){};
|
||||
~ObMulticurve() {};
|
||||
@ -791,8 +792,8 @@ public:
|
||||
class ObMultilinestring : public ObMulticurve
|
||||
{
|
||||
public:
|
||||
ObMultilinestring(uint32_t srid, ObIAllocator &allocator) :
|
||||
ObMulticurve(srid, allocator){};
|
||||
ObMultilinestring(uint32_t srid) :
|
||||
ObMulticurve(srid){};
|
||||
|
||||
ObMultilinestring() :
|
||||
ObMulticurve(){};
|
||||
@ -813,12 +814,12 @@ public:
|
||||
|
||||
public:
|
||||
ObCartesianMultilinestring(uint32_t srid, ObIAllocator &allocator)
|
||||
: ObMultilinestring(srid, allocator),
|
||||
lines_(page_allocator_) {}
|
||||
: ObMultilinestring(srid),
|
||||
lines_(ModulePageAllocator(allocator, "GISModule"), LINE_PAGE_SIZE_GEO) {}
|
||||
|
||||
ObCartesianMultilinestring()
|
||||
: ObMultilinestring(),
|
||||
lines_(page_allocator_) {}
|
||||
lines_(ModulePageAllocator(), LINE_PAGE_SIZE_GEO) {}
|
||||
|
||||
~ObCartesianMultilinestring() {}
|
||||
// Geometry interface
|
||||
@ -836,7 +837,7 @@ public:
|
||||
return true;
|
||||
}
|
||||
uint64_t size() const override { return lines_.size(); }
|
||||
void resize(int32_t size) { lines_.resize(size); }
|
||||
int resize(int64_t size) { return lines_.resize(size); }
|
||||
void clear() override { lines_.clear(); }
|
||||
ObCartesianLineString &front() { return *(lines_.begin()); }
|
||||
const ObCartesianLineString &front() const { return *(lines_.begin()); }
|
||||
@ -851,6 +852,7 @@ public:
|
||||
iterator end() { return lines_.end(); }
|
||||
const_iterator end() const { return lines_.end(); }
|
||||
int remove(int64_t idx) { return lines_.remove(idx); }
|
||||
int reserve(int64_t capacity) { return lines_.reserve(capacity); }
|
||||
TO_STRING_KV("type", "ObCartesianMultilinestring",
|
||||
"size", size());
|
||||
|
||||
@ -868,12 +870,12 @@ public:
|
||||
|
||||
public:
|
||||
ObGeographMultilinestring(uint32_t srid, ObIAllocator &allocator)
|
||||
: ObMultilinestring(srid, allocator),
|
||||
lines_(page_allocator_) {}
|
||||
: ObMultilinestring(srid),
|
||||
lines_(ModulePageAllocator(allocator, "GISModule"), LINE_PAGE_SIZE_GEO) {}
|
||||
|
||||
ObGeographMultilinestring()
|
||||
: ObMultilinestring(),
|
||||
lines_(page_allocator_) {}
|
||||
lines_(ModulePageAllocator(), LINE_PAGE_SIZE_GEO) {}
|
||||
|
||||
~ObGeographMultilinestring() {}
|
||||
|
||||
@ -893,7 +895,7 @@ public:
|
||||
return true;
|
||||
}
|
||||
uint64_t size() const override { return lines_.size(); }
|
||||
void resize(int32_t size) { lines_.resize(size); }
|
||||
int resize(int64_t size) { return lines_.resize(size); }
|
||||
void clear() override { lines_.clear(); }
|
||||
ObGeographLineString &front() { return *(lines_.begin()); }
|
||||
const ObGeographLineString &front() const { return *(lines_.begin()); }
|
||||
@ -907,6 +909,7 @@ public:
|
||||
const_iterator begin() const { return lines_.begin(); }
|
||||
iterator end() { return lines_.end(); }
|
||||
const_iterator end() const { return lines_.end(); }
|
||||
int reserve(int64_t capacity) { return lines_.reserve(capacity); }
|
||||
TO_STRING_KV("type", "ObGeographMultilinestring",
|
||||
"size", size());
|
||||
|
||||
@ -920,8 +923,8 @@ class ObMultisurface : public ObGeometrycollection
|
||||
public:
|
||||
// do nothing
|
||||
// constructor
|
||||
ObMultisurface(uint32_t srid, ObIAllocator &allocator) :
|
||||
ObGeometrycollection(srid, allocator){};
|
||||
ObMultisurface(uint32_t srid) :
|
||||
ObGeometrycollection(srid){};
|
||||
|
||||
ObMultisurface() :
|
||||
ObGeometrycollection(){};
|
||||
@ -931,8 +934,8 @@ public:
|
||||
class ObMultipolygon : public ObMultisurface
|
||||
{
|
||||
public:
|
||||
ObMultipolygon(uint32_t srid, ObIAllocator &allocator) :
|
||||
ObMultisurface(srid, allocator){};
|
||||
ObMultipolygon(uint32_t srid) :
|
||||
ObMultisurface(srid){};
|
||||
|
||||
ObMultipolygon() :
|
||||
ObMultisurface(){};
|
||||
@ -953,12 +956,12 @@ public:
|
||||
|
||||
public:
|
||||
ObCartesianMultipolygon(uint32_t srid, ObIAllocator &allocator)
|
||||
: ObMultipolygon(srid, allocator),
|
||||
polygons_(page_allocator_) {}
|
||||
: ObMultipolygon(srid),
|
||||
polygons_(ModulePageAllocator(allocator, "GISModule"), POLY_PAGE_SIZE_GEO) {}
|
||||
|
||||
ObCartesianMultipolygon()
|
||||
: ObMultipolygon(),
|
||||
polygons_(page_allocator_) {}
|
||||
polygons_(ModulePageAllocator(), POLY_PAGE_SIZE_GEO) {}
|
||||
|
||||
~ObCartesianMultipolygon() {}
|
||||
|
||||
@ -978,7 +981,7 @@ public:
|
||||
return true;
|
||||
}
|
||||
uint64_t size() const override { return polygons_.size(); }
|
||||
void resize(int32_t size) { polygons_.resize(size); }
|
||||
int resize(int64_t size) { return polygons_.resize(size); }
|
||||
void clear() override { polygons_.clear(); }
|
||||
ObCartesianPolygon &front() { return *(polygons_.begin()); }
|
||||
const ObCartesianPolygon &front() const { return *(polygons_.begin()); }
|
||||
@ -991,6 +994,7 @@ public:
|
||||
const_iterator begin() const { return polygons_.begin(); }
|
||||
iterator end() { return polygons_.end(); }
|
||||
const_iterator end() const { return polygons_.end(); }
|
||||
int reserve(int64_t capacity) { return polygons_.reserve(capacity); }
|
||||
TO_STRING_KV("type", "ObCartesianMultipolygon",
|
||||
"size", size());
|
||||
|
||||
@ -1008,12 +1012,12 @@ public:
|
||||
|
||||
public:
|
||||
ObGeographMultipolygon(uint32_t srid, ObIAllocator &allocator)
|
||||
: ObMultipolygon(srid, allocator),
|
||||
polygons_(page_allocator_) {}
|
||||
: ObMultipolygon(srid),
|
||||
polygons_(ModulePageAllocator(allocator, "GISModule"), POLY_PAGE_SIZE_GEO) {}
|
||||
|
||||
ObGeographMultipolygon()
|
||||
: ObMultipolygon(),
|
||||
polygons_(page_allocator_) {}
|
||||
polygons_(ModulePageAllocator(), POLY_PAGE_SIZE_GEO) {}
|
||||
~ObGeographMultipolygon() {}
|
||||
|
||||
// Geometry interface
|
||||
@ -1032,7 +1036,7 @@ public:
|
||||
return true;
|
||||
}
|
||||
uint64_t size() const override { return polygons_.size(); }
|
||||
void resize(int32_t size) { polygons_.resize(size); }
|
||||
int resize(int64_t size) { return polygons_.resize(size); }
|
||||
void clear() override { polygons_.clear(); }
|
||||
ObGeographPolygon &front() { return *(polygons_.begin()); }
|
||||
const ObGeographPolygon &front() const { return *(polygons_.begin()); }
|
||||
@ -1046,6 +1050,7 @@ public:
|
||||
const_iterator begin() const { return polygons_.begin(); }
|
||||
iterator end() { return polygons_.end(); }
|
||||
const_iterator end() const { return polygons_.end(); }
|
||||
int reserve(int64_t capacity) { return polygons_.reserve(capacity); }
|
||||
TO_STRING_KV("type", "ObGeographMultipolygon",
|
||||
"size", size());
|
||||
|
||||
@ -1157,22 +1162,20 @@ public:
|
||||
|
||||
public:
|
||||
ObCartesianGeometrycollection(uint32_t srid, ObIAllocator &allocator)
|
||||
: ObGeometrycollection(srid, allocator),
|
||||
mode_arena_(DEFAULT_PAGE_SIZE_GEO, page_allocator_),
|
||||
geoms_(&mode_arena_, common::ObModIds::OB_MODULE_PAGE_ALLOCATOR) {}
|
||||
: ObGeometrycollection(srid),
|
||||
geoms_(GEOM_PAGE_SIZE_GEO, ModulePageAllocator(allocator, "GISModule")) {}
|
||||
|
||||
ObCartesianGeometrycollection()
|
||||
: ObGeometrycollection(),
|
||||
mode_arena_(DEFAULT_PAGE_SIZE_GEO, page_allocator_),
|
||||
geoms_(&mode_arena_, common::ObModIds::OB_MODULE_PAGE_ALLOCATOR) {}
|
||||
~ObCartesianGeometrycollection() { geoms_.clear(); }
|
||||
geoms_(GEOM_PAGE_SIZE_GEO, ModulePageAllocator()) {}
|
||||
~ObCartesianGeometrycollection() {}
|
||||
ObGeoCRS crs() const override { return ObGeoCRS::Cartesian; }
|
||||
// visitor interface
|
||||
int do_visit(ObIGeoVisitor &visitor);
|
||||
void pop_front() override {
|
||||
geoms_.remove(geoms_.begin());
|
||||
geoms_.remove(0);
|
||||
}
|
||||
int push_back(const ObGeometry &g) { return geoms_.push_back(&g); }
|
||||
int push_back(const ObGeometry &g) { return geoms_.push_back(&const_cast<ObGeometry &>(g)); }
|
||||
bool empty() const override { return geoms_.size() == 0; }
|
||||
bool is_empty() const override {
|
||||
for (uint64_t i = 0; i < size(); i++) {
|
||||
@ -1183,8 +1186,8 @@ public:
|
||||
return true;
|
||||
}
|
||||
uint64_t size() const override { return geoms_.size(); }
|
||||
void resize(int32_t size) override { geoms_.reserve(size); }
|
||||
void clear() override { geoms_.clear(); }
|
||||
int resize(int64_t size) override;
|
||||
void clear() override { geoms_.reuse(); }
|
||||
|
||||
iterator begin() { return geoms_.begin(); }
|
||||
const_iterator begin() const { return geoms_.begin(); }
|
||||
@ -1200,10 +1203,13 @@ public:
|
||||
return *geoms_[i];
|
||||
}
|
||||
|
||||
int set(uint32_t index, ObGeometry *geo);
|
||||
int reserve(int64_t capacity) { return geoms_.reserve(capacity); }
|
||||
TO_STRING_KV("type", "ObCartesianGeometrycollection",
|
||||
"size", size());
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(ObCartesianGeometrycollection);
|
||||
ObCGeoModuleArena mode_arena_;
|
||||
ObVector<ObGeometry *, ObCGeoModuleArena> geoms_;
|
||||
ObArray<ObGeometry *> geoms_;
|
||||
};
|
||||
|
||||
class ObGeographGeometrycollection : public ObGeometrycollection
|
||||
@ -1219,22 +1225,20 @@ public:
|
||||
|
||||
public:
|
||||
ObGeographGeometrycollection(uint32_t srid, ObIAllocator &allocator)
|
||||
: ObGeometrycollection(srid, allocator),
|
||||
mode_arena_(DEFAULT_PAGE_SIZE_GEO, page_allocator_),
|
||||
geoms_(&mode_arena_, common::ObModIds::OB_MODULE_PAGE_ALLOCATOR) {}
|
||||
: ObGeometrycollection(srid),
|
||||
geoms_(GEOM_PAGE_SIZE_GEO, ModulePageAllocator(allocator, "GISModule")) {}
|
||||
|
||||
ObGeographGeometrycollection()
|
||||
: ObGeometrycollection(),
|
||||
mode_arena_(DEFAULT_PAGE_SIZE_GEO, page_allocator_),
|
||||
geoms_(&mode_arena_, common::ObModIds::OB_MODULE_PAGE_ALLOCATOR) {}
|
||||
~ObGeographGeometrycollection() { geoms_.clear(); }
|
||||
geoms_(GEOM_PAGE_SIZE_GEO, ModulePageAllocator()) {}
|
||||
~ObGeographGeometrycollection() {}
|
||||
ObGeoCRS crs() const override { return ObGeoCRS::Geographic; }
|
||||
// visitor interface
|
||||
int do_visit(ObIGeoVisitor &visitor);
|
||||
void pop_front() override {
|
||||
geoms_.remove(geoms_.begin());
|
||||
geoms_.remove(0);
|
||||
}
|
||||
int push_back(const ObGeometry &g) { return geoms_.push_back(&g); }
|
||||
int push_back(const ObGeometry &g) { return geoms_.push_back(&const_cast<ObGeometry &>(g)); }
|
||||
bool empty() const override { return geoms_.size() == 0; }
|
||||
bool is_empty() const override {
|
||||
for (uint64_t i = 0; i < size(); i++) {
|
||||
@ -1245,8 +1249,8 @@ public:
|
||||
return true;
|
||||
}
|
||||
uint64_t size() const override { return geoms_.size(); }
|
||||
void resize(int32_t size) override { geoms_.reserve(size); }
|
||||
void clear() override { geoms_.clear(); }
|
||||
int resize(int64_t size) override;
|
||||
void clear() override { geoms_.reuse(); }
|
||||
|
||||
iterator begin() { return geoms_.begin(); }
|
||||
const_iterator begin() const { return geoms_.begin(); }
|
||||
@ -1262,10 +1266,14 @@ public:
|
||||
return *geoms_[i];
|
||||
}
|
||||
|
||||
int set(uint32_t index, ObGeometry *geo);
|
||||
int reserve(int64_t capacity) { return geoms_.reserve(capacity); }
|
||||
TO_STRING_KV("type", "ObGeographGeometrycollection",
|
||||
"size", size());
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(ObGeographGeometrycollection);
|
||||
ObCGeoModuleArena mode_arena_;
|
||||
ObVector<ObGeometry *, ObCGeoModuleArena> geoms_;
|
||||
ObArray<ObGeometry *> geoms_;
|
||||
};
|
||||
|
||||
} // namespace common
|
||||
|
303
deps/oblib/src/lib/geo/ob_geo_utils.cpp
vendored
303
deps/oblib/src/lib/geo/ob_geo_utils.cpp
vendored
@ -1,4 +1,3 @@
|
||||
|
||||
/**
|
||||
* Copyright (c) 2021 OceanBase
|
||||
* OceanBase CE is licensed under Mulan PubL v2.
|
||||
@ -49,6 +48,8 @@
|
||||
#include "lib/geo/ob_geo_vertex_collect_visitor.h"
|
||||
#include "lib/geo/ob_geo_point_location_visitor.h"
|
||||
#include "lib/geo/ob_geo_zoom_in_visitor.h"
|
||||
#include "lib/geo/ob_geo_close_ring_visitor.h"
|
||||
#include "share/rc/ob_tenant_base.h"
|
||||
|
||||
namespace oceanbase
|
||||
{
|
||||
@ -367,7 +368,7 @@ int ObGeoTypeUtil::create_geo_by_type(ObIAllocator &allocator,
|
||||
}
|
||||
}
|
||||
} else if (is_3d_geo_type(geo_type)) {
|
||||
if (OB_ISNULL(geo = OB_NEWx(ObGeometry3D, (&allocator), srid, (&allocator)))) {
|
||||
if (OB_ISNULL(geo = OB_NEWx(ObGeometry3D, (&allocator), srid))) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
LOG_WARN("fail to create 3d geo object", K(ret), K(geo_type));
|
||||
} else {
|
||||
@ -501,23 +502,17 @@ int ObGeoTypeUtil::convert_geometry_3D_to_2D(
|
||||
int ObGeoTypeUtil::normalize_geometry(ObGeometry &geo, const ObSrsItem *srs)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
uint32_t zoom_in_value = 0;
|
||||
if (is_3d_geo_type(geo.type())) {
|
||||
ObGeometry3D *geo_3d = static_cast<ObGeometry3D *>(&geo);
|
||||
if (OB_FAIL(geo_3d->normalize(srs, zoom_in_value))) {
|
||||
if (OB_FAIL(geo_3d->normalize(srs))) {
|
||||
LOG_WARN("fail to check coordinate range", K(ret));
|
||||
}
|
||||
} else {
|
||||
ObGeoNormalizeVisitor normalize_visitor(srs);
|
||||
if (OB_FAIL(geo.do_visit(normalize_visitor))) {
|
||||
LOG_WARN("normalize geo failed", K(ret));
|
||||
} else {
|
||||
zoom_in_value = normalize_visitor.get_zoom_in_value();
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
geo.set_zoom_in_value(zoom_in_value);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -564,14 +559,20 @@ int ObGeoTypeUtil::build_geometry(ObIAllocator &allocator,
|
||||
geo->set_srid(header.srid_);
|
||||
ObString wkb;
|
||||
uint32_t offset = 0;
|
||||
ObString wkb_data;
|
||||
if (OB_FAIL(ObGeoTypeUtil::get_wkb_from_swkb(swkb, wkb, offset))) {
|
||||
LOG_WARN("fail to get wkb from swkb", K(ret), K(swkb));
|
||||
} else if (OB_FAIL(ob_write_string(allocator, wkb, wkb_data))) {
|
||||
LOG_WARN("Failed to copy swkb memory", K(ret));
|
||||
} else {
|
||||
geo->set_data(wkb_data);
|
||||
if (!is_3d_geo_type(header.type_)) {
|
||||
ObString wkb_data;
|
||||
if (build_flag & ObGeoBuildFlag::GEO_NOT_COPY_WKB) {
|
||||
wkb_data = wkb;
|
||||
} else {
|
||||
if (OB_FAIL(ob_write_string(allocator, wkb, wkb_data))) {
|
||||
LOG_WARN("Failed to copy swkb memory", K(ret));
|
||||
}
|
||||
}
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (FALSE_IT(geo->set_data(wkb_data))) {
|
||||
} else if (!is_3d_geo_type(header.type_)) {
|
||||
bool need_check_ring = build_flag & ObGeoBuildFlag::GEO_CHECK_RING;
|
||||
ObGeoWkbCheckVisitor wkb_check(wkb_data, header.bo_, need_check_ring);
|
||||
if (OB_FAIL(geo->do_visit(wkb_check))) {
|
||||
@ -622,7 +623,8 @@ int ObGeoTypeUtil::construct_geometry(ObIAllocator &allocator,
|
||||
const ObString &swkb,
|
||||
const ObSrsItem *srs,
|
||||
ObGeometry *&geo,
|
||||
bool has_srid /* = true */)
|
||||
bool has_srid /* = true */,
|
||||
bool with_copy /* = true */)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
// has_srid is always true currently
|
||||
@ -670,14 +672,18 @@ int ObGeoTypeUtil::construct_geometry(ObIAllocator &allocator,
|
||||
ret = OB_ERR_GIS_INVALID_DATA;
|
||||
LOG_WARN("invalid point data length", K(ret), K(len));
|
||||
} else {
|
||||
ObString wkb_copy;
|
||||
if (OB_FAIL(ob_write_string(allocator, wkb, wkb_copy))) {
|
||||
LOG_WARN("Failed to copy wkb memory", K(ret));
|
||||
} else {
|
||||
geo->set_data(wkb_copy);
|
||||
if (has_srid) {
|
||||
geo->set_srid(srid);
|
||||
if (has_srid) {
|
||||
geo->set_srid(srid);
|
||||
}
|
||||
if (with_copy) {
|
||||
ObString wkb_copy;
|
||||
if (OB_FAIL(ob_write_string(allocator, wkb, wkb_copy))) {
|
||||
LOG_WARN("Failed to copy wkb memory", K(ret));
|
||||
} else {
|
||||
geo->set_data(wkb_copy);
|
||||
}
|
||||
} else {
|
||||
geo->set_data(wkb);
|
||||
}
|
||||
|
||||
if (OB_FAIL(ret)) {
|
||||
@ -704,21 +710,20 @@ int ObGeoTypeUtil::construct_geometry(ObIAllocator &allocator,
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObGeoTypeUtil::copy_geometry(ObIAllocator &allocator,
|
||||
int ObGeoTypeUtil::copy_geometry(lib::MemoryContext& ctx,
|
||||
ObGeometry &origin_geo,
|
||||
ObGeometry *©_geo)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
copy_geo = nullptr;
|
||||
ObString data;
|
||||
if (OB_FAIL(ObGeoTypeUtil::create_geo_by_type(allocator, origin_geo.type(), origin_geo.crs() == ObGeoCRS::Geographic, true, copy_geo))) {
|
||||
if (OB_FAIL(ObGeoTypeUtil::create_geo_by_type(ctx->get_arena_allocator(), origin_geo.type(), origin_geo.crs() == ObGeoCRS::Geographic, true, copy_geo))) {
|
||||
LOG_WARN("fail to create geo by type", K(ret));
|
||||
} else if (OB_FAIL(ob_write_string(allocator, ObString(origin_geo.length(), origin_geo.val()), data))) {
|
||||
} else if (OB_FAIL(ob_write_string(ctx->get_arena_allocator(), ObString(origin_geo.length(), origin_geo.val()), data))) {
|
||||
LOG_WARN("fail to copy geo data", K(ret));
|
||||
} else {
|
||||
copy_geo->set_data(data);
|
||||
copy_geo->set_srid(origin_geo.get_srid());
|
||||
copy_geo->set_zoom_in_value(origin_geo.get_zoom_in_value());
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@ -729,21 +734,21 @@ int ObGeoTypeUtil::correct_polygon(ObIAllocator &alloc,
|
||||
ObGeometry &geo)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
|
||||
if (geo.type() == ObGeoType::POLYGON
|
||||
|| geo.type() == ObGeoType::MULTIPOLYGON
|
||||
|| geo.type() == ObGeoType::GEOMETRYCOLLECTION) {
|
||||
if (!is_ring_closed && !geo.is_tree() &&
|
||||
OB_FAIL(ObGeoTypeUtil::geo_close_ring(geo, alloc))) {
|
||||
if (!is_ring_closed && OB_FAIL(ObGeoTypeUtil::geo_close_ring(geo, alloc))) {
|
||||
LOG_WARN("wkb close ring failed", K(ret));
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
ObGeoEvalCtx correct_context(&alloc, srs);
|
||||
int res_unused;
|
||||
if (OB_FAIL(correct_context.append_geo_arg(&geo))) {
|
||||
LOG_WARN("build geo gis context failed", K(ret));
|
||||
} else if (OB_FAIL(ObGeoFunc<ObGeoFuncType::Correct>::geo_func::eval(correct_context, res_unused))) {
|
||||
LOG_WARN("eval geo correct failed", K(ret));
|
||||
CREATE_WITH_TEMP_CONTEXT(lib::ContextParam().set_mem_attr(MTL_ID(), "GISModule", ObCtxIds::DEFAULT_CTX_ID)) {
|
||||
ObGeoEvalCtx correct_context(CURRENT_CONTEXT, srs);
|
||||
int res_unused;
|
||||
if (OB_FAIL(correct_context.append_geo_arg(&geo))) {
|
||||
LOG_WARN("build geo gis context failed", K(ret));
|
||||
} else if (OB_FAIL(ObGeoFunc<ObGeoFuncType::Correct>::geo_func::eval(correct_context, res_unused))) {
|
||||
LOG_WARN("eval geo correct failed", K(ret));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -825,34 +830,35 @@ int ObGeoTypeUtil::get_buffered_geo(ObArenaAllocator *allocator,
|
||||
const ObSrsItem *srs,
|
||||
ObString &res_wkb)
|
||||
{
|
||||
ObGeoBufferStrategy buf_strat;
|
||||
ObGeoEvalCtx gis_context(allocator, srs);
|
||||
int correct_result;
|
||||
int ret = OB_SUCCESS;
|
||||
ObGeometry *geo = NULL;
|
||||
ObGeometry *res_geo = NULL;
|
||||
buf_strat.distance_val_ = distance;
|
||||
ObGeoErrLogInfo log_info;
|
||||
if (OB_FAIL(ObGeoTypeUtil::build_geometry(*allocator, wkb_str, geo, srs, log_info, ObGeoBuildFlag::GEO_ALLOW_3D))) {
|
||||
LOG_WARN("fail to build geometry", K(ret));
|
||||
} else if (OB_FAIL(gis_context.append_geo_arg(geo))) {
|
||||
LOG_WARN("failed to append geo arg to gis context", K(ret), K(gis_context.get_geo_count()));
|
||||
} else if (OB_FAIL(ObGeoFunc<ObGeoFuncType::Correct>::geo_func::eval(gis_context, correct_result))) {
|
||||
LOG_WARN("eval boost correct failed", K(ret));
|
||||
} else if (OB_FAIL(gis_context.append_val_arg(&buf_strat))) {
|
||||
LOG_WARN("failed to append buffer strategy to gis context", K(ret), K(gis_context.get_geo_count()));
|
||||
} else if (OB_FAIL(ObGeoFunc<ObGeoFuncType::Buffer>::geo_func::eval(gis_context, res_geo))) {
|
||||
LOG_WARN("eval st_buffer failed", K(ret));
|
||||
} else if (OB_ISNULL(res_geo)) {
|
||||
ret = OB_ERR_NULL_VALUE;
|
||||
LOG_WARN("eval st_buffer null result", K(ret));
|
||||
} else if (OB_FAIL(ObGeoTypeUtil::to_wkb(*allocator,
|
||||
*res_geo,
|
||||
srs,
|
||||
res_wkb))) {
|
||||
LOG_WARN("transform to binary failed", K(ret));
|
||||
CREATE_WITH_TEMP_CONTEXT(lib::ContextParam().set_mem_attr(MTL_ID(), "GISModule", ObCtxIds::DEFAULT_CTX_ID)) {
|
||||
ObGeoBufferStrategy buf_strat;
|
||||
ObGeoEvalCtx gis_context(CURRENT_CONTEXT, srs);
|
||||
int correct_result;
|
||||
ObGeometry *geo = NULL;
|
||||
ObGeometry *res_geo = NULL;
|
||||
buf_strat.distance_val_ = distance;
|
||||
ObGeoErrLogInfo log_info;
|
||||
if (OB_FAIL(ObGeoTypeUtil::build_geometry(*allocator, wkb_str, geo, srs, log_info, ObGeoBuildFlag::GEO_ALLOW_3D))) {
|
||||
LOG_WARN("fail to build geometry", K(ret));
|
||||
} else if (OB_FAIL(gis_context.append_geo_arg(geo))) {
|
||||
LOG_WARN("failed to append geo arg to gis context", K(ret), K(gis_context.get_geo_count()));
|
||||
} else if (OB_FAIL(ObGeoFunc<ObGeoFuncType::Correct>::geo_func::eval(gis_context, correct_result))) {
|
||||
LOG_WARN("eval boost correct failed", K(ret));
|
||||
} else if (OB_FAIL(gis_context.append_val_arg(&buf_strat))) {
|
||||
LOG_WARN("failed to append buffer strategy to gis context", K(ret), K(gis_context.get_geo_count()));
|
||||
} else if (OB_FAIL(ObGeoFunc<ObGeoFuncType::Buffer>::geo_func::eval(gis_context, res_geo))) {
|
||||
LOG_WARN("eval st_buffer failed", K(ret));
|
||||
} else if (OB_ISNULL(res_geo)) {
|
||||
ret = OB_ERR_NULL_VALUE;
|
||||
LOG_WARN("eval st_buffer null result", K(ret));
|
||||
} else if (OB_FAIL(ObGeoTypeUtil::to_wkb(*allocator,
|
||||
*res_geo,
|
||||
srs,
|
||||
res_wkb))) {
|
||||
LOG_WARN("transform to binary failed", K(ret));
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -1449,18 +1455,19 @@ void ObGeoBoxUtil::get_point2d_from_geom_point(const ObWkbGeomInnerPoint &point,
|
||||
p2d.y = point.get<1>();
|
||||
}
|
||||
|
||||
int ObGeoBoxUtil::clip_by_box(ObGeometry &geo_in, ObIAllocator &allocator, const ObGeogBox &gbox, ObGeometry *&geo_out, bool is_called_in_pg_expr)
|
||||
int ObGeoBoxUtil::clip_by_box(ObGeometry &geo_in, lib::MemoryContext &mem_ctx, const ObGeogBox &gbox, ObGeometry *&geo_out, bool is_called_in_pg_expr)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObArenaAllocator tmp_allocator;
|
||||
ObGeoEvalCtx box_ctx(&tmp_allocator);
|
||||
ObGeoEvalCtx box_ctx(mem_ctx);
|
||||
box_ctx.set_is_called_in_pg_expr(is_called_in_pg_expr); // clip only used in PG expr currently
|
||||
ObGeogBox *gbox_in = nullptr;
|
||||
ObGeometry *geo_tree = nullptr;
|
||||
ObGeometry *geo_bin = nullptr;
|
||||
ObArenaAllocator &allocator = mem_ctx->get_arena_allocator();
|
||||
if (geo_in.is_tree()) {
|
||||
geo_tree = &geo_in;
|
||||
if (OB_FAIL(ObGeoTypeUtil::tree_to_bin(allocator, geo_tree, geo_bin, nullptr))) {
|
||||
if (OB_FAIL(ObGeoTypeUtil::tree_to_bin(tmp_allocator, geo_tree, geo_bin, nullptr))) {
|
||||
LOG_WARN("fail to do tree to bin", K(ret));
|
||||
}
|
||||
} else {
|
||||
@ -1496,7 +1503,7 @@ int ObGeoBoxUtil::clip_by_box(ObGeometry &geo_in, ObIAllocator &allocator, const
|
||||
} else if (!ObGeoBoxUtil::is_box_valid(gbox)) {
|
||||
geo_out = nullptr;
|
||||
} else {
|
||||
ObGeoBoxClipVisitor clip_visitor(gbox, allocator);
|
||||
ObGeoBoxClipVisitor clip_visitor(gbox, mem_ctx);
|
||||
if (OB_FAIL(geo_tree->do_visit(clip_visitor))) {
|
||||
if (ret == OB_ERR_GIS_INVALID_DATA) {
|
||||
// pg behavior: return null
|
||||
@ -1837,8 +1844,10 @@ int ObGeoTypeUtil::geo_close_ring(ObGeometry &geo, ObIAllocator &allocator)
|
||||
int ret = OB_SUCCESS;
|
||||
ObGeoStringBuffer res(&allocator);
|
||||
if (geo.is_tree()) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("tree geo is not support", K(ret));
|
||||
ObGeoCloseRingVisitor cr_visitor;
|
||||
if (OB_FAIL(geo.do_visit(cr_visitor))) {
|
||||
LOG_WARN("fail to do close ring visitor", K(ret));
|
||||
}
|
||||
} else if (OB_ISNULL(geo.val())) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("geo value is null", K(ret));
|
||||
@ -1874,7 +1883,7 @@ int ObGeoTypeUtil::geo_close_ring(ObGeometry &geo, ObIAllocator &allocator)
|
||||
LOG_WARN("geo type is not support", K(geo.type()));
|
||||
}
|
||||
|
||||
if (OB_SUCC(ret)) {
|
||||
if (OB_SUCC(ret) && !geo.is_tree()) {
|
||||
ObString wkb_nosrid(res.length(), res.ptr());
|
||||
geo.set_data(wkb_nosrid);
|
||||
}
|
||||
@ -2056,26 +2065,28 @@ int ObGeoTypeUtil::get_mbr_polygon(ObIAllocator &allocator,
|
||||
int ret = OB_SUCCESS;
|
||||
ObCartesianBox box; // mbr box of input geo
|
||||
ObCartesianBox bounds_box; // bounds box of corresponding srs
|
||||
ObGeoEvalCtx gis_context(&allocator, NULL);
|
||||
if (OB_FAIL(srs_bounds_to_mbr_box(bounds, bounds_box))) {
|
||||
LOG_WARN("get srs bounds box failed", K(ret));
|
||||
} else if (OB_FAIL(gis_context.append_geo_arg(&geo_bin))) {
|
||||
LOG_WARN("build gis context failed", K(ret), K(gis_context.get_geo_count()));
|
||||
} else if (OB_FAIL(ObGeoFuncEnvelope::eval(gis_context, box))) {
|
||||
LOG_WARN("get mbr box failed", K(ret));
|
||||
} else if (box.is_empty()) {
|
||||
ret = OB_ERR_GIS_INVALID_DATA;
|
||||
// how about some box points is nan?
|
||||
LOG_WARN("get mbr box failed", K(ret));
|
||||
} else {
|
||||
ObCartesianBox final; // result box
|
||||
boost::geometry::intersection(box, bounds_box, final);
|
||||
if (final.is_empty()) {
|
||||
ret = OB_EMPTY_RESULT;
|
||||
LOG_WARN("no intersection in bounds", K(ret), K(*bounds), K(box));
|
||||
} else if (OB_FAIL(mbr_box_to_geometry(geo_bin.get_srid(), allocator, final, geo_bin_out))) {
|
||||
LOG_WARN("failed to convert box to geo", K(ret), K(final));
|
||||
} else { /* do nothing */ }
|
||||
CREATE_WITH_TEMP_CONTEXT(lib::ContextParam().set_mem_attr(MTL_ID(), "GISModule", ObCtxIds::DEFAULT_CTX_ID)) {
|
||||
ObGeoEvalCtx gis_context(CURRENT_CONTEXT, NULL);
|
||||
if (OB_FAIL(srs_bounds_to_mbr_box(bounds, bounds_box))) {
|
||||
LOG_WARN("get srs bounds box failed", K(ret));
|
||||
} else if (OB_FAIL(gis_context.append_geo_arg(&geo_bin))) {
|
||||
LOG_WARN("build gis context failed", K(ret), K(gis_context.get_geo_count()));
|
||||
} else if (OB_FAIL(ObGeoFuncEnvelope::eval(gis_context, box))) {
|
||||
LOG_WARN("get mbr box failed", K(ret));
|
||||
} else if (box.is_empty()) {
|
||||
ret = OB_ERR_GIS_INVALID_DATA;
|
||||
// how about some box points is nan?
|
||||
LOG_WARN("get mbr box failed", K(ret));
|
||||
} else {
|
||||
ObCartesianBox final; // result box
|
||||
boost::geometry::intersection(box, bounds_box, final);
|
||||
if (final.is_empty()) {
|
||||
ret = OB_EMPTY_RESULT;
|
||||
LOG_WARN("no intersection in bounds", K(ret), K(*bounds), K(box));
|
||||
} else if (OB_FAIL(mbr_box_to_geometry(geo_bin.get_srid(), allocator, final, geo_bin_out))) {
|
||||
LOG_WARN("failed to convert box to geo", K(ret), K(final));
|
||||
} else { /* do nothing */ }
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@ -2537,7 +2548,7 @@ int ObGeoTypeUtil::get_varry_obj_from_map(const QualifiedMap &map, const ObStrin
|
||||
int ObGeoTypeUtil::sql_geo_obj_to_ewkt(const QualifiedMap &map, ObIAllocator &allocator, ObString &ewkt)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObSdoGeoObject sdo_geometry;
|
||||
ObSdoGeoObject sdo_geometry(allocator);
|
||||
bool is_null_result = false;
|
||||
|
||||
uint64_t gtype_num;
|
||||
@ -2774,6 +2785,74 @@ int ObGeoTypeUtil::check_empty(ObGeometry *geo, bool &is_empty)
|
||||
return ret;
|
||||
}
|
||||
|
||||
template<typename MpType>
|
||||
int ObGeoTypeUtil::is_in_geometry(lib::MemoryContext &mem_ctx, const ObGeometry &geo, const MpType &multi_geo,
|
||||
const ObSrsItem *srs, bool &res, uint32_t start_idx /* = 0*/)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
for (int32_t j = start_idx; j < multi_geo.size() && OB_SUCC(ret) && !res; j++) {
|
||||
ObGeoEvalCtx gis_context(mem_ctx, srs);
|
||||
if (OB_FAIL(gis_context.append_geo_arg(&geo)) || OB_FAIL(gis_context.append_geo_arg(&multi_geo[j]))) {
|
||||
OB_LOG(WARN, "build gis context failed", K(ret), K(gis_context.get_geo_count()));
|
||||
} else if (OB_FAIL(ObGeoFunc<ObGeoFuncType::Equals>::geo_func::eval(gis_context, res))) {
|
||||
OB_LOG(WARN, "eval st intersection failed", K(ret));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObGeoTypeUtil::remove_duplicate_geo(ObGeometry *&geo, lib::MemoryContext &mem_ctx, const ObSrsItem *srs, bool need_simplify/* = true*/)
|
||||
{
|
||||
INIT_SUCC(ret);
|
||||
if (geo == NULL) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("input geo is null", K(ret));
|
||||
} else if ((srs == NULL || srs->srs_type() != ObSrsType::GEOGRAPHIC_SRS)
|
||||
&& geo->crs() == ObGeoCRS::Geographic) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("invalid srs type", K(ret), KP(srs), K(geo->crs()));
|
||||
} else {
|
||||
bool is_duplicate = false;
|
||||
switch (geo->crs()) {
|
||||
case ObGeoCRS::Geographic : {
|
||||
if (OB_FAIL(check_if_geo_duplicate<ObGeographGeometrycollection>(geo, mem_ctx, srs, is_duplicate))) {
|
||||
LOG_WARN("fail to check if geometry has duplicate", K(ret));
|
||||
} else if (is_duplicate && OB_FAIL(remove_duplicate_multi_geo<ObGeographGeometrycollection>(geo, mem_ctx, srs))) {
|
||||
LOG_WARN("failed to remove duplicate geo", K(ret), K(geo->crs()));
|
||||
} else if (need_simplify) {
|
||||
if (OB_FAIL((simplify_multi_geo<ObGeographGeometrycollection>(geo, mem_ctx->get_arena_allocator())))) {
|
||||
OB_LOG(WARN, "fail to simplify result", K(ret));
|
||||
} else if (geo->type() == ObGeoType::GEOMETRYCOLLECTION
|
||||
&& OB_FAIL(simplify_geo_collection<ObGeographGeometrycollection>(geo, mem_ctx->get_arena_allocator(), srs))) {
|
||||
OB_LOG(WARN, "fail to simplify_geo_collection", K(ret));
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ObGeoCRS::Cartesian : {
|
||||
if (OB_FAIL(check_if_geo_duplicate<ObCartesianGeometrycollection>(geo, mem_ctx, srs, is_duplicate))) {
|
||||
LOG_WARN("fail to check if geometry has duplicate", K(ret));
|
||||
} else if (is_duplicate && OB_FAIL(remove_duplicate_multi_geo<ObCartesianGeometrycollection>(geo, mem_ctx, srs))) {
|
||||
LOG_WARN("failed to remove duplicate geo", K(ret), K(geo->crs()));
|
||||
} else if (need_simplify) {
|
||||
if (OB_FAIL((simplify_multi_geo<ObCartesianGeometrycollection>(geo, mem_ctx->get_arena_allocator())))) {
|
||||
OB_LOG(WARN, "fail to simplify result", K(ret));
|
||||
} else if (geo->type() == ObGeoType::GEOMETRYCOLLECTION
|
||||
&& OB_FAIL(simplify_geo_collection<ObCartesianGeometrycollection>(geo, mem_ctx->get_arena_allocator(), srs))) {
|
||||
OB_LOG(WARN, "fail to simplify_geo_collection", K(ret));
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default : {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("invalid geo type", K(ret), K(srs->srs_type()), K(geo->crs()));
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObGeoMVTUtil::affine_transformation(ObGeometry *geo, const ObAffineMatrix &affine)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
@ -2824,7 +2903,7 @@ int ObGeoTypeUtil::get_polygon_size(ObGeometry &geo)
|
||||
return size;
|
||||
}
|
||||
|
||||
int ObGeoTypeUtil::magnify_and_recheck(ObIAllocator &allocator, ObGeometry &geo, ObGeoEvalCtx& gis_context, bool& invalid_for_cache)
|
||||
int ObGeoTypeUtil::magnify_and_recheck(lib::MemoryContext& ctx, ObGeometry &geo, ObGeoEvalCtx& gis_context, bool& invalid_for_cache)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObGeometry *tmp_geo = nullptr;
|
||||
@ -2832,7 +2911,7 @@ int ObGeoTypeUtil::magnify_and_recheck(ObIAllocator &allocator, ObGeometry &geo,
|
||||
bool need_recheck = false;
|
||||
ObGeoZoomInVisitor zoom_in_visitor(RECHECK_ZOOM_IN_VALUE);
|
||||
const ObGeoNormalVal *val_arg = nullptr;
|
||||
if (OB_FAIL(copy_geometry(allocator, geo, tmp_geo)) || OB_ISNULL(tmp_geo)) {
|
||||
if (OB_FAIL(copy_geometry(ctx, geo, tmp_geo)) || OB_ISNULL(tmp_geo)) {
|
||||
// do nothing, return invalid_for_cache
|
||||
} else if (OB_FAIL(tmp_geo->do_visit(zoom_in_visitor))) {
|
||||
LOG_WARN("failed to zoom in visit", K(ret));
|
||||
@ -2868,10 +2947,10 @@ int ObGeoTypeUtil::check_valid_and_self_intersects(ObGeoEvalCtx& gis_context, bo
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObGeoTypeUtil::polygon_check_self_intersections(ObIAllocator &allocator, ObGeometry &geo, const ObSrsItem *srs, bool& invalid_for_cache)
|
||||
int ObGeoTypeUtil::polygon_check_self_intersections(lib::MemoryContext& ctx, ObGeometry &geo, const ObSrsItem *srs, bool& invalid_for_cache)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObGeoEvalCtx gis_context(&allocator, srs);
|
||||
ObGeoEvalCtx gis_context(ctx, srs);
|
||||
ObGeoNormalVal reason;
|
||||
bool valid = false;
|
||||
const ObGeoNormalVal *val_arg = nullptr;
|
||||
@ -2882,7 +2961,7 @@ int ObGeoTypeUtil::polygon_check_self_intersections(ObIAllocator &allocator, ObG
|
||||
LOG_WARN("add reason val to context failed", K(ret));
|
||||
} else if (OB_FAIL(check_valid_and_self_intersects(gis_context, invalid_for_cache, need_recheck))) {
|
||||
LOG_WARN("fail to check_valid_if_self_intersects.", K(ret));
|
||||
} else if (invalid_for_cache && need_recheck && OB_FAIL(magnify_and_recheck(allocator, geo, gis_context, invalid_for_cache))) {
|
||||
} else if (invalid_for_cache && need_recheck && OB_FAIL(magnify_and_recheck(ctx, geo, gis_context, invalid_for_cache))) {
|
||||
LOG_WARN("fail to magnify_and_recheck.", K(ret));
|
||||
} else if (invalid_for_cache) {
|
||||
LOG_WARN("self intersects, use geo cache base.", K(ret));
|
||||
@ -3245,5 +3324,37 @@ int ObGeoMVTUtil::simplify_geometry(ObGeometry *geo, double tolerance, bool keep
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
} // namespace common
|
||||
} // namespace oceanbase
|
||||
|
||||
ObGeoBoostAllocGuard::~ObGeoBoostAllocGuard()
|
||||
{
|
||||
if (inited_) {
|
||||
DESTROY_CONTEXT(mem_context_);
|
||||
}
|
||||
}
|
||||
|
||||
int ObGeoBoostAllocGuard::init()
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
lib::ContextParam param;
|
||||
param.set_mem_attr(tenant_id_, "GISModule", ObCtxIds::DEFAULT_CTX_ID)
|
||||
.set_properties(lib::USE_TL_PAGE_OPTIONAL) // todo: need thread safe?
|
||||
.set_page_size(OB_MALLOC_NORMAL_BLOCK_SIZE);
|
||||
if (OB_FAIL(CURRENT_CONTEXT->CREATE_CONTEXT(mem_context_, param))) {
|
||||
LOG_WARN("failed to create memory context", K(ret));
|
||||
} else if (OB_ISNULL(mem_context_)) {
|
||||
ret = OB_ERR_NULL_VALUE;
|
||||
LOG_WARN("failed to create memory context", K(ret));
|
||||
} else {
|
||||
inited_ = true;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
lib::MemoryContext *ObGeoBoostAllocGuard::get_memory_ctx()
|
||||
{
|
||||
return inited_ ? &mem_context_ : nullptr;
|
||||
}
|
||||
|
||||
|
||||
} // namespace common
|
||||
} // namespace oceanbase
|
||||
|
392
deps/oblib/src/lib/geo/ob_geo_utils.h
vendored
392
deps/oblib/src/lib/geo/ob_geo_utils.h
vendored
@ -45,6 +45,7 @@ enum ObGeoBuildFlag: uint8_t {
|
||||
GEO_ALLOW_3D = 0x08,
|
||||
GEO_CHECK_RANGE = 0x10,
|
||||
GEO_RESERVE_3D = 0x20, // do not convert 3D Geometry to 2D
|
||||
GEO_NOT_COPY_WKB = 0x40, // copy input wkb str to output geo data
|
||||
GEO_DEFAULT = GEO_NORMALIZE | GEO_CORRECT | GEO_CHECK_RANGE,
|
||||
GEO_ALLOW_3D_DEFAULT = GEO_DEFAULT | GEO_ALLOW_3D,
|
||||
GEO_CARTESIAN = GEO_CORRECT,
|
||||
@ -153,8 +154,9 @@ public:
|
||||
const ObString &wkb,
|
||||
const ObSrsItem *srs,
|
||||
ObGeometry *&geo,
|
||||
bool has_srid = true);
|
||||
static int copy_geometry(ObIAllocator &allocator,
|
||||
bool has_srid = true,
|
||||
bool with_copy = true);
|
||||
static int copy_geometry(lib::MemoryContext& ctx,
|
||||
ObGeometry &origin_geo,
|
||||
ObGeometry *©_geo);
|
||||
static int correct_polygon(ObIAllocator &alloc,
|
||||
@ -249,7 +251,7 @@ public:
|
||||
// caculate end point quadrant direction relative to start point
|
||||
static int get_quadrant_direction(const ObPoint2d &start, const ObPoint2d &end, QuadDirection &res);
|
||||
static int get_polygon_size(ObGeometry &geo);
|
||||
static int polygon_check_self_intersections(ObIAllocator &allocator, ObGeometry &geo, const ObSrsItem *srs, bool& invalid_for_cache);
|
||||
static int polygon_check_self_intersections(lib::MemoryContext& ctx, ObGeometry &geo, const ObSrsItem *srs, bool& invalid_for_cache);
|
||||
static int create_cached_geometry(ObIAllocator &allocator, ObIAllocator &tmp_allocator, ObGeometry *geo,
|
||||
const ObSrsItem *srs, ObCachedGeom *&cached_geo);
|
||||
template<typename CachedGeoType>
|
||||
@ -262,6 +264,15 @@ public:
|
||||
static bool use_point_polygon_short_circuit(const ObGeometry& geo1, const ObGeometry& geo2, ObItemType func_type);
|
||||
static int get_point_polygon_res(ObGeometry *geo1, ObGeometry *geo2, ObItemType func_type, bool& result);
|
||||
static bool need_get_srs(const uint32_t srid);
|
||||
template<typename GcTreeType>
|
||||
static int remove_duplicate_multi_geo(ObGeometry *&geo, lib::MemoryContext &mem_ctx, const ObSrsItem *srs);
|
||||
template<typename GcTreeType>
|
||||
static int simplify_geo_collection(ObGeometry *&geo, common::ObIAllocator &allocator, const ObSrsItem *srs);
|
||||
template<typename GcType>
|
||||
static int simplify_multi_geo(ObGeometry *&geo, common::ObIAllocator &allocator);
|
||||
static int remove_duplicate_geo(ObGeometry *&geo, lib::MemoryContext &mem_ctx, const ObSrsItem *srs, bool need_simplify = true);
|
||||
template<typename GcTreeType>
|
||||
static int check_if_geo_duplicate(ObGeometry *geo, lib::MemoryContext &mem_ctx, const ObSrsItem *srs, bool &is_duplicate);
|
||||
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,
|
||||
@ -295,9 +306,12 @@ private:
|
||||
template<typename T_IBIN, typename T_BIN>
|
||||
static int collection_has_dimension(T_IBIN *geo, ObGeoDimension dim, bool& has);
|
||||
static int point_polygon_short_circuit(ObGeometry *poly, ObGeometry *point, ObPointLocation& loc, bool& has_internal, bool get_fartest);
|
||||
static int magnify_and_recheck(ObIAllocator &allocator, ObGeometry &geo, ObGeoEvalCtx& gis_context, bool& invalid_for_cache);
|
||||
static int magnify_and_recheck(lib::MemoryContext& ctx, ObGeometry &geo, ObGeoEvalCtx& gis_context, bool& invalid_for_cache);
|
||||
static int check_valid_and_self_intersects(ObGeoEvalCtx& gis_context, bool& invalid_for_cache, bool& need_recheck);
|
||||
|
||||
template<typename MpType>
|
||||
static int is_in_geometry(lib::MemoryContext &mem_ctx, const ObGeometry &geo, const MpType &multi_geo,
|
||||
const ObSrsItem *srs, bool &res, uint32_t start_idx = 0);
|
||||
DISALLOW_COPY_AND_ASSIGN(ObGeoTypeUtil);
|
||||
};
|
||||
|
||||
@ -368,7 +382,7 @@ public:
|
||||
static void get_point2d_from_geom_point(const ObWkbGeomInnerPoint &point, ObPoint2d &p2d);
|
||||
template<typename GeometryType>
|
||||
static int get_geom_line_box(const GeometryType &line, ObGeogBox &box);
|
||||
static int clip_by_box(ObGeometry &geo_in, ObIAllocator &allocator, const ObGeogBox &box, ObGeometry *&geo_out, bool is_called_in_pg_expr);
|
||||
static int clip_by_box(ObGeometry &geo_in, lib::MemoryContext &mem_ctx, const ObGeogBox &box, ObGeometry *&geo_out, bool is_called_in_pg_expr);
|
||||
static bool boxes_overlaps(const ObGeogBox &box1, const ObGeogBox &box2);
|
||||
static bool boxes_contains(const ObGeogBox &box1, const ObGeogBox &box2);
|
||||
template<typename GeometryType>
|
||||
@ -381,8 +395,6 @@ public:
|
||||
static inline bool is_float_gteq(double left, double right) { return (left + OB_GEO_TOLERANCE) >= right; }
|
||||
static inline bool is_float_zero(double ft) { return fabs(ft) <= OB_GEO_TOLERANCE; }
|
||||
static bool is_box_valid(const ObGeogBox &box);
|
||||
|
||||
static constexpr double OB_GEO_TOLERANCE = 5e-14;
|
||||
};
|
||||
|
||||
/*
|
||||
@ -418,6 +430,28 @@ typedef struct
|
||||
double z_size;
|
||||
} ObGeoGrid;
|
||||
|
||||
class ObGeoBoostAllocGuard
|
||||
{
|
||||
public:
|
||||
ObGeoBoostAllocGuard(uint64_t tenant_id)
|
||||
: mem_context_(nullptr),
|
||||
inited_(false),
|
||||
malloc_guard_(lib::ObMemAttr(tenant_id, "GISModule")),
|
||||
tenant_id_(tenant_id)
|
||||
{}
|
||||
~ObGeoBoostAllocGuard();
|
||||
int init();
|
||||
lib::MemoryContext *get_memory_ctx();
|
||||
bool is_inited() { return inited_; }
|
||||
private:
|
||||
static const int64_t CONTEXT_MEMORY_LIMIT = 512 << 10;
|
||||
lib::MemoryContext mem_context_;
|
||||
bool inited_;
|
||||
lib::ObMallocHookAttrGuard malloc_guard_;
|
||||
uint64_t tenant_id_;
|
||||
};
|
||||
|
||||
|
||||
class ObGeoMVTUtil
|
||||
{
|
||||
public:
|
||||
@ -469,31 +503,31 @@ int ObGeoTypeUtil::create_geo_bin_by_type(ObIAllocator &allocator,
|
||||
|
||||
switch(geo_type) {
|
||||
case ObGeoType::POINT: {
|
||||
tmp_geo = OB_NEWx(PT, (&allocator), srid, (&allocator));
|
||||
tmp_geo = OB_NEWx(PT, (&allocator), srid);
|
||||
break;
|
||||
}
|
||||
case ObGeoType::LINESTRING: {
|
||||
tmp_geo = OB_NEWx(LN, (&allocator), srid, (&allocator));
|
||||
tmp_geo = OB_NEWx(LN, (&allocator), srid);
|
||||
break;
|
||||
}
|
||||
case ObGeoType::POLYGON: {
|
||||
tmp_geo = OB_NEWx(PY, (&allocator), srid, (&allocator));
|
||||
tmp_geo = OB_NEWx(PY, (&allocator), srid);
|
||||
break;
|
||||
}
|
||||
case ObGeoType::MULTIPOINT: {
|
||||
tmp_geo = OB_NEWx(MPT, (&allocator), srid, (&allocator));
|
||||
tmp_geo = OB_NEWx(MPT, (&allocator), srid);
|
||||
break;
|
||||
}
|
||||
case ObGeoType::MULTILINESTRING: {
|
||||
tmp_geo = OB_NEWx(MLN, (&allocator), srid, (&allocator));
|
||||
tmp_geo = OB_NEWx(MLN, (&allocator), srid);
|
||||
break;
|
||||
}
|
||||
case ObGeoType::MULTIPOLYGON: {
|
||||
tmp_geo = OB_NEWx(MPY, (&allocator), srid, (&allocator));
|
||||
tmp_geo = OB_NEWx(MPY, (&allocator), srid);
|
||||
break;
|
||||
}
|
||||
case ObGeoType::GEOMETRYCOLLECTION: {
|
||||
tmp_geo = OB_NEWx(GC, (&allocator), srid, (&allocator));
|
||||
tmp_geo = OB_NEWx(GC, (&allocator), srid);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
@ -525,7 +559,7 @@ int ObGeoTypeUtil::create_geo_tree_by_type(ObIAllocator &allocator,
|
||||
|
||||
switch(geo_type) {
|
||||
case ObGeoType::POINT: {
|
||||
tmp_geo = OB_NEWx(PT, (&allocator), srid, (&allocator));
|
||||
tmp_geo = OB_NEWx(PT, (&allocator), srid);
|
||||
break;
|
||||
}
|
||||
case ObGeoType::LINESTRING: {
|
||||
@ -570,6 +604,334 @@ int ObGeoTypeUtil::create_geo_tree_by_type(ObIAllocator &allocator,
|
||||
return ret;
|
||||
}
|
||||
|
||||
template<typename GcType>
|
||||
int ObGeoTypeUtil::simplify_multi_geo(ObGeometry *&geo, common::ObIAllocator &allocator)
|
||||
{
|
||||
// e.g. MULTILINESTRING((0 0, 1 1)) -> LINESTRING(0 0, 1 1)
|
||||
int ret= OB_SUCCESS;
|
||||
switch (geo->type()) {
|
||||
case ObGeoType::MULTILINESTRING: {
|
||||
typename GcType::sub_ml_type *mp = reinterpret_cast<typename GcType::sub_ml_type *>(geo);
|
||||
if (OB_ISNULL(mp)) {
|
||||
ret = OB_ERR_GIS_INVALID_DATA;
|
||||
OB_LOG(WARN, "invalid null pointer", K(ret));
|
||||
} else if (mp->size() == 1) {
|
||||
geo = &(mp->front());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ObGeoType::MULTIPOINT: {
|
||||
typename GcType::sub_mpt_type *mpt = reinterpret_cast<typename GcType::sub_mpt_type *>(geo);
|
||||
if (OB_ISNULL(mpt)) {
|
||||
ret = OB_ERR_GIS_INVALID_DATA;
|
||||
OB_LOG(WARN, "invalid null pointer", K(ret));
|
||||
} else if (mpt->size() == 1) {
|
||||
typename GcType::sub_pt_type *p = OB_NEWx(typename GcType::sub_pt_type, &allocator, geo->get_srid());
|
||||
if (OB_ISNULL(p)) {
|
||||
ret = OB_ERR_GIS_INVALID_DATA;
|
||||
OB_LOG(WARN, "invalid null pointer", K(ret));
|
||||
} else {
|
||||
p->set_data(mpt->front());
|
||||
geo = p;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ObGeoType::MULTIPOLYGON: {
|
||||
typename GcType::sub_mp_type *mp = reinterpret_cast<typename GcType::sub_mp_type *>(geo);
|
||||
if (OB_ISNULL(mp)) {
|
||||
ret = OB_ERR_GIS_INVALID_DATA;
|
||||
OB_LOG(WARN, "invalid null pointer", K(ret));
|
||||
} else if (mp->size() == 1) {
|
||||
geo = &(mp->front());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ObGeoType::GEOMETRYCOLLECTION: {
|
||||
GcType *mp = reinterpret_cast<GcType *>(geo);
|
||||
if (OB_ISNULL(mp)) {
|
||||
ret = OB_ERR_GIS_INVALID_DATA;
|
||||
OB_LOG(WARN, "invalid null pointer", K(ret));
|
||||
} else if (mp->size() > 0) {
|
||||
for (uint32_t i = 0; i < mp->size() && OB_SUCC(ret); i++) {
|
||||
bool in_res_geo = false;
|
||||
ObGeometry *cur_geo = &(*mp)[i];
|
||||
if (OB_FAIL(simplify_multi_geo<GcType>(cur_geo, allocator))) {
|
||||
OB_LOG(WARN, "fail to remove dupilicate multi geometry", K(ret));
|
||||
} else if (OB_FAIL(mp->set(i, cur_geo))) {
|
||||
OB_LOG(WARN, "fail to set geometry", K(ret), K(i), KP(cur_geo));
|
||||
}
|
||||
}
|
||||
if (mp->size() == 1) {
|
||||
geo = &(mp->front());
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
break; // do nothing
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
// for geo tree
|
||||
template<typename GcTreeType>
|
||||
int ObGeoTypeUtil::simplify_geo_collection(ObGeometry *&geo, common::ObIAllocator &allocator, const ObSrsItem *srs)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (geo->type() != ObGeoType::GEOMETRYCOLLECTION) {
|
||||
// do nothing
|
||||
} else {
|
||||
GcTreeType *&geo_coll = reinterpret_cast<GcTreeType *&>(geo);
|
||||
ObGeoType front_type;
|
||||
bool need_simplify = true;
|
||||
if (geo_coll->size() < 2) {
|
||||
need_simplify = false;
|
||||
} else {
|
||||
front_type = geo_coll->front().type();
|
||||
for (uint32_t i = 1; need_simplify && i < geo_coll->size(); ++i) {
|
||||
if (((*geo_coll)[i]).type() != front_type) {
|
||||
need_simplify = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (need_simplify) {
|
||||
switch(front_type) {
|
||||
case ObGeoType::POINT: {
|
||||
typename GcTreeType::sub_mpt_type *res_geo = OB_NEWx(typename GcTreeType::sub_mpt_type, &allocator, geo->get_srid(), allocator);
|
||||
if (OB_ISNULL(res_geo)) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
OB_LOG(WARN, "fail to alloc memory", K(ret));
|
||||
}
|
||||
for (uint32_t i = 0; OB_SUCC(ret) && i < geo_coll->size(); ++i) {
|
||||
typename GcTreeType::sub_pt_type &geo_point = reinterpret_cast<typename GcTreeType::sub_pt_type &>((*geo_coll)[i]);
|
||||
if (OB_FAIL(res_geo->push_back(geo_point))) {
|
||||
OB_LOG(WARN, "failed to add point to multipoint", K(ret));
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
geo = res_geo;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ObGeoType::LINESTRING: {
|
||||
typename GcTreeType::sub_ml_type *res_geo = OB_NEWx(typename GcTreeType::sub_ml_type, &allocator, geo->get_srid(), allocator);
|
||||
if (OB_ISNULL(res_geo)) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
OB_LOG(WARN, "fail to alloc memory", K(ret));
|
||||
}
|
||||
for (uint32_t i = 0; OB_SUCC(ret) && i < geo_coll->size(); ++i) {
|
||||
if (OB_FAIL(res_geo->push_back((*geo_coll)[i]))) {
|
||||
OB_LOG(WARN, "failed to add linestring to multilinestring", K(ret));
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
geo = res_geo;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ObGeoType::POLYGON: {
|
||||
typename GcTreeType::sub_mp_type *res_geo = OB_NEWx(typename GcTreeType::sub_mp_type, &allocator, geo->get_srid(), allocator);
|
||||
if (OB_ISNULL(res_geo)) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
OB_LOG(WARN, "fail to alloc memory", K(ret));
|
||||
}
|
||||
for (uint32_t i = 0; OB_SUCC(ret) && i < geo_coll->size(); ++i) {
|
||||
if (OB_FAIL(res_geo->push_back((*geo_coll)[i]))) {
|
||||
OB_LOG(WARN, "failed to add polygon to multipolygon", K(ret));
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
geo = res_geo;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
// do nothing
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
// for geo tree
|
||||
template<typename GcTreeType>
|
||||
int ObGeoTypeUtil::remove_duplicate_multi_geo(ObGeometry *&geo, lib::MemoryContext &mem_ctx, const ObSrsItem *srs)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObArenaAllocator &allocator = mem_ctx->get_arena_allocator();
|
||||
switch (geo->type()) {
|
||||
case ObGeoType::POINT:
|
||||
case ObGeoType::LINESTRING:
|
||||
case ObGeoType::POLYGON: {
|
||||
break;
|
||||
}
|
||||
case ObGeoType::MULTIPOINT: {
|
||||
typename GcTreeType::sub_mpt_type *res_geo = OB_NEWx(typename GcTreeType::sub_mpt_type, &allocator, geo->get_srid(), allocator);
|
||||
typename GcTreeType::sub_mpt_type &sp_geo = reinterpret_cast<typename GcTreeType::sub_mpt_type &>(*geo);
|
||||
if (OB_ISNULL(res_geo)) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
OB_LOG(WARN, "failt to allocate memory for geometry", K(ret), K(geo->type()));
|
||||
}
|
||||
for (int32_t i = 0; i < sp_geo.size() && OB_SUCC(ret); i++) {
|
||||
bool in_res_geo = false;
|
||||
for (int32_t j = 0; j < res_geo->size() && OB_SUCC(ret) && !in_res_geo; j++) {
|
||||
if ((sp_geo[i].template get<0>() == sp_geo[j].template get<0>())
|
||||
&& (sp_geo[i].template get<1>() == sp_geo[j].template get<1>())) {
|
||||
in_res_geo = true;
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret) && !in_res_geo) {
|
||||
typename GcTreeType::sub_pt_type pt(sp_geo[i].template get<0>(), sp_geo[i].template get<1>());
|
||||
if (OB_FAIL(res_geo->push_back(pt))) {
|
||||
OB_LOG(WARN, "fail to push back geometry", K(ret));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
geo = res_geo;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ObGeoType::MULTILINESTRING: {
|
||||
typename GcTreeType::sub_ml_type *res_geo = OB_NEWx(typename GcTreeType::sub_ml_type, &allocator, geo->get_srid(), allocator);
|
||||
typename GcTreeType::sub_ml_type &sp_geo = reinterpret_cast<typename GcTreeType::sub_ml_type &>(*geo);
|
||||
if (OB_ISNULL(res_geo)) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
OB_LOG(WARN, "failt to allocate memory for geometry", K(ret), K(geo->type()));
|
||||
}
|
||||
for (int32_t i = 0; i < sp_geo.size() && OB_SUCC(ret); i++) {
|
||||
bool in_res_geo = false;
|
||||
if (OB_FAIL(is_in_geometry(mem_ctx, sp_geo[i], *res_geo, srs, in_res_geo))) {
|
||||
OB_LOG(WARN, "fail to check is in geometry", K(ret));
|
||||
} else if (!in_res_geo && OB_FAIL(res_geo->push_back(sp_geo[i]))) {
|
||||
OB_LOG(WARN, "fail to push back geometry", K(ret));
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
geo = res_geo;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ObGeoType::MULTIPOLYGON: {
|
||||
typename GcTreeType::sub_mp_type *res_geo = OB_NEWx(typename GcTreeType::sub_mp_type, &allocator, geo->get_srid(), allocator);
|
||||
typename GcTreeType::sub_mp_type &sp_geo = reinterpret_cast<typename GcTreeType::sub_mp_type &>(*geo);
|
||||
if (OB_ISNULL(res_geo)) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
OB_LOG(WARN, "failt to allocate memory for geometry", K(ret), K(geo->type()));
|
||||
}
|
||||
for (int32_t i = 0; i < sp_geo.size() && OB_SUCC(ret); i++) {
|
||||
bool in_res_geo = false;
|
||||
if (OB_FAIL(is_in_geometry(mem_ctx, sp_geo[i], *res_geo, srs, in_res_geo))) {
|
||||
OB_LOG(WARN, "fail to check is in geometry", K(ret));
|
||||
} else if (!in_res_geo && OB_FAIL(res_geo->push_back(sp_geo[i]))) {
|
||||
OB_LOG(WARN, "fail to push back geometry", K(ret));
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
geo = res_geo;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ObGeoType::GEOMETRYCOLLECTION: {
|
||||
GcTreeType *res_geo = OB_NEWx(GcTreeType, &allocator, geo->get_srid(), allocator);
|
||||
GcTreeType *&sp_geo = reinterpret_cast<GcTreeType *&>(geo);
|
||||
if (OB_ISNULL(res_geo)) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
OB_LOG(WARN, "failt to allocate memory for geometry", K(ret), K(geo->type()));
|
||||
}
|
||||
for (int32_t i = 0; i < sp_geo->size() && OB_SUCC(ret); i++) {
|
||||
bool in_res_geo = false;
|
||||
ObGeometry *cur_geo = &(*sp_geo)[i];
|
||||
if (OB_FAIL(remove_duplicate_multi_geo<GcTreeType>(cur_geo, mem_ctx, srs))) {
|
||||
OB_LOG(WARN, "fail to remove dupilicate multi geometry", K(ret));
|
||||
} else if (OB_FAIL(is_in_geometry(mem_ctx, *cur_geo, *res_geo, srs, in_res_geo))) {
|
||||
OB_LOG(WARN, "fail to check is in geometry", K(ret));
|
||||
} else if (!in_res_geo && OB_FAIL(res_geo->push_back(*cur_geo))) {
|
||||
OB_LOG(WARN, "fail to push back geometry", K(ret));
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
geo = res_geo;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
ret = OB_NOT_SUPPORTED;
|
||||
OB_LOG(WARN, "geometry type not supported", K(ret), K(geo->type()));
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
template<typename GcTreeType>
|
||||
int ObGeoTypeUtil::check_if_geo_duplicate(ObGeometry *geo, lib::MemoryContext &mem_ctx,
|
||||
const ObSrsItem *srs, bool &is_duplicate)
|
||||
{
|
||||
INIT_SUCC(ret);
|
||||
ObArenaAllocator &allocator = mem_ctx->get_arena_allocator();
|
||||
is_duplicate = false;
|
||||
switch (geo->type()) {
|
||||
case ObGeoType::POINT:
|
||||
case ObGeoType::LINESTRING:
|
||||
case ObGeoType::POLYGON: {
|
||||
break;
|
||||
}
|
||||
case ObGeoType::MULTIPOINT: {
|
||||
typename GcTreeType::sub_mpt_type &sp_geo = reinterpret_cast<typename GcTreeType::sub_mpt_type &>(*geo);
|
||||
for (int32_t i = 0; i < sp_geo.size() && OB_SUCC(ret) && !is_duplicate; i++) {
|
||||
for (int32_t j = i + 1; j < sp_geo.size() && OB_SUCC(ret) && !is_duplicate; j++) {
|
||||
if ((sp_geo[i].template get<0>() == sp_geo[j].template get<0>())
|
||||
&& (sp_geo[i].template get<1>() == sp_geo[j].template get<1>())) {
|
||||
is_duplicate = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ObGeoType::MULTILINESTRING: {
|
||||
typename GcTreeType::sub_ml_type &sp_geo = reinterpret_cast<typename GcTreeType::sub_ml_type &>(*geo);
|
||||
for (int32_t i = 0; i < sp_geo.size() && OB_SUCC(ret) && !is_duplicate; i++) {
|
||||
if (OB_FAIL(is_in_geometry(mem_ctx, sp_geo[i], sp_geo, srs, is_duplicate, i + 1))) {
|
||||
OB_LOG(WARN, "fail to check is in geometry", K(ret));
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ObGeoType::MULTIPOLYGON: {
|
||||
typename GcTreeType::sub_mp_type &sp_geo = reinterpret_cast<typename GcTreeType::sub_mp_type &>(*geo);
|
||||
for (int32_t i = 0; i < sp_geo.size() && OB_SUCC(ret) && !is_duplicate; i++) {
|
||||
if (OB_FAIL(is_in_geometry(mem_ctx, sp_geo[i], sp_geo, srs, is_duplicate, i + 1))) {
|
||||
OB_LOG(WARN, "fail to check is in geometry", K(ret));
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ObGeoType::GEOMETRYCOLLECTION: {
|
||||
GcTreeType *&sp_geo = reinterpret_cast<GcTreeType *&>(geo);
|
||||
for (int32_t i = 0; i < sp_geo->size() && OB_SUCC(ret) && !is_duplicate; i++) {
|
||||
ObGeometry *cur_geo = &(*sp_geo)[i];
|
||||
if (OB_FAIL(check_if_geo_duplicate<GcTreeType>(cur_geo, mem_ctx, srs, is_duplicate))) {
|
||||
OB_LOG(WARN, "fail to remove dupilicate multi geometry", K(ret));
|
||||
} else if (!is_duplicate && OB_FAIL(is_in_geometry(mem_ctx, *cur_geo, *sp_geo, srs, is_duplicate))) {
|
||||
OB_LOG(WARN, "fail to check is in geometry", K(ret));
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
ret = OB_NOT_SUPPORTED;
|
||||
OB_LOG(WARN, "geometry type not supported", K(ret), K(geo->type()));
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
// only support PLINESTRING/MULTILINESTRING in catesian bin (ObWkbGeom)
|
||||
template<typename GeometryType>
|
||||
int ObGeoBoxUtil::fast_box(const GeometryType *g, ObGeogBox &box, bool &has_fast_box)
|
||||
|
@ -19,14 +19,31 @@ namespace common {
|
||||
template<typename T_Point>
|
||||
int ObGeoZoomInVisitor::zoom_in_point(T_Point *geo)
|
||||
{
|
||||
uint32_t count = 0;
|
||||
while (count++ < zoom_in_value_) {
|
||||
double longti = geo->x();
|
||||
double lati = geo->y();
|
||||
longti *= 10;
|
||||
lati *= 10;
|
||||
geo->x(longti);
|
||||
geo->y(lati);
|
||||
if (!is_calc_zoom_) {
|
||||
uint32_t count = 0;
|
||||
while (count++ < zoom_in_value_) {
|
||||
double longti = geo->x();
|
||||
double lati = geo->y();
|
||||
longti *= 10;
|
||||
lati *= 10;
|
||||
geo->x(longti);
|
||||
geo->y(lati);
|
||||
}
|
||||
} else {
|
||||
uint32_t count = 0;
|
||||
double nx_tmp = geo->x();
|
||||
double ny_tmp = geo->y();
|
||||
while (nx_tmp != 0.0 && std::fabs(nx_tmp) < ZOOM_IN_THRESHOLD) {
|
||||
nx_tmp *= 10;
|
||||
count++;
|
||||
}
|
||||
zoom_in_value_ = count > zoom_in_value_ ? count : zoom_in_value_;
|
||||
count = 0;
|
||||
while (ny_tmp != 0.0 && std::fabs(ny_tmp) < ZOOM_IN_THRESHOLD) {
|
||||
ny_tmp *= 10;
|
||||
count++;
|
||||
}
|
||||
zoom_in_value_ = count > zoom_in_value_ ? count : zoom_in_value_;
|
||||
}
|
||||
return OB_SUCCESS;
|
||||
}
|
||||
|
@ -25,7 +25,8 @@ namespace common
|
||||
class ObGeoZoomInVisitor : public ObEmptyGeoVisitor
|
||||
{
|
||||
public:
|
||||
ObGeoZoomInVisitor(uint32_t zoom_in_value) : zoom_in_value_(zoom_in_value) {}
|
||||
ObGeoZoomInVisitor(uint32_t zoom_in_value, bool is_calc_zoom = false)
|
||||
: zoom_in_value_(zoom_in_value), is_calc_zoom_(is_calc_zoom) {}
|
||||
virtual ~ObGeoZoomInVisitor() {}
|
||||
bool prepare(ObGeometry *geo) { UNUSED(geo); return true; }
|
||||
int visit(ObGeometry *geo) override { UNUSED(geo); return OB_SUCCESS; }
|
||||
@ -33,11 +34,17 @@ public:
|
||||
int visit(ObIWkbGeogPoint *geo);
|
||||
int visit(ObCartesianPoint *geo);
|
||||
int visit(ObIWkbGeomPoint *geo);
|
||||
uint32_t get_zoom_in_value() { return zoom_in_value_; }
|
||||
void set_zoom_in_value(uint32_t zoom_in_value) { zoom_in_value_ = zoom_in_value;}
|
||||
void set_is_calc_zoom(bool is_calc_zoom) { is_calc_zoom_ = is_calc_zoom;}
|
||||
|
||||
private:
|
||||
static constexpr double ZOOM_IN_THRESHOLD = 0.00000001;
|
||||
template<typename T_Point>
|
||||
int zoom_in_point(T_Point *geo);
|
||||
|
||||
uint32_t zoom_in_value_;
|
||||
bool is_calc_zoom_;
|
||||
DISALLOW_COPY_AND_ASSIGN(ObGeoZoomInVisitor);
|
||||
};
|
||||
|
||||
|
2
deps/oblib/src/lib/geo/ob_geometry_cast.cpp
vendored
2
deps/oblib/src/lib/geo/ob_geometry_cast.cpp
vendored
@ -1027,7 +1027,7 @@ int ObGeomcollectionTypeCast::cast(const ObGeometry &src,
|
||||
} else {
|
||||
double x = iter->template get<0>();
|
||||
double y = iter->template get<1>();
|
||||
P *point = new (buf) P (x, y, src.get_srid(), allocator);
|
||||
P *point = new (buf) P (x, y, src.get_srid());
|
||||
if (OB_FAIL(res.push_back(*point))) {
|
||||
LOG_WARN("fail to push back point", K(ret));
|
||||
}
|
||||
|
29
deps/oblib/src/lib/geo/ob_s2adapter.cpp
vendored
29
deps/oblib/src/lib/geo/ob_s2adapter.cpp
vendored
@ -295,20 +295,21 @@ int64_t ObS2Adapter::get_mbr(ObSpatialMBR &mbr)
|
||||
mbr.x_max_ = rect.lng_hi().degrees();
|
||||
}
|
||||
} else {
|
||||
ObCartesianBox box;
|
||||
ObArenaAllocator tmp_allocator;
|
||||
ObGeoEvalCtx gis_context(&tmp_allocator, NULL);
|
||||
if (OB_FAIL(gis_context.append_geo_arg(geo_))) {
|
||||
LOG_WARN("build gis context failed", K(ret), K(gis_context.get_geo_count()));
|
||||
} else if (OB_FAIL(ObGeoFuncEnvelope::eval(gis_context, box))) {
|
||||
LOG_WARN("get mbr box failed", K(ret));
|
||||
} else if (box.is_empty()) {
|
||||
LOG_DEBUG("It's might be empty geometry collection", K(geo_->type()), K(geo_->is_empty()));
|
||||
} else {
|
||||
mbr.x_min_ = box.min_corner().get<0>();
|
||||
mbr.y_min_ = box.min_corner().get<1>();
|
||||
mbr.x_max_ = box.max_corner().get<0>();
|
||||
mbr.y_max_ = box.max_corner().get<1>();
|
||||
CREATE_WITH_TEMP_CONTEXT(lib::ContextParam().set_mem_attr(MTL_ID(), "GISModule", ObCtxIds::DEFAULT_CTX_ID)) {
|
||||
ObCartesianBox box;
|
||||
ObGeoEvalCtx gis_context(CURRENT_CONTEXT, NULL);
|
||||
if (OB_FAIL(gis_context.append_geo_arg(geo_))) {
|
||||
LOG_WARN("build gis context failed", K(ret), K(gis_context.get_geo_count()));
|
||||
} else if (OB_FAIL(ObGeoFuncEnvelope::eval(gis_context, box))) {
|
||||
LOG_WARN("get mbr box failed", K(ret));
|
||||
} else if (box.is_empty()) {
|
||||
LOG_DEBUG("It's might be empty geometry collection", K(geo_->type()), K(geo_->is_empty()));
|
||||
} else {
|
||||
mbr.x_min_ = box.min_corner().get<0>();
|
||||
mbr.y_min_ = box.min_corner().get<1>();
|
||||
mbr.x_max_ = box.max_corner().get<0>();
|
||||
mbr.y_max_ = box.max_corner().get<1>();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
14
deps/oblib/src/lib/geo/ob_sdo_geo_object.cpp
vendored
14
deps/oblib/src/lib/geo/ob_sdo_geo_object.cpp
vendored
@ -51,14 +51,14 @@ int ObSdoPoint::to_text(ObStringBuffer &buf)
|
||||
} else if ((len = snprintf(number_buf, 128, format_str_x.ptr(), x_)) < 0) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("fail to val to string", K(ret), K(x_));
|
||||
} else if (OB_FAIL(buf.append(number_buf, len))) {
|
||||
} else if (OB_FAIL(buf.append(number_buf, len, 0))) {
|
||||
LOG_WARN("fail to print gtype", K(ret));
|
||||
} else if (OB_FAIL(buf.append(", "))) {
|
||||
LOG_WARN("fail to print ,", K(ret));
|
||||
} else if ((len = snprintf(number_buf, 128, format_str_y.ptr(), y_)) < 0) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("fail to val to string", K(ret), K(y_));
|
||||
} else if (OB_FAIL(buf.append(number_buf, len))) {
|
||||
} else if (OB_FAIL(buf.append(number_buf, len, 0))) {
|
||||
LOG_WARN("fail to print gtype", K(ret));
|
||||
} else if (OB_FAIL(buf.append(", "))) {
|
||||
LOG_WARN("fail to print ,", K(ret));
|
||||
@ -66,7 +66,7 @@ int ObSdoPoint::to_text(ObStringBuffer &buf)
|
||||
if ((len = snprintf(number_buf, 128, format_str_z.ptr(), z_)) < 0) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("fail to val to string", K(ret), K(x_));
|
||||
} else if (OB_FAIL(buf.append(number_buf, len))) {
|
||||
} else if (OB_FAIL(buf.append(number_buf, len, 0))) {
|
||||
LOG_WARN("fail to print gtype", K(ret));
|
||||
} else if (OB_FAIL(buf.append(")"))){
|
||||
LOG_WARN("fail to print (", K(ret));
|
||||
@ -94,7 +94,7 @@ int ObSdoGeoObject::to_text(ObStringBuffer &buf)
|
||||
} else if ((len = snprintf(number_buf, 128, "%lu", gtype_num)) < 0) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("fail to val to string", K(ret));
|
||||
} else if (OB_FAIL(buf.append(number_buf, len))) {
|
||||
} else if (OB_FAIL(buf.append(number_buf, len, 0))) {
|
||||
LOG_WARN("fail to print gtype", K(ret));
|
||||
} else if (OB_FAIL(buf.append(", "))) {
|
||||
LOG_WARN("fail to print ,", K(ret));
|
||||
@ -102,7 +102,7 @@ int ObSdoGeoObject::to_text(ObStringBuffer &buf)
|
||||
LOG_WARN("fail to print srid", K(ret));
|
||||
} else if (srid_ != UINT32_MAX &&
|
||||
((len = snprintf(number_buf, 128, "%u", srid_)) < 0 ||
|
||||
OB_FAIL(buf.append(number_buf, len)))) {
|
||||
OB_FAIL(buf.append(number_buf, len, 0)))) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("fail to val to string", K(ret), K(len));
|
||||
} else if (OB_FAIL(buf.append(", "))) {
|
||||
@ -125,7 +125,7 @@ int ObSdoGeoObject::to_text(ObStringBuffer &buf)
|
||||
if ((len = snprintf(number_buf, 128, "%lu", elem_info_.at(i))) < 0) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("fail to val to string", K(ret));
|
||||
} else if (OB_FAIL(buf.append(number_buf, len))) {
|
||||
} else if (OB_FAIL(buf.append(number_buf, len, 0))) {
|
||||
LOG_WARN("fail to print gtype", K(ret));
|
||||
} else if (i + 1 != elem_info_.count() && OB_FAIL(buf.append(", "))) {
|
||||
LOG_WARN("fail to print ,", K(ret));
|
||||
@ -152,7 +152,7 @@ int ObSdoGeoObject::to_text(ObStringBuffer &buf)
|
||||
if ((len = snprintf(number_buf, 128, format_str.ptr(), ordinates_.at(i))) < 0) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("fail to val to string", K(ret));
|
||||
} else if (OB_FAIL(buf.append(number_buf, len))) {
|
||||
} else if (OB_FAIL(buf.append(number_buf, len, 0))) {
|
||||
LOG_WARN("fail to print gtype", K(ret));
|
||||
} else if (i + 1 != ordinates_.count() && OB_FAIL(buf.append(", "))) {
|
||||
LOG_WARN("fail to print ,", K(ret));
|
||||
|
20
deps/oblib/src/lib/geo/ob_sdo_geo_object.h
vendored
20
deps/oblib/src/lib/geo/ob_sdo_geo_object.h
vendored
@ -67,13 +67,22 @@ private:
|
||||
class ObSdoGeoObject
|
||||
{
|
||||
public:
|
||||
ObSdoGeoObject(ObGeoType gtype, ObSdoPoint point, uint32_t srid = UINT32_MAX)
|
||||
: gtype_(gtype), point_(point), srid_(srid) {}
|
||||
ObSdoGeoObject(ObGeoType gtype, ObSdoPoint point, ObIAllocator &allocator, uint32_t srid = UINT32_MAX)
|
||||
: gtype_(gtype), point_(point), srid_(srid),
|
||||
elem_info_(OB_MALLOC_NORMAL_BLOCK_SIZE, ModulePageAllocator(allocator, common::ObModIds::OB_MODULE_PAGE_ALLOCATOR)),
|
||||
ordinates_(DEFAULT_PAGE_SIZE_ORDINATES, ModulePageAllocator(allocator, common::ObModIds::OB_MODULE_PAGE_ALLOCATOR))
|
||||
{}
|
||||
|
||||
ObSdoGeoObject(ObGeoType gtype, ObArray<uint64_t> elem_info,
|
||||
ObArray<double> ordinates, uint32_t srid = UINT32_MAX)
|
||||
: gtype_(gtype), elem_info_(elem_info), ordinates_(ordinates), srid_(srid)
|
||||
ObArray<double> ordinates, ObIAllocator &allocator, uint32_t srid = UINT32_MAX)
|
||||
: gtype_(gtype), srid_(srid),
|
||||
elem_info_(OB_MALLOC_NORMAL_BLOCK_SIZE, ModulePageAllocator(allocator, common::ObModIds::OB_MODULE_PAGE_ALLOCATOR)),
|
||||
ordinates_(DEFAULT_PAGE_SIZE_ORDINATES, ModulePageAllocator(allocator, common::ObModIds::OB_MODULE_PAGE_ALLOCATOR))
|
||||
{}
|
||||
ObSdoGeoObject(ObIAllocator &allocator) : gtype_(ObGeoType::GEOTYPEMAX), srid_(UINT32_MAX),
|
||||
elem_info_(OB_MALLOC_NORMAL_BLOCK_SIZE, ModulePageAllocator(allocator, common::ObModIds::OB_MODULE_PAGE_ALLOCATOR)),
|
||||
ordinates_(DEFAULT_PAGE_SIZE_ORDINATES, ModulePageAllocator(allocator, common::ObModIds::OB_MODULE_PAGE_ALLOCATOR))
|
||||
{}
|
||||
ObSdoGeoObject() : gtype_(ObGeoType::GEOTYPEMAX), srid_(UINT32_MAX) {}
|
||||
~ObSdoGeoObject()
|
||||
{}
|
||||
@ -96,13 +105,14 @@ public:
|
||||
TO_STRING_KV(K_(gtype), K_(srid), K_(point), K_(elem_info), K_(ordinates));
|
||||
|
||||
private:
|
||||
static const int64_t DEFAULT_PAGE_SIZE_ORDINATES = 1024; // 1KB
|
||||
bool need_sci_format(double num) { return num <= -1e9 || num >= 1e10; }
|
||||
|
||||
ObGeoType gtype_;
|
||||
ObSdoPoint point_;
|
||||
uint32_t srid_;
|
||||
ObArray<uint64_t> elem_info_;
|
||||
ObArray<double> ordinates_;
|
||||
uint32_t srid_;
|
||||
DISALLOW_COPY_AND_ASSIGN(ObSdoGeoObject);
|
||||
};
|
||||
} // namespace common
|
||||
|
1095
deps/oblib/src/lib/geo/ob_wkb_to_json_bin_visitor.cpp
vendored
Normal file
1095
deps/oblib/src/lib/geo/ob_wkb_to_json_bin_visitor.cpp
vendored
Normal file
File diff suppressed because it is too large
Load Diff
149
deps/oblib/src/lib/geo/ob_wkb_to_json_bin_visitor.h
vendored
Normal file
149
deps/oblib/src/lib/geo/ob_wkb_to_json_bin_visitor.h
vendored
Normal file
@ -0,0 +1,149 @@
|
||||
/**
|
||||
* Copyright (c) 2021 OceanBase
|
||||
* OceanBase CE is licensed under Mulan PubL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PubL v2.
|
||||
* You may obtain a copy of Mulan PubL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPubL-2.0
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PubL v2 for more details.
|
||||
*/
|
||||
|
||||
#ifndef OCEANBASE_LIB_GEO_OB_GEO_TO_JSON_BIN_VISITOR_
|
||||
#define OCEANBASE_LIB_GEO_OB_GEO_TO_JSON_BIN_VISITOR_
|
||||
#include "lib/geo/ob_geo_visitor.h"
|
||||
#include "lib/geo/ob_geo_utils.h"
|
||||
#include "lib/json_type/ob_json_bin.h"
|
||||
#include "lib/xml/ob_multi_mode_bin.h"
|
||||
|
||||
namespace oceanbase
|
||||
{
|
||||
namespace common
|
||||
{
|
||||
class ObWkbToJsonBinVisitor : public ObEmptyGeoVisitor
|
||||
{
|
||||
public:
|
||||
static const int MAX_DIGITS_IN_DOUBLE = 25;
|
||||
explicit ObWkbToJsonBinVisitor(
|
||||
ObIAllocator *allocator,
|
||||
uint32_t max_dec_digits = UINT_MAX32,
|
||||
uint8_t flag = 0,
|
||||
const ObGeoSrid srid = 0);
|
||||
|
||||
~ObWkbToJsonBinVisitor() {}
|
||||
bool prepare(ObGeometry *geo) { UNUSED(geo); return true; }
|
||||
int visit(ObIWkbGeogPoint *geo);
|
||||
int visit(ObIWkbGeomPoint *geo);
|
||||
int visit(ObIWkbGeogLineString *geo);
|
||||
int visit(ObIWkbGeomLineString *geo);
|
||||
int visit(ObIWkbGeogMultiPoint *geo);
|
||||
int visit(ObIWkbGeomMultiPoint *geo);
|
||||
int visit(ObIWkbGeogMultiLineString *geo);
|
||||
int visit(ObIWkbGeomMultiLineString *geo);
|
||||
int visit(ObIWkbGeogPolygon *geo);
|
||||
int visit(ObIWkbGeomPolygon *geo);
|
||||
int visit(ObIWkbGeogMultiPolygon *geo);
|
||||
int visit(ObIWkbGeomMultiPolygon *geo);
|
||||
int visit(ObIWkbGeogCollection *geo);
|
||||
int visit(ObIWkbGeomCollection *geo);
|
||||
|
||||
bool is_end(ObGeometry *geo) { UNUSED(geo); return true; }
|
||||
int to_jsonbin(ObGeometry *geo, ObString &geojsonbin);
|
||||
|
||||
void reset();
|
||||
private:
|
||||
// for Point
|
||||
int appendCoordinatePoint(double x, double y, ObJsonBin &bin, uint64_t start_pos, uint64_t &val_idx);
|
||||
template<typename T_IBIN>
|
||||
int appendPointObj(T_IBIN *geo, const ObString &type_name);
|
||||
// for LineString
|
||||
template<typename T_BIN>
|
||||
int appendLine(const T_BIN *line, ObJsonBin &bin, uint64_t &start_pos, uint64_t &val_idx);
|
||||
template<typename T_IBIN, typename T_BIN>
|
||||
int appendLineObj(T_IBIN *geo, const ObString &type_name);
|
||||
template<typename T_IBIN, typename T_BIN, typename T_BIN_LINE>
|
||||
int appendMultiLineObj(T_IBIN *geo, const ObString &type_name);
|
||||
// for Polygon
|
||||
template<typename T_BIN, typename T_BIN_RING, typename T_BIN_INNER_RING>
|
||||
int appendPolygon(const T_BIN *poly, ObJsonBin &bin, uint64_t &start_pos, uint64_t &val_idx);
|
||||
template<typename T_IBIN, typename T_BIN, typename T_BIN_RING, typename T_BIN_INNER_RING>
|
||||
int appendPolygonObj(T_IBIN *geo, const ObString &type_name);
|
||||
template<typename T_IBIN, typename T_BIN, typename T_BIN_POLY, typename T_BIN_RING, typename T_BIN_INNER_RING>
|
||||
int appendMultiPolygonObj(T_IBIN *geo, const ObString &type_name);
|
||||
// for Collection
|
||||
template<
|
||||
typename T_IPOINT,
|
||||
typename T_IMULTIPOINT,
|
||||
typename T_ILINE,
|
||||
typename T_IMULTILINE,
|
||||
typename T_IPOLY,
|
||||
typename T_IMULTIPOLY,
|
||||
typename T_ICOLLC,
|
||||
typename T_POINT,
|
||||
typename T_MULTIPOINT,
|
||||
typename T_LINE,
|
||||
typename T_MULTILINE,
|
||||
typename T_POLY,
|
||||
typename T_LINEARRING,
|
||||
typename T_INNERRING,
|
||||
typename T_MULTIPOLY,
|
||||
typename T_COLLC>
|
||||
int appendCollectionSub(
|
||||
typename T_COLLC::const_pointer sub_ptr,
|
||||
const T_COLLC *collection,
|
||||
ObJsonBin &bin,
|
||||
uint64_t &start_pos,
|
||||
uint64_t &val_idx);
|
||||
|
||||
int appendCollectionSubWrapper(
|
||||
ObWkbGeogCollection::const_pointer sub_ptr,
|
||||
const ObWkbGeogCollection *collection,
|
||||
ObJsonBin &bin,
|
||||
uint64_t &start_pos,
|
||||
uint64_t &val_idx);
|
||||
int appendCollectionSubWrapper(
|
||||
ObWkbGeomCollection::const_pointer sub_ptr,
|
||||
const ObWkbGeomCollection *collection,
|
||||
ObJsonBin &bin,
|
||||
uint64_t &start_pos,
|
||||
uint64_t &val_idx);
|
||||
template<typename T_IBIN, typename T_BIN>
|
||||
int appendCollectionObj(T_IBIN *geo, const ObString &type_name);
|
||||
// common
|
||||
int appendJsonCommon(
|
||||
const ObString type_name,
|
||||
ObGeometry *geo,
|
||||
ObJsonBin &bin,
|
||||
uint64_t &start_pos,
|
||||
uint64_t &val_idx);
|
||||
int appendMeta(ObJsonBin &bin, uint64_t &start_pos, int type_flag, uint64_t element_count, uint64_t size_size = 3);
|
||||
int appendObjKey(const ObString key_str, ObJsonBin &bin, uint64_t &start_pos, int &key_idx);
|
||||
int fillHeaderSize(ObJsonBin &bin, uint64_t start_pos);
|
||||
int appendCrs(ObJsonBin &bin, uint64_t start_pos, uint64_t &val_idx);
|
||||
int appendCrsProp(ObJsonBin &bin, uint64_t start_pos, uint64_t &val_idx);
|
||||
int appendBbox(ObGeometry *geo, ObJsonBin &bin, uint64_t start_pos, uint64_t &val_idx);
|
||||
int appendString(const ObString &str, ObJsonBin &bin, uint64_t start_pos, uint64_t &val_idx);
|
||||
int appendDouble(double value, ObJsonBin &bin, uint64_t start_pos, uint64_t &val_idx);
|
||||
int appendArrayHeader(
|
||||
ObJsonBin &bin,
|
||||
uint64_t start_pos,
|
||||
uint64_t val_idx,
|
||||
uint64_t size,
|
||||
ObJsonBin &array_bin,
|
||||
uint64_t &array_start_pos);
|
||||
|
||||
ObJsonBuffer json_buf_;
|
||||
uint8_t flag_;
|
||||
ObGeoSrid srid_;
|
||||
ObIAllocator *allocator_;
|
||||
uint32_t max_dec_digits_;
|
||||
bool is_appendCrs;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(ObWkbToJsonBinVisitor);
|
||||
};
|
||||
|
||||
} // namespace common
|
||||
} // namespace oceanbase
|
||||
|
||||
#endif
|
@ -23,6 +23,7 @@
|
||||
#include "lib/geo/ob_geo_func_register.h"
|
||||
#include "lib/utility/ob_fast_convert.h"
|
||||
#include "rpc/obmysql/ob_mysql_global.h"
|
||||
#include "share/rc/ob_tenant_base.h"
|
||||
|
||||
namespace oceanbase {
|
||||
namespace common {
|
||||
@ -696,17 +697,19 @@ int ObWkbToJsonVisitor::appendMySQLFlagInfo(ObGeometry *geo)
|
||||
} else {
|
||||
box_geo = geo;
|
||||
}
|
||||
ObGeoEvalCtx geo_ctx(allocator_);
|
||||
if (OB_FAIL(ret)) {
|
||||
// do nothing
|
||||
} else if (OB_FAIL(geo_ctx.append_geo_arg(box_geo))) {
|
||||
LOG_WARN("build gis context failed", K(ret));
|
||||
} else if (OB_FAIL(ObGeoFunc<ObGeoFuncType::Box>::geo_func::eval(geo_ctx, box))) {
|
||||
LOG_WARN("failed to do box functor failed", K(ret));
|
||||
} else if (OB_FAIL(appendBox(*box))) {
|
||||
LOG_WARN("fail to append bbox field", K(ret));
|
||||
} else if (OB_FAIL(buffer_.append(", "))) {
|
||||
LOG_WARN("fail to append comma", K(ret));
|
||||
CREATE_WITH_TEMP_CONTEXT(lib::ContextParam().set_mem_attr(MTL_ID(), "GISModule", ObCtxIds::DEFAULT_CTX_ID)) {
|
||||
ObGeoEvalCtx geo_ctx(CURRENT_CONTEXT);
|
||||
if (OB_FAIL(ret)) {
|
||||
// do nothing
|
||||
} else if (OB_FAIL(geo_ctx.append_geo_arg(box_geo))) {
|
||||
LOG_WARN("build gis context failed", K(ret));
|
||||
} else if (OB_FAIL(ObGeoFunc<ObGeoFuncType::Box>::geo_func::eval(geo_ctx, box))) {
|
||||
LOG_WARN("failed to do box functor failed", K(ret));
|
||||
} else if (OB_FAIL(appendBox(*box))) {
|
||||
LOG_WARN("fail to append bbox field", K(ret));
|
||||
} else if (OB_FAIL(buffer_.append(", "))) {
|
||||
LOG_WARN("fail to append comma", K(ret));
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
|
303
deps/oblib/src/lib/json_type/ob_json_base.cpp
vendored
303
deps/oblib/src/lib/json_type/ob_json_base.cpp
vendored
@ -23,6 +23,7 @@
|
||||
#include "rpc/obmysql/ob_mysql_global.h" // DOUBLE_TO_STRING_CONVERSION_BUFFER_SIZE
|
||||
#include "lib/charset/ob_charset.h" // for strntod
|
||||
#include "common/ob_smart_var.h" // for SMART_VAR
|
||||
#include "common/ob_smart_call.h"
|
||||
|
||||
namespace oceanbase {
|
||||
namespace common {
|
||||
@ -1689,7 +1690,7 @@ int ObIJsonBase::find_string_method(ObIAllocator* allocator, ObSeekParentInfo &p
|
||||
}
|
||||
} else if (!str_only) {
|
||||
ObJsonBuffer j_buf(allocator);
|
||||
if (OB_FAIL(print(j_buf, true, false, 0))) {
|
||||
if (OB_FAIL(print(j_buf, true, 0, false, 0))) {
|
||||
trans_fail = true;
|
||||
} else {
|
||||
ObJsonString* tmp_ans = static_cast<ObJsonString*> (allocator->alloc(sizeof(ObJsonString)));
|
||||
@ -1773,7 +1774,7 @@ int ObIJsonBase::find_trans_method(ObIAllocator* allocator, ObSeekParentInfo &pa
|
||||
src = ObString(get_data_length(), get_data());
|
||||
} else if (type != ObJsonNodeType::J_NULL) {
|
||||
ObJsonBuffer j_buf(allocator);
|
||||
if (OB_FAIL(print(j_buf, true, false, 0))) {
|
||||
if (OB_FAIL(print(j_buf, true, 0, false, 0))) {
|
||||
trans_fail = true;
|
||||
} else {
|
||||
src = ObString(j_buf.length(), j_buf.ptr());
|
||||
@ -3200,7 +3201,7 @@ int ObIJsonBase::get_str_comp_result(ObIAllocator* allocator, ObSeekParentInfo &
|
||||
right_str = ObString(var->get_data_length(), var->get_data());
|
||||
} else {
|
||||
ObJsonBuffer j_buf(allocator);
|
||||
if (OB_FAIL(var->print(j_buf, true, false, 0))) {
|
||||
if (OB_FAIL(var->print(j_buf, true, 0, false, 0))) {
|
||||
LOG_WARN("fail to get string of sql_var.", K(ret));
|
||||
} else {
|
||||
right_str = ObString(j_buf.length(), j_buf.ptr());
|
||||
@ -3566,7 +3567,7 @@ int ObIJsonBase::print_array(ObJsonBuffer &j_buf, uint64_t depth, bool is_pretty
|
||||
jb_ptr = &j_bin;
|
||||
if (OB_FAIL(get_array_element(i, jb_ptr))) {
|
||||
LOG_WARN("fail to get array element", K(ret), K(depth), K(i));
|
||||
} else if (OB_FAIL(jb_ptr->print(j_buf, true, is_pretty, depth))) {
|
||||
} else if (OB_FAIL(jb_ptr->print(j_buf, true, 0, is_pretty, depth))) {
|
||||
LOG_WARN("fail to print json value to string", K(ret), K(i), K(is_pretty), K(depth));
|
||||
}
|
||||
}
|
||||
@ -3631,7 +3632,7 @@ int ObIJsonBase::print_object(ObJsonBuffer &j_buf, uint64_t depth, bool is_prett
|
||||
jb_ptr = &j_bin;
|
||||
if (OB_FAIL(get_object_value(i, jb_ptr))) {
|
||||
LOG_WARN("fail to get object value", K(ret), K(i), K(is_pretty), K(depth));
|
||||
} else if (OB_FAIL(jb_ptr->print(j_buf, true, is_pretty, depth))) { // value
|
||||
} else if (OB_FAIL(jb_ptr->print(j_buf, true, 0, is_pretty, depth))) { // value
|
||||
LOG_WARN("fail to print json value to string", K(ret), K(i), K(is_pretty), K(depth));
|
||||
}
|
||||
}
|
||||
@ -3823,7 +3824,7 @@ int ObIJsonBase::print_opaque(ObJsonBuffer &j_buf, uint64_t depth, bool is_quote
|
||||
// base64::typeXX:<binary data>
|
||||
if (OB_FAIL(base64_buf.append("base64:type"))) {
|
||||
LOG_WARN("fail to append \" base64:type \"", K(ret), K(depth));
|
||||
} else if (OB_FAIL(base64_buf.append(field_buf, field_len))) {
|
||||
} else if (OB_FAIL(base64_buf.append(field_buf, field_len, 0))) {
|
||||
LOG_WARN("fail to append field type", K(ret), K(depth), K(f_type));
|
||||
} else if (OB_FAIL(base64_buf.append(":"))) {
|
||||
LOG_WARN("fail to append \":\"", K(ret), K(depth));
|
||||
@ -3847,7 +3848,7 @@ int ObIJsonBase::print_opaque(ObJsonBuffer &j_buf, uint64_t depth, bool is_quote
|
||||
base64_buf.length()))) {
|
||||
LOG_WARN("fail to add double quote", K(ret), K(depth), K(f_type), K(base64_buf));
|
||||
}
|
||||
} else if (OB_FAIL(j_buf.append(base64_buf.ptr(), base64_buf.length()))) {
|
||||
} else if (OB_FAIL(j_buf.append(base64_buf.ptr(), base64_buf.length(), 0))) {
|
||||
LOG_WARN("fail to append base64_buf", K(ret), K(depth), K(f_type), K(base64_buf));
|
||||
}
|
||||
}
|
||||
@ -3858,138 +3859,141 @@ int ObIJsonBase::print_opaque(ObJsonBuffer &j_buf, uint64_t depth, bool is_quote
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObIJsonBase::print(ObJsonBuffer &j_buf, bool is_quoted, bool is_pretty, uint64_t depth) const
|
||||
int ObIJsonBase::print(ObJsonBuffer &j_buf, bool is_quoted, uint64_t reserve_len, bool is_pretty, uint64_t depth) const
|
||||
{
|
||||
INIT_SUCC(ret);
|
||||
ObJsonNodeType j_type = json_type();
|
||||
|
||||
// consistent with mysql 5.7
|
||||
// in mysql 8.0, varstring is handled as json string, obvarchartype is considered as varstring.
|
||||
switch (j_type) {
|
||||
case ObJsonNodeType::J_DATE:
|
||||
case ObJsonNodeType::J_TIME:
|
||||
case ObJsonNodeType::J_DATETIME:
|
||||
case ObJsonNodeType::J_TIMESTAMP:
|
||||
case ObJsonNodeType::J_ORACLEDATE:
|
||||
case ObJsonNodeType::J_ODATE:
|
||||
case ObJsonNodeType::J_OTIMESTAMP:
|
||||
case ObJsonNodeType::J_OTIMESTAMPTZ: {
|
||||
if (OB_FAIL(print_jtime(j_buf, is_quoted))) {
|
||||
LOG_WARN("fail to change jtime to string", K(ret), K(is_quoted), K(is_pretty), K(depth));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case ObJsonNodeType::J_ARRAY: {
|
||||
++depth;
|
||||
if (OB_FAIL(SMART_CALL(print_array(j_buf, depth, is_pretty)))) {
|
||||
LOG_WARN("fail to change jarray to string", K(ret), K(is_quoted), K(is_pretty), K(depth));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case ObJsonNodeType::J_OBJECT: {
|
||||
++depth;
|
||||
if (OB_FAIL(SMART_CALL(print_object(j_buf, depth, is_pretty)))) {
|
||||
LOG_WARN("fail to print object to string", K(ret), K(depth), K(j_type), K(is_pretty));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case ObJsonNodeType::J_BOOLEAN: {
|
||||
if (get_boolean() ? OB_FAIL(j_buf.append("true", sizeof("true") - 1)) :
|
||||
OB_FAIL(j_buf.append("false", sizeof("false") - 1))) {
|
||||
LOG_WARN("fail to append boolean", K(ret), K(get_boolean()), K(j_type));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case ObJsonNodeType::J_DECIMAL:
|
||||
case ObJsonNodeType::J_ODECIMAL: {
|
||||
if (OB_FAIL(print_decimal(j_buf))) {
|
||||
LOG_WARN("fail to print decimal to string", K(ret), K(depth), K(j_type));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case ObJsonNodeType::J_DOUBLE:
|
||||
case ObJsonNodeType::J_ODOUBLE: {
|
||||
if (OB_FAIL(print_double(j_buf))) {
|
||||
LOG_WARN("fail to print double to string", K(ret), K(depth), K(j_type));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case ObJsonNodeType::J_OFLOAT: {
|
||||
if (OB_FAIL(print_float(j_buf))) {
|
||||
LOG_WARN("fail to print float to string", K(ret), K(depth), K(j_type));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case ObJsonNodeType::J_NULL: {
|
||||
if (!(this)->is_real_json_null(this) && OB_FAIL(j_buf.append("", 0))) {
|
||||
LOG_WARN("fail to append NULL upper string to buffer", K(ret), K(j_type));
|
||||
} else if ((this)->is_real_json_null(this) && OB_FAIL(j_buf.append("null", sizeof("null") - 1))) {
|
||||
LOG_WARN("fail to append null string to buffer", K(ret), K(j_type));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case ObJsonNodeType::J_OPAQUE: {
|
||||
if (OB_FAIL(print_opaque(j_buf, depth, is_quoted))) {
|
||||
LOG_WARN("fail to print opaque to string", K(ret), K(depth), K(j_type), K(is_quoted));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case ObJsonNodeType::J_STRING:
|
||||
case ObJsonNodeType::J_OBINARY:
|
||||
case ObJsonNodeType::J_OOID:
|
||||
case ObJsonNodeType::J_ORAWHEX:
|
||||
case ObJsonNodeType::J_ORAWID:
|
||||
case ObJsonNodeType::J_ODAYSECOND:
|
||||
case ObJsonNodeType::J_OYEARMONTH: {
|
||||
uint64_t data_len = get_data_length();
|
||||
const char *data = get_data();
|
||||
if (is_quoted && data_len == 0) {
|
||||
if (OB_FAIL(j_buf.append("\"\"", 2))) {
|
||||
LOG_WARN("fail to append empty string", K(ret), K(j_type), K(is_quoted));
|
||||
if (reserve_len > 0 && OB_FAIL(j_buf.reserve(reserve_len * 1.2))) {
|
||||
LOG_WARN("failed to reserve j_str", K(ret), K(reserve_len));
|
||||
} else {
|
||||
// consistent with mysql 5.7
|
||||
// in mysql 8.0, varstring is handled as json string, obvarchartype is considered as varstring.
|
||||
switch (j_type) {
|
||||
case ObJsonNodeType::J_DATE:
|
||||
case ObJsonNodeType::J_TIME:
|
||||
case ObJsonNodeType::J_DATETIME:
|
||||
case ObJsonNodeType::J_TIMESTAMP:
|
||||
case ObJsonNodeType::J_ORACLEDATE:
|
||||
case ObJsonNodeType::J_ODATE:
|
||||
case ObJsonNodeType::J_OTIMESTAMP:
|
||||
case ObJsonNodeType::J_OTIMESTAMPTZ: {
|
||||
if (OB_FAIL(print_jtime(j_buf, is_quoted))) {
|
||||
LOG_WARN("fail to change jtime to string", K(ret), K(is_quoted), K(is_pretty), K(depth));
|
||||
}
|
||||
} else if (OB_ISNULL(data) && data_len != 0) {
|
||||
ret = OB_ERR_NULL_VALUE;
|
||||
LOG_WARN("data is null", K(ret), K(data_len));
|
||||
} else if (OB_FAIL(ObJsonBaseUtil::append_string(j_buf, is_quoted, data, data_len))) {
|
||||
// if data is null, data_len is 0, it is an empty string
|
||||
LOG_WARN("fail to append string", K(ret), K(j_type), K(is_quoted));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case ObJsonNodeType::J_INT:
|
||||
case ObJsonNodeType::J_OINT: {
|
||||
char tmp_buf[ObFastFormatInt::MAX_DIGITS10_STR_SIZE] = {0};
|
||||
int64_t len = ObFastFormatInt::format_signed(get_int(), tmp_buf);
|
||||
if (OB_FAIL(j_buf.append(tmp_buf, len))) {
|
||||
LOG_WARN("fail to append json int to buffer", K(ret), K(get_int()), K(len), K(j_type));
|
||||
case ObJsonNodeType::J_ARRAY: {
|
||||
++depth;
|
||||
if (OB_FAIL(SMART_CALL(print_array(j_buf, depth, is_pretty)))) {
|
||||
LOG_WARN("fail to change jarray to string", K(ret), K(is_quoted), K(is_pretty), K(depth));
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case ObJsonNodeType::J_UINT:
|
||||
case ObJsonNodeType::J_OLONG: {
|
||||
char tmp_buf[ObFastFormatInt::MAX_DIGITS10_STR_SIZE] = {0};
|
||||
int64_t len = ObFastFormatInt::format_unsigned(get_uint(), tmp_buf);
|
||||
if (OB_FAIL(j_buf.append(tmp_buf, len))) {
|
||||
LOG_WARN("fail to append json uint to buffer", K(ret), K(get_uint()), K(len), K(j_type));
|
||||
case ObJsonNodeType::J_OBJECT: {
|
||||
++depth;
|
||||
if (OB_FAIL(SMART_CALL(print_object(j_buf, depth, is_pretty)))) {
|
||||
LOG_WARN("fail to print object to string", K(ret), K(depth), K(j_type), K(is_pretty));
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("undefined json node type", K(ret), K(j_type));
|
||||
break;
|
||||
case ObJsonNodeType::J_BOOLEAN: {
|
||||
if (get_boolean() ? OB_FAIL(j_buf.append("true", sizeof("true") - 1, 0)) :
|
||||
OB_FAIL(j_buf.append("false", sizeof("false") - 1, 0))) {
|
||||
LOG_WARN("fail to append boolean", K(ret), K(get_boolean()), K(j_type));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case ObJsonNodeType::J_DECIMAL:
|
||||
case ObJsonNodeType::J_ODECIMAL: {
|
||||
if (OB_FAIL(print_decimal(j_buf))) {
|
||||
LOG_WARN("fail to print decimal to string", K(ret), K(depth), K(j_type));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case ObJsonNodeType::J_DOUBLE:
|
||||
case ObJsonNodeType::J_ODOUBLE: {
|
||||
if (OB_FAIL(print_double(j_buf))) {
|
||||
LOG_WARN("fail to print double to string", K(ret), K(depth), K(j_type));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case ObJsonNodeType::J_OFLOAT: {
|
||||
if (OB_FAIL(print_float(j_buf))) {
|
||||
LOG_WARN("fail to print float to string", K(ret), K(depth), K(j_type));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case ObJsonNodeType::J_NULL: {
|
||||
if (!(this)->is_real_json_null(this) && OB_FAIL(j_buf.append("", 0, 0))) {
|
||||
LOG_WARN("fail to append NULL upper string to buffer", K(ret), K(j_type));
|
||||
} else if ((this)->is_real_json_null(this) && OB_FAIL(j_buf.append("null", sizeof("null") - 1, 0))) {
|
||||
LOG_WARN("fail to append null string to buffer", K(ret), K(j_type));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case ObJsonNodeType::J_OPAQUE: {
|
||||
if (OB_FAIL(print_opaque(j_buf, depth, is_quoted))) {
|
||||
LOG_WARN("fail to print opaque to string", K(ret), K(depth), K(j_type), K(is_quoted));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case ObJsonNodeType::J_STRING:
|
||||
case ObJsonNodeType::J_OBINARY:
|
||||
case ObJsonNodeType::J_OOID:
|
||||
case ObJsonNodeType::J_ORAWHEX:
|
||||
case ObJsonNodeType::J_ORAWID:
|
||||
case ObJsonNodeType::J_ODAYSECOND:
|
||||
case ObJsonNodeType::J_OYEARMONTH: {
|
||||
uint64_t data_len = get_data_length();
|
||||
const char *data = get_data();
|
||||
if (is_quoted && data_len == 0) {
|
||||
if (OB_FAIL(j_buf.append("\"\"", 2, 0))) {
|
||||
LOG_WARN("fail to append empty string", K(ret), K(j_type), K(is_quoted));
|
||||
}
|
||||
} else if (OB_ISNULL(data) && data_len != 0) {
|
||||
ret = OB_ERR_NULL_VALUE;
|
||||
LOG_WARN("data is null", K(ret), K(data_len));
|
||||
} else if (OB_FAIL(ObJsonBaseUtil::append_string(j_buf, is_quoted, data, data_len))) {
|
||||
// if data is null, data_len is 0, it is an empty string
|
||||
LOG_WARN("fail to append string", K(ret), K(j_type), K(is_quoted));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case ObJsonNodeType::J_INT:
|
||||
case ObJsonNodeType::J_OINT: {
|
||||
char tmp_buf[ObFastFormatInt::MAX_DIGITS10_STR_SIZE] = {0};
|
||||
int64_t len = ObFastFormatInt::format_signed(get_int(), tmp_buf);
|
||||
if (OB_FAIL(j_buf.append(tmp_buf, len, 0))) {
|
||||
LOG_WARN("fail to append json int to buffer", K(ret), K(get_int()), K(len), K(j_type));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case ObJsonNodeType::J_UINT:
|
||||
case ObJsonNodeType::J_OLONG: {
|
||||
char tmp_buf[ObFastFormatInt::MAX_DIGITS10_STR_SIZE] = {0};
|
||||
int64_t len = ObFastFormatInt::format_unsigned(get_uint(), tmp_buf);
|
||||
if (OB_FAIL(j_buf.append(tmp_buf, len, 0))) {
|
||||
LOG_WARN("fail to append json uint to buffer", K(ret), K(get_uint()), K(len), K(j_type));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("undefined json node type", K(ret), K(j_type));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -4809,26 +4813,6 @@ int ObIJsonBase::compare(const ObIJsonBase &other, int &res, bool is_path) const
|
||||
}
|
||||
|
||||
|
||||
uint32_t ObIJsonBase::depth()
|
||||
{
|
||||
INIT_SUCC(ret);
|
||||
uint32_t depth = 0;
|
||||
|
||||
if (is_bin()) {
|
||||
ObArenaAllocator allocator;
|
||||
ObIJsonBase *j_tree = NULL;
|
||||
if (OB_FAIL(ObJsonBaseFactory::transform(&allocator, this, ObJsonInType::JSON_TREE, j_tree))) {
|
||||
LOG_WARN("fail to transform to tree", K(ret));
|
||||
} else {
|
||||
depth = j_tree->depth();
|
||||
}
|
||||
} else {
|
||||
depth = static_cast<ObJsonNode *>(this)->depth();
|
||||
}
|
||||
|
||||
return depth;
|
||||
}
|
||||
|
||||
int ObIJsonBase::get_location(ObJsonBuffer &path)
|
||||
{
|
||||
INIT_SUCC(ret);
|
||||
@ -6297,15 +6281,16 @@ int ObJsonBaseUtil::append_newline_and_indent(ObJsonBuffer &j_buf, uint64_t leve
|
||||
{
|
||||
// Append newline and two spaces per indentation level.
|
||||
INIT_SUCC(ret);
|
||||
uint64_t reserve_size = level << 1;
|
||||
|
||||
if (OB_FAIL(j_buf.append("\n"))) {
|
||||
LOG_WARN("fail to append newline to buffer", K(ret), K(level));
|
||||
} else if (OB_FAIL(j_buf.reserve(level * 2))) {
|
||||
} else if (OB_FAIL(j_buf.reserve(reserve_size))) {
|
||||
LOG_WARN("fail to reserve memory for buffer", K(ret), K(level));
|
||||
} else {
|
||||
char str[level * 2];
|
||||
MEMSET(str, ' ', level * 2);
|
||||
if (OB_FAIL(j_buf.append(str, level * 2))) {
|
||||
char str[reserve_size];
|
||||
MEMSET(str, ' ', reserve_size);
|
||||
if (OB_FAIL(j_buf.append(str, reserve_size, 0))) {
|
||||
LOG_WARN("fail to append space to buffer", K(ret), K(level));
|
||||
}
|
||||
}
|
||||
@ -6359,7 +6344,7 @@ int ObJsonBaseUtil::escape_character(char c, ObJsonBuffer &j_buf)
|
||||
case '"':
|
||||
case '\\': {
|
||||
char str[1] = {c};
|
||||
if (OB_FAIL(j_buf.append(str, 1))) {
|
||||
if (OB_FAIL(j_buf.append(str, 1, 0))) {
|
||||
LOG_WARN("fail to append c to j_buf", K(ret), K(c));
|
||||
}
|
||||
break;
|
||||
@ -6371,11 +6356,11 @@ int ObJsonBaseUtil::escape_character(char c, ObJsonBuffer &j_buf)
|
||||
static char _dig_vec_lower[] = "0123456789abcdefghijklmnopqrstuvwxyz";
|
||||
char high[1] = {_dig_vec_lower[(c & 0xf0) >> 4]};
|
||||
char low[1] = {_dig_vec_lower[(c & 0x0f)]};
|
||||
if (OB_FAIL(j_buf.append("u00", 3))) {
|
||||
if (OB_FAIL(j_buf.append("u00", 3, 0))) {
|
||||
LOG_WARN("fail to append \"u00\" to j_buf", K(ret));
|
||||
} else if (OB_FAIL(j_buf.append(high, 1))) {
|
||||
} else if (OB_FAIL(j_buf.append(high, 1, 0))) {
|
||||
LOG_WARN("fail to append four high bits to j_buf", K(ret));
|
||||
} else if (OB_FAIL(j_buf.append(low, 1))) {
|
||||
} else if (OB_FAIL(j_buf.append(low, 1, 0))) {
|
||||
LOG_WARN("fail to append four low bits to j_buf", K(ret));
|
||||
}
|
||||
break;
|
||||
@ -6416,7 +6401,7 @@ int ObJsonBaseUtil::add_double_quote(ObJsonBuffer &j_buf, const char *cptr, uint
|
||||
|
||||
// Most characters do not need to be escaped.
|
||||
// Append the characters that do not need to be escaped
|
||||
if (OB_FAIL(j_buf.append(cptr, next_special - cptr))) {
|
||||
if (OB_FAIL(j_buf.append(cptr, next_special - cptr, 0))) {
|
||||
LOG_WARN("fail to append common segments to j_buf", K(ret), K(length),
|
||||
K(next_special - cptr));
|
||||
break;
|
||||
@ -6452,7 +6437,7 @@ int ObJsonBaseUtil::append_string(ObJsonBuffer &j_buf, bool is_quoted,
|
||||
LOG_WARN("fail to add double quote", K(ret), K(length));
|
||||
}
|
||||
} else {
|
||||
if (OB_FAIL(j_buf.append(data, length))) {
|
||||
if (OB_FAIL(j_buf.append(data, length, 0))) {
|
||||
LOG_WARN("fail to append data", K(ret), K(length));
|
||||
}
|
||||
}
|
||||
|
4
deps/oblib/src/lib/json_type/ob_json_base.h
vendored
4
deps/oblib/src/lib/json_type/ob_json_base.h
vendored
@ -309,7 +309,7 @@ public:
|
||||
// @param [in] is_pretty Whether from JSON_PRETTY function or not.
|
||||
// @param [in] depth The depth of json tree.
|
||||
// @return Returns OB_SUCCESS on success, error code otherwise.
|
||||
virtual int print(ObJsonBuffer &j_buf, bool is_quoted,
|
||||
virtual int print(ObJsonBuffer &j_buf, bool is_quoted, uint64_t reserve_len = 0,
|
||||
bool is_pretty = false, uint64_t depth = 0) const;
|
||||
|
||||
// calculate json hash value
|
||||
@ -330,7 +330,7 @@ public:
|
||||
// Get depth of current json document.
|
||||
//
|
||||
// @return uint32_t.
|
||||
virtual uint32_t depth();
|
||||
virtual uint32_t depth() const = 0;
|
||||
|
||||
// Returns a string in json path form from the root node to the current location.
|
||||
//
|
||||
|
90
deps/oblib/src/lib/json_type/ob_json_bin.cpp
vendored
90
deps/oblib/src/lib/json_type/ob_json_bin.cpp
vendored
@ -653,6 +653,37 @@ int ObJsonBinSerializer::serialize_json_decimal(ObJsonDecimal *json_dec, ObJsonB
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObJsonBinSerializer::serialize_json_double(double value, ObJsonBuffer &result)
|
||||
{
|
||||
INIT_SUCC(ret);
|
||||
if (isnan(value) || isinf(value)) {
|
||||
ret = OB_INVALID_NUMERIC;
|
||||
LOG_WARN("invalid float value", K(ret), K(value));
|
||||
} else if (OB_FAIL(result.append(reinterpret_cast<const char*>(&value), sizeof(double), 0))) {
|
||||
LOG_WARN("failed to append float json obj", K(ret));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObJsonBinSerializer::serialize_json_string(ObJBVerType vertype, const ObString &value, ObJsonBuffer &result)
|
||||
{
|
||||
INIT_SUCC(ret);
|
||||
int64_t str_len_size = serialization::encoded_length_vi64(value.length());
|
||||
int64_t pos = result.length() + sizeof(uint8_t);
|
||||
if (OB_FAIL(result.append(reinterpret_cast<const char*>(&vertype), sizeof(uint8_t), 0))) {
|
||||
LOG_WARN("failed to serialize type for str json obj", K(ret), K(str_len_size));
|
||||
} else if (OB_FAIL(result.reserve(str_len_size))) {
|
||||
LOG_WARN("failed to reserver serialize size for str json obj", K(ret), K(str_len_size));
|
||||
} else if (OB_FAIL(serialization::encode_vi64(result.ptr(), result.capacity(), pos, value.length()))) {
|
||||
LOG_WARN("failed to serialize for str json obj", K(ret), K(pos), K(value.length()));
|
||||
} else if (OB_FAIL(result.set_length(pos))) {
|
||||
LOG_WARN("failed to update len for str json obj", K(ret), K(pos));
|
||||
} else if (OB_FAIL(result.append(value.ptr(), value.length(), 0))) {
|
||||
LOG_WARN("failed to append string json obj value", K(ret));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObJsonBinSerializer::serialize_json_value(ObJsonNode *json_tree, ObJsonBuffer &result)
|
||||
{
|
||||
INIT_SUCC(ret);
|
||||
@ -693,11 +724,8 @@ int ObJsonBinSerializer::serialize_json_value(ObJsonNode *json_tree, ObJsonBuffe
|
||||
case ObJsonNodeType::J_ODOUBLE: {
|
||||
const ObJsonDouble *d = static_cast<const ObJsonDouble*>(json_tree);
|
||||
double value = d->value();
|
||||
if (isnan(value) || isinf(value)) {
|
||||
ret = OB_INVALID_NUMERIC;
|
||||
LOG_WARN("invalid double value", K(ret), K(value));
|
||||
} else if (OB_FAIL(result.append(reinterpret_cast<const char*>(&value), sizeof(double)))) {
|
||||
LOG_WARN("failed to append double json obj", K(ret));
|
||||
if (OB_FAIL(ObJsonBinSerializer::serialize_json_double(value, result))) {
|
||||
LOG_WARN("failed to serialize json double", K(ret), K(value));
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -720,19 +748,9 @@ int ObJsonBinSerializer::serialize_json_value(ObJsonNode *json_tree, ObJsonBuffe
|
||||
case ObJsonNodeType::J_OYEARMONTH:
|
||||
case ObJsonNodeType::J_STRING: { // [type][length][string]
|
||||
const ObJsonString *sub_obj = static_cast<const ObJsonString*>(json_tree);
|
||||
int64_t ser_len = serialization::encoded_length_vi64(sub_obj->length());
|
||||
int64_t pos = result.length() + sizeof(uint8_t);
|
||||
ObJBVerType vertype = ObJsonVerType::get_json_vertype(json_tree->json_type());
|
||||
if (OB_FAIL(result.append(reinterpret_cast<const char*>(&vertype), sizeof(uint8_t)))) {
|
||||
LOG_WARN("failed to serialize type for str json obj", K(ret), K(ser_len));
|
||||
} else if (OB_FAIL(result.reserve(ser_len))) {
|
||||
LOG_WARN("failed to reserver serialize size for str json obj", K(ret), K(ser_len));
|
||||
} else if (OB_FAIL(serialization::encode_vi64(result.ptr(), result.capacity(), pos, sub_obj->length()))) {
|
||||
LOG_WARN("failed to serialize for str json obj", K(ret), K(ser_len));
|
||||
} else if (OB_FAIL(result.set_length(pos))) {
|
||||
LOG_WARN("failed to update len for str json obj", K(ret), K(pos));
|
||||
} else if (OB_FAIL(result.append(sub_obj->value().ptr(), sub_obj->length()))) {
|
||||
LOG_WARN("failed to append string json obj value", K(ret));
|
||||
if (OB_FAIL(ObJsonBinSerializer::serialize_json_string(vertype, sub_obj->value(), result))) {
|
||||
LOG_WARN("failed to serialize json string", K(ret), K(sub_obj->value()));
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -950,7 +968,7 @@ int ObJsonBinSerializer::serialize(ObJsonNode *json_tree, ObString &data)
|
||||
if (root_type == ObJsonNodeType::J_ARRAY || root_type == ObJsonNodeType::J_OBJECT) {
|
||||
if (OB_FAIL(ObJsonBin::add_doc_header_v0(result))) {
|
||||
LOG_WARN("add_doc_header_v0 fail", K(ret));
|
||||
} else if (OB_FAIL(serialize_json_value(json_tree, result))) {
|
||||
} else if (OB_FAIL(SMART_CALL(serialize_json_value(json_tree, result)))) {
|
||||
LOG_WARN("serialize json tree fail", K(ret), K(root_type));
|
||||
} else if (OB_FAIL(ObJsonBin::set_doc_header_v0(result, result.length()))) {
|
||||
LOG_WARN("set_doc_header_v0 fail", K(ret));
|
||||
@ -960,7 +978,7 @@ int ObJsonBinSerializer::serialize(ObJsonNode *json_tree, ObString &data)
|
||||
if (!ObJsonVerType::is_opaque_or_string(ver_type) &&
|
||||
OB_FAIL(result.append(reinterpret_cast<const char*>(&ver_type), sizeof(uint8_t)))) {
|
||||
LOG_WARN("failed to serialize json tree at append used size", K(ret), K(result.length()));
|
||||
} else if (OB_FAIL(serialize_json_value(json_tree, result))) { // do recursion
|
||||
} else if (OB_FAIL(SMART_CALL(serialize_json_value(json_tree, result)))) { // do recursion
|
||||
LOG_WARN("failed to serialize json tree at recursion", K(ret));
|
||||
}
|
||||
}
|
||||
@ -1458,7 +1476,7 @@ int ObJsonBin::deserialize_json_object_v0(ObJsonObject *object)
|
||||
LOG_WARN("ob_write_string fail", K(ret), K(i), K(ori_key));
|
||||
} else if (OB_FAIL(get_value(i, child_bin))) {
|
||||
LOG_WARN("get child value fail", K(ret));
|
||||
} else if (OB_FAIL(child_bin.deserialize_json_value(node))) {
|
||||
} else if (OB_FAIL(SMART_CALL(child_bin.deserialize_json_value(node)))) {
|
||||
LOG_WARN("deserialize child node fail", K(ret), K(i), K(child_bin));
|
||||
} else if (OB_FAIL(object->add(key, node, false, true, false, is_schema_))) {
|
||||
LOG_WARN("add node to obj fail", K(ret), K(i));
|
||||
@ -3782,6 +3800,28 @@ int ObJsonBin::reset()
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint32_t ObJsonBin::depth() const
|
||||
{
|
||||
INIT_SUCC(ret);
|
||||
uint32_t max_child = 0;
|
||||
if (is_json_scalar(meta_.json_type())) {
|
||||
max_child = 0;
|
||||
} else {
|
||||
uint64_t count = meta_.element_count();
|
||||
uint64_t value_entry_start = meta_.value_offset_start_;
|
||||
for (uint64_t i = 0; OB_SUCC(ret) && i < count; i++) {
|
||||
ObJsonBin value(allocator_);
|
||||
if (OB_FAIL(this->get_value(i, value))) {
|
||||
LOG_WARN("get value failed.", K(ret), K(i), K(count));
|
||||
} else {
|
||||
max_child = max(max_child, value.depth());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return max_child + 1;
|
||||
}
|
||||
|
||||
int ObJsonBin::init_meta()
|
||||
{
|
||||
INIT_SUCC(ret);
|
||||
@ -4334,22 +4374,22 @@ int ObJsonVar::append_var(uint64_t var, uint8_t type, ObJsonBuffer &result)
|
||||
switch (size) {
|
||||
case JBLS_UINT8: {
|
||||
uint8_t var_trans = static_cast<uint8_t>(var);
|
||||
ret = result.append(reinterpret_cast<const char*>(&var_trans), sizeof(uint8_t));
|
||||
ret = result.append(reinterpret_cast<const char*>(&var_trans), sizeof(uint8_t), 0);
|
||||
break;
|
||||
}
|
||||
case JBLS_UINT16: {
|
||||
uint16_t var_trans = static_cast<uint16_t>(var);
|
||||
ret = result.append(reinterpret_cast<const char*>(&var_trans), sizeof(uint16_t));
|
||||
ret = result.append(reinterpret_cast<const char*>(&var_trans), sizeof(uint16_t), 0);
|
||||
break;
|
||||
}
|
||||
case JBLS_UINT32: {
|
||||
uint32_t var_trans = static_cast<uint32_t>(var);
|
||||
ret = result.append(reinterpret_cast<const char*>(&var_trans), sizeof(uint32_t));
|
||||
ret = result.append(reinterpret_cast<const char*>(&var_trans), sizeof(uint32_t), 0);
|
||||
break;
|
||||
}
|
||||
case JBLS_UINT64: {
|
||||
uint64_t var_trans = static_cast<uint64_t>(var);
|
||||
ret = result.append(reinterpret_cast<const char*>(&var_trans), sizeof(uint64_t));
|
||||
ret = result.append(reinterpret_cast<const char*>(&var_trans), sizeof(uint64_t), 0);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
@ -5149,7 +5189,7 @@ int ObJsonBinMeta::to_header(ObJsonBuffer &buffer)
|
||||
LOG_WARN("type not object or array", K(ret), "json type", json_type());
|
||||
} else if (OB_FAIL(to_header(header))) {
|
||||
LOG_WARN("to_header fail", K(ret));
|
||||
} else if (OB_FAIL(buffer.append(reinterpret_cast<char*>(&header), sizeof(header)))) {
|
||||
} else if (OB_FAIL(buffer.append(reinterpret_cast<char*>(&header), sizeof(header), 0))) {
|
||||
LOG_WARN("append header to buffer fail", K(ret));
|
||||
} else if (OB_FAIL(ObJsonVar::append_var(element_count(), element_count_var_type(), buffer))) {
|
||||
LOG_WARN("failed to append array header member count", K(ret));
|
||||
|
16
deps/oblib/src/lib/json_type/ob_json_bin.h
vendored
16
deps/oblib/src/lib/json_type/ob_json_bin.h
vendored
@ -597,6 +597,12 @@ public:
|
||||
int array_append(ObIJsonBase *value) override;
|
||||
int array_insert(uint64_t index, ObIJsonBase *value) override;
|
||||
int object_add(const common::ObString &key, ObIJsonBase *value) override;
|
||||
int set_key_entry(int index, uint64_t key_offset, uint64_t key_len, bool check=true);
|
||||
int set_value_entry(int index, uint64_t value_offset, uint8_t value_type, bool check=true);
|
||||
int set_current(const ObString &data, int64_t offset);
|
||||
int set_obj_size(uint64_t obj_size);
|
||||
static int add_doc_header_v0(ObJsonBuffer &buffer);
|
||||
static int set_doc_header_v0(ObJsonBuffer &buffer,int64_t extend_seg_offset);
|
||||
public:
|
||||
static OB_INLINE ObJBVerType get_null_vertype() { return J_NULL_V0; }
|
||||
static OB_INLINE ObJBVerType get_decimal_vertype() { return J_DECIMAL_V0; }
|
||||
@ -632,8 +638,6 @@ public:
|
||||
private:
|
||||
static OB_INLINE bool is_forward_v0(uint8_t type) { return J_FORWARD_V0 == type; }
|
||||
static OB_INLINE bool is_doc_header_v0(uint8_t type) { return J_DOC_HEADER_V0 == type; }
|
||||
static int add_doc_header_v0(ObJsonBuffer &buffer);
|
||||
static int set_doc_header_v0(ObJsonBuffer &buffer,int64_t extend_seg_offset);
|
||||
static int set_doc_header_v0(ObString &buffer, int64_t extend_seg_offset);
|
||||
public:
|
||||
TO_STRING_KV(
|
||||
@ -838,6 +842,7 @@ public:
|
||||
// release resource
|
||||
void destroy();
|
||||
void set_is_schema(bool is_schema) {is_schema_ = is_schema;}
|
||||
OB_INLINE uint32_t depth() const override;
|
||||
virtual int reset();
|
||||
OB_INLINE const ObILobCursor* get_cursor() const { return cursor_; }
|
||||
OB_INLINE ObILobCursor* get_cursor() { return cursor_; }
|
||||
@ -986,15 +991,12 @@ private:
|
||||
int get_value_entry(int index, uint64_t &value_offset, uint8_t &value_type) const;
|
||||
int64_t get_value_entry_size() const;
|
||||
int get_value(int index, ObJsonBin &value) const;
|
||||
int set_key_entry(int index, uint64_t key_offset, uint64_t key_len, bool check=true);
|
||||
int set_value_entry(int index, uint64_t value_offset, uint8_t value_type, bool check=true);
|
||||
OB_INLINE uint64_t get_value_entry_offset(int index) const { return meta_.get_value_entry_offset(index); }
|
||||
OB_INLINE uint64_t get_key_entry_offset(int index) const { return meta_.get_key_entry_offset(index); }
|
||||
OB_INLINE uint8_t entry_var_type() const { return meta_.entry_var_type(); }
|
||||
OB_INLINE uint64_t entry_var_size() const { return meta_.entry_var_size(); }
|
||||
|
||||
OB_INLINE uint64_t obj_size() const { return meta_.obj_size(); }
|
||||
int set_obj_size(uint64_t obj_size);
|
||||
OB_INLINE uint64_t obj_size_var_size() const { return meta_.obj_size_var_size(); }
|
||||
OB_INLINE uint64_t get_obj_size_offset() const { return meta_.get_obj_size_offset(); }
|
||||
OB_INLINE uint8_t obj_size_var_type() const { return meta_.obj_size_var_type(); }
|
||||
@ -1023,8 +1025,6 @@ private:
|
||||
int record_insert_offset(int index, int64_t value_offset, int64_t value_len, uint8_t value_type);
|
||||
int get_json_path_at_iter(int index, ObString &path) const;
|
||||
|
||||
int set_current(const ObString &data, int64_t offset);
|
||||
|
||||
int parse_type_();
|
||||
int skip_type_byte_();
|
||||
int parse_doc_header_();
|
||||
@ -1127,6 +1127,8 @@ public:
|
||||
public:
|
||||
static int serialize_json_integer(int64_t value, ObJsonBuffer &result);
|
||||
static int serialize_json_decimal(ObJsonDecimal *json_dec, ObJsonBuffer &result);
|
||||
static int serialize_json_double(double value, ObJsonBuffer &result);
|
||||
static int serialize_json_string(ObJBVerType vertype, const ObString &value, ObJsonBuffer &result);
|
||||
|
||||
private:
|
||||
ObIAllocator *allocator_;
|
||||
|
5
deps/oblib/src/lib/ob_name_def.h
vendored
5
deps/oblib/src/lib/ob_name_def.h
vendored
@ -1098,8 +1098,11 @@
|
||||
#define N_XML_ATTRIBUTES "xmlattributes"
|
||||
#define N_EXTRACTVALUE "extractvalue"
|
||||
#define N_EXTRACT_XML "extract_xml"
|
||||
#define N_EXISTSNODE_XML "existsnode_xml"
|
||||
#define N_XMLSERIALIZE "xmlserialize"
|
||||
#define N_XMLCAST "xmlcast"
|
||||
#define N_XML_CONCAT "xmlconcat"
|
||||
#define N_XML_FOREST "xmlforest"
|
||||
#define N_UPDATEXML "updatexml"
|
||||
#define N_INSERTCHILDXML "insertchildxml"
|
||||
#define N_XMLSEQUENCE "xmlsequence"
|
||||
@ -1189,4 +1192,6 @@
|
||||
#define N_RB_SELECT "rb_select"
|
||||
#define N_GET_MYSQL_ROUTINE_PARAMETER_TYPE_STR "get_mysql_routine_parameter_type_str"
|
||||
#define N_ORA_LOGIN_USER "ora_login_user"
|
||||
#define N_PRIV_ST_GEOHASH "_st_geohash"
|
||||
#define N_PRIV_ST_MAKEPOINT "_st_makepoint"
|
||||
#endif //OCEANBASE_LIB_OB_NAME_DEF_H_
|
||||
|
10
deps/oblib/src/lib/string/ob_string_buffer.cpp
vendored
10
deps/oblib/src/lib/string/ob_string_buffer.cpp
vendored
@ -58,10 +58,10 @@ int ObStringBuffer::get_result_string(ObString &buffer)
|
||||
|
||||
int ObStringBuffer::append(const char *str)
|
||||
{
|
||||
return append(str, NULL == str ? 0 : strlen(str));
|
||||
return append(str, NULL == str ? 0 : strlen(str), 0);
|
||||
}
|
||||
|
||||
int ObStringBuffer::append(const char *str, const uint64_t len, int8_t index)
|
||||
int ObStringBuffer::append(const char *str, const uint64_t len, int8_t flag)
|
||||
{
|
||||
INIT_SUCC(ret);
|
||||
if (OB_ISNULL(allocator_)) {
|
||||
@ -77,7 +77,7 @@ int ObStringBuffer::append(const char *str, const uint64_t len, int8_t index)
|
||||
if (need_len < len_) {
|
||||
ret = OB_SIZE_OVERFLOW;
|
||||
LOG_WARN("size over flow", K(ret), K(need_len), K(len_));
|
||||
} else if (OB_FAIL(reserve(index == -1 ? need_len : len))) {
|
||||
} else if (OB_FAIL(reserve(flag == -1 ? need_len : len))) {
|
||||
LOG_WARN("reserve data failed", K(ret), K(need_len), K(len_));
|
||||
} else {
|
||||
MEMCPY(data_ + len_, str, len);
|
||||
@ -90,9 +90,9 @@ int ObStringBuffer::append(const char *str, const uint64_t len, int8_t index)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObStringBuffer::append(const ObString &str)
|
||||
int ObStringBuffer::append(const ObString &str, int8_t flag)
|
||||
{
|
||||
return append(str.ptr(), str.length());
|
||||
return append(str.ptr(), str.length(), flag);
|
||||
}
|
||||
|
||||
int ObStringBuffer::reserve(const uint64_t len)
|
||||
|
10
deps/oblib/src/lib/string/ob_string_buffer.h
vendored
10
deps/oblib/src/lib/string/ob_string_buffer.h
vendored
@ -36,8 +36,14 @@ public:
|
||||
int get_result_string(ObString &buffer);
|
||||
|
||||
int append(const char *str);
|
||||
int append(const char *str, const uint64_t len, int8_t index = -1);
|
||||
int append(const ObString &str);
|
||||
|
||||
// Append data later
|
||||
// @param [in] flag reserves flag bits for other subsequent expansions
|
||||
// @return Returns OB_SUCCESS on success, error code otherwise.
|
||||
// When the flag is the default value -1, the size of len_*2 + len is used each time to expand the memory.
|
||||
// If the data is large, the default value is not used, and the memory application size is len_ + len.
|
||||
int append(const char *str, const uint64_t len, int8_t flag = -1);
|
||||
int append(const ObString &str, int8_t flag = -1);
|
||||
int reserve(const uint64_t len);
|
||||
int extend(const uint64_t len);
|
||||
|
||||
|
47
deps/oblib/src/lib/xml/ob_binary_aggregate.cpp
vendored
47
deps/oblib/src/lib/xml/ob_binary_aggregate.cpp
vendored
@ -231,7 +231,7 @@ int ObBinAggSerializer::add_element_xml(ObXmlBin *xml_bin)
|
||||
0 : key_info_.at(current_count - 1)->offset_ + key_info_.at(current_count -1)->key_len_;
|
||||
|
||||
if (OB_FAIL(key_info_.push_back(key_info))) {
|
||||
LOG_WARN("failed to append key info.", K(ret));
|
||||
LOG_WARN("failed to push back key info into array.", K(ret), K(key_info));
|
||||
} else if (OB_FAIL(key_.append(key.ptr(), key.length()))) {
|
||||
LOG_WARN("failed to append key into key_", K(ret), K(key));
|
||||
}
|
||||
@ -517,7 +517,9 @@ int ObBinAggSerializer::construct_header()
|
||||
int64_t buff_length = buff_.length();
|
||||
if (type_ == AGG_XML) {
|
||||
buff_length = buff_.length();
|
||||
doc_header_.serialize(doc_header_buff);
|
||||
if (OB_FAIL(doc_header_.serialize(doc_header_buff))) {
|
||||
LOG_WARN("failed to serialize doc header.", K(ret));
|
||||
}
|
||||
}
|
||||
|
||||
int64_t total_size = ObBinAggSerializer::estimate_total(value_len_ + key_len_,
|
||||
@ -526,7 +528,8 @@ int ObBinAggSerializer::construct_header()
|
||||
static_cast<ObMulModeNodeType>(header_type_),
|
||||
total_size,
|
||||
count_);
|
||||
if (OB_FAIL(header_serializer.serialize())) {
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (OB_FAIL(header_serializer.serialize())) {
|
||||
LOG_WARN("header serialize failed.", K(ret));
|
||||
} else if (OB_FALSE_IT(header_str = header_serializer.buffer()->string())) {
|
||||
} else if (OB_FAIL(buff_.reserve(total_size))) {
|
||||
@ -577,16 +580,24 @@ void ObBinAggSerializer::set_value_entry_for_json(int64_t entry_idx, uint8_t ty
|
||||
*reinterpret_cast<uint8_t*>(write_buf) = type;
|
||||
}
|
||||
|
||||
void ObBinAggSerializer::set_key(int64_t key_offset, int64_t key_len)
|
||||
int ObBinAggSerializer::set_key(int64_t key_offset, int64_t key_len)
|
||||
{
|
||||
INIT_SUCC(ret);
|
||||
char* write_buf = key_.ptr() + key_offset;
|
||||
buff_.append(write_buf, key_len);
|
||||
if (OB_FAIL(buff_.append(write_buf, key_len, 0))) {
|
||||
LOG_WARN("failed to append buff.", K(ret), K(buff_.length()), K(key_len));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void ObBinAggSerializer::set_value(int64_t value_offset, int64_t value_len)
|
||||
int ObBinAggSerializer::set_value(int64_t value_offset, int64_t value_len)
|
||||
{
|
||||
INIT_SUCC(ret);
|
||||
char* write_buf = value_.ptr() + value_offset;
|
||||
buff_.append(write_buf, value_len, 0);
|
||||
if (OB_FAIL(buff_.append(write_buf, value_len, 0))) {
|
||||
LOG_WARN("failed to append buff.", K(ret), K(buff_.length()), K(value_len));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void ObBinAggSerializer::set_xml_decl(ObString version, ObString encoding, uint16_t standalone)
|
||||
@ -812,31 +823,35 @@ int ObBinAggSerializer::deal_last_unparsed()
|
||||
return ret;
|
||||
}
|
||||
|
||||
void ObBinAggSerializer::construct_key_and_value()
|
||||
int ObBinAggSerializer::construct_key_and_value()
|
||||
{
|
||||
INIT_SUCC(ret);
|
||||
if (!is_json_array()) {
|
||||
for (int64_t i = 0; i < key_info_.count(); i++) {
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < key_info_.count(); i++) {
|
||||
ObAggBinKeyInfo *key_info = key_info_.at(i);
|
||||
if ((has_unique_flag() && key_info->unparsed_)) {
|
||||
// do nothing
|
||||
} else {
|
||||
set_key(key_info->offset_, key_info->key_len_);
|
||||
} else if (OB_FAIL(set_key(key_info->offset_, key_info->key_len_))) {
|
||||
LOG_WARN("failed to set key.", K(ret), K(key_info->offset_), K(key_info->key_len_));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!has_unique_flag()) {
|
||||
buff_.append(value_.ptr(), value_.length(), 0);
|
||||
if (OB_FAIL(buff_.append(value_.ptr(), value_.length(), 0))) {
|
||||
LOG_WARN("failed to append value into buff_.", K(ret), K(value_.length()));
|
||||
}
|
||||
} else {
|
||||
for (int64_t i = 0; i < key_info_.count(); i++) {
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < key_info_.count(); i++) {
|
||||
ObAggBinKeyInfo *key_info = key_info_.at(i);
|
||||
if (key_info->unparsed_) {
|
||||
// do nothing
|
||||
} else {
|
||||
set_value(key_info->value_offset_, key_info->value_len_);
|
||||
} else if (OB_FAIL(set_value(key_info->value_offset_, key_info->value_len_))) {
|
||||
LOG_WARN("failed to set value", K(ret), K(key_info->value_offset_), K(key_info->value_len_));
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObBinAggSerializer::copy_and_reset(ObIAllocator* new_allocator,
|
||||
@ -912,7 +927,7 @@ int ObBinAggSerializer::serialize()
|
||||
LOG_WARN("failed to construct header.", K(ret));
|
||||
} else if (OB_FAIL(construct_meta())) { // construct meta_
|
||||
LOG_WARN("failed to construct meta.", K(ret));
|
||||
} else if (OB_FALSE_IT(construct_key_and_value())) { // merge key_ and value_
|
||||
} else if (OB_FAIL(construct_key_and_value())) { // merge key_ and value_
|
||||
} else if (OB_FAIL(rewrite_total_size())) { // write total
|
||||
LOG_WARN("failed to rewrite total size.", K(ret));
|
||||
}
|
||||
|
6
deps/oblib/src/lib/xml/ob_binary_aggregate.h
vendored
6
deps/oblib/src/lib/xml/ob_binary_aggregate.h
vendored
@ -87,7 +87,7 @@ public:
|
||||
|
||||
private:
|
||||
int construct_meta();
|
||||
void construct_key_and_value();
|
||||
int construct_key_and_value();
|
||||
|
||||
int rewrite_total_size();
|
||||
|
||||
@ -128,8 +128,8 @@ private:
|
||||
ObIAllocator* get_array_allocator() { return arr_allocator_ == nullptr ? allocator_ : arr_allocator_; }
|
||||
|
||||
void set_value_entry_for_json(int64_t entry_idx, uint8_t type, int64_t value_offset);
|
||||
void set_key(int64_t key_offset, int64_t key_len);
|
||||
void set_value(int64_t value_offset, int64_t value_len);
|
||||
int set_key(int64_t key_offset, int64_t key_len);
|
||||
int set_value(int64_t value_offset, int64_t value_len);
|
||||
static int64_t estimate_total(int64_t base_length, int64_t count, int32_t type, int64_t xml_header_size = 4);
|
||||
static int text_serialize(ObString value, ObStringBuffer &res);
|
||||
static int text_deserialize(ObString value, ObStringBuffer &res);
|
||||
|
@ -174,6 +174,23 @@ int64_t ObIMulModeBase::get_serialize_size()
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ObIMulModeBase::get_bin_size(uint64_t &size)
|
||||
{
|
||||
INIT_SUCC(ret);
|
||||
if (is_binary() && meta_.data_type_ == OB_XML_TYPE) {
|
||||
ObXmlBin *bin = nullptr;
|
||||
if (OB_ISNULL(bin = static_cast<ObXmlBin*>(this))) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("failed to cast to bin.", K(ret));
|
||||
} else if (bin->meta_.len_ != 0) {
|
||||
size = bin->meta_.len_;
|
||||
} else if (OB_NOT_NULL(bin->buffer_.get_allocator())) {
|
||||
size = bin->buffer_.length();
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObIMulModeBase::print(ObStringBuffer& x_buf, uint32_t format_flag, uint64_t depth, uint64_t size, ObCollationType charset)
|
||||
{
|
||||
INIT_SUCC(ret);
|
||||
@ -313,7 +330,7 @@ int ObIMulModeBase::print_attr(ObStringBuffer& x_buf, uint32_t format_flag)
|
||||
if (OB_FAIL(ObXmlParserUtils::escape_xml_text(value, x_buf))) {
|
||||
LOG_WARN("fail to print text with escape char", K(ret), K(value));
|
||||
}
|
||||
} else if (OB_FAIL(x_buf.append(value))) {
|
||||
} else if (OB_FAIL(x_buf.append(value, 0))) {
|
||||
LOG_WARN("fail to print value in attr", K(ret), K(value));
|
||||
}
|
||||
|
||||
@ -348,7 +365,7 @@ int ObIMulModeBase::print_ns(ObStringBuffer& x_buf, uint32_t format_flag)
|
||||
if (OB_FAIL(ObXmlParserUtils::escape_xml_text(value, x_buf))) {
|
||||
LOG_WARN("fail to print text with escape char", K(ret), K(value));
|
||||
}
|
||||
} else if (OB_FAIL(x_buf.append(value))) {
|
||||
} else if (OB_FAIL(x_buf.append(value, 0))) {
|
||||
LOG_WARN("fail to print value in ns", K(ret), K(value));
|
||||
}
|
||||
|
||||
@ -372,12 +389,12 @@ int ObIMulModeBase::print_pi(ObStringBuffer& x_buf, uint32_t format_flag)
|
||||
LOG_WARN("fail to print =\" in attr", K(ret));
|
||||
} else if (OB_FAIL(x_buf.append("<?"))) {
|
||||
LOG_WARN("fail to print <? in pi", K(ret));
|
||||
} else if (OB_FAIL(x_buf.append(key))) {
|
||||
} else if (OB_FAIL(x_buf.append(key, 0))) {
|
||||
LOG_WARN("fail to print target in attr", K(ret), K(key));
|
||||
} else if (value.empty()) { // if value is empty then do nothing
|
||||
} else if (OB_FAIL(x_buf.append(" "))) {
|
||||
LOG_WARN("fail to print space in attr", K(ret));
|
||||
} else if (OB_FAIL(x_buf.append(value))) {
|
||||
} else if (OB_FAIL(x_buf.append(value, 0))) {
|
||||
LOG_WARN("fail to print value in attr", K(ret), K(value));
|
||||
}
|
||||
|
||||
@ -394,13 +411,18 @@ int ObIMulModeBase::print_unparsed(ObStringBuffer& x_buf, ObCollationType charse
|
||||
ObString version = get_version();
|
||||
ObString encoding = get_encoding();
|
||||
uint16_t standalone = get_standalone();
|
||||
if (!(format_flag & ObXmlFormatType::HIDE_PROLOG) && has_flags(XML_DECL_FLAG)) {
|
||||
uint64_t reserve_size = 0;
|
||||
if (OB_FAIL(get_bin_size(reserve_size))) {
|
||||
LOG_WARN("failed to get binary size.", K(ret));
|
||||
} else if (reserve_size > 0 && OB_FAIL(x_buf.reserve(reserve_size))) {
|
||||
LOG_WARN("failed to reserve x_buf.", K(ret), K(reserve_size));
|
||||
} else if (!(format_flag & ObXmlFormatType::HIDE_PROLOG) && has_flags(XML_DECL_FLAG)) {
|
||||
if (OB_FAIL(x_buf.append("<?xml"))) {
|
||||
LOG_WARN("fail to print <?xml in document", K(ret));
|
||||
} else if (!version.empty()) {
|
||||
if (OB_FAIL(x_buf.append(" version=\""))) {
|
||||
LOG_WARN("fail to print version=\" in document", K(ret));
|
||||
} else if (OB_FAIL(x_buf.append(version))) {
|
||||
} else if (OB_FAIL(x_buf.append(version, 0))) {
|
||||
LOG_WARN("fail to print version value in document", K(ret), K(version));
|
||||
} else if (OB_FAIL(x_buf.append("\""))) {
|
||||
LOG_WARN("fail to print \" in document", K(ret));
|
||||
@ -412,7 +434,7 @@ int ObIMulModeBase::print_unparsed(ObStringBuffer& x_buf, ObCollationType charse
|
||||
}
|
||||
if (OB_FAIL(x_buf.append(" encoding=\""))) {
|
||||
LOG_WARN("fail to print encoding=\" in document", K(ret));
|
||||
} else if (OB_FAIL(x_buf.append(encoding))) {
|
||||
} else if (OB_FAIL(x_buf.append(encoding, 0))) {
|
||||
LOG_WARN("fail to print encoding value in document", K(ret), K(encoding), K(charset));
|
||||
} else if (OB_FAIL(x_buf.append("\""))) {
|
||||
LOG_WARN("fail to print \" in document", K(ret));
|
||||
@ -461,14 +483,18 @@ int ObIMulModeBase::print_document(ObStringBuffer& x_buf, ObCollationType charse
|
||||
ObString encoding = get_encoding();
|
||||
uint16_t standalone = get_standalone();
|
||||
bool need_newline_end = true;
|
||||
|
||||
if (!(format_flag & ObXmlFormatType::HIDE_PROLOG) && has_flags(XML_DECL_FLAG)) {
|
||||
uint64_t reserve_size = 0;
|
||||
if (OB_FAIL(get_bin_size(reserve_size))) {
|
||||
LOG_WARN("failed to get binary size.", K(ret));
|
||||
} else if (reserve_size > 0 && OB_FAIL(x_buf.reserve(reserve_size))) {
|
||||
LOG_WARN("failed to reserve x_buf.", K(ret), K(reserve_size));
|
||||
} else if (!(format_flag & ObXmlFormatType::HIDE_PROLOG) && has_flags(XML_DECL_FLAG)) {
|
||||
if (OB_FAIL(x_buf.append("<?xml"))) {
|
||||
LOG_WARN("fail to print <?xml in document", K(ret));
|
||||
} else if (!version.empty()) {
|
||||
if (OB_FAIL(x_buf.append(" version=\""))) {
|
||||
LOG_WARN("fail to print version=\" in document", K(ret));
|
||||
} else if (OB_FAIL(x_buf.append(version))) {
|
||||
} else if (OB_FAIL(x_buf.append(version, 0))) {
|
||||
LOG_WARN("fail to print version value in document", K(ret), K(version));
|
||||
} else if (OB_FAIL(x_buf.append("\""))) {
|
||||
LOG_WARN("fail to print \" in document", K(ret));
|
||||
@ -480,7 +506,7 @@ int ObIMulModeBase::print_document(ObStringBuffer& x_buf, ObCollationType charse
|
||||
}
|
||||
if (OB_FAIL(x_buf.append(" encoding=\""))) {
|
||||
LOG_WARN("fail to print encoding=\" in document", K(ret));
|
||||
} else if (OB_FAIL(x_buf.append(encoding))) {
|
||||
} else if (OB_FAIL(x_buf.append(encoding, 0))) {
|
||||
LOG_WARN("fail to print encoding value in document", K(ret), K(encoding), K(charset));
|
||||
} else if (OB_FAIL(x_buf.append("\""))) {
|
||||
LOG_WARN("fail to print \" in document", K(ret));
|
||||
@ -551,14 +577,19 @@ int ObIMulModeBase::print_content(ObStringBuffer& x_buf, bool with_encoding, boo
|
||||
{
|
||||
INIT_SUCC(ret);
|
||||
bool need_newline_end = true;
|
||||
uint64_t reserve_size = 0;
|
||||
|
||||
if (with_encoding || with_version) {
|
||||
if (OB_FAIL(get_bin_size(reserve_size))) {
|
||||
LOG_WARN("failed to get binary size.", K(ret));
|
||||
} else if (reserve_size > 0 && OB_FAIL(x_buf.reserve(reserve_size))) {
|
||||
LOG_WARN("failed to reserve x_buf.", K(ret), K(reserve_size));
|
||||
} else if (with_encoding || with_version) {
|
||||
if (OB_FAIL(x_buf.append("<?xml"))) {
|
||||
LOG_WARN("fail to print <?xml in document", K(ret));
|
||||
} else if (with_version) {
|
||||
if (OB_FAIL(x_buf.append(" version=\""))) {
|
||||
LOG_WARN("fail to print version=\" in document", K(ret));
|
||||
} else if (OB_FAIL(x_buf.append(param_list.version))) {
|
||||
} else if (OB_FAIL(x_buf.append(param_list.version, 0))) {
|
||||
LOG_WARN("fail to print version value in document", K(ret), K(param_list.version));
|
||||
} else if (OB_FAIL(x_buf.append("\""))) {
|
||||
LOG_WARN("fail to print \" in document", K(ret));
|
||||
@ -567,7 +598,7 @@ int ObIMulModeBase::print_content(ObStringBuffer& x_buf, bool with_encoding, boo
|
||||
if (OB_SUCC(ret) && with_encoding) {
|
||||
if (OB_FAIL(x_buf.append(" encoding=\""))) {
|
||||
LOG_WARN("fail to print encoding=\" in document", K(ret));
|
||||
} else if (OB_FAIL(x_buf.append(param_list.encode))) {
|
||||
} else if (OB_FAIL(x_buf.append(param_list.encode, 0))) {
|
||||
LOG_WARN("fail to print encoding value in document", K(ret), K(param_list.encode));
|
||||
} else if (OB_FAIL(x_buf.append("\""))) {
|
||||
LOG_WARN("fail to print \" in document", K(ret));
|
||||
@ -650,7 +681,7 @@ int ObIMulModeBase::print_cdata(ObStringBuffer& x_buf, uint32_t format_flag)
|
||||
}
|
||||
} else if (OB_FAIL(x_buf.append("<![CDATA["))) {
|
||||
LOG_WARN("fail to print <![CDATA[ in pi", K(ret));
|
||||
} else if (OB_FAIL(x_buf.append(value))) {
|
||||
} else if (OB_FAIL(x_buf.append(value, 0))) {
|
||||
LOG_WARN("fail to print text in attr", K(ret), K(value));
|
||||
} else if (OB_FAIL(x_buf.append("]]>"))) {
|
||||
LOG_WARN("fail to print ]]> in attr", K(ret));
|
||||
@ -668,7 +699,7 @@ int ObIMulModeBase::print_comment(ObStringBuffer& x_buf, uint32_t format_flag)
|
||||
LOG_WARN("fail to get value.", K(ret));
|
||||
} else if (OB_FAIL(x_buf.append("<!--"))) {
|
||||
LOG_WARN("fail to print <!-- in pi", K(ret));
|
||||
} else if (OB_FAIL(x_buf.append(value))) {
|
||||
} else if (OB_FAIL(x_buf.append(value, 0))) {
|
||||
LOG_WARN("fail to print text in attr", K(ret), K(value));
|
||||
} else if (OB_FAIL(x_buf.append("-->"))) {
|
||||
LOG_WARN("fail to print --> in attr", K(ret));
|
||||
@ -686,7 +717,7 @@ int ObIMulModeBase::print_text(ObStringBuffer& x_buf, uint32_t format_flag)
|
||||
if (OB_FAIL(ObXmlParserUtils::escape_xml_text(value, x_buf))) {
|
||||
LOG_WARN("fail to print text with escape char", K(ret), K(value));
|
||||
}
|
||||
} else if (OB_FAIL(x_buf.append(value))) {
|
||||
} else if (OB_FAIL(x_buf.append(value, 0))) {
|
||||
LOG_WARN("fail to print text", K(ret), K(value));
|
||||
}
|
||||
return ret;
|
||||
|
@ -135,6 +135,7 @@ enum ObNodeDataType: int8_t {
|
||||
};
|
||||
|
||||
class ObIMulModeBase;
|
||||
class ObXmlNode;
|
||||
struct ObNodeMetaData {
|
||||
ObNodeMetaData(ObNodeMemType m_type, ObNodeDataType data_type)
|
||||
: m_type_(m_type),
|
||||
@ -371,6 +372,7 @@ public:
|
||||
* node type, json xml together enum
|
||||
*/
|
||||
virtual ObMulModeNodeType type() const = 0;
|
||||
virtual int clone(ObMulModeMemCtx *ctx, ObXmlNode *&node) { return OB_NOT_SUPPORTED; }
|
||||
|
||||
bool is_binary() const { return meta_.m_type_ == BINARY_TYPE; }
|
||||
|
||||
@ -601,6 +603,8 @@ public:
|
||||
* virtual int to_time(int64_t &value) const = 0;
|
||||
* virtual int to_bit(uint64_t &value) const = 0;
|
||||
**/
|
||||
private:
|
||||
int get_bin_size(uint64_t &size);
|
||||
|
||||
protected:
|
||||
ObNodeMetaData meta_;
|
||||
|
76
deps/oblib/src/lib/xml/ob_xml_bin.cpp
vendored
76
deps/oblib/src/lib/xml/ob_xml_bin.cpp
vendored
@ -49,10 +49,12 @@ int ObXmlElementBinHeader::serialize(ObStringBuffer& buffer)
|
||||
|
||||
*reinterpret_cast<uint8_t*>(data + pos) = flags_;
|
||||
pos += sizeof(uint8_t);
|
||||
buffer.set_length(pos);
|
||||
if (OB_FAIL(buffer.set_length(pos))) {
|
||||
LOG_WARN("failed to set length.", K(ret), K(pos));
|
||||
}
|
||||
|
||||
uint32_t left = header_len - sizeof(uint8_t);
|
||||
if (is_prefix_) {
|
||||
if (OB_SUCC(ret) && is_prefix_) {
|
||||
if (OB_FAIL(serialization::encode_vi64(data, pos + left, pos, prefix_len_))) {
|
||||
LOG_WARN("failed to serialize for str xml obj", K(ret), K(prefix_len_size_));
|
||||
} else if (OB_FAIL(buffer.set_length(pos))) {
|
||||
@ -61,7 +63,9 @@ int ObXmlElementBinHeader::serialize(ObStringBuffer& buffer)
|
||||
LOG_WARN("failed to append string obj value", K(ret));
|
||||
} else {
|
||||
pos += prefix_len_;
|
||||
buffer.set_length(pos);
|
||||
if (OB_FAIL(buffer.set_length(pos))) {
|
||||
LOG_WARN("failed to set length.", K(ret), K(pos));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -138,7 +142,9 @@ int ObXmlAttrBinHeader::serialize(ObStringBuffer* buffer)
|
||||
LOG_WARN("failed to append string obj value", K(ret));
|
||||
}
|
||||
} else {
|
||||
buffer->set_length(pos);
|
||||
if (OB_FAIL(buffer->set_length(pos))) {
|
||||
LOG_WARN("failed to set length.", K(ret), K(pos));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -408,8 +414,8 @@ int ObXmlTextSerializer::serialize()
|
||||
LOG_WARN("failed to reserver serialize size for str obj", K(ret), K(ser_len));
|
||||
} else if (OB_FAIL(ObMulModeVar::set_var(type_, ObMulModeBinLenSize::MBL_UINT8, buffer_->ptr() + buffer_->length()))) {
|
||||
LOG_WARN("failed to set var", K(ret), K(type_));
|
||||
} else {
|
||||
buffer_->set_length(buffer_->length() + header_len);
|
||||
} else if (OB_FAIL(buffer_->set_length(buffer_->length() + header_len))) {
|
||||
LOG_WARN("failed to set length.", K(ret), K(buffer_->length()), K(header_len));
|
||||
}
|
||||
|
||||
int64_t pos = buffer_->length();
|
||||
@ -542,21 +548,28 @@ ObXmlElementSerializer::ObXmlElementSerializer(ObIMulModeBase* root, ObStringBuf
|
||||
key_start_ = (value_entry_size_ + sizeof(uint8_t)) * size() + value_entry_start_;
|
||||
}
|
||||
|
||||
void ObXmlElementSerializer::set_index_entry(int64_t origin_index, int64_t sort_index)
|
||||
int ObXmlElementSerializer::set_index_entry(int64_t origin_index, int64_t sort_index)
|
||||
{
|
||||
INIT_SUCC(ret);
|
||||
int64_t offset = index_start_ + origin_index * header_.get_count_var_size();
|
||||
char* write_buf = header_.buffer()->ptr() + offset;
|
||||
ObMulModeVar::set_var(sort_index, header_.get_count_var_size_type(), write_buf);
|
||||
return ObMulModeVar::set_var(sort_index, header_.get_count_var_size_type(), write_buf);
|
||||
}
|
||||
|
||||
void ObXmlElementSerializer::set_key_entry(int64_t entry_idx, int64_t key_offset, int64_t key_len)
|
||||
int ObXmlElementSerializer::set_key_entry(int64_t entry_idx, int64_t key_offset, int64_t key_len)
|
||||
{
|
||||
INIT_SUCC(ret);
|
||||
int64_t offset = key_entry_start_ + entry_idx * (header_.get_entry_var_size() * 2);
|
||||
char* write_buf = header_.buffer()->ptr() + offset;
|
||||
ObMulModeVar::set_var(key_offset, header_.get_entry_var_size_type(), write_buf);
|
||||
|
||||
write_buf += header_.get_entry_var_size();
|
||||
ObMulModeVar::set_var(key_len, header_.get_entry_var_size_type(), write_buf);
|
||||
if (OB_FAIL(ObMulModeVar::set_var(key_offset, header_.get_entry_var_size_type(), write_buf))) {
|
||||
LOG_WARN("failed to set var.", K(ret), K(key_offset));
|
||||
} else {
|
||||
write_buf += header_.get_entry_var_size();
|
||||
if (OB_FAIL(ObMulModeVar::set_var(key_len, header_.get_entry_var_size_type(), write_buf))) {
|
||||
LOG_WARN("failed to set var.", K(ret), K(key_len));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObXmlElementSerializer::reserve_meta()
|
||||
@ -568,18 +581,19 @@ int ObXmlElementSerializer::reserve_meta()
|
||||
uint32_t reserve_size = key_start_ - index_start_;
|
||||
if (OB_FAIL(buffer.reserve(reserve_size))) {
|
||||
LOG_WARN("failed to reserve buffer.", K(ret), K(reserve_size), K(header_.start()));
|
||||
} else {
|
||||
buffer.set_length(pos + reserve_size);
|
||||
} else if (OB_FAIL(buffer.set_length(pos + reserve_size))) {
|
||||
LOG_WARN("failed to set length.", K(ret), K(pos + reserve_size));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void ObXmlElementSerializer::set_value_entry(int64_t entry_idx, uint8_t type, int64_t value_offset)
|
||||
int ObXmlElementSerializer::set_value_entry(int64_t entry_idx, uint8_t type, int64_t value_offset)
|
||||
{
|
||||
INIT_SUCC(ret);
|
||||
int64_t offset = value_entry_start_ + entry_idx * (header_.get_entry_var_size() + sizeof(uint8_t));
|
||||
char* write_buf = header_.buffer()->ptr() + offset;
|
||||
*reinterpret_cast<uint8_t*>(write_buf) = type;
|
||||
ObMulModeVar::set_var(value_offset, header_.get_entry_var_size_type(), write_buf + sizeof(uint8_t));
|
||||
return ObMulModeVar::set_var(value_offset, header_.get_entry_var_size_type(), write_buf + sizeof(uint8_t));
|
||||
}
|
||||
|
||||
int ObXmlElementSerializer::serialize_child_key(const ObString& key, int64_t idx)
|
||||
@ -590,9 +604,8 @@ int ObXmlElementSerializer::serialize_child_key(const ObString& key, int64_t idx
|
||||
|
||||
if (OB_FAIL(buffer.append(key.ptr(), key.length()))) {
|
||||
LOG_WARN("failed to append key string.", K(ret), K(buffer.length()), K(key.length()));
|
||||
} else {
|
||||
// idx fill later
|
||||
set_key_entry(idx, key_offset, key.length());
|
||||
} else if (OB_FAIL(set_key_entry(idx, key_offset, key.length()))) { // idx fill later
|
||||
LOG_WARN("failed to set key entry", K(key_offset), K(key.length()));
|
||||
}
|
||||
|
||||
return ret;
|
||||
@ -628,8 +641,8 @@ int ObXmlElementSerializer::serialize_key(int arr_idx, int64_t depth)
|
||||
case M_CDATA: {
|
||||
if (OB_FAIL(serialize_child_key(cur->get_key(), g_idx))) {
|
||||
LOG_WARN("failed to serialize key string.", K(ret), K(cur->get_key().length()), K(buffer.length()));
|
||||
} else {
|
||||
set_index_entry( cur->get_index() + child_arr_[arr_idx].g_start_, g_idx);
|
||||
} else if (OB_FAIL(set_index_entry( cur->get_index() + child_arr_[arr_idx].g_start_, g_idx))) {
|
||||
LOG_WARN("failed to set index entry.", K(ret));
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -672,8 +685,8 @@ int ObXmlElementSerializer::serialize_value(int arr_idx, int64_t depth)
|
||||
ObXmlElementSerializer ele_serializer(cur, header_.buffer());
|
||||
if (OB_FAIL(ele_serializer.serialize(depth + 1))) {
|
||||
LOG_WARN("failed to serialize element child", K(ret), K(buffer.length()));
|
||||
} else {
|
||||
set_value_entry(g_idx, cur_type, value_start);
|
||||
} else if (OB_FAIL(set_value_entry(g_idx, cur_type, value_start))) {
|
||||
LOG_WARN("failed to set value entry.", K(ret), K(value_start));
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -683,8 +696,8 @@ int ObXmlElementSerializer::serialize_value(int arr_idx, int64_t depth)
|
||||
ObXmlAttributeSerializer attr_serializer(cur, buffer);
|
||||
if (OB_FAIL(attr_serializer.serialize())) {
|
||||
LOG_WARN("failed to serialize attribute.", K(ret), K(cur_type), K(buffer.length()));
|
||||
} else {
|
||||
set_value_entry(g_idx, cur_type, value_start);
|
||||
} else if (OB_FAIL(set_value_entry(g_idx, cur_type, value_start))) {
|
||||
LOG_WARN("failed to set value entry.", K(ret), K(value_start));
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -694,8 +707,8 @@ int ObXmlElementSerializer::serialize_value(int arr_idx, int64_t depth)
|
||||
ObXmlTextSerializer serializer(cur, buffer);
|
||||
if (OB_FAIL(serializer.serialize())) {
|
||||
LOG_WARN("failed to serialize text.", K(ret), K(cur_type), K(buffer.length()));
|
||||
} else {
|
||||
set_value_entry(g_idx, cur_type, value_start);
|
||||
} else if (OB_FAIL(set_value_entry(g_idx, cur_type, value_start))) {
|
||||
LOG_WARN("failed to set value entry.", K(ret), K(value_start));
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -949,11 +962,12 @@ int ObXmlElementSerializer::serialize(int64_t depth)
|
||||
if (serialize_try_time_ >= MAX_RETRY_TIME) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("failed to serialize as meta info not match.", K(ret), K(total_size), K(children_num), K(header_));
|
||||
} else if (OB_FAIL(buffer.set_length(start))) {
|
||||
LOG_WARN("failed to set length.", K(ret), K(start));
|
||||
} else {
|
||||
int64_t delta = total_size - header_.get_obj_size();
|
||||
ele->set_delta_serialize_size(delta);
|
||||
serialize_try_time_++;
|
||||
buffer.set_length(start);
|
||||
new (this) ObXmlElementSerializer(root_, &buffer);
|
||||
if (OB_FAIL(serialize(depth))) {
|
||||
LOG_WARN("failed to serialize.", K(ret), K(buffer.length()));
|
||||
@ -3144,8 +3158,8 @@ int ObXmlBinMerge::reserve_meta(ObMulBinHeaderSerializer& header)
|
||||
uint32_t reserve_size = merge_meta_.key_start_ - merge_meta_.index_start_;
|
||||
if (OB_FAIL(merge_meta_.header_->buffer_->reserve(reserve_size))) {
|
||||
LOG_WARN("failed to reserve buffer.", K(ret), K(reserve_size));
|
||||
} else {
|
||||
header.buffer_->set_length(pos + reserve_size);
|
||||
} else if (OB_FAIL(header.buffer_->set_length(pos + reserve_size))) {
|
||||
LOG_WARN("failed to set length.", K(ret), K(pos + reserve_size));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
|
6
deps/oblib/src/lib/xml/ob_xml_bin.h
vendored
6
deps/oblib/src/lib/xml/ob_xml_bin.h
vendored
@ -258,12 +258,12 @@ public:
|
||||
int serialize(int64_t depth);
|
||||
int deserialize(ObIMulModeBase*& node);
|
||||
int reserve_meta();
|
||||
void set_key_entry(int64_t entry_idx, int64_t key_offset, int64_t key_len);
|
||||
void set_index_entry(int64_t origin_index, int64_t sort_index);
|
||||
int set_key_entry(int64_t entry_idx, int64_t key_offset, int64_t key_len);
|
||||
int set_index_entry(int64_t origin_index, int64_t sort_index);
|
||||
|
||||
int64_t size() { return attr_count_ + child_count_; }
|
||||
int serialize_child_key(const ObString& key, int64_t idx);
|
||||
void set_value_entry(int64_t entry_idx, uint8_t type, int64_t value_offset);
|
||||
int set_value_entry(int64_t entry_idx, uint8_t type, int64_t value_offset);
|
||||
|
||||
struct MemberArray {
|
||||
int64_t g_start_;
|
||||
|
124
deps/oblib/src/lib/xml/ob_xml_tree.cpp
vendored
124
deps/oblib/src/lib/xml/ob_xml_tree.cpp
vendored
@ -276,6 +276,62 @@ int ObXmlElement::get_attribute_pos(ObMulModeNodeType xml_type, const ObString&
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObXmlElement::clone(ObMulModeMemCtx *ctx, ObXmlNode *&node)
|
||||
{
|
||||
INIT_SUCC(ret);
|
||||
ObXmlElement *ele = nullptr;
|
||||
ObXmlNode *origin_node = nullptr;
|
||||
node = ObXmlUtil::clone_new_node<ObXmlElement>(ctx->allocator_, type(), ctx);
|
||||
if (OB_ISNULL(node)) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
LOG_WARN("failed to allocator xml text node.", K(ret));
|
||||
} else if (OB_ISNULL(ele = static_cast<ObXmlElement*>(node)) ||
|
||||
OB_ISNULL(origin_node = static_cast<ObXmlNode*>(this))) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("clone new node cast to element is null", K(ret));
|
||||
} else {
|
||||
ele->set_prefix(prefix_);
|
||||
ele->set_xml_key(tag_info_);
|
||||
ele->set_standalone(standalone_);
|
||||
ele->set_has_xml_decl(has_xml_decl_);
|
||||
ele->set_empty(is_empty_);
|
||||
ele->set_unparse(is_unparse_);
|
||||
ele->set_encoding_flag(encoding_val_empty_);
|
||||
|
||||
int64_t child_size = size();
|
||||
int64_t attr_count = attribute_size();
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < attr_count; i++) {
|
||||
ObXmlAttribute *attr = nullptr;
|
||||
ObXmlNode *clone_node = nullptr;
|
||||
if (OB_FAIL(get_attribute(attr, i))) {
|
||||
LOG_WARN("failed to get attribute.", K(ret), K(i));
|
||||
} else if (OB_ISNULL(attr)) {
|
||||
ret =OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("get attribute is null.", K(ret), K(i));
|
||||
} else if (OB_FAIL(attr->clone(ctx, clone_node))) {
|
||||
LOG_WARN("failed to clone attribute.", K(ret), KP(attr));
|
||||
} else if (OB_FAIL(ele->add_attribute(clone_node))) {
|
||||
LOG_WARN("failed to add attribute.", K(ret), K(i), KP(clone_node));
|
||||
}
|
||||
}
|
||||
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < child_size; i++) {
|
||||
ObXmlNode *child_node = nullptr;
|
||||
ObXmlNode *clone_node = nullptr;
|
||||
if (OB_ISNULL(child_node = origin_node->at(i))) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("failed to get child node.", K(ret), K(i), KP(origin_node));
|
||||
} else if (OB_FAIL(child_node->clone(ctx, clone_node))) {
|
||||
LOG_WARN("failed to clone child_node.", K(ret), KP(child_node));
|
||||
} else if (OB_FAIL(ele->add_element(clone_node, false, i))) {
|
||||
LOG_WARN("failed to add xmlnode into element.", K(ret), K(i), KP(child_node), KP(origin_node));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
ObXmlAttribute* ObXmlElement::get_attribute_by_name(const ObString& ns_value, const ObString& name) // get attr by name
|
||||
{
|
||||
ObXmlAttribute* res_node = NULL;
|
||||
@ -988,6 +1044,43 @@ int64_t ObXmlDocument::get_serialize_size()
|
||||
return res;
|
||||
}
|
||||
|
||||
int ObXmlDocument::clone(ObMulModeMemCtx *ctx, ObXmlNode *&node)
|
||||
{
|
||||
INIT_SUCC(ret);
|
||||
ObXmlDocument *doc = nullptr;
|
||||
ObXmlNode *origin_node = nullptr;
|
||||
node = ObXmlUtil::clone_new_node<ObXmlDocument>(ctx->allocator_, type(), ctx);
|
||||
if (OB_ISNULL(node)) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
LOG_WARN("failed to allocator xml text node.", K(ret));
|
||||
} else if (OB_ISNULL(doc = static_cast<ObXmlDocument*>(node)) ||
|
||||
OB_ISNULL(origin_node = static_cast<ObXmlNode*>(this))) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("clone new node cast to document is null", K(ret));
|
||||
} else {
|
||||
doc->set_version(version_);
|
||||
doc->set_encoding(encoding_);
|
||||
doc->set_extSubset(extSubset_);
|
||||
doc->set_inSubset(intSubset_);
|
||||
|
||||
int64_t child_size = size();
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < child_size; i++) {
|
||||
ObXmlNode *child_node = nullptr;
|
||||
ObXmlNode *clone_node = nullptr;
|
||||
if (OB_ISNULL(child_node = origin_node->at(i))) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("failed to get child node.", K(ret), K(i), KP(origin_node));
|
||||
} else if (OB_FAIL(child_node->clone(ctx, clone_node))) {
|
||||
LOG_WARN("failed to clone child_node.", K(ret), KP(child_node));
|
||||
} else if (OB_FAIL(doc->add_element(clone_node, false, i))) {
|
||||
LOG_WARN("failed to add xmlnode into element.", K(ret), K(i), KP(child_node), KP(origin_node));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObXmlElement::remove_attribute(int pos)
|
||||
{
|
||||
INIT_SUCC(ret);
|
||||
@ -1213,6 +1306,37 @@ int ObXmlText::compare(const ObString& key, int& res)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObXmlText::clone(ObMulModeMemCtx *ctx, ObXmlNode *&node)
|
||||
{
|
||||
INIT_SUCC(ret);
|
||||
node = ObXmlUtil::clone_new_node<ObXmlText>(ctx->allocator_, type(), ctx);
|
||||
if (OB_ISNULL(node)) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
LOG_WARN("failed to allocator xml text node.", K(ret));
|
||||
} else {
|
||||
node->set_value(text_);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObXmlAttribute::clone(ObMulModeMemCtx *ctx, ObXmlNode *&node)
|
||||
{
|
||||
INIT_SUCC(ret);
|
||||
node = ObXmlUtil::clone_new_node<ObXmlAttribute>(ctx->allocator_, type(), ctx);
|
||||
if (OB_ISNULL(node)) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
LOG_WARN("failed to allocator xml attributes node.", K(ret));
|
||||
} else {
|
||||
ObXmlAttribute *attr = static_cast<ObXmlAttribute*>(node);
|
||||
attr->set_prefix(prefix_);
|
||||
attr->set_ns(ns_);
|
||||
attr->set_xml_key(name_);
|
||||
attr->set_value(value_);
|
||||
attr->set_attr_decl(attr_decl_);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int64_t ObXmlAttribute::get_serialize_size()
|
||||
{
|
||||
int64_t res = 0;
|
||||
|
5
deps/oblib/src/lib/xml/ob_xml_tree.h
vendored
5
deps/oblib/src/lib/xml/ob_xml_tree.h
vendored
@ -177,6 +177,7 @@ public:
|
||||
virtual int get_value(ObIArray<ObXmlNode*> &value, const ObString& key_name) { return 0; }
|
||||
// compare
|
||||
virtual int compare(const ObIMulModeBase &other, int &res) { return 0; }
|
||||
virtual int clone(ObMulModeMemCtx *ctx, ObXmlNode *&node) override { return OB_NOT_SUPPORTED; }
|
||||
|
||||
virtual int set_flag_by_descandant();
|
||||
|
||||
@ -336,6 +337,7 @@ public:
|
||||
virtual int get_attribute(ObIArray<ObIMulModeBase*>& res, ObMulModeNodeType filter_type, int32_t flags = 0);
|
||||
virtual int get_attribute(ObIMulModeBase*& res, ObMulModeNodeType filter_type, const ObString& key1, const ObString &key2 = ObString());
|
||||
virtual bool check_if_defined_ns();
|
||||
int clone(ObMulModeMemCtx *ctx, ObXmlNode *&node) override;
|
||||
private:
|
||||
// namespace prefix
|
||||
ObString prefix_;
|
||||
@ -390,6 +392,7 @@ public:
|
||||
ObXmlNode* get_extSubset() { return extSubset_; }
|
||||
|
||||
int64_t get_serialize_size();
|
||||
int clone(ObMulModeMemCtx *ctx, ObXmlNode *&node);
|
||||
|
||||
protected:
|
||||
// xml prolog
|
||||
@ -465,6 +468,7 @@ class ObXmlAttribute : public ObXmlNode
|
||||
// ObXmlNode *clone(ObIAllocator* allocator) const;
|
||||
virtual int compare(const ObString& key, int& res);
|
||||
int64_t get_serialize_size();
|
||||
int clone(ObMulModeMemCtx *ctx, ObXmlNode *&node) override;
|
||||
protected:
|
||||
// namespace prefix
|
||||
ObString prefix_;
|
||||
@ -517,6 +521,7 @@ public:
|
||||
bool is_space() { return is_space_; }
|
||||
void set_is_space(bool is_space) { is_space_ = is_space; }
|
||||
int64_t get_serialize_size();
|
||||
int clone(ObMulModeMemCtx *ctx, ObXmlNode *&node) override;
|
||||
protected:
|
||||
ObString text_;
|
||||
int64_t length_;
|
||||
|
16
deps/oblib/src/lib/xml/ob_xml_util.cpp
vendored
16
deps/oblib/src/lib/xml/ob_xml_util.cpp
vendored
@ -1544,5 +1544,21 @@ int ObXmlUtil::restore_ns_vec(ObNsSortedVector* element_ns_vec, ObVector<ObNsPai
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <typename T, typename... Args>
|
||||
ObXmlNode* ObXmlUtil::clone_new_node(ObIAllocator* allocator, Args &&... args)
|
||||
{
|
||||
void *buf = allocator->alloc(sizeof(T));
|
||||
T *new_node = NULL;
|
||||
|
||||
if (OB_ISNULL(buf)) {
|
||||
LOG_WARN_RET(OB_ALLOCATE_MEMORY_FAILED, "fail to alloc memory for ObXmlNode");
|
||||
} else {
|
||||
new_node = new(buf)T(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
return static_cast<ObXmlNode *>(new_node);
|
||||
|
||||
}
|
||||
|
||||
} // namespace common
|
||||
} // namespace oceanbase
|
||||
|
2
deps/oblib/src/lib/xml/ob_xml_util.h
vendored
2
deps/oblib/src/lib/xml/ob_xml_util.h
vendored
@ -535,6 +535,8 @@ public:
|
||||
|
||||
static bool is_xml_doc_over_depth(uint64_t depth);
|
||||
static int revert_escape_character(ObIAllocator &allocator, ObString &input_str, ObString &output_str);
|
||||
template <typename T, typename... Args>
|
||||
static ObXmlNode* clone_new_node(ObIAllocator* allocator, Args &&... args);
|
||||
};
|
||||
|
||||
class ObMulModeFactory
|
||||
|
35
deps/oblib/src/lib/xml/ob_xpath.cpp
vendored
35
deps/oblib/src/lib/xml/ob_xpath.cpp
vendored
@ -2157,6 +2157,41 @@ ObIMulModeBase* ObPathExprIter::get_cur_res_parent()
|
||||
return path_ctx_.ancestor_record_.size() > 0 ? path_ctx_.ancestor_record_.top() : nullptr;
|
||||
}
|
||||
|
||||
int ObPathExprIter::get_node_exists(bool &is_exists)
|
||||
{
|
||||
INIT_SUCC(ret);
|
||||
is_exists = false;
|
||||
if (!is_inited_ || OB_ISNULL(path_node_)) {
|
||||
ret = OB_INIT_FAIL;
|
||||
LOG_WARN("should be inited", K(ret));
|
||||
} else {
|
||||
ObSeekResult path_res;
|
||||
while (OB_SUCC(ret) && !is_exists) {
|
||||
if (OB_FAIL(path_node_->eval_node(path_ctx_, path_res))) {
|
||||
if (ret != OB_ITER_END) {
|
||||
LOG_WARN("fail to seek", K(ret));
|
||||
}
|
||||
} else if (path_res.is_scalar_) {
|
||||
if (OB_ISNULL(path_res.result_.scalar_)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("xpath result scalar is null", K(ret));
|
||||
} else if (path_res.result_.scalar_->node_type_.get_arg_type() == ObArgType::PN_BOOLEAN
|
||||
&& !path_res.result_.scalar_->arg_.boolean_) {
|
||||
// do nothing, keep seeking
|
||||
} else {
|
||||
is_exists = true;
|
||||
}
|
||||
} else {
|
||||
is_exists = true;
|
||||
}
|
||||
} // end while
|
||||
if (ret == OB_ITER_END) {
|
||||
ret = OB_SUCCESS;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObPathExprIter::get_next_node(ObIMulModeBase*& res)
|
||||
{
|
||||
INIT_SUCC(ret);
|
||||
|
1
deps/oblib/src/lib/xml/ob_xpath.h
vendored
1
deps/oblib/src/lib/xml/ob_xpath.h
vendored
@ -934,6 +934,7 @@ public:
|
||||
int init(ObMulModeMemCtx* ctx, ObString& path, ObString& default_ns, ObIMulModeBase* doc, ObPathVarObject* pass_var, bool add_namespace = true);
|
||||
int open(); // begin to parse and seek
|
||||
int get_next_node(ObIMulModeBase*& res);
|
||||
int get_node_exists(bool &is_exists);
|
||||
|
||||
int get_first_node(ObPathNode*& loc);
|
||||
int get_first_axis(ObPathNodeAxis& first_axis);
|
||||
|
2
deps/oblib/src/rpc/obmysql/ob_mysql_util.cpp
vendored
2
deps/oblib/src/rpc/obmysql/ob_mysql_util.cpp
vendored
@ -1138,7 +1138,7 @@ int ObMySQLUtil::json_cell_str(uint64_t tenant_id, char *buf, const int64_t len,
|
||||
}
|
||||
} else if (OB_FAIL(j_bin.reset_iter())) {
|
||||
OB_LOG(WARN, "fail to reset json bin iter", K(ret), K(val));
|
||||
} else if (OB_FAIL(j_base->print(jbuf, true))) {
|
||||
} else if (OB_FAIL(j_base->print(jbuf, true, val.length()))) {
|
||||
OB_LOG(WARN, "json binary to string failed in mysql mode", K(ret), K(val), K(*j_base));
|
||||
} else {
|
||||
int64_t new_length = jbuf.length();
|
||||
|
@ -481,6 +481,8 @@
|
||||
INTERFACE_DEF(INTERFACE_XML_TYPE_TRANSFORM, "XML_TYPE_TRANSFORM", (ObXmlType::transform))
|
||||
INTERFACE_DEF(INTERFACE_XML_TYPE_GETCLOBVAL, "XML_TYPE_GETCLOBVAL", (ObXmlType::getclobval))
|
||||
INTERFACE_DEF(INTERFACE_XML_TYPE_GETSTRINGVAL, "XML_TYPE_GETSTRINGVAL", (ObXmlType::getstringval))
|
||||
INTERFACE_DEF(INTERFACE_XML_TYPE_EXISTSNODE, "XML_TYPE_EXISTSNODE", (ObXmlType::existsnode))
|
||||
INTERFACE_DEF(INTERFACE_XML_TYPE_EXTRACT, "XML_TYPE_EXTRACT", (ObXmlType::extract))
|
||||
INTERFACE_DEF(INTERFACE_XML_TYPE_CREATEXML, "XML_TYPE_CREATEXML", (ObXmlType::createxml))
|
||||
INTERFACE_DEF(INTERFACE_XML_TYPE_CONSTRUCTOR, "XML_TYPE_CONSTRUCTOR", (ObXmlType::constructor))
|
||||
//end of xmltype
|
||||
|
@ -8586,7 +8586,7 @@ static int json_raw(const ObObjType expect_type, ObObjCastParams ¶ms,
|
||||
ObIJsonBase *j_base = &j_bin;
|
||||
if (OB_FAIL(j_bin.reset_iter())) {
|
||||
LOG_WARN("failed to reset json bin iter", K(ret), K(j_bin_str));
|
||||
} else if (CAST_FAIL(j_base->print(j_buf, true))) {
|
||||
} else if (CAST_FAIL(j_base->print(j_buf, true, j_bin_str.length()))) {
|
||||
LOG_WARN("fail to cast json to other type", K(ret), K(j_bin_str), K(expect_type));
|
||||
ret = OB_ERR_INVALID_JSON_VALUE_FOR_CAST;
|
||||
LOG_USER_ERROR(OB_ERR_INVALID_JSON_VALUE_FOR_CAST);
|
||||
@ -8658,7 +8658,7 @@ static int json_string(const ObObjType expect_type, ObObjCastParams ¶ms,
|
||||
ObIJsonBase *j_base = &j_bin;
|
||||
if (OB_FAIL(j_bin.reset_iter())) {
|
||||
LOG_WARN("failed to reset json bin iter", K(ret), K(j_bin_str));
|
||||
} else if (CAST_FAIL(j_base->print(j_buf, true))) {
|
||||
} else if (CAST_FAIL(j_base->print(j_buf, true, j_bin_str.length()))) {
|
||||
LOG_WARN("fail to cast json to other type", K(ret), K(j_bin_str), K(expect_type));
|
||||
ret = OB_ERR_INVALID_JSON_VALUE_FOR_CAST;
|
||||
LOG_USER_ERROR(OB_ERR_INVALID_JSON_VALUE_FOR_CAST);
|
||||
@ -8727,7 +8727,7 @@ static int common_json_string(const ObObjType expect_type,
|
||||
ObString j_str;
|
||||
if (OB_FAIL(j_bin.reset_iter())) {
|
||||
LOG_WARN("failed to reset json bin iter", K(ret), K(j_bin_str));
|
||||
} else if (CAST_FAIL(j_base->print(j_buf, true))) {
|
||||
} else if (CAST_FAIL(j_base->print(j_buf, true, j_bin_str.length()))) {
|
||||
LOG_WARN("fail to cast json to other type", K(ret), K(j_bin_str), K(expect_type));
|
||||
ret = OB_ERR_INVALID_JSON_VALUE_FOR_CAST;
|
||||
LOG_USER_ERROR(OB_ERR_INVALID_JSON_VALUE_FOR_CAST);
|
||||
|
@ -2105,6 +2105,9 @@ DEF_INT(max_partition_num, OB_TENANT_PARAMETER, "8192", "[8192, 65536]",
|
||||
DEF_INT(json_document_max_depth, OB_TENANT_PARAMETER, "100", "[100,1024]",
|
||||
"maximum nesting depth allowed in a JSON document",
|
||||
ObParameterAttr(Section::TENANT, Source::DEFAULT, EditLevel::DYNAMIC_EFFECTIVE));
|
||||
DEF_INT(_multimodel_memory_trace_level, OB_TENANT_PARAMETER, "0", "[0,100)",
|
||||
"Multi-mode memory tracking mechanism",
|
||||
ObParameterAttr(Section::TENANT, Source::DEFAULT, EditLevel::DYNAMIC_EFFECTIVE));
|
||||
ERRSIM_DEF_INT(errsim_backup_task_batch_size, OB_CLUSTER_PARAMETER, "0", "[0,)",
|
||||
"the batch size backup task receive in errsim mode"
|
||||
"Range: [0,) in integer",
|
||||
|
@ -553,6 +553,7 @@ ob_set_subtarget(ob_sql engine_expr
|
||||
engine/expr/ob_expr_insert_child_xml.cpp
|
||||
engine/expr/ob_expr_xml_delete_xml.cpp
|
||||
engine/expr/ob_expr_xml_sequence.cpp
|
||||
engine/expr/ob_expr_existsnode_xml.cpp
|
||||
engine/expr/ob_expr_sql_udt_utils.cpp
|
||||
engine/expr/ob_expr_temp_table_ssid.cpp
|
||||
engine/expr/ob_expr_collection_construct.cpp
|
||||
@ -574,8 +575,11 @@ ob_set_subtarget(ob_sql engine_expr
|
||||
engine/expr/ob_expr_prefix_pattern.cpp
|
||||
engine/expr/ob_expr_sys_makexml.cpp
|
||||
engine/expr/ob_expr_xml_func_helper.cpp
|
||||
engine/expr/ob_expr_multi_mode_func_helper.cpp
|
||||
engine/expr/ob_expr_xmlparse.cpp
|
||||
engine/expr/ob_expr_xml_element.cpp
|
||||
engine/expr/ob_expr_xml_concat.cpp
|
||||
engine/expr/ob_expr_xml_forest.cpp
|
||||
engine/expr/ob_expr_xml_attributes.cpp
|
||||
engine/expr/ob_expr_xml_serialize.cpp
|
||||
engine/expr/ob_expr_priv_xml_binary.cpp
|
||||
@ -591,6 +595,8 @@ ob_set_subtarget(ob_sql engine_expr
|
||||
engine/expr/ob_expr_st_geomfromewkt.cpp
|
||||
engine/expr/ob_expr_priv_st_geogfromtext.cpp
|
||||
engine/expr/ob_expr_priv_st_geographyfromtext.cpp
|
||||
engine/expr/ob_expr_priv_st_geohash.cpp
|
||||
engine/expr/ob_expr_priv_st_makepoint.cpp
|
||||
engine/expr/ob_expr_st_asewkt.cpp
|
||||
engine/expr/ob_expr_st_srid.cpp
|
||||
engine/expr/ob_expr_st_distance.cpp
|
||||
|
@ -7865,16 +7865,14 @@ int ObAggregateProcessor::get_ora_json_arrayagg_result(const ObAggrInfo &aggr_in
|
||||
} else if (ob_is_string_type(rsp_type) || ob_is_raw(rsp_type)) {
|
||||
ObIJsonBase *j_base = NULL;
|
||||
ObStringBuffer *buff = bin_agg.get_buffer();
|
||||
if (OB_FAIL(string_buffer.reserve(buff->length()))) {
|
||||
LOG_WARN("fail to reserve string.", K(ret), K(buff->length()));
|
||||
} else if (OB_FAIL(ObJsonBaseFactory::get_json_base(&tmp_alloc,
|
||||
if (OB_FAIL(ObJsonBaseFactory::get_json_base(&tmp_alloc,
|
||||
buff->string(),
|
||||
ObJsonInType::JSON_BIN,
|
||||
ObJsonInType::JSON_BIN,
|
||||
j_base, 0,
|
||||
ObJsonExprHelper::get_json_max_depth_config()))) {
|
||||
LOG_WARN("fail to get real data.", K(ret), K(buff));
|
||||
} else if (OB_FAIL(j_base->print(string_buffer, true, false))) {
|
||||
} else if (OB_FAIL(j_base->print(string_buffer, true, buff->length(), false))) {
|
||||
LOG_WARN("failed: get json string text", K(ret));
|
||||
} else if (rsp_type == ObVarcharType && string_buffer.length() > rsp_len) {
|
||||
char res_ptr[OB_MAX_DECIMAL_PRECISION] = {0};
|
||||
@ -8086,7 +8084,8 @@ int ObAggregateProcessor::get_ora_xmlagg_result(const ObAggrInfo &aggr_info,
|
||||
int ret = OB_SUCCESS;
|
||||
#ifdef OB_BUILD_ORACLE_PL
|
||||
ObString result;
|
||||
common::ObArenaAllocator tmp_alloc(ObModIds::OB_SQL_AGGR_FUNC, OB_MALLOC_NORMAL_BLOCK_SIZE, MTL_ID());
|
||||
common::ObArenaAllocator tmp_allocator(ObModIds::OB_SQL_AGGR_FUNC, OB_MALLOC_NORMAL_BLOCK_SIZE, MTL_ID());
|
||||
MultimodeAlloctor tmp_alloc(tmp_allocator, T_FUN_ORA_XMLAGG, MTL_ID(), ret);
|
||||
ObXmlDocument *content = NULL;
|
||||
ObXmlDocument* doc = NULL;
|
||||
ObString blob_locator;
|
||||
@ -8315,6 +8314,7 @@ int ObAggregateProcessor::get_ora_xmlagg_result(const ObAggrInfo &aggr_info,
|
||||
} else if (OB_FAIL(ObXMLExprHelper::pack_binary_res(*aggr_info.expr_, eval_ctx_, bin_agg.get_buffer()->string(), blob_locator))) {
|
||||
LOG_WARN("pack binary res failed", K(ret));
|
||||
} else {
|
||||
tmp_alloc.set_baseline_size_and_flag(bin_agg.get_buffer()->length());
|
||||
concat_result.set_string(blob_locator.ptr(), blob_locator.length());
|
||||
}
|
||||
}
|
||||
@ -8477,16 +8477,14 @@ int ObAggregateProcessor::get_ora_json_objectagg_result(const ObAggrInfo &aggr_i
|
||||
} else if (OB_FALSE_IT(buff = bin_agg.get_buffer())) {
|
||||
} else if (ob_is_string_type(rsp_type) || ob_is_raw(rsp_type)) {
|
||||
ObIJsonBase *j_base = NULL;
|
||||
if (OB_FAIL(string_buffer.reserve(buff->length()))) {
|
||||
LOG_WARN("fail to reserve string.", K(ret), K(buff->length()));
|
||||
} else if (OB_FAIL(ObJsonBaseFactory::get_json_base(&tmp_alloc,
|
||||
if (OB_FAIL(ObJsonBaseFactory::get_json_base(&tmp_alloc,
|
||||
buff->string(),
|
||||
ObJsonInType::JSON_BIN,
|
||||
ObJsonInType::JSON_BIN,
|
||||
j_base, 0,
|
||||
ObJsonExprHelper::get_json_max_depth_config()))) {
|
||||
LOG_WARN("fail to get real data.", K(ret), K(buff));
|
||||
} else if (OB_FAIL(j_base->print(string_buffer, true, false))) {
|
||||
} else if (OB_FAIL(j_base->print(string_buffer, true, buff->length(), false))) {
|
||||
LOG_WARN("failed: get json string text", K(ret));
|
||||
} else if (rsp_type == ObVarcharType && string_buffer.length() > rsp_len) {
|
||||
char res_ptr[OB_MAX_DECIMAL_PRECISION] = {0};
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "sql/session/ob_sql_session_info.h"
|
||||
#include "sql/engine/ob_physical_plan.h"
|
||||
#include "sql/engine/expr/ob_expr_json_func_helper.h"
|
||||
#include "sql/engine/expr/ob_expr_multi_mode_func_helper.h"
|
||||
#include "sql/engine/expr/ob_expr_json_value.h"
|
||||
#include "sql/engine/expr/ob_expr_json_query.h"
|
||||
#include "sql/engine/expr/ob_expr_json_exists.h"
|
||||
@ -669,15 +670,20 @@ int ObJsonTableOp::reset_variable()
|
||||
jt_ctx_.is_cover_error_ = false;
|
||||
jt_ctx_.error_code_ = 0;
|
||||
jt_ctx_.is_need_end_ = 0;
|
||||
|
||||
if (OB_FAIL(ObXmlUtil::create_mulmode_tree_context(&jt_ctx_.row_alloc_, jt_ctx_.mem_ctx_))) {
|
||||
LOG_WARN("fail to create tree memory context", K(ret));
|
||||
MultimodeAlloctor *tmp_allocator = nullptr;
|
||||
if (OB_ISNULL(tmp_allocator = static_cast<MultimodeAlloctor*>(jt_ctx_.row_alloc_.alloc(sizeof(MultimodeAlloctor))))) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
LOG_WARN("failed to allocate Multimode alloc buf", K(ret));
|
||||
} else {
|
||||
new (tmp_allocator)MultimodeAlloctor(jt_ctx_.row_alloc_, T_XML_TABLE_EXPRESSION, ret);
|
||||
}
|
||||
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (MY_SPEC.value_exprs_.empty()) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("failed to open iter, value expr is null.", K(ret));
|
||||
} else if (OB_FAIL(ObXmlUtil::create_mulmode_tree_context(tmp_allocator, jt_ctx_.mem_ctx_))) {
|
||||
LOG_WARN("fail to create tree memory context", K(ret));
|
||||
} else if (OB_FAIL(root_->reset(&jt_ctx_))) {
|
||||
LOG_WARN("failed to open table func xml column node.", K(ret));
|
||||
} else {
|
||||
@ -696,6 +702,7 @@ int ObJsonTableOp::switch_iterator()
|
||||
int ObJsonTableOp::init()
|
||||
{
|
||||
INIT_SUCC(ret);
|
||||
uint64_t tenant_id = -1;
|
||||
if (!is_inited_) {
|
||||
const ObJsonTableSpec* spec_ptr = reinterpret_cast<const ObJsonTableSpec*>(&spec_);
|
||||
jt_ctx_.spec_ptr_ = const_cast<ObJsonTableSpec*>(spec_ptr);
|
||||
@ -703,7 +710,6 @@ int ObJsonTableOp::init()
|
||||
LOG_WARN("fail to init json table op, as generate exec tree occur error.", K(ret));
|
||||
} else {
|
||||
const sql::ObSQLSessionInfo *session = get_exec_ctx().get_my_session();
|
||||
uint64_t tenant_id = -1;
|
||||
if (OB_ISNULL(session)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("session is NULL", K(ret));
|
||||
@ -758,7 +764,15 @@ int ObJsonTableOp::init()
|
||||
jt_ctx_.is_cover_error_ = false;
|
||||
jt_ctx_.error_code_ = 0;
|
||||
jt_ctx_.is_need_end_ = 0;
|
||||
if (OB_SUCC(ret) && OB_FAIL(ObXmlUtil::create_mulmode_tree_context(&jt_ctx_.row_alloc_, jt_ctx_.mem_ctx_))) {
|
||||
MultimodeAlloctor *tmp_allocator = nullptr;
|
||||
if (OB_ISNULL(tmp_allocator = static_cast<MultimodeAlloctor*>(jt_ctx_.row_alloc_.alloc(sizeof(MultimodeAlloctor))))) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
LOG_WARN("failed to allocate Multimode alloc buf", K(ret));
|
||||
} else {
|
||||
new (tmp_allocator)MultimodeAlloctor(jt_ctx_.row_alloc_, T_XML_TABLE_EXPRESSION, ret);
|
||||
}
|
||||
|
||||
if (OB_SUCC(ret) && OB_FAIL(ObXmlUtil::create_mulmode_tree_context(tmp_allocator, jt_ctx_.mem_ctx_))) {
|
||||
LOG_WARN("fail to create tree memory context", K(ret));
|
||||
}
|
||||
return ret;
|
||||
@ -2947,6 +2961,7 @@ int JsonTableFunc::eval_input(ObJsonTableOp &jt, JtScanCtx& ctx, ObEvalCtx &eval
|
||||
ObString j_str;
|
||||
bool is_null = false;
|
||||
ObIJsonBase* in = NULL;
|
||||
MultimodeAlloctor tmp_allocator(ctx.row_alloc_, T_JSON_TABLE_EXPRESSION, ret);
|
||||
|
||||
if (doc_type == ObNullType) {
|
||||
ret = OB_ITER_END;
|
||||
@ -2959,11 +2974,12 @@ int JsonTableFunc::eval_input(ObJsonTableOp &jt, JtScanCtx& ctx, ObEvalCtx &eval
|
||||
} else {
|
||||
jt.reset_columns();
|
||||
if (OB_FAIL(ObJsonExprHelper::get_json_or_str_data(ctx.spec_ptr_->value_exprs_.at(0), eval_ctx,
|
||||
ctx.row_alloc_, j_str, is_null))) {
|
||||
tmp_allocator, j_str, is_null))) {
|
||||
ret = OB_ERR_INPUT_JSON_TABLE;
|
||||
LOG_WARN("get real data failed", K(ret));
|
||||
} else if (is_null) {
|
||||
ret = OB_ITER_END;
|
||||
} else if (OB_FALSE_IT(tmp_allocator.set_baseline_size(j_str.length()))) {
|
||||
} else if ((ob_is_string_type(doc_type) || doc_type == ObLobType)
|
||||
&& (doc_cs_type != CS_TYPE_BINARY)
|
||||
&& (ObCharset::charset_type_by_coll(doc_cs_type) != CHARSET_UTF8MB4)) {
|
||||
@ -2973,7 +2989,7 @@ int JsonTableFunc::eval_input(ObJsonTableOp &jt, JtScanCtx& ctx, ObEvalCtx &eval
|
||||
int64_t buf_len = j_str.length() * factor;
|
||||
uint32_t result_len = 0;
|
||||
|
||||
if (OB_ISNULL(buf = static_cast<char*>(ctx.row_alloc_.alloc(buf_len)))) {
|
||||
if (OB_ISNULL(buf = static_cast<char*>(tmp_allocator.alloc(buf_len)))) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
LOG_WARN("alloc memory failed", K(ret));
|
||||
} else if (OB_FAIL(ObCharset::charset_convert(doc_cs_type, j_str.ptr(),
|
||||
@ -2994,7 +3010,7 @@ int JsonTableFunc::eval_input(ObJsonTableOp &jt, JtScanCtx& ctx, ObEvalCtx &eval
|
||||
|
||||
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (OB_FAIL(ObJsonBaseFactory::get_json_base(&ctx.row_alloc_, j_str, j_in_type, expect_type, in, parse_flag, ObJsonExprHelper::get_json_max_depth_config()))
|
||||
} else if (OB_FAIL(ObJsonBaseFactory::get_json_base(&tmp_allocator, j_str, j_in_type, expect_type, in, parse_flag, ObJsonExprHelper::get_json_max_depth_config()))
|
||||
|| (in->json_type() != ObJsonNodeType::J_ARRAY && in->json_type() != ObJsonNodeType::J_OBJECT)) {
|
||||
if (OB_FAIL(ret) || (is_ensure_json)) {
|
||||
in= nullptr;
|
||||
|
@ -2636,7 +2636,7 @@ static int common_json_string(const ObExpr &expr,
|
||||
// get json string
|
||||
if (OB_FAIL(j_bin.reset_iter())) {
|
||||
LOG_WARN("failed to reset json bin iter", K(ret), K(j_bin_str));
|
||||
} else if (CAST_FAIL(j_base->print(j_buf, true))) {
|
||||
} else if (CAST_FAIL(j_base->print(j_buf, true, j_bin_str.length()))) {
|
||||
LOG_WARN("fail to convert json to string", K(ret), K(j_bin_str));
|
||||
ret = OB_ERR_INVALID_JSON_VALUE_FOR_CAST;
|
||||
LOG_USER_ERROR(OB_ERR_INVALID_JSON_VALUE_FOR_CAST);
|
||||
@ -8625,7 +8625,7 @@ CAST_FUNC_NAME(json, raw)
|
||||
|
||||
if (OB_FAIL(j_bin.reset_iter())) {
|
||||
LOG_WARN("failed to reset json bin iter", K(ret), K(j_bin_str));
|
||||
} else if (CAST_FAIL(j_base->print(j_buf, true))) {
|
||||
} else if (CAST_FAIL(j_base->print(j_buf, true, j_bin_str.length()))) {
|
||||
LOG_WARN("fail to convert json to string", K(ret), K(j_bin_str));
|
||||
ret = OB_ERR_INVALID_JSON_VALUE_FOR_CAST;
|
||||
LOG_USER_ERROR(OB_ERR_INVALID_JSON_VALUE_FOR_CAST);
|
||||
@ -8675,7 +8675,7 @@ CAST_FUNC_NAME(json, string)
|
||||
|
||||
if (OB_FAIL(j_bin.reset_iter())) {
|
||||
LOG_WARN("failed to reset json bin iter", K(ret), K(j_bin_str));
|
||||
} else if (CAST_FAIL(j_base->print(j_buf, true))) {
|
||||
} else if (CAST_FAIL(j_base->print(j_buf, true, j_bin_str.length()))) {
|
||||
LOG_WARN("fail to convert json to string", K(ret), K(j_bin_str));
|
||||
ret = OB_ERR_INVALID_JSON_VALUE_FOR_CAST;
|
||||
LOG_USER_ERROR(OB_ERR_INVALID_JSON_VALUE_FOR_CAST);
|
||||
|
@ -325,12 +325,15 @@
|
||||
#include "ob_expr_xml_attributes.h"
|
||||
#include "ob_expr_extract_value.h"
|
||||
#include "ob_expr_extract_xml.h"
|
||||
#include "ob_expr_existsnode_xml.h"
|
||||
#include "ob_expr_xml_serialize.h"
|
||||
#include "ob_expr_xmlcast.h"
|
||||
#include "ob_expr_update_xml.h"
|
||||
#include "ob_expr_insert_child_xml.h"
|
||||
#include "ob_expr_xml_delete_xml.h"
|
||||
#include "ob_expr_xml_sequence.h"
|
||||
#include "ob_expr_xml_concat.h"
|
||||
#include "ob_expr_xml_forest.h"
|
||||
#include "ob_expr_generator_func.h"
|
||||
#include "ob_expr_random.h"
|
||||
#include "ob_expr_randstr.h"
|
||||
@ -406,6 +409,8 @@
|
||||
#include "ob_expr_can_access_trigger.h"
|
||||
#include "ob_expr_split_part.h"
|
||||
#include "ob_expr_get_mysql_routine_parameter_type_str.h"
|
||||
#include "ob_expr_priv_st_geohash.h"
|
||||
#include "ob_expr_priv_st_makepoint.h"
|
||||
|
||||
namespace oceanbase
|
||||
{
|
||||
@ -1169,9 +1174,9 @@ static ObExpr::EvalFunc g_expr_eval_functions[] = {
|
||||
eval_questionmark_decint2decint_eqcast, /* 659 */
|
||||
eval_questionmark_decint2decint_normalcast, /* 660 */
|
||||
ObExprExtractExpiredTime::eval_extract_cert_expired_time, /* 661 */
|
||||
NULL, //ObExprXmlConcat::eval_xml_concat, /* 662 */
|
||||
NULL, //ObExprXmlForest::eval_xml_forest, /* 663 */
|
||||
NULL, //ObExprExistsNodeXml::eval_existsnode_xml, /* 664 */
|
||||
ObExprXmlConcat::eval_xml_concat, /* 662 */
|
||||
ObExprXmlForest::eval_xml_forest, /* 663 */
|
||||
ObExprExistsNodeXml::eval_existsnode_xml, /* 664 */
|
||||
ObExprPassword::eval_password, /* 665 */
|
||||
ObExprDocID::generate_doc_id, /* 666 */
|
||||
ObExprWordSegment::generate_fulltext_column, /* 667 */
|
||||
@ -1186,8 +1191,8 @@ static ObExpr::EvalFunc g_expr_eval_functions[] = {
|
||||
ObExprIs::json_is_false, /* 676 */
|
||||
ObExprCurrentRole::eval_current_role, /* 677 */
|
||||
ObExprMod::mod_decimalint, /* 678 */
|
||||
NULL, // ObExprPrivSTGeoHash::eval_priv_st_geohash, /* 679 */
|
||||
NULL, // ObExprPrivSTMakePoint::eval_priv_st_makepoint, /* 680 */
|
||||
ObExprPrivSTGeoHash::eval_priv_st_geohash, /* 679 */
|
||||
ObExprPrivSTMakePoint::eval_priv_st_makepoint, /* 680 */
|
||||
ObExprGetLock::get_lock, /* 681 */
|
||||
ObExprIsFreeLock::is_free_lock, /* 682 */
|
||||
ObExprIsUsedLock::is_used_lock, /* 683 */
|
||||
|
166
src/sql/engine/expr/ob_expr_existsnode_xml.cpp
Normal file
166
src/sql/engine/expr/ob_expr_existsnode_xml.cpp
Normal file
@ -0,0 +1,166 @@
|
||||
/**
|
||||
* Copyright (c) 2021 OceanBase
|
||||
* OceanBase CE is licensed under Mulan PubL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PubL v2.
|
||||
* You may obtain a copy of Mulan PubL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPubL-2.0
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PubL v2 for more details.
|
||||
* This file is for func existsnode(xml).
|
||||
*/
|
||||
|
||||
#include "ob_expr_existsnode_xml.h"
|
||||
#include "lib/xml/ob_xml_parser.h"
|
||||
#include "lib/xml/ob_xml_util.h"
|
||||
#include "sql/engine/expr/ob_expr_xml_func_helper.h"
|
||||
#include "sql/engine/ob_exec_context.h"
|
||||
|
||||
#define USING_LOG_PREFIX SQL_ENG
|
||||
|
||||
using namespace oceanbase::common;
|
||||
|
||||
namespace oceanbase
|
||||
{
|
||||
namespace sql
|
||||
{
|
||||
|
||||
ObExprExistsNodeXml::ObExprExistsNodeXml(common::ObIAllocator &alloc)
|
||||
: ObFuncExprOperator(
|
||||
alloc,
|
||||
T_FUN_SYS_XML_EXISTSNODE,
|
||||
N_EXISTSNODE_XML,
|
||||
MORE_THAN_ONE,
|
||||
VALID_FOR_GENERATED_COL,
|
||||
NOT_ROW_DIMENSION)
|
||||
{
|
||||
}
|
||||
|
||||
ObExprExistsNodeXml::~ObExprExistsNodeXml() {}
|
||||
|
||||
int ObExprExistsNodeXml::calc_result_typeN(
|
||||
ObExprResType &type,
|
||||
ObExprResType *types,
|
||||
int64_t param_num,
|
||||
common::ObExprTypeCtx &type_ctx) const
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (OB_UNLIKELY(param_num != 3)) {
|
||||
ret = OB_ERR_PARAM_SIZE;
|
||||
LOG_WARN("invalid argument number", K(ret), K(param_num));
|
||||
} else if (!is_called_in_sql()) {
|
||||
ret = OB_ERR_SP_LILABEL_MISMATCH;
|
||||
LOG_WARN("expr call in pl semantics disallowed", K(ret), K(N_EXISTSNODE_XML));
|
||||
LOG_USER_ERROR(OB_ERR_SP_LILABEL_MISMATCH, static_cast<int>(strlen(N_EXISTSNODE_XML)), N_EXISTSNODE_XML);
|
||||
} else {
|
||||
ObObjType in_type = types[0].get_type();
|
||||
if (types[0].is_ext() && types[0].get_udt_id() == T_OBJ_XML) {
|
||||
types[0].get_calc_meta().set_sql_udt(ObXMLSqlType);
|
||||
} else if (!ob_is_xml_sql_type(in_type, types[0].get_subschema_id())) {
|
||||
ret = OB_ERR_INVALID_XML_DATATYPE;
|
||||
LOG_USER_ERROR(OB_ERR_INVALID_XML_DATATYPE, "-", "-");
|
||||
LOG_WARN("inconsistent datatypes", K(ret), K(ob_obj_type_str(in_type)));
|
||||
}
|
||||
for (int8_t i = 1; i < param_num && OB_SUCC(ret); i++) {
|
||||
ObObjType param_type = types[i].get_type();
|
||||
if (param_type == ObNullType) {
|
||||
if (i == 1) {
|
||||
ret = OB_ERR_INVALID_XPATH_EXPRESSION;
|
||||
LOG_WARN("invalid xpath expression", K(ret));
|
||||
}
|
||||
} else if (ob_is_string_type(param_type)) {
|
||||
if (types[i].get_charset_type() != CHARSET_UTF8MB4) {
|
||||
types[i].set_calc_collation_type(CS_TYPE_UTF8MB4_BIN);
|
||||
}
|
||||
} else {
|
||||
ret = OB_ERR_INVALID_XPATH_EXPRESSION;
|
||||
LOG_WARN("invalid xpath expression", K(ret));
|
||||
}
|
||||
}
|
||||
|
||||
if (OB_SUCC(ret)) {
|
||||
type.set_int32();
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObExprExistsNodeXml::eval_existsnode_xml(const ObExpr &expr, ObEvalCtx &ctx, ObDatum &res)
|
||||
{
|
||||
INIT_SUCC(ret);
|
||||
bool is_exists = false;
|
||||
ObEvalCtx::TempAllocGuard tmp_alloc_g(ctx);
|
||||
common::ObArenaAllocator &allocator = tmp_alloc_g.get_allocator();
|
||||
lib::ObMallocHookAttrGuard malloc_guard(lib::ObMemAttr(ObMultiModeExprHelper::get_tenant_id(ctx.exec_ctx_.get_my_session()), "XMLModule"));
|
||||
ObDatum *xml_datum = NULL;
|
||||
ObIMulModeBase *xml_doc = NULL;
|
||||
ObMulModeNodeType node_type = M_MAX_TYPE;
|
||||
ObString xpath_str;
|
||||
ObPathExprIter xpath_iter(&allocator);
|
||||
ObString namespace_str;
|
||||
ObString default_ns;
|
||||
ObPathVarObject prefix_ns(allocator);
|
||||
ObMulModeMemCtx* mem_ctx = nullptr;
|
||||
|
||||
// Check and read param
|
||||
CK(OB_NOT_NULL(ctx.exec_ctx_.get_my_session()));
|
||||
OZ(ObXmlUtil::create_mulmode_tree_context(&allocator, mem_ctx));
|
||||
CK(expr.arg_cnt_ == 3);
|
||||
OZ(ObXMLExprHelper::get_xmltype_from_expr(expr.args_[0], ctx, xml_datum), expr.args_[0]);
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (expr.args_[1]->datum_meta_.type_ == ObNullType) {
|
||||
ret = OB_ERR_INVALID_XPATH_EXPRESSION;
|
||||
LOG_WARN("invalid xpath expression", K(ret), K(expr.args_[1]->datum_meta_.type_ ));
|
||||
} else if (OB_FAIL(ObXMLExprHelper::get_str_from_expr(expr.args_[1], ctx, xpath_str, allocator))) {
|
||||
LOG_WARN("fail to get xpath str", K(ret), K(expr.args_[1]));
|
||||
} else if (expr.args_[2]->datum_meta_.type_ == ObNullType){
|
||||
// do noting
|
||||
} else if (OB_FAIL(ObXMLExprHelper::get_str_from_expr(expr.args_[2], ctx, namespace_str, allocator))) {
|
||||
LOG_WARN("fail to get namespace str", K(ret), K(expr.args_[2]));
|
||||
}
|
||||
|
||||
// process xmltype and xpath
|
||||
OZ(ObXMLExprHelper::get_xml_base(
|
||||
mem_ctx, xml_datum,
|
||||
ObCollationType::CS_TYPE_INVALID,
|
||||
ObNodeMemType::BINARY_TYPE,
|
||||
xml_doc,
|
||||
node_type,
|
||||
ObGetXmlBaseType::OB_SHOULD_CHECK));
|
||||
OZ(ObXMLExprHelper::construct_namespace_params(namespace_str, default_ns, prefix_ns, allocator));
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (OB_FAIL(xpath_iter.init(mem_ctx, xpath_str, default_ns, xml_doc, &prefix_ns))) {
|
||||
LOG_WARN("fail to init xpath iterator", K(xpath_str), K(default_ns), K(ret));
|
||||
ObXMLExprHelper::replace_xpath_ret_code(ret);
|
||||
} else if (OB_FAIL(xpath_iter.open())) {
|
||||
LOG_WARN("fail to open xpath iterator", K(ret));
|
||||
ObXMLExprHelper::replace_xpath_ret_code(ret);
|
||||
} else if (OB_FAIL(xpath_iter.get_node_exists(is_exists))) {
|
||||
LOG_WARN("fail to get node exists", K(ret));
|
||||
}
|
||||
|
||||
int tmp_ret = OB_SUCCESS;
|
||||
if (OB_SUCCESS != (tmp_ret = xpath_iter.close())) {
|
||||
LOG_WARN("fail to close xpath iter", K(tmp_ret));
|
||||
ret = COVER_SUCC(tmp_ret);
|
||||
}
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (is_exists) {
|
||||
res.set_int(1);
|
||||
} else {
|
||||
res.set_int(0);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObExprExistsNodeXml::cg_expr(ObExprCGCtx &expr_cg_ctx, const ObRawExpr &raw_expr, ObExpr &rt_expr) const
|
||||
{
|
||||
UNUSED(expr_cg_ctx);
|
||||
UNUSED(raw_expr);
|
||||
rt_expr.eval_func_ = eval_existsnode_xml;
|
||||
return OB_SUCCESS;
|
||||
}
|
||||
|
||||
} // sql
|
||||
} // oceanbase
|
45
src/sql/engine/expr/ob_expr_existsnode_xml.h
Normal file
45
src/sql/engine/expr/ob_expr_existsnode_xml.h
Normal file
@ -0,0 +1,45 @@
|
||||
/**
|
||||
* Copyright (c) 2021 OceanBase
|
||||
* OceanBase CE is licensed under Mulan PubL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PubL v2.
|
||||
* You may obtain a copy of Mulan PubL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPubL-2.0
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PubL v2 for more details.
|
||||
* This file is for func existsnode(xml).
|
||||
*/
|
||||
|
||||
#ifndef OCEANBASE_SQL_ENGINE_EXPR_OB_EXPR_EXISTSNODE_XML_H
|
||||
#define OCEANBASE_SQL_ENGINE_EXPR_OB_EXPR_EXISTSNODE_XML_H
|
||||
|
||||
#include "sql/engine/expr/ob_expr_operator.h"
|
||||
#include "lib/xml/ob_xpath.h"
|
||||
namespace oceanbase
|
||||
{
|
||||
|
||||
namespace sql
|
||||
{
|
||||
class ObExprExistsNodeXml : public ObFuncExprOperator
|
||||
{
|
||||
public:
|
||||
explicit ObExprExistsNodeXml(common::ObIAllocator &alloc);
|
||||
virtual ~ObExprExistsNodeXml();
|
||||
virtual int calc_result_typeN(
|
||||
ObExprResType &type,
|
||||
ObExprResType *types,
|
||||
int64_t param_num,
|
||||
common::ObExprTypeCtx &type_ctx) const override;
|
||||
static int eval_existsnode_xml(const ObExpr &expr, ObEvalCtx &ctx, ObDatum &res);
|
||||
virtual int cg_expr(ObExprCGCtx &expr_cg_ctx, const ObRawExpr &raw_expr, ObExpr &rt_expr) const override;
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(ObExprExistsNodeXml);
|
||||
};
|
||||
|
||||
} // sql
|
||||
} // oceanbase
|
||||
|
||||
|
||||
#endif //OCEANBASE_SQL_ENGINE_EXPR_OB_EXPR_EXISTSNODE_XML_H
|
@ -124,7 +124,8 @@ int ObExprExtractValue::eval_extract_value(const ObExpr &expr, ObEvalCtx &ctx, O
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObEvalCtx::TempAllocGuard tmp_alloc_g(ctx);
|
||||
common::ObArenaAllocator &allocator = tmp_alloc_g.get_allocator();
|
||||
uint64_t tenant_id = ObMultiModeExprHelper::get_tenant_id(ctx.exec_ctx_.get_my_session());
|
||||
MultimodeAlloctor allocator(tmp_alloc_g.get_allocator(), expr.type_, tenant_id, ret);
|
||||
ObDatum *xml_datum = NULL;
|
||||
ObString xpath_str;
|
||||
ObString namespace_str;
|
||||
@ -136,7 +137,7 @@ int ObExprExtractValue::eval_extract_value(const ObExpr &expr, ObEvalCtx &ctx, O
|
||||
ObString xml_res;
|
||||
ObCollationType cs_type = CS_TYPE_INVALID;
|
||||
ObMulModeMemCtx* xml_mem_ctx = nullptr;
|
||||
lib::ObMallocHookAttrGuard malloc_guard(lib::ObMemAttr(ObXMLExprHelper::get_tenant_id(ctx.exec_ctx_.get_my_session()), "XMLModule"));
|
||||
lib::ObMallocHookAttrGuard malloc_guard(lib::ObMemAttr(tenant_id, "XMLModule"));
|
||||
|
||||
if (OB_ISNULL(ctx.exec_ctx_.get_my_session())) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
@ -146,7 +147,7 @@ int ObExprExtractValue::eval_extract_value(const ObExpr &expr, ObEvalCtx &ctx, O
|
||||
} else if (OB_UNLIKELY(expr.arg_cnt_ != 2 && expr.arg_cnt_ != 3)) {
|
||||
ret = OB_ERR_PARAM_SIZE;
|
||||
LOG_WARN("invalid arg_cnt_", K(ret), K(expr.arg_cnt_));
|
||||
} else if (OB_FAIL(ObXMLExprHelper::get_xmltype_from_expr(expr.args_[0], ctx, xml_datum))) {
|
||||
} else if (OB_FAIL(ObXMLExprHelper::get_xmltype_from_expr(expr.args_[0], ctx, xml_datum, allocator))) {
|
||||
LOG_WARN("fail to get xml str", K(ret));
|
||||
} else if (ObNullType == expr.args_[1]->datum_meta_.type_) {
|
||||
ret = OB_ERR_INVALID_XPATH_EXPRESSION;
|
||||
@ -179,7 +180,8 @@ int ObExprExtractValue::eval_mysql_extract_value(const ObExpr &expr, ObEvalCtx &
|
||||
{
|
||||
INIT_SUCC(ret);
|
||||
ObEvalCtx::TempAllocGuard tmp_alloc_g(ctx);
|
||||
common::ObArenaAllocator &allocator = tmp_alloc_g.get_allocator();
|
||||
uint64_t tenant_id = ObMultiModeExprHelper::get_tenant_id(ctx.exec_ctx_.get_my_session());
|
||||
MultimodeAlloctor allocator(tmp_alloc_g.get_allocator(), expr.type_, tenant_id, ret);
|
||||
ObTextStringDatumResult output_result(expr.datum_meta_.type_, &expr, &ctx, &res);
|
||||
ObString xml_frag;
|
||||
ObString xpath_expr;
|
||||
@ -188,11 +190,8 @@ int ObExprExtractValue::eval_mysql_extract_value(const ObExpr &expr, ObEvalCtx &
|
||||
ObStringBuffer xml_res(&allocator);
|
||||
|
||||
ObMulModeMemCtx* xml_mem_ctx = nullptr;
|
||||
lib::ObMallocHookAttrGuard malloc_guard(lib::ObMemAttr(ObXMLExprHelper::get_tenant_id(ctx.exec_ctx_.get_my_session()), "XMLModule"));
|
||||
if (OB_ISNULL(ctx.exec_ctx_.get_my_session())) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("get session failed.", K(ret));
|
||||
} else if (OB_FAIL(ObXmlUtil::create_mulmode_tree_context(&allocator, xml_mem_ctx))) {
|
||||
lib::ObMallocHookAttrGuard malloc_guard(lib::ObMemAttr(tenant_id, "XMLModule"));
|
||||
if (OB_FAIL(ObXmlUtil::create_mulmode_tree_context(&allocator, xml_mem_ctx))) {
|
||||
LOG_WARN("fail to create tree memory context", K(ret));
|
||||
} else if (expr.arg_cnt_ != 2) {
|
||||
ret = OB_ERR_PARAM_SIZE;
|
||||
@ -204,6 +203,7 @@ int ObExprExtractValue::eval_mysql_extract_value(const ObExpr &expr, ObEvalCtx &
|
||||
LOG_WARN("get xml frag string failed", K(ret));
|
||||
} else if (xml_frag.empty()) {
|
||||
// do nothing
|
||||
} else if (OB_FALSE_IT(allocator.set_baseline_size(xml_frag.length()))) {
|
||||
} else if (OB_FAIL(ObXMLExprHelper::get_str_from_expr(expr.args_[1], ctx, xpath_expr, allocator))) {
|
||||
LOG_WARN("get xpath expr failed.", K(ret));
|
||||
} else if (OB_FAIL(ObMulModeFactory::get_xml_base(xml_mem_ctx, xml_frag, ObNodeMemType::TREE_TYPE, ObNodeMemType::BINARY_TYPE, xml_base, M_DOCUMENT))) {
|
||||
|
@ -82,7 +82,8 @@ int ObExprExtractXml::eval_extract_xml(const ObExpr &expr, ObEvalCtx &ctx, ObDat
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObEvalCtx::TempAllocGuard tmp_alloc_g(ctx);
|
||||
common::ObArenaAllocator &allocator = tmp_alloc_g.get_allocator();
|
||||
uint64_t tenant_id = ObMultiModeExprHelper::get_tenant_id(ctx.exec_ctx_.get_my_session());
|
||||
MultimodeAlloctor allocator(tmp_alloc_g.get_allocator(), expr.type_, tenant_id, ret);
|
||||
ObDatum *xml_datum = NULL;
|
||||
ObString xpath_str;
|
||||
ObString namespace_str;
|
||||
@ -91,15 +92,15 @@ int ObExprExtractXml::eval_extract_xml(const ObExpr &expr, ObEvalCtx &ctx, ObDat
|
||||
ObPathExprIter xpath_iter(&allocator);
|
||||
ObString default_ns;
|
||||
ObPathVarObject prefix_ns(allocator);
|
||||
ObString xml_res;
|
||||
ObXmlDocument *root = nullptr;
|
||||
ObString bin_str;
|
||||
ObMulModeNodeType node_type = M_MAX_TYPE;
|
||||
ObString input_str;
|
||||
ObCollationType cs_type = CS_TYPE_INVALID;
|
||||
bool is_null_res = false;
|
||||
ObString blob_locator;
|
||||
// eval arg
|
||||
|
||||
ObMulModeMemCtx* mem_ctx = nullptr;
|
||||
lib::ObMallocHookAttrGuard malloc_guard(lib::ObMemAttr(ObXMLExprHelper::get_tenant_id(ctx.exec_ctx_.get_my_session()), "XMLModule"));
|
||||
lib::ObMallocHookAttrGuard malloc_guard(lib::ObMemAttr(tenant_id, "XMLModule"));
|
||||
|
||||
if (OB_ISNULL(ctx.exec_ctx_.get_my_session())) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
@ -109,7 +110,7 @@ int ObExprExtractXml::eval_extract_xml(const ObExpr &expr, ObEvalCtx &ctx, ObDat
|
||||
} else if (OB_UNLIKELY(expr.arg_cnt_ != 3)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("invalid arg_cnt_", K(ret), K(expr.arg_cnt_));
|
||||
} else if (OB_FAIL(ObXMLExprHelper::get_xmltype_from_expr(expr.args_[0], ctx, xml_datum))) {
|
||||
} else if (OB_FAIL(ObXMLExprHelper::get_xmltype_from_expr(expr.args_[0], ctx, xml_datum, allocator))) {
|
||||
LOG_WARN("fail to get xmltype value", K(ret));
|
||||
} else if (ObNullType == expr.args_[1]->datum_meta_.type_) {
|
||||
ret = OB_ERR_INVALID_XPATH_EXPRESSION;
|
||||
@ -129,138 +130,18 @@ int ObExprExtractXml::eval_extract_xml(const ObExpr &expr, ObEvalCtx &ctx, ObDat
|
||||
} else if (OB_FAIL(xpath_iter.init(mem_ctx, xpath_str, default_ns, xml_doc, &prefix_ns))) {
|
||||
LOG_WARN("fail to init xpath iterator", K(xpath_str), K(default_ns), K(ret));
|
||||
ObXMLExprHelper::replace_xpath_ret_code(ret);
|
||||
} else if (OB_FAIL(concat_xpath_result(expr, ctx, xpath_iter, cs_type, res, node_type, mem_ctx))) {
|
||||
} else if (OB_FAIL(ObXMLExprHelper::concat_xpath_result(mem_ctx, xpath_iter, bin_str, is_null_res))) {
|
||||
LOG_WARN("fail to concat xpath result", K(ret));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObExprExtractXml::concat_xpath_result(const ObExpr &expr,
|
||||
ObEvalCtx &eval_ctx,
|
||||
ObPathExprIter &xpath_iter,
|
||||
ObCollationType cs_type,
|
||||
ObDatum &res,
|
||||
ObMulModeNodeType &node_type,
|
||||
ObMulModeMemCtx* mem_ctx)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObStringBuffer buff(mem_ctx->allocator_);
|
||||
ObIMulModeBase *node = NULL;
|
||||
int64_t append_node_num = 0;
|
||||
int element_count = 0;
|
||||
int text_count = 0;
|
||||
ObString version;
|
||||
ObString encoding;
|
||||
uint16_t standalone;
|
||||
ObString blob_locator;
|
||||
bool first_is_doc = false;
|
||||
ObIMulModeBase* last_parent = nullptr;
|
||||
common::hash::ObHashMap<ObString, ObString> ns_map;
|
||||
|
||||
if (OB_FAIL(xpath_iter.open())) {
|
||||
LOG_WARN("fail to open xpath iterator", K(ret));
|
||||
ObXMLExprHelper::replace_xpath_ret_code(ret);
|
||||
} else if (OB_FAIL(ns_map.create(10, lib::ObMemAttr(MTL_ID(), "XMLModule")))) {
|
||||
LOG_WARN("ns map create failed", K(ret));
|
||||
}
|
||||
|
||||
ObBinAggSerializer bin_agg(mem_ctx->allocator_, ObBinAggType::AGG_XML, static_cast<uint8_t>(M_CONTENT));
|
||||
|
||||
while (OB_SUCC(ret)) {
|
||||
ObIMulModeBase* tmp = nullptr;
|
||||
ObXmlBin extend;
|
||||
if (OB_FAIL(xpath_iter.get_next_node(node))) {
|
||||
if (ret != OB_ITER_END) {
|
||||
LOG_WARN("fail to get next xml node", K(ret));
|
||||
}
|
||||
} else if (OB_ISNULL(node)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("xpath result node is null", K(ret));
|
||||
} else if (node->is_tree() && OB_FAIL(ObMulModeFactory::transform(mem_ctx, node, BINARY_TYPE, node))) {
|
||||
LOG_WARN("fail to transform to tree", K(ret));
|
||||
} else {
|
||||
ObXmlBin *bin = nullptr;
|
||||
if (OB_ISNULL(bin = static_cast<ObXmlBin*>(node))) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("get bin failed", K(ret));
|
||||
} else if (bin->meta_.len_ == 0) {
|
||||
// do nothing
|
||||
} else if (bin->check_extend()) {
|
||||
bool conflict = false;
|
||||
// check key conflict
|
||||
if (OB_FAIL(bin->get_extend(extend))) {
|
||||
LOG_WARN("fail to get extend", K(ret));
|
||||
} else if (OB_FAIL(ObXmlUtil::check_ns_conflict(xpath_iter.get_cur_res_parent(), last_parent, &extend, ns_map, conflict))) {
|
||||
LOG_WARN("fail to check conflict", K(ret));
|
||||
} else if (conflict) {
|
||||
// if conflict, merge bin
|
||||
if (OB_FAIL(bin->merge_extend(extend))) {
|
||||
LOG_WARN("fail to merge extend", K(ret));
|
||||
} else {
|
||||
bin = &extend;
|
||||
}
|
||||
} else if (OB_FAIL(bin->remove_extend())) { // if not conflict, erase extend
|
||||
LOG_WARN("fail to remove extend", K(ret));
|
||||
}
|
||||
}
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (OB_FAIL(bin_agg.append_key_and_value(bin))) {
|
||||
LOG_WARN("failed to append binary", K(ret));
|
||||
} else {
|
||||
ObMulModeNodeType type = node->type();
|
||||
if (append_node_num == 0 && type == ObMulModeNodeType::M_DOCUMENT) {
|
||||
version = node->get_version();
|
||||
encoding = node->get_encoding();
|
||||
standalone = node->get_standalone();
|
||||
first_is_doc = version.empty() ? false : true;
|
||||
}
|
||||
|
||||
if (type == ObMulModeNodeType::M_ELEMENT || type == ObMulModeNodeType::M_DOCUMENT) {
|
||||
element_count++;
|
||||
} else if (type == ObMulModeNodeType::M_TEXT || type == ObMulModeNodeType::M_CDATA) {
|
||||
text_count++;
|
||||
} else if (type == ObMulModeNodeType::M_CONTENT) {
|
||||
append_node_num += bin->count() - 1;
|
||||
}
|
||||
append_node_num++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == OB_ITER_END) {
|
||||
ret = OB_SUCCESS;
|
||||
if (element_count > 1 || element_count == 0) {
|
||||
node_type = ObMulModeNodeType::M_CONTENT;
|
||||
} else if (element_count == 1 && text_count > 0) {
|
||||
node_type = ObMulModeNodeType::M_CONTENT;
|
||||
} else if (append_node_num == 0) {
|
||||
// do nothing
|
||||
} else {
|
||||
node_type = ObMulModeNodeType::M_DOCUMENT;
|
||||
}
|
||||
|
||||
bin_agg.set_header_type(node_type);
|
||||
if (first_is_doc && append_node_num == 1) {
|
||||
bin_agg.set_xml_decl(version, encoding, standalone);
|
||||
}
|
||||
}
|
||||
|
||||
int tmp_ret = OB_SUCCESS;
|
||||
if (OB_SUCCESS != (tmp_ret = xpath_iter.close())) {
|
||||
LOG_WARN("fail to close xpath iter", K(tmp_ret));
|
||||
ret = COVER_SUCC(tmp_ret);
|
||||
} else if (append_node_num == 0) {
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (is_null_res) {
|
||||
res.set_null();
|
||||
} else if (OB_FAIL(bin_agg.serialize())) {
|
||||
LOG_WARN("failed to serialize binary.", K(ret));
|
||||
} else if (ns_map.size() > 0 && OB_FAIL(ObXmlUtil::ns_to_extend(mem_ctx, ns_map, bin_agg.get_buffer()))) {
|
||||
LOG_WARN("failed to serialize extend.", K(ret));
|
||||
} else if (OB_FAIL(ObXMLExprHelper::pack_binary_res(expr, eval_ctx, bin_agg.get_buffer()->string(), blob_locator))) {
|
||||
} else if (OB_FAIL(ObXMLExprHelper::pack_binary_res(expr, ctx, bin_str, blob_locator))) {
|
||||
LOG_WARN("failed to pack binary res.", K(ret));
|
||||
} else {
|
||||
res.set_string(blob_locator.ptr(), blob_locator.length());
|
||||
}
|
||||
ns_map.clear();
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -36,13 +36,6 @@ class ObExprExtractXml : public ObFuncExprOperator
|
||||
ObExpr &rt_expr)
|
||||
const override;
|
||||
private:
|
||||
static int concat_xpath_result(const ObExpr &expr,
|
||||
ObEvalCtx &eval_ctx,
|
||||
ObPathExprIter &xpath_iter,
|
||||
ObCollationType cs_type,
|
||||
ObDatum &res,
|
||||
ObMulModeNodeType &node_type,
|
||||
ObMulModeMemCtx* ctx);
|
||||
static int check_and_set_res(const ObExpr &expr,
|
||||
ObEvalCtx &ctx,
|
||||
ObDatum &res,
|
||||
|
@ -103,7 +103,8 @@ int ObExprInsertChildXml::eval_insert_child_xml(const ObExpr &expr, ObEvalCtx &c
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObEvalCtx::TempAllocGuard tmp_alloc_g(ctx);
|
||||
common::ObArenaAllocator &allocator = tmp_alloc_g.get_allocator();
|
||||
uint64_t tenant_id = ObMultiModeExprHelper::get_tenant_id(ctx.exec_ctx_.get_my_session());
|
||||
MultimodeAlloctor allocator(tmp_alloc_g.get_allocator(), expr.type_, tenant_id, ret);
|
||||
ObDatum *xml_datum = NULL;
|
||||
ObIMulModeBase *xml_tree = NULL;
|
||||
ObString xpath_str;
|
||||
@ -118,7 +119,7 @@ int ObExprInsertChildXml::eval_insert_child_xml(const ObExpr &expr, ObEvalCtx &c
|
||||
bool is_insert_attributes = false;
|
||||
|
||||
ObMulModeMemCtx* mem_ctx = nullptr;
|
||||
lib::ObMallocHookAttrGuard malloc_guard(lib::ObMemAttr(MTL_ID(), "XMLModule"));
|
||||
lib::ObMallocHookAttrGuard malloc_guard(lib::ObMemAttr(tenant_id, "XMLModule"));
|
||||
if (OB_FAIL(ObXmlUtil::create_mulmode_tree_context(&allocator, mem_ctx))) {
|
||||
LOG_WARN("fail to create tree memory context", K(ret));
|
||||
} else if (OB_UNLIKELY(expr.arg_cnt_ != 5)) {
|
||||
@ -127,7 +128,7 @@ int ObExprInsertChildXml::eval_insert_child_xml(const ObExpr &expr, ObEvalCtx &c
|
||||
} else if (ObNullType == expr.args_[1]->datum_meta_.type_) {
|
||||
ret = OB_ERR_INVALID_XPATH_EXPRESSION;
|
||||
LOG_WARN("invalid xpath expression", K(ret));
|
||||
} else if (OB_FAIL(ObXMLExprHelper::get_xmltype_from_expr(expr.args_[0], ctx, xml_datum))) {
|
||||
} else if (OB_FAIL(ObXMLExprHelper::get_xmltype_from_expr(expr.args_[0], ctx, xml_datum, allocator))) {
|
||||
LOG_WARN("fail to get xmltype value", K(ret));
|
||||
} else if (OB_FAIL(ObXMLExprHelper::get_str_from_expr(expr.args_[1], ctx, xpath_str, allocator))) {
|
||||
LOG_WARN("fail to get xpath str", K(ret));
|
||||
@ -204,7 +205,7 @@ int ObExprInsertChildXml::eval_insert_child_xml(const ObExpr &expr, ObEvalCtx &c
|
||||
int ObExprInsertChildXml::insert_child_xml(const ObExpr &expr,
|
||||
ObEvalCtx &ctx,
|
||||
ObMulModeMemCtx* mem_ctx,
|
||||
ObArenaAllocator &allocator,
|
||||
MultimodeAlloctor &allocator,
|
||||
ObPathExprIter &xpath_iter,
|
||||
ObString child_str,
|
||||
ObString value_str,
|
||||
@ -219,7 +220,8 @@ int ObExprInsertChildXml::insert_child_xml(const ObExpr &expr,
|
||||
uint64_t ele_index = 0;
|
||||
ObDatum *value_datum = NULL;
|
||||
CK(OB_NOT_NULL(expr.args_[3]));
|
||||
if (expr.args_[3]->datum_meta_.type_ == ObUserDefinedSQLType) {
|
||||
ObObjType type = expr.args_[3]->datum_meta_.type_;
|
||||
if (type == ObUserDefinedSQLType) {
|
||||
if (OB_FAIL(ObXMLExprHelper::get_xmltype_from_expr(expr.args_[3], ctx, value_datum))) {
|
||||
LOG_WARN("fail to get xmltype value", K(ret));
|
||||
} else if (OB_FAIL(ObXMLExprHelper::get_xml_base(mem_ctx, value_datum, CS_TYPE_INVALID, ObNodeMemType::TREE_TYPE, value_doc))) {
|
||||
@ -280,6 +282,17 @@ int ObExprInsertChildXml::insert_child_xml(const ObExpr &expr,
|
||||
ret = OB_SUCCESS;
|
||||
}
|
||||
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (type == ObUserDefinedSQLType) {
|
||||
if (OB_FAIL(allocator.add_baseline_size(value_datum, true, res_array.size()))) {
|
||||
LOG_WARN("failed to add base line size", K(ret));
|
||||
}
|
||||
} else {
|
||||
if (OB_FAIL(allocator.add_baseline_size(expr.args_[3], ctx, res_array.size()))) {
|
||||
LOG_WARN("failed to add base line size", K(ret));
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; OB_SUCC(ret) && i < res_array.size(); i++) {
|
||||
ObIMulModeBase* insert_node = res_array[i];
|
||||
if (OB_ISNULL(insert_node)) {
|
||||
@ -290,10 +303,13 @@ int ObExprInsertChildXml::insert_child_xml(const ObExpr &expr,
|
||||
LOG_WARN("fail to insert attributes node", K(ret), K(child_str), K(value_str));
|
||||
}
|
||||
} else {
|
||||
ObIMulModeBase *value_doc = NULL;
|
||||
if (OB_FAIL(ObXMLExprHelper::get_xml_base(mem_ctx, value_datum, CS_TYPE_INVALID, ObNodeMemType::TREE_TYPE, value_doc))) {
|
||||
LOG_WARN("fail to parse xml doc", K(ret));
|
||||
} else if (OB_FAIL(insert_element_node(allocator, insert_node, value_doc->at(ele_index)))) {
|
||||
ObXmlNode *value_clone = nullptr;
|
||||
if (OB_ISNULL(value_doc->at(ele_index))) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("get index is null", K(ret), K(ele_index), KP(value_doc));
|
||||
} else if (OB_FAIL(value_doc->at(ele_index)->clone(mem_ctx, value_clone))) {
|
||||
LOG_WARN("failed to clone.", K(ret), K(value_doc));
|
||||
} else if (OB_FAIL(insert_element_node(allocator, insert_node, value_clone))) {
|
||||
LOG_WARN("fail to insert element node", K(ret));
|
||||
}
|
||||
}
|
||||
@ -308,7 +324,7 @@ int ObExprInsertChildXml::insert_child_xml(const ObExpr &expr,
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObExprInsertChildXml::insert_element_node(ObArenaAllocator &allocator,
|
||||
int ObExprInsertChildXml::insert_element_node(ObIAllocator &allocator,
|
||||
ObIMulModeBase *insert_node,
|
||||
ObIMulModeBase *value_node)
|
||||
{
|
||||
@ -389,7 +405,7 @@ int ObExprInsertChildXml::insert_attributes_node(ObString key_str,
|
||||
|
||||
int ObExprInsertChildXml::check_child_expr(const ObExpr &expr,
|
||||
ObEvalCtx &ctx,
|
||||
ObArenaAllocator &allocator,
|
||||
ObIAllocator &allocator,
|
||||
ObMulModeMemCtx* mem_ctx,
|
||||
ObString &child_str,
|
||||
ObString &value_str,
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
#include "sql/engine/expr/ob_expr_operator.h"
|
||||
#include "lib/xml/ob_xpath.h"
|
||||
#include "sql/engine/expr/ob_expr_multi_mode_func_helper.h"
|
||||
|
||||
namespace oceanbase
|
||||
{
|
||||
@ -41,7 +42,7 @@ private:
|
||||
static int insert_child_xml(const ObExpr &expr,
|
||||
ObEvalCtx &ctx,
|
||||
ObMulModeMemCtx* mem_ctx,
|
||||
ObArenaAllocator &allocator,
|
||||
MultimodeAlloctor &allocator,
|
||||
ObPathExprIter &xpath_iter,
|
||||
ObString child_str,
|
||||
ObString value_str,
|
||||
@ -49,14 +50,14 @@ private:
|
||||
|
||||
static int check_child_expr(const ObExpr &expr,
|
||||
ObEvalCtx &ctx,
|
||||
ObArenaAllocator &allocator,
|
||||
ObIAllocator &allocator,
|
||||
ObMulModeMemCtx* mem_ctx,
|
||||
ObString &child_str,
|
||||
ObString &value_str,
|
||||
bool &is_insert_attributes);
|
||||
static bool is_first_char_attribute(ObString child_str);
|
||||
|
||||
static int insert_element_node(ObArenaAllocator &allocator, ObIMulModeBase *insert_node, ObIMulModeBase *value_node);
|
||||
static int insert_element_node(ObIAllocator &allocator, ObIMulModeBase *insert_node, ObIMulModeBase *value_node);
|
||||
|
||||
static int insert_attributes_node(ObString key_str,
|
||||
ObString value_str,
|
||||
|
@ -82,7 +82,7 @@ int ObExprIsJson::calc_result_typeN(ObExprResType& type,
|
||||
|
||||
int ObExprIsJson::check_is_json(const ObExpr &expr, ObEvalCtx &ctx,
|
||||
const ObDatum &data, ObObjType type,
|
||||
ObCollationType cs_type, ObArenaAllocator &allocator,
|
||||
ObCollationType cs_type, MultimodeAlloctor &allocator,
|
||||
uint8_t strict_opt, uint8_t scalar_opt, uint8_t unique_opt,
|
||||
bool check_for_is_json, ObDatum &res)
|
||||
{
|
||||
@ -275,7 +275,9 @@ int ObExprIsJson::eval_is_json(const ObExpr &expr, ObEvalCtx &ctx, ObDatum &res)
|
||||
LOG_WARN("eval json arg failed", K(ret));
|
||||
} else {
|
||||
ObEvalCtx::TempAllocGuard tmp_alloc_g(ctx);
|
||||
common::ObArenaAllocator &temp_allocator = tmp_alloc_g.get_allocator();
|
||||
uint64_t tenant_id = ObMultiModeExprHelper::get_tenant_id(ctx.exec_ctx_.get_my_session());
|
||||
MultimodeAlloctor temp_allocator(tmp_alloc_g.get_allocator(), expr.type_, tenant_id, ret);
|
||||
lib::ObMallocHookAttrGuard malloc_guard(lib::ObMemAttr(tenant_id, "JSONModule"));
|
||||
if (OB_FAIL(check_is_json(expr, ctx, *json_datum,
|
||||
json_arg->datum_meta_.type_,
|
||||
cs_type, temp_allocator,
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
#include "sql/engine/expr/ob_expr_operator.h"
|
||||
#include "sql/engine/expr/ob_expr_lob_utils.h"
|
||||
#include "sql/engine/expr/ob_expr_multi_mode_func_helper.h"
|
||||
|
||||
namespace oceanbase
|
||||
{
|
||||
@ -33,7 +34,7 @@ public:
|
||||
static int get_is_json_option(const ObExpr &expr, ObEvalCtx &ctx, int64_t idx, uint8_t& is_json_mode);
|
||||
static int check_is_json(const ObExpr &expr, ObEvalCtx &ctx,
|
||||
const ObDatum &data, ObObjType type,
|
||||
ObCollationType cs_type, ObArenaAllocator &allocator,
|
||||
ObCollationType cs_type, MultimodeAlloctor &allocator,
|
||||
uint8_t strict_opt, uint8_t scalar_opt, uint8_t unique_opt,
|
||||
bool check_for_is_json, ObDatum &res);
|
||||
static int eval_is_json(const ObExpr &expr, ObEvalCtx &ctx, ObDatum &res);
|
||||
|
@ -144,8 +144,8 @@ int ObExprJsonArray::eval_ora_json_array(const ObExpr &expr, ObEvalCtx &ctx, ObD
|
||||
INIT_SUCC(ret);
|
||||
ObDatum *json_datum = NULL;
|
||||
ObEvalCtx::TempAllocGuard tmp_alloc_g(ctx);
|
||||
common::ObArenaAllocator &temp_allocator = tmp_alloc_g.get_allocator();
|
||||
|
||||
uint64_t tenant_id = ObMultiModeExprHelper::get_tenant_id(ctx.exec_ctx_.get_my_session());
|
||||
MultimodeAlloctor temp_allocator(tmp_alloc_g.get_allocator(), expr.type_, tenant_id, ret);
|
||||
uint32_t max_val_idx = expr.arg_cnt_ - 3;
|
||||
int64_t opt_array[OPT_MAX_ID] = {0};
|
||||
int64_t& opt_strict = opt_array[OPT_STRICT_ID];
|
||||
@ -154,7 +154,7 @@ int ObExprJsonArray::eval_ora_json_array(const ObExpr &expr, ObEvalCtx &ctx, ObD
|
||||
ObDatum *opt_datum = NULL;
|
||||
ObExpr *opt_expr = expr.args_[i];
|
||||
ObObjType val_type = opt_expr->datum_meta_.type_;
|
||||
if (OB_UNLIKELY(OB_FAIL(opt_expr->eval(ctx, opt_datum)))) {
|
||||
if (OB_FAIL(temp_allocator.eval_arg(opt_expr, ctx, opt_datum))) {
|
||||
LOG_WARN("eval json arg failed", K(ret));
|
||||
} else if (val_type == ObNullType || opt_datum->is_null()) {
|
||||
} else if (!ob_is_integer_type(val_type)) {
|
||||
@ -187,7 +187,7 @@ int ObExprJsonArray::eval_ora_json_array(const ObExpr &expr, ObEvalCtx &ctx, ObD
|
||||
ObObjType val_type = opt_expr->datum_meta_.type_;
|
||||
bool is_format_json = false;
|
||||
ObIJsonBase* j_val = nullptr;
|
||||
if (OB_UNLIKELY(OB_FAIL(opt_expr->eval(ctx, opt_format)))) {
|
||||
if (OB_FAIL(temp_allocator.eval_arg(opt_expr, ctx, opt_format))) {
|
||||
LOG_WARN("eval json arg failed", K(ret));
|
||||
} else if (val_type == ObNullType || opt_format->is_null()) {
|
||||
} else if (!ob_is_integer_type(val_type)) {
|
||||
@ -221,7 +221,7 @@ int ObExprJsonArray::eval_ora_json_array(const ObExpr &expr, ObEvalCtx &ctx, ObD
|
||||
} else {
|
||||
if (OB_FAIL(string_buffer.reserve(j_arr.get_serialize_size()))) {
|
||||
LOG_WARN("fail to reserve string.", K(ret), K(j_arr.get_serialize_size()));
|
||||
} else if (OB_FAIL(j_arr.print(string_buffer, true, false))) {
|
||||
} else if (OB_FAIL(j_arr.print(string_buffer, true, 0, false))) {
|
||||
LOG_WARN("failed: get json string text", K(ret));
|
||||
} else {
|
||||
ObCollationType in_cs_type = CS_TYPE_UTF8MB4_BIN;
|
||||
@ -262,7 +262,9 @@ int ObExprJsonArray::eval_json_array(const ObExpr &expr, ObEvalCtx &ctx, ObDatum
|
||||
INIT_SUCC(ret);
|
||||
ObDatum *json_datum = NULL;
|
||||
ObEvalCtx::TempAllocGuard tmp_alloc_g(ctx);
|
||||
common::ObArenaAllocator &temp_allocator = tmp_alloc_g.get_allocator();
|
||||
uint64_t tenant_id = ObMultiModeExprHelper::get_tenant_id(ctx.exec_ctx_.get_my_session());
|
||||
MultimodeAlloctor temp_allocator(tmp_alloc_g.get_allocator(), expr.type_, tenant_id, ret);
|
||||
lib::ObMallocHookAttrGuard malloc_guard(lib::ObMemAttr(tenant_id, "JSONModule"));
|
||||
ObJsonArray j_arr(&temp_allocator);
|
||||
ObIJsonBase *j_base = &j_arr;
|
||||
|
||||
@ -273,7 +275,10 @@ int ObExprJsonArray::eval_json_array(const ObExpr &expr, ObEvalCtx &ctx, ObDatum
|
||||
|
||||
for (uint32_t i = 0; OB_SUCC(ret) && i < expr.arg_cnt_; i++) {
|
||||
ObIJsonBase *j_val;
|
||||
if (OB_FAIL(ObJsonExprHelper::get_json_val(expr, ctx, &temp_allocator, i, j_val))) {
|
||||
if (OB_FAIL(temp_allocator.add_baseline_size(expr.args_[i], ctx))) {
|
||||
LOG_WARN("failed to add baselien size", K(ret), K(i));
|
||||
} else if (OB_FAIL(ObJsonExprHelper::get_json_val(expr, ctx, &temp_allocator, i, j_val))) {
|
||||
ret = OB_ERR_INVALID_JSON_TEXT_IN_PARAM;
|
||||
LOG_WARN("failed: get_json_val failed", K(ret));
|
||||
} else if (OB_FAIL(j_base->array_append(j_val))) {
|
||||
LOG_WARN("failed: json array append json value", K(ret));
|
||||
|
@ -95,7 +95,9 @@ int ObExprJsonArrayAppend::eval_json_array_append(const ObExpr &expr, ObEvalCtx
|
||||
{
|
||||
INIT_SUCC(ret);
|
||||
ObEvalCtx::TempAllocGuard tmp_alloc_g(ctx);
|
||||
common::ObArenaAllocator &temp_allocator = tmp_alloc_g.get_allocator();
|
||||
uint64_t tenant_id = ObMultiModeExprHelper::get_tenant_id(ctx.exec_ctx_.get_my_session());
|
||||
MultimodeAlloctor temp_allocator(tmp_alloc_g.get_allocator(), expr.type_, tenant_id, ret);
|
||||
lib::ObMallocHookAttrGuard malloc_guard(lib::ObMemAttr(tenant_id, "JSONModule"));
|
||||
ObIJsonBase *j_base = NULL;
|
||||
bool is_null = false;
|
||||
ObJsonSeekResult hit;
|
||||
@ -119,7 +121,7 @@ int ObExprJsonArrayAppend::eval_json_array_append(const ObExpr &expr, ObEvalCtx
|
||||
ObExpr *arg = expr.args_[i];
|
||||
ObDatum *json_datum = NULL;
|
||||
hit.reset();
|
||||
if (OB_FAIL(expr.args_[i]->eval(ctx, json_datum))) {
|
||||
if (OB_FAIL(temp_allocator.eval_arg(expr.args_[i], ctx, json_datum))) {
|
||||
LOG_WARN("failed: eval json path datum.", K(ret));
|
||||
} else if (arg->datum_meta_.type_ == ObNullType || json_datum->is_null()) {
|
||||
is_null = true;
|
||||
@ -136,7 +138,9 @@ int ObExprJsonArrayAppend::eval_json_array_append(const ObExpr &expr, ObEvalCtx
|
||||
// do nothing
|
||||
} else {
|
||||
ObIJsonBase *j_val = NULL;
|
||||
if (OB_FAIL(ObJsonExprHelper::get_json_val(expr, ctx, &temp_allocator, i+1, j_val))) {
|
||||
if (OB_FAIL(temp_allocator.add_baseline_size(expr.args_[i+1], ctx))) {
|
||||
LOG_WARN("failed to add baselien size", K(ret), K(i + 1));
|
||||
} else if (OB_FAIL(ObJsonExprHelper::get_json_val(expr, ctx, &temp_allocator, i+1, j_val))) {
|
||||
ret = OB_ERR_INVALID_JSON_TEXT_IN_PARAM;
|
||||
LOG_WARN("failed: get_json_val.", K(ret), K(i));
|
||||
} else {
|
||||
|
@ -81,7 +81,8 @@ int ObExprJsonArrayInsert::eval_json_array_insert(const ObExpr &expr, ObEvalCtx
|
||||
{
|
||||
INIT_SUCC(ret);
|
||||
ObEvalCtx::TempAllocGuard tmp_alloc_g(ctx);
|
||||
common::ObArenaAllocator &temp_allocator = tmp_alloc_g.get_allocator();
|
||||
uint64_t tenant_id = ObMultiModeExprHelper::get_tenant_id(ctx.exec_ctx_.get_my_session());
|
||||
MultimodeAlloctor temp_allocator(tmp_alloc_g.get_allocator(), expr.type_, tenant_id, ret);
|
||||
ObIJsonBase *j_base = NULL;
|
||||
bool is_null = false;
|
||||
ObJsonSeekResult hit;
|
||||
@ -104,7 +105,7 @@ int ObExprJsonArrayInsert::eval_json_array_insert(const ObExpr &expr, ObEvalCtx
|
||||
hit.reset();
|
||||
ObExpr *arg = expr.args_[i];
|
||||
ObDatum *json_datum = NULL;
|
||||
if (OB_FAIL(expr.args_[i]->eval(ctx, json_datum))) {
|
||||
if (OB_FAIL(temp_allocator.eval_arg(expr.args_[i], ctx, json_datum))) {
|
||||
LOG_WARN("failed: eval json path datum.", K(ret));
|
||||
} else if (json_datum->is_null() || arg->datum_meta_.type_ == ObNullType) {
|
||||
is_null = true;
|
||||
@ -129,7 +130,9 @@ int ObExprJsonArrayInsert::eval_json_array_insert(const ObExpr &expr, ObEvalCtx
|
||||
ObIJsonBase *j_pos_node = hit[0];
|
||||
if (j_pos_node->json_type() == ObJsonNodeType::J_ARRAY) {
|
||||
ObIJsonBase *j_val = NULL;
|
||||
if (OB_FAIL(ObJsonExprHelper::get_json_val(expr, ctx, &temp_allocator, i+1, j_val))) {
|
||||
if (OB_FAIL(temp_allocator.add_baseline_size(expr.args_[i+1], ctx))) {
|
||||
LOG_WARN("failed to add baselien size", K(ret), K(i + 1));
|
||||
} else if (OB_FAIL(ObJsonExprHelper::get_json_val(expr, ctx, &temp_allocator, i+1, j_val))) {
|
||||
ret = OB_ERR_INVALID_JSON_TEXT_IN_PARAM;
|
||||
LOG_WARN("failed: get_json_val", K(ret));
|
||||
} else {
|
||||
|
@ -74,7 +74,8 @@ int ObExprJsonContains::eval_json_contains(const ObExpr &expr, ObEvalCtx &ctx, O
|
||||
ObIJsonBase *json_candidate = NULL;
|
||||
bool is_null_result = false;
|
||||
ObEvalCtx::TempAllocGuard tmp_alloc_g(ctx);
|
||||
common::ObArenaAllocator &temp_allocator = tmp_alloc_g.get_allocator();
|
||||
uint64_t tenant_id = ObMultiModeExprHelper::get_tenant_id(ctx.exec_ctx_.get_my_session());
|
||||
MultimodeAlloctor temp_allocator(tmp_alloc_g.get_allocator(), expr.type_, tenant_id, ret);
|
||||
if (OB_FAIL(ObJsonExprHelper::get_json_doc(expr, ctx, temp_allocator, 0,
|
||||
json_target, is_null_result))) {
|
||||
LOG_WARN("get_json_doc failed", K(ret));
|
||||
@ -95,7 +96,7 @@ int ObExprJsonContains::eval_json_contains(const ObExpr &expr, ObEvalCtx &ctx, O
|
||||
path_cache = ((path_cache != NULL) ? path_cache : &ctx_cache);
|
||||
|
||||
ObDatum *path_data = NULL;
|
||||
if (OB_FAIL(expr.args_[2]->eval(ctx, path_data))) {
|
||||
if (OB_FAIL(temp_allocator.eval_arg(expr.args_[2], ctx, path_data))) {
|
||||
LOG_WARN("eval json path datum failed", K(ret));
|
||||
} else if (expr.args_[2]->datum_meta_.type_ == ObNullType || path_data->is_null()) {
|
||||
is_null_result = true;
|
||||
|
@ -79,7 +79,8 @@ int ObExprJsonContainsPath::eval_json_contains_path(const ObExpr &expr,
|
||||
ObIJsonBase *json_target = NULL;
|
||||
bool is_null_result = false;
|
||||
ObEvalCtx::TempAllocGuard tmp_alloc_g(ctx);
|
||||
common::ObArenaAllocator &temp_allocator = tmp_alloc_g.get_allocator();
|
||||
uint64_t tenant_id = ObMultiModeExprHelper::get_tenant_id(ctx.exec_ctx_.get_my_session());
|
||||
MultimodeAlloctor temp_allocator(tmp_alloc_g.get_allocator(), expr.type_, tenant_id, ret);
|
||||
if (OB_FAIL(ObJsonExprHelper::get_json_doc(expr, ctx, temp_allocator, 0, json_target, is_null_result, false))) {
|
||||
LOG_WARN("get_json_doc failed", K(ret));
|
||||
} else {
|
||||
@ -88,7 +89,7 @@ int ObExprJsonContainsPath::eval_json_contains_path(const ObExpr &expr,
|
||||
ObDatum *json_datum = NULL;
|
||||
ObExpr *json_arg = expr.args_[1];
|
||||
ObObjType val_type = json_arg->datum_meta_.type_;
|
||||
if (OB_FAIL(json_arg->eval(ctx, json_datum))) {
|
||||
if (OB_FAIL(temp_allocator.eval_arg(json_arg, ctx, json_datum))) {
|
||||
LOG_WARN("eval json arg failed", K(ret));
|
||||
} else if (val_type == ObNullType || json_datum->is_null()) {
|
||||
is_null_result = true;
|
||||
@ -115,7 +116,7 @@ int ObExprJsonContainsPath::eval_json_contains_path(const ObExpr &expr,
|
||||
for (int64_t i = 2; OB_SUCC(ret) && i < expr.arg_cnt_ && !is_null_result; i++) {
|
||||
ObJsonSeekResult hit;
|
||||
ObDatum *path_data = NULL;
|
||||
if (OB_FAIL(expr.args_[i]->eval(ctx, path_data))) {
|
||||
if (OB_FAIL(temp_allocator.eval_arg(expr.args_[i], ctx, path_data))) {
|
||||
LOG_WARN("eval json path datum failed", K(ret));
|
||||
} else if (expr.args_[i]->datum_meta_.type_ == ObNullType || path_data->is_null()) {
|
||||
is_null_result = true;
|
||||
|
@ -59,13 +59,14 @@ int ObExprJsonDepth::eval_json_depth(const ObExpr &expr, ObEvalCtx &ctx, ObDatum
|
||||
bool is_null_result = false;
|
||||
|
||||
ObEvalCtx::TempAllocGuard tmp_alloc_g(ctx);
|
||||
common::ObArenaAllocator &temp_allocator = tmp_alloc_g.get_allocator();
|
||||
if (OB_FAIL(json_arg->eval(ctx, json_datum))) {
|
||||
uint64_t tenant_id = ObMultiModeExprHelper::get_tenant_id(ctx.exec_ctx_.get_my_session());
|
||||
MultimodeAlloctor temp_allocator(tmp_alloc_g.get_allocator(), expr.type_, tenant_id, ret);
|
||||
if (OB_FAIL(temp_allocator.eval_arg(json_arg, ctx, json_datum))) {
|
||||
LOG_WARN("eval json arg failed", K(ret));
|
||||
} else if (val_type == ObNullType || json_datum->is_null()) {
|
||||
is_null_result = true;
|
||||
} else if (OB_FAIL(ObJsonExprHelper::get_json_doc(expr, ctx, temp_allocator, 0,
|
||||
json_doc, is_null_result))) {
|
||||
json_doc, is_null_result, false))) {
|
||||
LOG_WARN("get_json_doc failed", K(ret));
|
||||
} else {
|
||||
// do nothing
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user