[CP] [to #56242693] move pl opaque type impl to close_moudle/pl

This commit is contained in:
obdev 2024-04-26 11:46:31 +00:00 committed by ob-robot
parent 6bdeecb4d0
commit 6a23c064bc
8 changed files with 11 additions and 1489 deletions

View File

@ -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
)

View File

@ -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"

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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
{

View File

@ -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"