[CP] [to #56242693] move pl opaque type impl to close_moudle/pl
This commit is contained in:
parent
6bdeecb4d0
commit
6a23c064bc
@ -34,7 +34,6 @@ ob_set_subtarget(ob_pl common
|
||||
ob_pl_stmt.cpp
|
||||
ob_pl_type.cpp
|
||||
ob_pl_user_type.cpp
|
||||
ob_pl_json_type.cpp
|
||||
ob_pl_persistent.cpp
|
||||
)
|
||||
|
||||
|
@ -23,7 +23,6 @@
|
||||
#include "pl/ob_pl_compile.h"
|
||||
#include "pl/ob_pl_code_generator.h"
|
||||
#include "pl/ob_pl_user_type.h"
|
||||
#include "pl/ob_pl_json_type.h"
|
||||
#include "pl/ob_pl_stmt.h"
|
||||
#include "pl/ob_pl_interface_pragma.h"
|
||||
#include "observer/ob_server_struct.h"
|
||||
@ -47,6 +46,7 @@
|
||||
#include "pl/ob_pl_udt_object_manager.h"
|
||||
#include "pl/debug/ob_pl_debugger.h"
|
||||
#include "pl/debug/ob_pl_debugger_manager.h"
|
||||
#include "pl/opaque/ob_pl_json_type.h"
|
||||
#endif
|
||||
#include "pl/pl_cache/ob_pl_cache_mgr.h"
|
||||
#include "sql/engine/dml/ob_trigger_handler.h"
|
||||
|
@ -1,477 +0,0 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifdef OB_BUILD_ORACLE_PL
|
||||
#define USING_LOG_PREFIX PL
|
||||
#include "pl/ob_pl_user_type.h"
|
||||
#include "pl/ob_pl_json_type.h"
|
||||
|
||||
namespace oceanbase
|
||||
{
|
||||
using namespace common;
|
||||
using namespace share::schema;
|
||||
using namespace jit;
|
||||
using namespace obmysql;
|
||||
using namespace sql;
|
||||
|
||||
namespace pl
|
||||
{
|
||||
|
||||
int ObPLJsonBaseType::deep_copy(ObPLOpaque *dst)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObPlJsonNode* pl_node = data_;
|
||||
ObJsonNode* ref_node = nullptr;
|
||||
ObJsonNode* data_node = nullptr;
|
||||
ObPlJsonTypeManager* pl_manager = nullptr;
|
||||
if (OB_NOT_NULL(data_)) {
|
||||
ref_node = pl_node->get_ref_node();
|
||||
data_node = pl_node->get_data_node();
|
||||
pl_manager = pl_node->get_manager();
|
||||
}
|
||||
|
||||
ObPLJsonBaseType *copy = NULL;
|
||||
OZ (ObPLOpaque::deep_copy(dst));
|
||||
CK (OB_NOT_NULL(copy = new(dst)ObPLJsonBaseType()));
|
||||
OX (copy->set_err_behavior(static_cast<int32_t>(behavior_)));
|
||||
if (OB_SUCC(ret) && OB_NOT_NULL(data_)) {
|
||||
ObPlJsonNode* dup = nullptr;
|
||||
if (OB_FAIL(pl_manager->create_empty_node(dup))) {
|
||||
LOG_WARN("fail to create empty node", K(ret), K(pl_manager->get_map_count()),
|
||||
K(pl_manager->get_list_count()), K(pl_manager->get_alloc_count()),
|
||||
K(pl_manager->get_free_count()), K(pl_manager->get_holding_count()));
|
||||
} else if (OB_FAIL(dup->assign(pl_node))) {
|
||||
LOG_WARN("fail to assign node", K(ret));
|
||||
} else {
|
||||
copy->set_data(dup);
|
||||
if (OB_FAIL(pl_manager->check_candidate_list())) {
|
||||
LOG_WARN("fail to checkin candidate list node.", K(ret));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
ObPlJsonNode::ObPlJsonNode(ObPlJsonTypeManager *pl_handle, ObJsonNode* json_node)
|
||||
: ObPlJsonNode(pl_handle)
|
||||
{
|
||||
set_data_node(json_node);
|
||||
increase_ref();
|
||||
}
|
||||
|
||||
|
||||
int ObPlJsonNode::assign(ObPlJsonNode* from)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
|
||||
if (from->get_ref_node()) {
|
||||
ObJsonNode* origin = from->get_ref_node();
|
||||
ObPlJsonNode* from_origin = nullptr;
|
||||
if (OB_FAIL(pl_manager_->get_node(origin, from_origin))) {
|
||||
LOG_WARN("fail to get node from manger", K(ret));
|
||||
} else {
|
||||
from_origin->increase_ref();
|
||||
set_ref_node(from_origin->get_data_node());
|
||||
set_data_node(from->get_data_node());
|
||||
}
|
||||
} else {
|
||||
from->increase_ref();
|
||||
set_ref_node(from->get_data_node());
|
||||
set_data_node(from->get_data_node());
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObPlJsonNode::clone(ObPlJsonNode* other, bool is_deep_copy)
|
||||
{
|
||||
return clone(other->get_data_node(), is_deep_copy);
|
||||
}
|
||||
|
||||
int ObPlJsonNode::clone(ObJsonNode* other, bool is_deep_copy)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObJsonNode *json_dst = other->clone(&allocator_, true);
|
||||
if (OB_ISNULL(json_dst)) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
LOG_WARN("alloc memory for clone json node failed", K(ret));
|
||||
} else {
|
||||
set_data_node(json_dst);
|
||||
increase_ref();
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObPlJsonNode::parse_tree(const ObString& text, ObJsonInType in_type)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObJsonNode* tree = nullptr;
|
||||
if (OB_FAIL(ObJsonBaseFactory::get_json_tree(&allocator_, text, in_type, tree, ObJsonParser::JSN_RELAXED_FLAG))) {
|
||||
LOG_WARN("fail to get json base", K(ret), K(in_type));
|
||||
} else {
|
||||
set_data_node(tree);
|
||||
increase_ref();
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObPlJsonNode::unref()
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (OB_NOT_NULL(get_ref_node())) {
|
||||
ObPlJsonNode* dom_node = nullptr;
|
||||
if (OB_FAIL(pl_manager_->get_node(get_ref_node(), dom_node))) {
|
||||
LOG_WARN("fail to get node from manger", K(ret));
|
||||
} else if (OB_ISNULL(dom_node)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("fail to unassign get dom node is null", K(ret));
|
||||
} else if (dom_node->decrease_ref() == 0) {
|
||||
if (OB_FAIL(pl_manager_->remove_node(dom_node, false))) {
|
||||
LOG_WARN("fail to remove node from manger", K(ret));
|
||||
}
|
||||
}
|
||||
} else if (decrease_ref() == 0) {
|
||||
if (OB_FAIL(pl_manager_->remove_node(this, false))) {
|
||||
LOG_WARN("fail to remove node from manger", K(ret));
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void ObPlJsonNode::reuse()
|
||||
{
|
||||
data_ = nullptr;
|
||||
origin_ = nullptr;
|
||||
ref_count_ = 0;
|
||||
ref_type_ = 0;
|
||||
allocator_.reset();
|
||||
}
|
||||
|
||||
void ObPlJsonNode::free()
|
||||
{
|
||||
reuse();
|
||||
}
|
||||
|
||||
int ObPlJsonTypeManager::destroy_node(ObPlJsonNode* node)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (OB_FAIL(node->unref())) {
|
||||
LOG_WARN("failed to unref current node", K(ret));
|
||||
} else if (OB_FAIL(check_candidate_list())) {
|
||||
LOG_WARN("failed to eliminate node", K(ret));
|
||||
} else if (node->get_ref_node()) {
|
||||
free_empty_node(node);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
ObPlJsonTypeManager::ObPlJsonTypeManager(uint64_t tenant_id)
|
||||
: dom_node_allocator_(sizeof(ObPlJsonNode),
|
||||
common::OB_MALLOC_NORMAL_BLOCK_SIZE - 32,
|
||||
ObMalloc(lib::ObMemAttr(tenant_id, "JsonPlDom"))),
|
||||
candidates_(dom_node_allocator_),
|
||||
json_dom_map_(),
|
||||
tenant_id_(tenant_id),
|
||||
is_init_(false)
|
||||
{
|
||||
}
|
||||
|
||||
void ObPlJsonTypeManager::free_empty_node(ObPlJsonNode* node)
|
||||
{
|
||||
dom_node_allocator_.free(node);
|
||||
++free_count_;
|
||||
}
|
||||
|
||||
|
||||
int ObPlJsonTypeManager::create_empty_node(ObPlJsonNode*& res)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObPlJsonNode* tmp = nullptr;
|
||||
|
||||
if (OB_ISNULL(tmp = static_cast<ObPlJsonNode*>(dom_node_allocator_.alloc(PL_JSON_DOM_LEN)))) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
LOG_WARN("failed to alloc empty dom node", K(ret), K(*this));
|
||||
} else {
|
||||
res = new (tmp) ObPlJsonNode(this);
|
||||
++alloc_count_;
|
||||
}
|
||||
|
||||
LOG_DEBUG("json pl manager statistic:", K(get_map_count()), K(get_list_count()),
|
||||
K(get_alloc_count()), K(get_free_count()), K(get_holding_count()));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObPlJsonTypeManager::create_new_node(ObJsonNode* data, ObPlJsonNode*& res)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObPlJsonNode* tmp = nullptr;
|
||||
ObJsonNode* clone = nullptr;
|
||||
|
||||
if (OB_FAIL(init())) {
|
||||
LOG_WARN("failed to init", K(ret));
|
||||
} else if (OB_FAIL(create_empty_node(tmp))) {
|
||||
LOG_WARN("failed to create empty node", K(ret), K(get_map_count()), K(get_list_count()),
|
||||
K(get_alloc_count()), K(get_free_count()), K(get_holding_count()));
|
||||
} else if (OB_ISNULL(clone = data->clone(&tmp->get_allocator(), true))) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
LOG_WARN("failed to clone node", K(ret));
|
||||
} else {
|
||||
tmp->set_data_node(clone);
|
||||
tmp->increase_ref();
|
||||
|
||||
if (OB_FAIL(add_node(tmp))) {
|
||||
LOG_WARN("failed to add tree", K(ret), K(get_map_count()), K(get_list_count()),
|
||||
K(get_alloc_count()), K(get_free_count()), K(get_holding_count()));
|
||||
} else {
|
||||
res = tmp;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObPlJsonTypeManager::create_ref_node(ObJsonNode* data, ObJsonNode* ref, ObPlJsonNode*& res)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObPlJsonNode* tmp = nullptr;
|
||||
ObPlJsonNode* origin = nullptr;
|
||||
|
||||
if (OB_FAIL(init())) {
|
||||
LOG_WARN("failed to init", K(ret));
|
||||
} else if (OB_FAIL(get_node(ref, origin))) {
|
||||
LOG_WARN("failed to get node", K(ret));
|
||||
} else if (OB_FAIL(create_empty_node(tmp))) {
|
||||
LOG_WARN("failed to create empty node", K(ret), K(get_map_count()), K(get_list_count()),
|
||||
K(get_alloc_count()), K(get_free_count()), K(get_holding_count()));
|
||||
} else {
|
||||
tmp->set_data_node(data);
|
||||
tmp->set_ref_node(origin->get_data_node());
|
||||
origin->increase_ref();
|
||||
|
||||
res = tmp;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObPlJsonTypeManager::create_new_node(const ObString& text, ObJsonInType in_type, ObPlJsonNode*& res)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
|
||||
ObPlJsonNode* tmp = nullptr;
|
||||
if (OB_FAIL(init())) {
|
||||
LOG_WARN("failed to init", K(ret));
|
||||
} else if (OB_FAIL(create_empty_node(tmp))) {
|
||||
LOG_WARN("failed to create empty node", K(ret), K(get_map_count()), K(get_list_count()),
|
||||
K(get_alloc_count()), K(get_free_count()), K(get_holding_count()));
|
||||
} else if (OB_FAIL(tmp->parse_tree(text, in_type))) {
|
||||
LOG_WARN("failed to parse tree", K(ret));
|
||||
} else if (OB_FAIL(add_node(tmp))) {
|
||||
LOG_WARN("failed to add tree", K(ret), K(get_map_count()), K(get_list_count()),
|
||||
K(get_alloc_count()), K(get_free_count()), K(get_holding_count()));
|
||||
} else {
|
||||
res = tmp;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObPlJsonTypeManager::init()
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (!is_init_) {
|
||||
ObMemAttr bucket_attr(tenant_id_, "jsonPlBucket");
|
||||
ObMemAttr node_attr(tenant_id_, "jsonPlBuckNode");
|
||||
if (OB_FAIL(json_dom_map_.create(JSON_PL_BUCKET_NUM, bucket_attr, node_attr))) {
|
||||
LOG_WARN("failed to create json bucket num", K(ret));
|
||||
} else {
|
||||
is_init_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObPlJsonTypeManager::add_node(ObPlJsonNode* node)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObPlJsonNode* value = nullptr;
|
||||
|
||||
if (OB_FAIL(init())) {
|
||||
LOG_WARN("failed to init", K(ret));
|
||||
} else if (OB_NOT_NULL(node->data_)
|
||||
&& OB_FAIL(json_dom_map_.get_refactored(reinterpret_cast<uint64_t>(node->data_), value))) {
|
||||
if (ret == OB_HASH_NOT_EXIST) {
|
||||
if (OB_FAIL(json_dom_map_.set_refactored(reinterpret_cast<uint64_t>(node->data_), node))) {
|
||||
LOG_WARN("failed to set json pl object into bucket.", K(ret));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObPlJsonTypeManager::remove_node(ObPlJsonNode* node, bool do_force)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObPlJsonNode* dom_value = nullptr;
|
||||
|
||||
if (OB_FAIL(init())) {
|
||||
LOG_WARN("failed to init", K(ret));
|
||||
} else if (OB_FAIL(json_dom_map_.get_refactored(reinterpret_cast<uint64_t>(node->data_), dom_value))) {
|
||||
if (ret != OB_HASH_NOT_EXIST) {
|
||||
LOG_WARN("failed to set json pl object into bucket.", K(ret));
|
||||
} else {
|
||||
ret = OB_SUCCESS;
|
||||
}
|
||||
} else if (!do_force && OB_FAIL(candidates_.push_front(node))) {
|
||||
LOG_WARN("failed to add into candidates list.", K(ret));
|
||||
} else if (OB_FAIL(json_dom_map_.erase_refactored(reinterpret_cast<uint64_t>(node->data_)))) {
|
||||
LOG_WARN("failed to remove from candidates list.", K(ret));
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObPlJsonTypeManager::get_node(ObJsonNode* node, ObPlJsonNode*& value)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
value = nullptr;
|
||||
ObPlJsonNode* dom_value = nullptr;
|
||||
|
||||
if (OB_FAIL(init())) {
|
||||
LOG_WARN("failed to init", K(ret));
|
||||
} else if (OB_FAIL(json_dom_map_.get_refactored(reinterpret_cast<uint64_t>(node), dom_value))) {
|
||||
if (ret != OB_HASH_NOT_EXIST) {
|
||||
LOG_WARN("failed to set json pl object into bucket.", K(ret));
|
||||
} else {
|
||||
ObList<ObPlJsonNode*, ObIAllocator>::iterator it = candidates_.begin();
|
||||
for (; it != candidates_.end(); ++it) {
|
||||
ObPlJsonNode* temp = *it;
|
||||
if (temp->data_ == node) {
|
||||
value = temp;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (OB_NOT_NULL(value)) {
|
||||
ret = OB_SUCCESS;
|
||||
}
|
||||
}
|
||||
} else if (OB_ISNULL(dom_value)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("failed to get json node from hash.", K(ret));
|
||||
} else {
|
||||
value = dom_value;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObPlJsonTypeManager::check_candidate_list()
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
|
||||
if (OB_FAIL(init())) {
|
||||
LOG_WARN("failed to init", K(ret));
|
||||
} else {
|
||||
ObList<ObPlJsonNode*, ObIAllocator>::iterator it = candidates_.begin();
|
||||
for (; it != candidates_.end(); ) {
|
||||
ObPlJsonNode* temp = *it;
|
||||
if (temp->ref_count()) {
|
||||
if (OB_FAIL(json_dom_map_.set_refactored(reinterpret_cast<uint64_t>(temp->data_), temp))) {
|
||||
LOG_WARN("failed to init", K(ret));
|
||||
} else {
|
||||
++it;
|
||||
}
|
||||
} else if (!temp->ref_count()) {
|
||||
++it;
|
||||
free(temp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void ObPlJsonTypeManager::free(ObPlJsonNode* node)
|
||||
{
|
||||
node->free();
|
||||
candidates_.erase(node);
|
||||
dom_node_allocator_.free(node);
|
||||
}
|
||||
|
||||
void ObPlJsonTypeManager::destroy()
|
||||
{
|
||||
ObJsonDomMap::iterator iter = json_dom_map_.begin();
|
||||
for (; iter != json_dom_map_.end(); ) {
|
||||
ObPlJsonNode* node = iter->second;
|
||||
if (OB_NOT_NULL(node)) {
|
||||
iter++;
|
||||
node->free();
|
||||
} else {
|
||||
++iter;
|
||||
}
|
||||
}
|
||||
|
||||
candidates_.clear();
|
||||
json_dom_map_.destroy();
|
||||
dom_node_allocator_.reset();
|
||||
is_init_ = false;
|
||||
}
|
||||
uint64_t ObPlJsonTypeManager::get_map_count()
|
||||
{
|
||||
return json_dom_map_.size();
|
||||
}
|
||||
|
||||
uint64_t ObPlJsonTypeManager::get_list_count()
|
||||
{
|
||||
return candidates_.size();
|
||||
}
|
||||
|
||||
uint64_t ObPlJsonTypeManager::get_alloc_count()
|
||||
{
|
||||
return alloc_count_;
|
||||
}
|
||||
|
||||
uint64_t ObPlJsonTypeManager::get_free_count()
|
||||
{
|
||||
return free_count_;
|
||||
}
|
||||
|
||||
uint64_t ObPlJsonTypeManager::get_holding_count()
|
||||
{
|
||||
return alloc_count_ - free_count_;
|
||||
}
|
||||
|
||||
void ObPlJsonTypeManager::release(intptr_t handle)
|
||||
{
|
||||
ObPlJsonTypeManager* manager = reinterpret_cast<ObPlJsonTypeManager*>(handle);
|
||||
if (manager) {
|
||||
manager->destroy();
|
||||
}
|
||||
}
|
||||
|
||||
void ObPlJsonTypeManager::release_useless_resource(intptr_t handle)
|
||||
{
|
||||
ObPlJsonTypeManager* manager = reinterpret_cast<ObPlJsonTypeManager*>(handle);
|
||||
if (manager) {
|
||||
manager->check_candidate_list();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace pl
|
||||
} // namespace oceanbase
|
||||
#endif
|
@ -1,173 +0,0 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifdef OB_BUILD_ORACLE_PL
|
||||
#ifndef DEV_SRC_PL_OB_PL_JSON_TYPE_H_
|
||||
#define DEV_SRC_PL_OB_PL_JSON_TYPE_H_
|
||||
#include "pl/ob_pl_type.h"
|
||||
#include "lib/hash/ob_hashmap.h"
|
||||
#include "lib/json_type/ob_json_tree.h"
|
||||
#include "lib/json_type/ob_json_parse.h"
|
||||
#include "pl/ob_pl_user_type.h"
|
||||
|
||||
|
||||
namespace oceanbase
|
||||
{
|
||||
namespace pl
|
||||
{
|
||||
|
||||
struct ObPlJsonNode;
|
||||
|
||||
class ObPlJsonTypeManager {
|
||||
public:
|
||||
const uint32_t JSON_PL_BUCKET_NUM = 1000;
|
||||
typedef common::hash::ObHashMap<uint64_t, ObPlJsonNode*, common::hash::NoPthreadDefendMode> ObJsonDomMap;
|
||||
|
||||
ObPlJsonTypeManager(uint64_t tenant_id);
|
||||
int create_new_node(const ObString& text, ObJsonInType in_type, ObPlJsonNode*& res);
|
||||
int create_ref_node(ObJsonNode* data, ObJsonNode* ref, ObPlJsonNode*& res);
|
||||
int create_new_node(ObJsonNode* data, ObPlJsonNode*& res);
|
||||
int create_empty_node(ObPlJsonNode*& res);
|
||||
void free_empty_node(ObPlJsonNode* node);
|
||||
int destroy_node(ObPlJsonNode* node);
|
||||
int add_node(ObPlJsonNode*);
|
||||
int remove_node(ObPlJsonNode*, bool force = true);
|
||||
int get_node(ObJsonNode*, ObPlJsonNode*&);
|
||||
int init();
|
||||
int check_candidate_list();
|
||||
void destroy();
|
||||
void free(ObPlJsonNode* node);
|
||||
common::ObIAllocator* get_dom_node_allocator() { return &dom_node_allocator_; }
|
||||
|
||||
static void release(intptr_t handle);
|
||||
static void release_useless_resource(intptr_t handle);
|
||||
|
||||
uint64_t get_map_count();
|
||||
uint64_t get_list_count();
|
||||
uint64_t get_alloc_count();
|
||||
uint64_t get_free_count();
|
||||
uint64_t get_holding_count();
|
||||
|
||||
common::ObSmallBlockAllocator<> dom_node_allocator_;
|
||||
ObList<ObPlJsonNode*, common::ObIAllocator> candidates_;
|
||||
ObJsonDomMap json_dom_map_;
|
||||
uint64_t tenant_id_;
|
||||
bool is_init_;
|
||||
|
||||
uint64_t alloc_count_;
|
||||
uint64_t free_count_;
|
||||
|
||||
TO_STRING_KV("alloc total size", dom_node_allocator_.get_total_mem_size(),
|
||||
"node map count", json_dom_map_.size(),
|
||||
"list count", candidates_.size(),
|
||||
K_(tenant_id),
|
||||
K_(alloc_count),
|
||||
K_(free_count));
|
||||
};
|
||||
|
||||
struct ObPlJsonNode {
|
||||
ObPlJsonNode(ObPlJsonTypeManager *pl_handle)
|
||||
: data_(nullptr),
|
||||
origin_(nullptr),
|
||||
ref_count_(0),
|
||||
ref_type_(0),
|
||||
allocator_(ObMemAttr(pl_handle->tenant_id_, "JsonPlManager"), OB_MALLOC_NORMAL_BLOCK_SIZE),
|
||||
pl_manager_(pl_handle) {}
|
||||
|
||||
ObPlJsonNode(ObPlJsonTypeManager *pl_handle,
|
||||
ObJsonNode* json_node);
|
||||
|
||||
int parse_tree(const ObString& text, ObJsonInType in_type);
|
||||
common::ObIAllocator& get_allocator() { return allocator_; }
|
||||
int clone(ObPlJsonNode* other, bool is_deep_copy = true);
|
||||
int clone(ObJsonNode* other, bool is_deep_copy = true);
|
||||
|
||||
int32_t increase_ref() { return ++ref_count_; }
|
||||
int32_t decrease_ref() { return --ref_count_; }
|
||||
void set_data_node(ObJsonNode* node) { data_ = node; }
|
||||
void set_ref_node(ObJsonNode* node) { origin_ = node; }
|
||||
ObJsonNode* get_ref_node() { return origin_; }
|
||||
ObJsonNode* get_data_node() { return data_; }
|
||||
int32_t ref_count() { return ref_count_; }
|
||||
|
||||
|
||||
ObPlJsonTypeManager* get_manager() { return pl_manager_; }
|
||||
|
||||
int unref();
|
||||
int assign(ObPlJsonNode* from);
|
||||
|
||||
void reuse();
|
||||
void free();
|
||||
|
||||
ObJsonNode* data_; // for save current using obj
|
||||
ObJsonNode* origin_; // for save reference original obj
|
||||
int32_t ref_count_;
|
||||
int32_t ref_type_;
|
||||
common::ObArenaAllocator allocator_;
|
||||
ObPlJsonTypeManager *pl_manager_;
|
||||
|
||||
TO_STRING_KV(KPC(data_), KPC(origin_), K_(ref_count), KPC(pl_manager_));
|
||||
};
|
||||
|
||||
static uint32_t PL_JSON_DOM_LEN = sizeof(ObPlJsonNode);
|
||||
|
||||
class ObPLJsonBaseType : public ObPLOpaque
|
||||
{
|
||||
public:
|
||||
enum JSN_ERR_BEHAVIOR {
|
||||
JSN_PL_NULL_ON_ERR,
|
||||
JSN_PL_ERR_ON_ERR,
|
||||
JSN_PL_ERR_ON_EMP,
|
||||
JSN_PL_ERR_ON_MISMATCH,
|
||||
JSN_PL_ERR_ON_INVALID = 7
|
||||
};
|
||||
|
||||
ObPLJsonBaseType()
|
||||
: ObPLOpaque(ObPLOpaqueType::PL_JSON_TYPE),
|
||||
data_(NULL),
|
||||
behavior_(0)
|
||||
{}
|
||||
|
||||
void destroy()
|
||||
{
|
||||
if (OB_NOT_NULL(data_)) {
|
||||
ObPlJsonTypeManager* manager = data_->get_manager();
|
||||
manager->destroy_node(data_);
|
||||
}
|
||||
|
||||
data_ = NULL;
|
||||
behavior_ = 0;
|
||||
}
|
||||
|
||||
virtual ~ObPLJsonBaseType()
|
||||
{
|
||||
destroy();
|
||||
}
|
||||
|
||||
public:
|
||||
virtual int deep_copy(ObPLOpaque *dst);
|
||||
void set_data(ObPlJsonNode *data) { data_ = data; }
|
||||
void set_err_behavior(int behavior) { behavior_ = behavior; }
|
||||
int get_err_behavior() { return behavior_ ; }
|
||||
ObPlJsonNode* get_data() { return data_; }
|
||||
|
||||
TO_STRING_KV(KPC(data_), K_(behavior));
|
||||
|
||||
private:
|
||||
ObPlJsonNode *data_;
|
||||
int behavior_;
|
||||
};
|
||||
|
||||
} // namespace pl
|
||||
} // namespace oceanbase
|
||||
#endif /* DEV_SRC_PL_OB_PL_JSON_TYPE_H_ */
|
||||
#endif
|
@ -4981,565 +4981,6 @@ int64_t ObPLAssocArray::get_last()
|
||||
return last_;
|
||||
}
|
||||
|
||||
ObIAllocator& ObPLOpaque::get_allocator()
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (allocator_.used() > 1024 * 1024 * 512) {
|
||||
LOG_ERROR("opaque allocator hold too much memory", K(allocator_.used()));
|
||||
}
|
||||
return allocator_;
|
||||
}
|
||||
|
||||
int ObPLOpaque::deep_copy(ObPLOpaque *dst)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
CK (OB_NOT_NULL(dst));
|
||||
OX (dst->~ObPLOpaque());
|
||||
OX (dst = new(dst)ObPLOpaque());
|
||||
return ret;
|
||||
}
|
||||
|
||||
int64_t ObPLOpaque::get_init_size() const
|
||||
{
|
||||
int64_t init_size = sizeof(ObPLOpaque);
|
||||
init_size = init_size < sizeof(ObPLAnyData) ? sizeof(ObPLAnyData) : init_size;
|
||||
init_size = init_size < sizeof(ObPLAnyType) ? sizeof(ObPLAnyType) : init_size;
|
||||
init_size = init_size < sizeof(ObPLXmlType) ? sizeof(ObPLXmlType) : init_size;
|
||||
init_size = init_size < sizeof(ObPLJsonBaseType) ? sizeof(ObPLJsonBaseType) : init_size;
|
||||
return init_size;
|
||||
}
|
||||
|
||||
bool ObPLAnyType::is_obj_type(ObPLAnyType::TypeCode code)
|
||||
{
|
||||
bool is_obj_type = false;
|
||||
switch (code) {
|
||||
case TypeCode::TYPECODE_DATE:
|
||||
case TypeCode::TYPECODE_NUMBER:
|
||||
case TypeCode::TYPECODE_RAW:
|
||||
case TypeCode::TYPECODE_CHAR:
|
||||
case TypeCode::TYPECODE_VARCHAR2:
|
||||
case TypeCode::TYPECODE_VARCHAR:
|
||||
case TypeCode::TYPECODE_MLSLABEL:
|
||||
case TypeCode::TYPECODE_BLOB:
|
||||
case TypeCode::TYPECODE_BFILE:
|
||||
case TypeCode::TYPECODE_CLOB:
|
||||
case TypeCode::TYPECODE_CFILE:
|
||||
case TypeCode::TYPECODE_TIMESTAMP:
|
||||
case TypeCode::TYPECODE_TIMESTAMP_TZ:
|
||||
case TypeCode::TYPECODE_TIMESTAMP_LTZ:
|
||||
case TypeCode::TYPECODE_INTERVAL_YM:
|
||||
case TypeCode::TYPECODE_INTERVAL_DS:
|
||||
case TypeCode::TYPECODE_NCHAR:
|
||||
case TypeCode::TYPECODE_NVARCHAR2:
|
||||
case TypeCode::TYPECODE_NCLOB:
|
||||
case TypeCode::TYPECODE_BFLOAT:
|
||||
case TypeCode::TYPECODE_BDOUBLE:
|
||||
case TypeCode::TYPECODE_UROWID: {
|
||||
is_obj_type = true;
|
||||
} break;
|
||||
default: {
|
||||
} break;
|
||||
}
|
||||
return is_obj_type;
|
||||
}
|
||||
|
||||
bool ObPLAnyType::is_valid_type(ObPLAnyType::TypeCode code)
|
||||
{
|
||||
bool valid = false;
|
||||
switch (code) {
|
||||
case TypeCode::TYPECODE_DATE:
|
||||
case TypeCode::TYPECODE_NUMBER:
|
||||
case TypeCode::TYPECODE_RAW:
|
||||
case TypeCode::TYPECODE_CHAR:
|
||||
case TypeCode::TYPECODE_VARCHAR2:
|
||||
case TypeCode::TYPECODE_VARCHAR:
|
||||
case TypeCode::TYPECODE_MLSLABEL:
|
||||
case TypeCode::TYPECODE_BLOB:
|
||||
case TypeCode::TYPECODE_BFILE:
|
||||
case TypeCode::TYPECODE_CLOB:
|
||||
case TypeCode::TYPECODE_CFILE:
|
||||
case TypeCode::TYPECODE_TIMESTAMP:
|
||||
case TypeCode::TYPECODE_TIMESTAMP_TZ:
|
||||
case TypeCode::TYPECODE_TIMESTAMP_LTZ:
|
||||
case TypeCode::TYPECODE_INTERVAL_YM:
|
||||
case TypeCode::TYPECODE_INTERVAL_DS:
|
||||
case TypeCode::TYPECODE_REF:
|
||||
case TypeCode::TYPECODE_OBJECT:
|
||||
case TypeCode::TYPECODE_VARRAY:
|
||||
case TypeCode::TYPECODE_TABLE:
|
||||
case TypeCode::TYPECODE_NAMEDCOLLECTION:
|
||||
case TypeCode::TYPECODE_OPAQUE:
|
||||
case TypeCode::TYPECODE_NCHAR:
|
||||
case TypeCode::TYPECODE_NVARCHAR2:
|
||||
case TypeCode::TYPECODE_NCLOB:
|
||||
case TypeCode::TYPECODE_BFLOAT:
|
||||
case TypeCode::TYPECODE_BDOUBLE:
|
||||
case TypeCode::TYPECODE_UROWID: {
|
||||
valid = true;
|
||||
} break;
|
||||
default: {
|
||||
} break;
|
||||
}
|
||||
return valid;
|
||||
}
|
||||
|
||||
int ObPLAnyType::pltype_to_typecode(
|
||||
const ObPLDataType &pl_type, ObPLAnyType::TypeCode &typecode)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
typecode = ObPLAnyType::TypeCode::TYPECODE_INVALID;
|
||||
if (pl_type.is_obj_type()) {
|
||||
|
||||
#define TO_TYPECODE(obj_type, code) \
|
||||
case obj_type: { \
|
||||
typecode = code; \
|
||||
} break;
|
||||
|
||||
switch (pl_type.get_obj_type()) {
|
||||
TO_TYPECODE(ObDateType, ObPLAnyType::TypeCode::TYPECODE_DATE);
|
||||
TO_TYPECODE(ObDateTimeType, ObPLAnyType::TypeCode::TYPECODE_DATE);
|
||||
|
||||
TO_TYPECODE(ObTinyIntType, ObPLAnyType::TypeCode::TYPECODE_NUMBER);
|
||||
TO_TYPECODE(ObSmallIntType, ObPLAnyType::TypeCode::TYPECODE_NUMBER);
|
||||
TO_TYPECODE(ObMediumIntType, ObPLAnyType::TypeCode::TYPECODE_NUMBER);
|
||||
TO_TYPECODE(ObInt32Type, ObPLAnyType::TypeCode::TYPECODE_NUMBER);
|
||||
TO_TYPECODE(ObIntType, ObPLAnyType::TypeCode::TYPECODE_NUMBER);
|
||||
TO_TYPECODE(ObUTinyIntType, ObPLAnyType::TypeCode::TYPECODE_NUMBER);
|
||||
TO_TYPECODE(ObUSmallIntType, ObPLAnyType::TypeCode::TYPECODE_NUMBER);
|
||||
TO_TYPECODE(ObUMediumIntType, ObPLAnyType::TypeCode::TYPECODE_NUMBER);
|
||||
TO_TYPECODE(ObUInt32Type, ObPLAnyType::TypeCode::TYPECODE_NUMBER);
|
||||
TO_TYPECODE(ObUInt64Type, ObPLAnyType::TypeCode::TYPECODE_NUMBER);
|
||||
TO_TYPECODE(ObNumberType, ObPLAnyType::TypeCode::TYPECODE_NUMBER);
|
||||
TO_TYPECODE(ObUNumberType, ObPLAnyType::TypeCode::TYPECODE_NUMBER);
|
||||
TO_TYPECODE(ObNumberFloatType, ObPLAnyType::TypeCode::TYPECODE_NUMBER);
|
||||
|
||||
TO_TYPECODE(ObRawType, ObPLAnyType::TypeCode::TYPECODE_RAW);
|
||||
TO_TYPECODE(ObCharType, ObPLAnyType::TypeCode::TYPECODE_CHAR);
|
||||
|
||||
TO_TYPECODE(ObVarcharType, ObPLAnyType::TypeCode::TYPECODE_VARCHAR2);
|
||||
// typecode = ObPLAnyType::TypeCode::TYPECODE_VARCHAR;
|
||||
// typecode = ObPLAnyType::TypeCode::TYPECODE_MLSLABEL;
|
||||
|
||||
case ObLobType: {
|
||||
if (IS_CLUSTER_VERSION_BEFORE_4_1_0_0) {
|
||||
if (pl_type.get_meta_type()->is_blob_locator()) {
|
||||
typecode = ObPLAnyType::TypeCode::TYPECODE_BLOB;
|
||||
} else {
|
||||
typecode = ObPLAnyType::TypeCode::TYPECODE_CLOB;
|
||||
}
|
||||
// typecode = ObPLAnyType::TypeCode::TYPECODE_BFILE;
|
||||
// typecode = ObPLAnyType::TypeCode::TYPECODE_CFILE;
|
||||
} else {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("invalid lob type for after 4.1", K(ret));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case ObLongTextType: {
|
||||
if (!IS_CLUSTER_VERSION_BEFORE_4_1_0_0) {
|
||||
if (pl_type.get_meta_type()->is_blob()) {
|
||||
typecode = ObPLAnyType::TypeCode::TYPECODE_BLOB;
|
||||
} else {
|
||||
typecode = ObPLAnyType::TypeCode::TYPECODE_CLOB;
|
||||
}
|
||||
} else {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("invalid lob type for before 4.1", K(ret));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
TO_TYPECODE(ObTimestampType, ObPLAnyType::TypeCode::TYPECODE_TIMESTAMP);
|
||||
TO_TYPECODE(ObTimestampNanoType, ObPLAnyType::TypeCode::TYPECODE_TIMESTAMP);
|
||||
TO_TYPECODE(ObTimestampTZType, ObPLAnyType::TypeCode::TYPECODE_TIMESTAMP_TZ);
|
||||
TO_TYPECODE(ObTimestampLTZType, ObPLAnyType::TypeCode::TYPECODE_TIMESTAMP_LTZ);
|
||||
TO_TYPECODE(ObIntervalYMType, ObPLAnyType::TypeCode::TYPECODE_INTERVAL_YM);
|
||||
TO_TYPECODE(ObIntervalDSType, ObPLAnyType::TypeCode::TYPECODE_INTERVAL_DS);
|
||||
TO_TYPECODE(ObNCharType, ObPLAnyType::TypeCode::TYPECODE_NCHAR);
|
||||
TO_TYPECODE(ObNVarchar2Type, ObPLAnyType::TypeCode::TYPECODE_NVARCHAR2);
|
||||
// typecode = ObPLAnyType::TypeCode::TYPECODE_NCLOB;
|
||||
TO_TYPECODE(ObFloatType, ObPLAnyType::TypeCode::TYPECODE_BFLOAT);
|
||||
TO_TYPECODE(ObDoubleType, ObPLAnyType::TypeCode::TYPECODE_BDOUBLE);
|
||||
TO_TYPECODE(ObURowIDType, ObPLAnyType::TypeCode::TYPECODE_UROWID);
|
||||
default: {
|
||||
ret = OB_NOT_SUPPORTED;
|
||||
LOG_WARN("not supported type for type_to_typecode", K(ret), K(pl_type.get_obj_type()));
|
||||
LOG_USER_ERROR(OB_NOT_SUPPORTED, "type for type_to_type_code");
|
||||
}
|
||||
}
|
||||
#undef TO_TYPECODE
|
||||
|
||||
} else if (pl_type.is_record_type()) {
|
||||
typecode = ObPLAnyType::TypeCode::TYPECODE_OBJECT;
|
||||
} else if (pl_type.is_nested_table_type() || pl_type.is_associative_array_type()) {
|
||||
if (pl_type.is_udt_type()) {
|
||||
typecode = ObPLAnyType::TypeCode::TYPECODE_NAMEDCOLLECTION;
|
||||
} else {
|
||||
typecode = ObPLAnyType::TypeCode::TYPECODE_TABLE;
|
||||
}
|
||||
} else if (pl_type.is_varray_type()) {
|
||||
typecode = ObPLAnyType::TypeCode::TYPECODE_VARRAY;
|
||||
} else if (pl_type.is_ref_cursor_type()) {
|
||||
typecode = ObPLAnyType::TypeCode::TYPECODE_REF;
|
||||
} else {
|
||||
ret = OB_NOT_SUPPORTED;
|
||||
LOG_WARN("not supported type for type_to_typecode", K(ret), K(pl_type.get_obj_type()));
|
||||
LOG_USER_ERROR(OB_NOT_SUPPORTED, "type for type_to_typecode");
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObPLAnyType::deep_copy(ObPLOpaque *dst)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObPLAnyType *copy = NULL;
|
||||
CK (OB_NOT_NULL(dst));
|
||||
OZ (ObPLOpaque::deep_copy(dst));
|
||||
CK (OB_NOT_NULL(copy = new(dst)ObPLAnyType()));
|
||||
|
||||
if (OB_SUCC(ret) && OB_NOT_NULL(type_)) {
|
||||
ObPLDataType *dst_type = NULL;
|
||||
OZ (ObPLDataType::deep_copy_pl_type(copy->get_allocator(), *type_, dst_type));
|
||||
OX (copy->set_type_ptr(dst_type));
|
||||
}
|
||||
|
||||
OX (copy->set_in_begincreate(in_begincreate_));
|
||||
OX (copy->set_typecode(code_));
|
||||
OX (copy->set_rowsize(rowsize_));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool ObPLAnyType::typecode_compatible(ObPLAnyType::TypeCode &src, ObPLAnyType::TypeCode &dst)
|
||||
{
|
||||
return src == dst
|
||||
|| (ObPLAnyType::TypeCode::TYPECODE_TABLE == dst
|
||||
&& (ObPLAnyType::TypeCode::TYPECODE_VARRAY == src
|
||||
|| ObPLAnyType::TypeCode::TYPECODE_TABLE == src
|
||||
|| ObPLAnyType::TypeCode::TYPECODE_NAMEDCOLLECTION == src))
|
||||
|| (ObPLAnyType::TYPECODE_VARCHAR == dst && ObPLAnyType::TYPECODE_VARCHAR2 == src)
|
||||
|| (ObPLAnyType::TYPECODE_VARCHAR2 == dst && ObPLAnyType::TYPECODE_VARCHAR == src);
|
||||
}
|
||||
|
||||
int ObPLAnyData::deep_copy(ObPLOpaque *dst)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
|
||||
ObPLAnyData *copy = NULL;
|
||||
OZ (ObPLOpaque::deep_copy(dst));
|
||||
CK (OB_NOT_NULL(copy = new(dst)ObPLAnyData()));
|
||||
OX (copy->set_in_begincreate(in_begincreate_));
|
||||
OX (copy->set_piecewise(in_piecewise_));
|
||||
OX (copy->set_rowsize(rowsize_));
|
||||
OX (copy->set_current_pos(current_pos_));
|
||||
OX (copy->set_is_last_elem(is_last_elem_));
|
||||
OX (copy->set_is_no_data(is_no_data_));
|
||||
OX (copy->set_type_code(type_code_));
|
||||
|
||||
if (OB_NOT_NULL(data_)) {
|
||||
OZ (copy->set_data(*data_));
|
||||
}
|
||||
if (OB_NOT_NULL(type_)) {
|
||||
ObPLDataType *dst_type = NULL;
|
||||
OZ (ObPLDataType::deep_copy_pl_type(
|
||||
copy->get_allocator(), *(const_cast<ObPLDataType*>(type_)), dst_type));
|
||||
CK (OB_NOT_NULL(dst_type));
|
||||
OX (copy->set_type(dst_type));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObPLAnyData::set_data(const ObObj &obj)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (OB_ISNULL(data_)) {
|
||||
if (OB_ISNULL(data_ = reinterpret_cast<ObObj*>(get_allocator().alloc(sizeof(ObObj))))) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
LOG_WARN("faild to alloc memory for new object", K(ret));
|
||||
} else {
|
||||
new (data_) ObObj();
|
||||
}
|
||||
}
|
||||
if (obj.is_ext()) {
|
||||
OZ (ObUserDefinedType::deep_copy_obj(get_allocator(), obj, *data_, true, true));
|
||||
} else {
|
||||
OZ (deep_copy_obj(get_allocator(), obj, *data_));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObPLAnyData::get_current_data(
|
||||
ObObj &obj, ObPLAnyType::TypeCode &dst_typecode)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
|
||||
#define CHECK_TYPE(src_type) \
|
||||
OZ (ObPLAnyType::pltype_to_typecode(src_type, src_typecode)); \
|
||||
if (OB_SUCC(ret) && !ObPLAnyType::typecode_compatible(src_typecode, dst_typecode)) { \
|
||||
ret = OB_ERR_TYPE_MISMATCH; \
|
||||
LOG_WARN("ORA-22626: Type Mismatch while constructing or accessing OCIAnyData", \
|
||||
K(ret), KPC(type_), K(dst_typecode), K(src_typecode), K(in_piecewise_)); \
|
||||
}
|
||||
|
||||
ObPLAnyType::TypeCode src_typecode = ObPLAnyType::TypeCode::TYPECODE_INVALID;
|
||||
const ObPLDataType *pl_type = NULL;
|
||||
CK (OB_NOT_NULL(type_));
|
||||
CK (OB_NOT_NULL(data_));
|
||||
OZ (get_current_type(pl_type));
|
||||
CK (OB_NOT_NULL(pl_type));
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (is_in_piecewise()) {
|
||||
if (get_type()->is_record_type()) {
|
||||
const ObRecordType *c_type = dynamic_cast<const ObRecordType *>(get_type());
|
||||
ObPLRecord *record = reinterpret_cast<ObPLRecord*>(data_->get_ext());
|
||||
if (OB_ISNULL(c_type)) {
|
||||
ret = OB_NOT_SUPPORTED;
|
||||
LOG_WARN("src type is incomplete, can not extract data.");
|
||||
LOG_USER_ERROR(OB_NOT_SUPPORTED, "extract data with incomplete type");
|
||||
}
|
||||
CK (OB_NOT_NULL(record));
|
||||
|
||||
CK (OB_NOT_NULL(c_type->get_record_member_type(current_pos_)));
|
||||
CHECK_TYPE(*(c_type->get_record_member_type(current_pos_)));
|
||||
OZ (record->get_element(current_pos_, obj));
|
||||
if (OB_SUCC(ret)
|
||||
&& current_pos_ == (c_type->get_member_count() - 1)) {
|
||||
set_is_no_data(true);
|
||||
}
|
||||
} else if (get_type()->is_collection_type()) {
|
||||
const ObCollectionType *c_type = dynamic_cast<const ObCollectionType *>(get_type());
|
||||
ObPLCollection *coll = reinterpret_cast<ObPLCollection *>(data_->get_ext());
|
||||
ObObj* coll_list = NULL;
|
||||
|
||||
if (OB_ISNULL(c_type)) {
|
||||
ret = OB_NOT_SUPPORTED;
|
||||
LOG_WARN("src type is incomplete, can not extract data.");
|
||||
LOG_USER_ERROR(OB_NOT_SUPPORTED, "extract data with incomplete type");
|
||||
}
|
||||
CK (OB_NOT_NULL(coll));
|
||||
CK (OB_NOT_NULL(coll_list = reinterpret_cast<ObObj*>(coll->get_data())));
|
||||
|
||||
CHECK_TYPE(c_type->get_element_type());
|
||||
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (current_pos_ >= coll->get_count()) {
|
||||
ret = OB_ERR_DATA_NOT_WELL_FORMAT;
|
||||
LOG_WARN("ORA-22625: OCIAnyData is not well-formed", K(ret), K(current_pos_), KPC(coll));
|
||||
} else {
|
||||
obj = coll_list[current_pos_];
|
||||
set_is_no_data(current_pos_ == (coll->get_count() - 1));
|
||||
}
|
||||
}
|
||||
OX (current_pos_ += 1);
|
||||
} else {
|
||||
CHECK_TYPE(*pl_type);
|
||||
OX (obj = *data_);
|
||||
}
|
||||
#undef CHECK_TYPE
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObPLAnyData::get_current_type(const ObPLDataType *&pl_type)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
CK (OB_NOT_NULL(type_));
|
||||
if (is_in_piecewise()) {
|
||||
if (get_type()->is_record_type()) {
|
||||
const ObRecordType *r_type = dynamic_cast<const ObRecordType *>(type_);
|
||||
if (OB_ISNULL(r_type)) {
|
||||
ret = OB_NOT_SUPPORTED;
|
||||
LOG_WARN("src type is incomplete, can not extract data.");
|
||||
LOG_USER_ERROR(OB_NOT_SUPPORTED, "extract data with incomplete type");
|
||||
} else if (current_pos_ >= r_type->get_member_count()) {
|
||||
ret = OB_ERR_DATA_NOT_WELL_FORMAT;
|
||||
LOG_WARN("ORA-22625: OCIAnyData is not well-formed",
|
||||
K(ret), K(current_pos_), KPC(r_type));
|
||||
} else {
|
||||
pl_type = r_type->get_record_member_type(current_pos_);
|
||||
}
|
||||
} else if (get_type()->is_collection_type()) {
|
||||
const ObCollectionType *c_type = dynamic_cast<const ObCollectionType *>(type_);
|
||||
if (OB_ISNULL(c_type)) {
|
||||
ret = OB_NOT_SUPPORTED;
|
||||
LOG_WARN("src type is incomplete, can not extract data.");
|
||||
LOG_USER_ERROR(OB_NOT_SUPPORTED, "extract data with incomplete type");
|
||||
} else {
|
||||
pl_type = c_type->get_member(0);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
pl_type = type_;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObPLAnyData::set_record_element(ObObj &obj)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
const ObRecordType *r_type = dynamic_cast<const ObRecordType *>(type_);
|
||||
ObObj* record_list = NULL;
|
||||
ObObj* new_data = NULL;
|
||||
if (OB_ISNULL(r_type)) {
|
||||
ret = OB_NOT_SUPPORTED;
|
||||
LOG_WARN("src type is incomplete, can not extract data.");
|
||||
LOG_USER_ERROR(OB_NOT_SUPPORTED, "extract data with incomplete type");
|
||||
} else if (obj.is_ext()) {
|
||||
ret = OB_NOT_SUPPORTED;
|
||||
LOG_WARN("not supported record element also a complex value", K(ret), K(obj));
|
||||
LOG_USER_ERROR(OB_NOT_SUPPORTED, "record element also a complex value in Set*()");
|
||||
} else if (OB_ISNULL(data_)) {
|
||||
if (OB_ISNULL(new_data = reinterpret_cast<ObObj*>(get_allocator().alloc(sizeof(ObObj))))) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
LOG_WARN("faild to alloc memory for new object", K(ret));
|
||||
} else if (OB_ISNULL(record_list = reinterpret_cast<ObObj*>
|
||||
(get_allocator().alloc(
|
||||
r_type->get_data_offset(r_type->get_record_member_count()) + sizeof(ObObj) * r_type->get_member_count())))) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
LOG_WARN("failed to alloc memory for new record list",
|
||||
K(ret), K(r_type->get_member_count()));
|
||||
} else {
|
||||
new (new_data) ObObj(ObExtendType);
|
||||
new_data->set_extend(reinterpret_cast<int64_t>(record_list), PL_RECORD_TYPE);
|
||||
ObPLRecord *record = new (record_list) ObPLRecord(r_type->get_user_type_id(), r_type->get_record_member_count());
|
||||
ObObj *member = NULL;
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < r_type->get_record_member_count(); ++i) {
|
||||
CK (OB_NOT_NULL(r_type->get_member(i)));
|
||||
OZ (record->get_element(i, member));
|
||||
CK (OB_NOT_NULL(member));
|
||||
CK (r_type->get_member(i)->is_obj_type());
|
||||
OX (new (member) ObObj(ObNullType));
|
||||
}
|
||||
OX (current_pos_ = 0);
|
||||
OZ (record->get_element(current_pos_, member));
|
||||
OZ (deep_copy_obj(get_allocator(), obj, *member));
|
||||
OX (data_ = new_data);
|
||||
}
|
||||
} else {
|
||||
ObPLRecord *record = NULL;
|
||||
ObObj *member = NULL;
|
||||
CK (data_->is_ext());
|
||||
CK (OB_NOT_NULL(record = reinterpret_cast<ObPLRecord*>(data_->get_ext())));
|
||||
OZ (record->get_element(current_pos_, member));
|
||||
CK (OB_NOT_NULL(member));
|
||||
OZ (deep_copy_obj(get_allocator(), obj, *member));
|
||||
}
|
||||
OX (current_pos_ += 1);
|
||||
if (OB_SUCC(ret) && current_pos_ >= r_type->get_member_count()) {
|
||||
set_is_last_elem(true);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObPLAnyData::set_collection_element(ObObj &obj)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
const ObCollectionType *c_type = dynamic_cast<const ObCollectionType *>(type_);
|
||||
ObPLNestedTable *new_coll = NULL;
|
||||
ObObj* new_data = NULL;
|
||||
int64_t init_size = 0;
|
||||
if (OB_ISNULL(c_type)) {
|
||||
ret = OB_NOT_SUPPORTED;
|
||||
LOG_WARN("src type is incomplete, can not extract data.");
|
||||
LOG_USER_ERROR(OB_NOT_SUPPORTED, "extract data with incomplete type");
|
||||
} else if (OB_ISNULL(data_)) {
|
||||
if (OB_ISNULL(new_data = reinterpret_cast<ObObj*>(get_allocator().alloc(sizeof(ObObj))))) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
LOG_WARN("faild to alloc memory for new object", K(ret));
|
||||
} else if (OB_FAIL(c_type->get_init_size(init_size))) {
|
||||
LOG_WARN("failed to get init size", K(ret), KPC(c_type));
|
||||
} else if (OB_ISNULL(new_coll =
|
||||
reinterpret_cast<ObPLNestedTable *>(get_allocator().alloc(init_size)))) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
LOG_WARN("faild to alloc memory for new collection", K(ret));
|
||||
} else if (c_type->is_associative_array_type()) {
|
||||
new (new_coll) ObPLAssocArray(c_type->get_user_type_id());
|
||||
} else if (c_type->is_varray_type()) {
|
||||
ObPLVArray *varray = NULL;
|
||||
const ObVArrayType *v_type = NULL;
|
||||
new (new_coll) ObPLVArray(c_type->get_user_type_id());
|
||||
CK (OB_NOT_NULL(varray = static_cast<ObPLVArray *>(new_coll)));
|
||||
CK (OB_NOT_NULL(v_type = static_cast<const ObVArrayType *>(c_type)));
|
||||
OX (varray->set_capacity(v_type->get_capacity()));
|
||||
} else if (c_type->is_nested_table_type()) {
|
||||
new (new_coll) ObPLNestedTable(c_type->get_user_type_id());
|
||||
}
|
||||
|
||||
if (OB_SUCC(ret)) {
|
||||
ObElemDesc elem_desc;
|
||||
elem_desc.set_pl_type(c_type->get_element_type().get_type());
|
||||
elem_desc.set_not_null(c_type->get_element_type().get_not_null());
|
||||
if (OB_ISNULL(c_type->get_element_type().get_data_type())) {
|
||||
ret = OB_NOT_SUPPORTED;
|
||||
LOG_WARN("not support set composite for anydata", K(ret));
|
||||
LOG_USER_ERROR(OB_NOT_SUPPORTED, "set composite for anydata");
|
||||
} else {
|
||||
elem_desc.set_data_type(*(c_type->get_element_type().get_data_type()));
|
||||
elem_desc.set_field_count(1);
|
||||
}
|
||||
OX (new_coll->set_element_desc(elem_desc));
|
||||
}
|
||||
|
||||
OX (new_coll->set_inited());
|
||||
OZ (ObSPIService::spi_set_collection(OB_INVALID_ID, NULL, get_allocator(), *new_coll, 1, true)); //TODO:@ryan.ly here must by a BUG!!!
|
||||
OX (new (new_data) ObObj());
|
||||
OX (new_data->set_extend(reinterpret_cast<int64_t>(new_coll), c_type->get_type()));
|
||||
CK (0 == current_pos_);
|
||||
} else {
|
||||
CK (data_->is_ext());
|
||||
CK (OB_NOT_NULL(new_coll = reinterpret_cast<ObPLNestedTable *>(data_->get_ext())));
|
||||
OZ (ObSPIService::spi_set_collection(OB_INVALID_ID, NULL, get_allocator(), *new_coll, 1, true));
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
ObObj* elements = reinterpret_cast<ObObj*>(
|
||||
reinterpret_cast<int64_t>(new_coll->get_data())
|
||||
+ (sizeof(ObObj) * (new_coll->get_count() - 1)));
|
||||
CK (OB_NOT_NULL(elements));
|
||||
if (!obj.is_ext()) {
|
||||
OZ (deep_copy_obj(*new_coll->get_allocator(), obj, *elements));
|
||||
} else {
|
||||
// TODO:
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret) && OB_ISNULL(data_)) {
|
||||
data_ = new_data;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObPLAnyData::set_current_data(
|
||||
ObObj &obj, ObPLAnyType::TypeCode &src_typecode, bool is_last_elem)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
const ObPLDataType *pl_type = NULL;
|
||||
ObPLAnyType::TypeCode dst_typecode = ObPLAnyType::TypeCode::TYPECODE_INVALID;
|
||||
|
||||
CK (is_in_begincreate());
|
||||
CK (is_in_piecewise());
|
||||
CK (OB_NOT_NULL(get_type()));
|
||||
CK (get_type()->is_record_type() || get_type()->is_collection_type());
|
||||
OZ (get_current_type(pl_type));
|
||||
CK (OB_NOT_NULL(pl_type));
|
||||
OZ (ObPLAnyType::pltype_to_typecode(*pl_type, dst_typecode));
|
||||
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (!ObPLAnyType::typecode_compatible(dst_typecode, src_typecode)) {
|
||||
ret = OB_ERR_TYPE_MISMATCH;
|
||||
LOG_WARN("ORA-22626: Type Mismatch while constructing or accessing OCIAnyData",
|
||||
K(ret), KPC(type_), K(dst_typecode), K(src_typecode), K(in_piecewise_));
|
||||
} else if (is_last_elem_) {
|
||||
ret = OB_ERR_INCORRECT_METHOD_USAGE;
|
||||
LOG_WARN("ORA-22370: incorrect usage of method Set*()", K(ret), KPC(this));
|
||||
LOG_USER_ERROR(OB_ERR_INCORRECT_METHOD_USAGE, "Set*()");
|
||||
} else if (get_type()->is_record_type()) {
|
||||
OZ (set_record_element(obj));
|
||||
} else if (get_type()->is_collection_type()) {
|
||||
OZ (set_collection_element(obj));
|
||||
OX (set_is_last_elem(is_last_elem));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObPLAssocArray::get_serialize_size(int64_t &size)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
@ -5591,30 +5032,6 @@ int ObPLAssocArray::deserialize(common::ObIAllocator &allocator,
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObPLXmlType::deep_copy(ObPLOpaque *dst)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
|
||||
ObPLXmlType *copy = NULL;
|
||||
OZ (ObPLOpaque::deep_copy(dst));
|
||||
CK (OB_NOT_NULL(copy = new(dst)ObPLXmlType()));
|
||||
|
||||
if (OB_NOT_NULL(data_)) {
|
||||
ObObj *new_data = NULL;
|
||||
if (OB_ISNULL(new_data = static_cast<ObObj *>(copy->get_allocator().alloc(sizeof(ObObj))))) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_ERROR("alloc memory for start_obj failed", K(ret));
|
||||
} else {
|
||||
copy->set_data(new_data);
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
OZ(ob_write_obj(copy->get_allocator(), *data_, *(copy->get_data())));
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
//---------- for ObPLVarray ----------
|
||||
|
||||
int ObPLVArray::deep_copy(ObPLCollection *src, ObIAllocator *allocator, bool ignore_del_element)
|
||||
|
@ -20,6 +20,12 @@
|
||||
#include "lib/json_type/ob_json_tree.h"
|
||||
#include "share/rc/ob_tenant_base.h"
|
||||
|
||||
#ifdef OB_BUILD_ORACLE_PL
|
||||
#include "pl/opaque/ob_pl_opaque.h"
|
||||
#include "pl/opaque/ob_pl_xml.h"
|
||||
#include "pl/opaque/ob_pl_json_type.h"
|
||||
#endif
|
||||
|
||||
namespace oceanbase
|
||||
{
|
||||
namespace sql
|
||||
@ -1187,258 +1193,6 @@ private:
|
||||
int64_t capacity_;
|
||||
};
|
||||
|
||||
class ObPLOpaque
|
||||
{
|
||||
public:
|
||||
ObPLOpaque(ObPLOpaqueType type)
|
||||
: type_(type), allocator_("PlOpaque", OB_MALLOC_NORMAL_BLOCK_SIZE, MTL_ID()) {}
|
||||
ObPLOpaque()
|
||||
: type_(ObPLOpaqueType::PL_INVALID), allocator_("PlOpaque", OB_MALLOC_NORMAL_BLOCK_SIZE, MTL_ID()) {}
|
||||
|
||||
virtual ~ObPLOpaque() { allocator_.reset(); }
|
||||
|
||||
inline ObPLOpaqueType get_type() const { return type_; }
|
||||
|
||||
static ObPLOpaqueType get_type(uint64_t id)
|
||||
{
|
||||
ObPLOpaqueType type = ObPLOpaqueType::PL_INVALID;
|
||||
switch (id)
|
||||
{
|
||||
case 300001: {
|
||||
type = ObPLOpaqueType::PL_XML_TYPE;
|
||||
} break;
|
||||
case 300004: {
|
||||
type = ObPLOpaqueType::PL_ANY_TYPE;
|
||||
} break;
|
||||
case 300005: {
|
||||
type = ObPLOpaqueType::PL_ANY_DATA;
|
||||
} break;
|
||||
case 300023:
|
||||
case 300024: {
|
||||
type = ObPLOpaqueType::PL_JSON_TYPE;
|
||||
} break;
|
||||
default :{
|
||||
} break;
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
inline bool is_invalid() const { return ObPLOpaqueType::PL_INVALID == type_; }
|
||||
inline bool is_anytype() const { return ObPLOpaqueType::PL_ANY_TYPE == type_; }
|
||||
inline bool is_anydata() const { return ObPLOpaqueType::PL_ANY_DATA == type_; }
|
||||
inline bool is_xmltype() const { return ObPLOpaqueType::PL_XML_TYPE == type_; }
|
||||
inline bool is_json_type() const { return ObPLOpaqueType::PL_JSON_TYPE == type_; }
|
||||
|
||||
ObIAllocator& get_allocator(); // { return allocator_; }
|
||||
|
||||
virtual int deep_copy(ObPLOpaque *dst);
|
||||
|
||||
int64_t get_init_size() const;
|
||||
|
||||
TO_STRING_KV(K_(type));
|
||||
|
||||
private:
|
||||
ObPLOpaqueType type_;
|
||||
ObArenaAllocator allocator_;
|
||||
};
|
||||
|
||||
class ObPLAnyType : public ObPLOpaque
|
||||
{
|
||||
public:
|
||||
enum TypeCode {
|
||||
TYPECODE_INVALID = -1,
|
||||
TYPECODE_DATE = 12,
|
||||
TYPECODE_NUMBER = 2,
|
||||
TYPECODE_RAW = 95,
|
||||
TYPECODE_CHAR = 96,
|
||||
TYPECODE_VARCHAR2 = 9,
|
||||
TYPECODE_VARCHAR = 1,
|
||||
TYPECODE_MLSLABEL = 105,
|
||||
TYPECODE_BLOB = 113,
|
||||
TYPECODE_BFILE = 114,
|
||||
TYPECODE_CLOB = 112,
|
||||
TYPECODE_CFILE = 115,
|
||||
TYPECODE_TIMESTAMP = 187,
|
||||
TYPECODE_TIMESTAMP_TZ = 188,
|
||||
TYPECODE_TIMESTAMP_LTZ = 232,
|
||||
TYPECODE_INTERVAL_YM = 189,
|
||||
TYPECODE_INTERVAL_DS = 190,
|
||||
|
||||
TYPECODE_REF = 110,
|
||||
TYPECODE_OBJECT = 108,
|
||||
TYPECODE_VARRAY = 247, // COLLECTION TYPE
|
||||
TYPECODE_TABLE = 248, // COLLECTION TYPE
|
||||
TYPECODE_NAMEDCOLLECTION = 122,
|
||||
TYPECODE_OPAQUE = 58, // OPAQUE TYPE
|
||||
|
||||
TYPECODE_NCHAR = 286,
|
||||
TYPECODE_NVARCHAR2 = 287,
|
||||
TYPECODE_NCLOB = 288,
|
||||
|
||||
TYPECODE_BFLOAT = 100,
|
||||
TYPECODE_BDOUBLE = 101,
|
||||
TYPECODE_UROWID = 104,
|
||||
};
|
||||
|
||||
public:
|
||||
ObPLAnyType()
|
||||
: ObPLOpaque(ObPLOpaqueType::PL_ANY_TYPE),
|
||||
in_begincreate_(false),
|
||||
rowsize_(0),
|
||||
code_(TypeCode::TYPECODE_INVALID),
|
||||
type_(NULL) {}
|
||||
|
||||
virtual ~ObPLAnyType() {}
|
||||
|
||||
public:
|
||||
virtual int deep_copy(ObPLOpaque *dst);
|
||||
static int pltype_to_typecode(const ObPLDataType &pl_type, ObPLAnyType::TypeCode &typecode);
|
||||
static bool typecode_compatible(ObPLAnyType::TypeCode &src, ObPLAnyType::TypeCode &dst);
|
||||
|
||||
public:
|
||||
void set_in_begincreate(bool v) { in_begincreate_ = v; }
|
||||
bool is_in_begincreate() { return in_begincreate_; }
|
||||
|
||||
void set_rowsize(int64_t v) { rowsize_ = v; }
|
||||
int64_t get_rowsize() { return rowsize_; }
|
||||
|
||||
void set_type_ptr(ObPLDataType *type) { type_ = type; }
|
||||
ObPLDataType* get_type_ptr() { return type_; }
|
||||
|
||||
void set_typecode(TypeCode code)
|
||||
{
|
||||
if (is_valid_type(code)) {
|
||||
code_ = code;
|
||||
}
|
||||
}
|
||||
TypeCode get_typecode() { return code_; }
|
||||
|
||||
bool is_valid_type() { return is_valid_type(code_); }
|
||||
|
||||
static bool is_obj_type(TypeCode code);
|
||||
static bool is_valid_type(TypeCode code);
|
||||
|
||||
|
||||
TO_STRING_KV(K_(in_begincreate), K_(code), K_(type));
|
||||
|
||||
private:
|
||||
bool in_begincreate_;
|
||||
int64_t rowsize_;
|
||||
TypeCode code_;
|
||||
ObPLDataType *type_;
|
||||
};
|
||||
|
||||
class ObPLAnyData : public ObPLOpaque
|
||||
{
|
||||
public:
|
||||
ObPLAnyData()
|
||||
: ObPLOpaque(ObPLOpaqueType::PL_ANY_DATA),
|
||||
in_begincreate_(false),
|
||||
in_piecewise_(false),
|
||||
is_last_elem_(false),
|
||||
is_no_data_(false),
|
||||
rowsize_(0),
|
||||
current_pos_(0),
|
||||
type_code_(ObPLAnyType::TypeCode::TYPECODE_INVALID),
|
||||
type_(NULL),
|
||||
data_(NULL) {}
|
||||
|
||||
virtual ~ObPLAnyData()
|
||||
{
|
||||
in_piecewise_ = false;
|
||||
in_begincreate_ = false;
|
||||
is_last_elem_ = false;
|
||||
is_no_data_ = false;
|
||||
rowsize_ = 0;
|
||||
current_pos_ = 0;
|
||||
type_code_ = ObPLAnyType::TypeCode::TYPECODE_INVALID;
|
||||
type_ = NULL;
|
||||
if (NULL != data_) {
|
||||
(void)ObUserDefinedType::destruct_obj(*data_);
|
||||
data_ = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
virtual int deep_copy(ObPLOpaque *dst);
|
||||
|
||||
int set_data(const ObObj &data);
|
||||
ObObj* get_data() { return data_; }
|
||||
|
||||
void set_type_code(ObPLAnyType::TypeCode type_code) { type_code_ = type_code; }
|
||||
ObPLAnyType::TypeCode get_type_code() { return type_code_; }
|
||||
|
||||
void set_type(const ObPLDataType *type) { type_ = type; }
|
||||
const ObPLDataType* get_type() { return type_; }
|
||||
|
||||
void set_in_begincreate(bool v) { in_begincreate_ = v; }
|
||||
bool is_in_begincreate() { return in_begincreate_; }
|
||||
|
||||
void set_piecewise(bool v) { in_piecewise_ = v; }
|
||||
bool is_in_piecewise() { return in_piecewise_; }
|
||||
|
||||
void set_rowsize(int64_t v) { rowsize_ = v; }
|
||||
int64_t get_rowsize() { return rowsize_; }
|
||||
|
||||
void set_current_pos(int64_t pos) { current_pos_ = pos; }
|
||||
int64_t get_current_pos() { return current_pos_; }
|
||||
|
||||
void set_is_last_elem(bool v) { is_last_elem_ = v; }
|
||||
bool is_last_elem() { return is_last_elem_; }
|
||||
|
||||
void set_is_no_data(bool v) { is_no_data_ = v; }
|
||||
bool is_no_data() { return is_no_data_; }
|
||||
|
||||
int get_current_data(ObObj &obj, ObPLAnyType::TypeCode &dst_typecode);
|
||||
int set_current_data(ObObj &obj, ObPLAnyType::TypeCode &src_typecode, bool is_last_elem);
|
||||
|
||||
int get_current_type(const ObPLDataType *&pl_type);
|
||||
int set_record_element(ObObj &obj);
|
||||
int set_collection_element(ObObj &obj);
|
||||
|
||||
TO_STRING_KV(K_(in_begincreate),
|
||||
K_(in_piecewise),
|
||||
K_(current_pos),
|
||||
KPC(type_),
|
||||
KPC(data_));
|
||||
|
||||
private:
|
||||
bool in_begincreate_;
|
||||
bool in_piecewise_;
|
||||
bool is_last_elem_;
|
||||
bool is_no_data_;
|
||||
int64_t rowsize_;
|
||||
int64_t current_pos_;
|
||||
ObPLAnyType::TypeCode type_code_;
|
||||
const ObPLDataType *type_;
|
||||
ObObj *data_;
|
||||
};
|
||||
|
||||
class ObPLXmlType : public ObPLOpaque
|
||||
{
|
||||
public:
|
||||
ObPLXmlType()
|
||||
: ObPLOpaque(ObPLOpaqueType::PL_XML_TYPE),
|
||||
data_(NULL) {
|
||||
}
|
||||
|
||||
virtual ~ObPLXmlType()
|
||||
{
|
||||
data_ = NULL;
|
||||
}
|
||||
|
||||
public:
|
||||
virtual int deep_copy(ObPLOpaque *dst);
|
||||
|
||||
void set_data(ObObj *data) { data_ = data; }
|
||||
ObObj* get_data() { return data_; }
|
||||
|
||||
TO_STRING_KV(KPC(data_));
|
||||
|
||||
private:
|
||||
ObObj *data_;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace pl
|
||||
|
@ -17,7 +17,7 @@
|
||||
#include "lib/json_type/ob_json_tree.h"
|
||||
#include "sql/engine/ob_exec_context.h"
|
||||
#include "sql/session/ob_sql_session_info.h"
|
||||
#include "pl/ob_pl_json_type.h"
|
||||
#include "pl/opaque/ob_pl_json_type.h"
|
||||
|
||||
namespace oceanbase
|
||||
{
|
||||
|
@ -36,7 +36,9 @@
|
||||
#include "share/rc/ob_tenant_base.h"
|
||||
#include "pl/sys_package/ob_dbms_sql.h"
|
||||
#include "pl/ob_pl_package_state.h"
|
||||
#include "pl/ob_pl_json_type.h"
|
||||
#ifdef OB_BUILD_ORACLE_PL
|
||||
#include "pl/opaque/ob_pl_json_type.h"
|
||||
#endif
|
||||
#include "rpc/obmysql/ob_sql_sock_session.h"
|
||||
#include "sql/engine/expr/ob_expr_regexp_context.h"
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user