diff --git a/deps/oblib/src/lib/json_type/ob_json_base.h b/deps/oblib/src/lib/json_type/ob_json_base.h index d9fb3cdc70..7777b9ec7a 100644 --- a/deps/oblib/src/lib/json_type/ob_json_base.h +++ b/deps/oblib/src/lib/json_type/ob_json_base.h @@ -301,6 +301,11 @@ public: // @return Returns object_iterator virtual JsonObjectIterator object_iterator() const; + // Get member count of json. + // scalar 1, array, object as child number + // @return json containner returns the capacity, json scalar return 1. + virtual uint64_t member_count() const = 0; + // getter virtual bool get_boolean() const = 0; virtual double get_double() const = 0; diff --git a/deps/oblib/src/lib/json_type/ob_json_bin.h b/deps/oblib/src/lib/json_type/ob_json_bin.h index 8b3e39e0e4..862894f29c 100644 --- a/deps/oblib/src/lib/json_type/ob_json_bin.h +++ b/deps/oblib/src/lib/json_type/ob_json_bin.h @@ -194,6 +194,7 @@ public: { return field_type_; } + int get_array_element(uint64_t index, ObIJsonBase *&value) const override; int get_object_value(uint64_t index, ObIJsonBase *&value) const override; int get_object_value(const ObString &key, ObIJsonBase *&value) const override; @@ -398,6 +399,12 @@ public: // release resource void destroy(); + virtual uint64_t member_count() const override + { + return (json_type() == ObJsonNodeType::J_ARRAY || json_type() == ObJsonNodeType::J_OBJECT) ? + element_count() : 1; + } + private: // used as stack struct ObJBNodeMeta { diff --git a/deps/oblib/src/lib/json_type/ob_json_tree.h b/deps/oblib/src/lib/json_type/ob_json_tree.h index 3d0c30f3f2..3199721349 100644 --- a/deps/oblib/src/lib/json_type/ob_json_tree.h +++ b/deps/oblib/src/lib/json_type/ob_json_tree.h @@ -70,6 +70,7 @@ public: int get_obtime(ObTime &t) const override; OB_INLINE ObJsonInType get_internal_type() const override { return ObJsonInType::JSON_TREE; } OB_INLINE uint64_t element_count() const override { return 1; } + virtual uint64_t member_count() const override { return element_count(); } OB_INLINE ObObjType field_type() const override { return ObMaxType; // ObJsonOpaque override diff --git a/src/pl/ob_pl_user_type.cpp b/src/pl/ob_pl_user_type.cpp index f1f671a07e..6a68c7fb36 100644 --- a/src/pl/ob_pl_user_type.cpp +++ b/src/pl/ob_pl_user_type.cpp @@ -5300,8 +5300,19 @@ int ObPLJsonBaseType::deep_copy(ObPLOpaque *dst) OZ (ObPLOpaque::deep_copy(dst)); CK (OB_NOT_NULL(copy = new(dst)ObPLJsonBaseType())); OX (copy->set_err_behavior(static_cast(behavior_))); - if (OB_NOT_NULL(data_)) { - OX (copy->set_data(data_)); + if (OB_SUCC(ret) && OB_NOT_NULL(data_)) { + if (need_shallow_copy()) { + copy->set_data(data_); + copy->set_shallow_copy(1); + } else { + ObJsonNode *json_dst = data_->clone(©->get_allocator(), true); + if (OB_ISNULL(json_dst)) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("alloc memory for clone json node failed", K(ret)); + } else { + copy->set_data(json_dst); + } + } } return ret; diff --git a/src/pl/ob_pl_user_type.h b/src/pl/ob_pl_user_type.h index f1456e59d2..5939d461d0 100644 --- a/src/pl/ob_pl_user_type.h +++ b/src/pl/ob_pl_user_type.h @@ -1433,7 +1433,8 @@ public: ObPLJsonBaseType() : ObPLOpaque(ObPLOpaqueType::PL_JSON_TYPE), data_(NULL), - behavior_(0) + behavior_(0), + is_shallow_copy_(0) {} virtual ~ObPLJsonBaseType() @@ -1448,12 +1449,15 @@ public: void set_err_behavior(int behavior) { behavior_ = behavior; } int get_err_behavior() { return behavior_ ; } ObJsonNode* get_data() { return data_; } + bool need_shallow_copy() { return is_shallow_copy_ > 0; } + void set_shallow_copy(int value) { is_shallow_copy_ = value; } - TO_STRING_KV(KPC(data_), K_(behavior)); + TO_STRING_KV(KPC(data_), K_(behavior), K_(is_shallow_copy)); private: ObJsonNode *data_; int behavior_; + int is_shallow_copy_; }; #endif diff --git a/src/pl/sys_package/ob_json_pl_utils.h b/src/pl/sys_package/ob_json_pl_utils.h index b7aad1595e..deb8f8fedd 100644 --- a/src/pl/sys_package/ob_json_pl_utils.h +++ b/src/pl/sys_package/ob_json_pl_utils.h @@ -27,7 +27,8 @@ namespace pl class ObPlJsonUtil { enum { JSN_PL_ELEMENT_TYPE_ID = 300023, - JSN_PL_OBJECT_TYPE_ID = 300024 + JSN_PL_OBJECT_TYPE_ID = 300024, + JSN_PL_ARRAY_TYPE_ID = 300025, }; public: @@ -61,13 +62,14 @@ public: static int check_on_error(ObObj &obj, int& err_val); static bool proc_on_error(common::ObObj &result, int error_behavior, int &ret); static bool is_pl_jsontype(int64_t id) { - return (id == JSN_PL_ELEMENT_TYPE_ID || id == JSN_PL_OBJECT_TYPE_ID); + return (id == JSN_PL_ELEMENT_TYPE_ID || id == JSN_PL_OBJECT_TYPE_ID || id == JSN_PL_ARRAY_TYPE_ID); } static bool is_hex(const uint8_t input); static bool is_hex_string(const ObString& hex_str); static bool is_pl_json_element_type(int64_t id) { return (id == JSN_PL_ELEMENT_TYPE_ID); } static bool is_pl_json_object_type(int64_t id) { return (id == JSN_PL_OBJECT_TYPE_ID); } + static bool is_pl_json_array_type(int64_t id) { return (id == JSN_PL_ARRAY_TYPE_ID); } static int get_lob_inner(ObIAllocator& allocator, const ObString& val_str, ObPlJsonUtil::PL_JSN_STRING_TYPE type, ObIJsonBase*& j_base); }; diff --git a/src/share/inner_table/sys_package/json_array_type.sql b/src/share/inner_table/sys_package/json_array_type.sql index a0de3b0480..2c8eac6332 100644 --- a/src/share/inner_table/sys_package/json_array_type.sql +++ b/src/share/inner_table/sys_package/json_array_type.sql @@ -1,19 +1,21 @@ -CREATE OR REPLACE TYPE JSON_ARRAY_T OID '300025' AS OPAQUE +CREATE OR REPLACE TYPE JSON_ARRAY_T FORCE OID '300025' AS OPAQUE ( STATIC FUNCTION parse(jsn VARCHAR2) return JSON_ARRAY_T, STATIC FUNCTION parse(jsn CLOB) return JSON_ARRAY_T, STATIC FUNCTION parse(jsn BLOB) return JSON_ARRAY_T, + CONSTRUCTOR FUNCTION JSON_ARRAY_T RETURN SELF AS RESULT, CONSTRUCTOR FUNCTION JSON_ARRAY_T(o JSON_ELEMENT_T) RETURN SELF AS RESULT, CONSTRUCTOR FUNCTION JSON_ARRAY_T(o JSON_ARRAY_T) RETURN SELF AS RESULT, CONSTRUCTOR FUNCTION JSON_ARRAY_T(jsn VARCHAR2) RETURN SELF AS RESULT, CONSTRUCTOR FUNCTION JSON_ARRAY_T(jsn CLOB) RETURN SELF AS RESULT, CONSTRUCTOR FUNCTION JSON_ARRAY_T(jsn BLOB) RETURN SELF AS RESULT, - MEMBER PROCEDURE on_Error(val NUMBER), - MEMBER FUNCTION get(pos NUMBER) return JSON_ELEMENT_T, + + MEMBER PROCEDURE on_Error(SELF IN OUT NOCOPY JSON_ARRAY_T, val NUMBER), + MEMBER FUNCTION get(SELF IN OUT NOCOPY JSON_ARRAY_T, pos NUMBER) return JSON_ELEMENT_T, MEMBER FUNCTION get_Type(pos NUMBER) return VARCHAR2, MEMBER FUNCTION get_Size RETURN NUMBER, MEMBER FUNCTION to_String RETURN VARCHAR2, - MEMBER FUNCTION clone RETURN JSON_ARRAY_T + MEMBER FUNCTION clone(SELF IN OUT NOCOPY JSON_ARRAY_T) RETURN JSON_ARRAY_T ); // \ No newline at end of file diff --git a/src/share/inner_table/sys_package/json_array_type_body.sql b/src/share/inner_table/sys_package/json_array_type_body.sql new file mode 100644 index 0000000000..ee356687ee --- /dev/null +++ b/src/share/inner_table/sys_package/json_array_type_body.sql @@ -0,0 +1,46 @@ +CREATE OR REPLACE TYPE BODY JSON_ARRAY_T AS + STATIC function parse(jsn VARCHAR2) return JSON_ARRAY_T; + PRAGMA INTERFACE(c, JSON_ARRAY_PARSE); + + STATIC FUNCTION parse(jsn CLOB) return JSON_ARRAY_T; + PRAGMA INTERFACE(c, JSON_ARRAY_PARSE); + STATIC FUNCTION parse(jsn BLOB) return JSON_ARRAY_T; + PRAGMA INTERFACE(c, JSON_ARRAY_PARSE); + + CONSTRUCTOR FUNCTION JSON_ARRAY_T RETURN SELF AS RESULT; + PRAGMA INTERFACE(c, JSON_ARRAY_CONSTRUCTOR); + + CONSTRUCTOR FUNCTION JSON_ARRAY_T(jsn VARCHAR2) RETURN SELF AS RESULT; + PRAGMA INTERFACE(c, JSON_ARRAY_CONSTRUCTOR); + + CONSTRUCTOR FUNCTION JSON_ARRAY_T(jsn CLOB) RETURN SELF AS RESULT; + PRAGMA INTERFACE(c, JSON_ARRAY_CONSTRUCTOR); + + CONSTRUCTOR FUNCTION JSON_ARRAY_T(jsn BLOB) RETURN SELF AS RESULT; + PRAGMA INTERFACE(c, JSON_ARRAY_CONSTRUCTOR); + + CONSTRUCTOR FUNCTION JSON_ARRAY_T(o JSON_ELEMENT_T) RETURN SELF AS RESULT; + PRAGMA INTERFACE(c, JSON_ARRAY_CONSTRUCTOR); + + CONSTRUCTOR FUNCTION JSON_ARRAY_T(o JSON_ARRAY_T) RETURN SELF AS RESULT; + PRAGMA INTERFACE(c, JSON_ARRAY_CONSTRUCTOR); + + MEMBER FUNCTION get(SELF IN OUT NOCOPY JSON_ARRAY_T, pos IN NUMBER) return JSON_ELEMENT_T; + PRAGMA INTERFACE(c, JSON_ARRAY_GET); + + MEMBER PROCEDURE on_Error(SELF IN OUT NOCOPY JSON_ARRAY_T, val IN NUMBER); + PRAGMA INTERFACE(c, JSON_ARRAY_ON_ERROR); + + MEMBER FUNCTION get_Type(pos IN NUMBER) return VARCHAR2; + PRAGMA INTERFACE(c, JSON_ARRAY_GET_TYPE); + + MEMBER FUNCTION to_String RETURN VARCHAR2; + PRAGMA INTERFACE(c, JSON_TO_STRING); + + MEMBER FUNCTION get_Size RETURN NUMBER; + PRAGMA INTERFACE(c, JSON_GET_SIZE); + + MEMBER FUNCTION clone(SELF IN OUT NOCOPY JSON_ARRAY_T) RETURN JSON_ARRAY_T; + PRAGMA INTERFACE(c, JSON_ARRAY_CLONE); +END; +// \ No newline at end of file diff --git a/src/share/inner_table/sys_package/json_object_type.sql b/src/share/inner_table/sys_package/json_object_type.sql index 7cc476cb98..1dd7ec2f4a 100644 --- a/src/share/inner_table/sys_package/json_object_type.sql +++ b/src/share/inner_table/sys_package/json_object_type.sql @@ -5,8 +5,8 @@ CREATE OR REPLACE TYPE JSON_OBJECT_T OID '300024' AS OPAQUE STATIC FUNCTION parse(jsn BLOB) return JSON_OBJECT_T, CONSTRUCTOR FUNCTION JSON_OBJECT_T RETURN SELF AS RESULT, - CONSTRUCTOR FUNCTION JSON_OBJECT_T(o JSON_ELEMENT_T) RETURN SELF AS RESULT, - CONSTRUCTOR FUNCTION JSON_OBJECT_T(o JSON_OBJECT_T) RETURN SELF AS RESULT, + CONSTRUCTOR FUNCTION JSON_OBJECT_T(jsn JSON_ELEMENT_T) RETURN SELF AS RESULT, + CONSTRUCTOR FUNCTION JSON_OBJECT_T(jsn JSON_OBJECT_T) RETURN SELF AS RESULT, CONSTRUCTOR FUNCTION JSON_OBJECT_T(jsn VARCHAR2) RETURN SELF AS RESULT, CONSTRUCTOR FUNCTION JSON_OBJECT_T(jsn CLOB) RETURN SELF AS RESULT, CONSTRUCTOR FUNCTION JSON_OBJECT_T(jsn BLOB) RETURN SELF AS RESULT, @@ -35,36 +35,37 @@ CREATE OR REPLACE TYPE JSON_OBJECT_T OID '300024' AS OPAQUE MEMBER PROCEDURE to_Clob(c IN OUT CLOB), MEMBER PROCEDURE to_Blob(c IN OUT BLOB), - MEMBER FUNCTION get_String(key VARCHAR2) return VARCHAR2, - MEMBER FUNCTION get_Number(key VARCHAR2) return NUMBER, - MEMBER FUNCTION get_Date(key VARCHAR2) return DATE, - MEMBER FUNCTION get_Timestamp(key VARCHAR2) return TIMESTAMP, - MEMBER FUNCTION get_Boolean(key VARCHAR2) return BOOLEAN, - MEMBER FUNCTION get_Clob(key VARCHAR2) return CLOB, - MEMBER FUNCTION get_Blob(key VARCHAR2) return BLOB, - MEMBER FUNCTION get_Object(key VARCHAR2) return JSON_OBJECT_T, - MEMBER FUNCTION get(key VARCHAR2) return JSON_ELEMENT_T, + MEMBER FUNCTION get_String(SELF IN OUT NOCOPY JSON_OBJECT_T, key VARCHAR2) return VARCHAR2, + MEMBER FUNCTION get_Number(SELF IN OUT NOCOPY JSON_OBJECT_T, key VARCHAR2) return NUMBER, + MEMBER FUNCTION get_Date(SELF IN OUT NOCOPY JSON_OBJECT_T, key VARCHAR2) return DATE, + MEMBER FUNCTION get_Timestamp(SELF IN OUT NOCOPY JSON_OBJECT_T, key VARCHAR2) return TIMESTAMP, + MEMBER FUNCTION get_Boolean(SELF IN OUT NOCOPY JSON_OBJECT_T, key VARCHAR2) return BOOLEAN, + MEMBER FUNCTION get_Clob(self IN OUT NOCOPY JSON_OBJECT_T, key VARCHAR2) return CLOB, + MEMBER FUNCTION get_Blob(self IN OUT NOCOPY JSON_OBJECT_T, key VARCHAR2) return BLOB, + MEMBER FUNCTION get_Object(self IN OUT NOCOPY JSON_OBJECT_T, key VARCHAR2) return JSON_OBJECT_T, + MEMBER FUNCTION get(self IN OUT NOCOPY JSON_OBJECT_T, key VARCHAR2) return JSON_ELEMENT_T, - MEMBER PROCEDURE get_Clob(key VARCHAR2, c IN OUT CLOB), - MEMBER PROCEDURE get_Blob(key VARCHAR2, c IN OUT BLOB), - MEMBER PROCEDURE put(key VARCHAR2, value BOOLEAN), - MEMBER PROCEDURE put(key VARCHAR2, value JSON_OBJECT_T), - MEMBER PROCEDURE put(key VARCHAR2, value JSON_ELEMENT_T), - MEMBER PROCEDURE put(key VARCHAR2, value VARCHAR2), - MEMBER PROCEDURE put(key VARCHAR2, value NUMBER), - MEMBER PROCEDURE put(key VARCHAR2, value DATE), - MEMBER PROCEDURE put(key VARCHAR2, value TIMESTAMP), - MEMBER PROCEDURE put(key VARCHAR2, value BLOB), - MEMBER PROCEDURE put(key VARCHAR2, value CLOB), - MEMBER PROCEDURE put(key VARCHAR2, value JSON), - MEMBER PROCEDURE put_Null(key VARCHAR2), - MEMBER PROCEDURE remove(key VARCHAR2), - MEMBER PROCEDURE rename_Key(keyOld VARCHAR2, keyNew VARCHAR2), - MEMBER PROCEDURE on_Error(val NUMBER), + MEMBER PROCEDURE get_Clob(self IN OUT NOCOPY JSON_OBJECT_T, key VARCHAR2, c IN OUT CLOB), + MEMBER PROCEDURE get_Blob(self IN OUT NOCOPY JSON_OBJECT_T, key VARCHAR2, c IN OUT BLOB), + + MEMBER PROCEDURE put(SELF IN OUT NOCOPY JSON_OBJECT_T, key VARCHAR2, value BOOLEAN), + MEMBER PROCEDURE put(SELF IN OUT NOCOPY JSON_OBJECT_T, key VARCHAR2, value JSON_OBJECT_T), + MEMBER PROCEDURE put(SELF IN OUT NOCOPY JSON_OBJECT_T, key VARCHAR2, value JSON_ELEMENT_T), + MEMBER PROCEDURE put(SELF IN OUT NOCOPY JSON_OBJECT_T, key VARCHAR2, value VARCHAR2), + MEMBER PROCEDURE put(SELF IN OUT NOCOPY JSON_OBJECT_T, key VARCHAR2, value NUMBER), + MEMBER PROCEDURE put(SELF IN OUT NOCOPY JSON_OBJECT_T, key VARCHAR2, value DATE), + MEMBER PROCEDURE put(SELF IN OUT NOCOPY JSON_OBJECT_T, key VARCHAR2, value TIMESTAMP), + MEMBER PROCEDURE put(SELF IN OUT NOCOPY JSON_OBJECT_T, key VARCHAR2, value BLOB), + MEMBER PROCEDURE put(SELF IN OUT NOCOPY JSON_OBJECT_T, key VARCHAR2, value CLOB), + MEMBER PROCEDURE put(SELF IN OUT NOCOPY JSON_OBJECT_T, key VARCHAR2, value JSON), + MEMBER PROCEDURE put_Null(SELF IN OUT NOCOPY JSON_OBJECT_T, key VARCHAR2), + MEMBER PROCEDURE remove(SELF IN OUT NOCOPY JSON_OBJECT_T, key VARCHAR2), + MEMBER PROCEDURE rename_Key(SELF IN OUT NOCOPY JSON_OBJECT_T, keyOld VARCHAR2, keyNew VARCHAR2), + MEMBER PROCEDURE on_Error(SELF IN OUT NOCOPY JSON_OBJECT_T, val NUMBER), MEMBER FUNCTION has(key VARCHAR2) return BOOLEAN, MEMBER FUNCTION get_Type(key VARCHAR2) return VARCHAR2, - MEMBER FUNCTION clone RETURN JSON_OBJECT_T + MEMBER FUNCTION clone(self IN OUT NOCOPY JSON_OBJECT_T) RETURN JSON_OBJECT_T ); // \ No newline at end of file diff --git a/src/share/inner_table/sys_package/json_object_type_body.sql b/src/share/inner_table/sys_package/json_object_type_body.sql index 00c5a92d8b..8cd941ca95 100644 --- a/src/share/inner_table/sys_package/json_object_type_body.sql +++ b/src/share/inner_table/sys_package/json_object_type_body.sql @@ -20,10 +20,10 @@ CREATE OR REPLACE TYPE BODY JSON_OBJECT_T AS CONSTRUCTOR FUNCTION JSON_OBJECT_T(jsn BLOB) RETURN SELF AS RESULT; PRAGMA INTERFACE(c, JSON_OBJECT_CONSTRUCTOR); - CONSTRUCTOR FUNCTION JSON_OBJECT_T(o JSON_ELEMENT_T) RETURN SELF AS RESULT; + CONSTRUCTOR FUNCTION JSON_OBJECT_T(jsn JSON_ELEMENT_T) RETURN SELF AS RESULT; PRAGMA INTERFACE(c, JSON_OBJECT_CONSTRUCTOR); - CONSTRUCTOR FUNCTION JSON_OBJECT_T(o JSON_OBJECT_T) RETURN SELF AS RESULT; + CONSTRUCTOR FUNCTION JSON_OBJECT_T(jsn JSON_OBJECT_T) RETURN SELF AS RESULT; PRAGMA INTERFACE(c, JSON_OBJECT_CONSTRUCTOR); MEMBER FUNCTION is_Object RETURN BOOLEAN; @@ -89,79 +89,79 @@ CREATE OR REPLACE TYPE BODY JSON_OBJECT_T AS MEMBER FUNCTION get_Size RETURN NUMBER; PRAGMA INTERFACE(c, JSON_GET_SIZE); - MEMBER FUNCTION get_String(key VARCHAR2) return VARCHAR2; + MEMBER FUNCTION get_String(SELF IN OUT NOCOPY JSON_OBJECT_T, key VARCHAR2) return VARCHAR2; PRAGMA INTERFACE(c, JSON_OBJECT_GETSTR); - MEMBER FUNCTION get_Number(key VARCHAR2) return NUMBER; + MEMBER FUNCTION get_Number(SELF IN OUT NOCOPY JSON_OBJECT_T, key VARCHAR2) return NUMBER; PRAGMA INTERFACE(c, JSON_OBJECT_GET_NUMBER); - MEMBER FUNCTION get_Date(key VARCHAR2) return DATE; + MEMBER FUNCTION get_Date(SELF IN OUT NOCOPY JSON_OBJECT_T, key VARCHAR2) return DATE; PRAGMA INTERFACE(c, JSON_OBJECT_GET_DATE); - MEMBER FUNCTION get_Timestamp(key VARCHAR2) return TIMESTAMP; + MEMBER FUNCTION get_Timestamp(SELF IN OUT NOCOPY JSON_OBJECT_T, key VARCHAR2) return TIMESTAMP; PRAGMA INTERFACE(c, JSON_OBJECT_GET_TIMESTAMP); - MEMBER FUNCTION get_Boolean(key VARCHAR2) return BOOLEAN; + MEMBER FUNCTION get_Boolean(SELF IN OUT NOCOPY JSON_OBJECT_T, key VARCHAR2) return BOOLEAN; PRAGMA INTERFACE(c, JSON_OBJECT_GET_BOOLEAN); - MEMBER FUNCTION get_Clob(key VARCHAR2) return CLOB; + MEMBER FUNCTION get_Clob(SELF IN OUT NOCOPY JSON_OBJECT_T, key VARCHAR2) return CLOB; PRAGMA INTERFACE(c, JSON_OBJECT_GET_CLOB); - MEMBER FUNCTION get_Blob(key VARCHAR2) return BLOB; + MEMBER FUNCTION get_Blob(SELF IN OUT NOCOPY JSON_OBJECT_T, key VARCHAR2) return BLOB; PRAGMA INTERFACE(c, JSON_OBJECT_GET_BLOB); - MEMBER FUNCTION get_Object(key VARCHAR2) return JSON_OBJECT_T; + MEMBER FUNCTION get_Object(SELF IN OUT NOCOPY JSON_OBJECT_T, key VARCHAR2) return JSON_OBJECT_T; PRAGMA INTERFACE(c, JSON_OBJECT_GET_OBJECT); - MEMBER FUNCTION get(key VARCHAR2) return JSON_ELEMENT_T; + MEMBER FUNCTION get(SELF IN OUT NOCOPY JSON_OBJECT_T, key VARCHAR2) return JSON_ELEMENT_T; PRAGMA INTERFACE(c, JSON_OBJECT_GET_ELEMENT); - MEMBER PROCEDURE get_Clob(key VARCHAR2, c IN OUT CLOB); + MEMBER PROCEDURE get_Clob(SELF IN OUT NOCOPY JSON_OBJECT_T, key VARCHAR2, c IN OUT CLOB); PRAGMA INTERFACE(c, JSON_OBJECT_GET_CLOB_PROC); - MEMBER PROCEDURE get_Blob(key VARCHAR2, c IN OUT BLOB); + MEMBER PROCEDURE get_Blob(SELF IN OUT NOCOPY JSON_OBJECT_T, key VARCHAR2, c IN OUT BLOB); PRAGMA INTERFACE(c, JSON_OBJECT_GET_BLOB_PROC); - MEMBER PROCEDURE put(key VARCHAR2, value BOOLEAN); + MEMBER PROCEDURE put(SELF IN OUT NOCOPY JSON_OBJECT_T, key VARCHAR2, value BOOLEAN); PRAGMA INTERFACE(c, JSON_OBJECT_PUT_BOOL); - MEMBER PROCEDURE put(key VARCHAR2, value JSON_OBJECT_T); + MEMBER PROCEDURE put(SELF IN OUT NOCOPY JSON_OBJECT_T, key VARCHAR2, value JSON_OBJECT_T); PRAGMA INTERFACE(c, JSON_OBJECT_PUT); - MEMBER PROCEDURE put(key VARCHAR2, value JSON_ELEMENT_T); + MEMBER PROCEDURE put(SELF IN OUT NOCOPY JSON_OBJECT_T, key VARCHAR2, value JSON_ELEMENT_T); PRAGMA INTERFACE(c, JSON_OBJECT_PUT); - MEMBER PROCEDURE put(key VARCHAR2, value VARCHAR2); + MEMBER PROCEDURE put(SELF IN OUT NOCOPY JSON_OBJECT_T, key VARCHAR2, value VARCHAR2); PRAGMA INTERFACE(c, JSON_OBJECT_PUT_VARCHAR); - MEMBER PROCEDURE put(key VARCHAR2, value NUMBER); + MEMBER PROCEDURE put(SELF IN OUT NOCOPY JSON_OBJECT_T, key VARCHAR2, value NUMBER); PRAGMA INTERFACE(c, JSON_OBJECT_PUT); - MEMBER PROCEDURE put(key VARCHAR2, value DATE); + MEMBER PROCEDURE put(SELF IN OUT NOCOPY JSON_OBJECT_T, key VARCHAR2, value DATE); PRAGMA INTERFACE(c, JSON_OBJECT_PUT); - MEMBER PROCEDURE put(key VARCHAR2, value TIMESTAMP); + MEMBER PROCEDURE put(SELF IN OUT NOCOPY JSON_OBJECT_T, key VARCHAR2, value TIMESTAMP); PRAGMA INTERFACE(c, JSON_OBJECT_PUT); - MEMBER PROCEDURE put(key VARCHAR2, value BLOB); + MEMBER PROCEDURE put(SELF IN OUT NOCOPY JSON_OBJECT_T, key VARCHAR2, value BLOB); PRAGMA INTERFACE(c, JSON_OBJECT_PUT_BLOB); - MEMBER PROCEDURE put(key VARCHAR2, value CLOB); + MEMBER PROCEDURE put(SELF IN OUT NOCOPY JSON_OBJECT_T, key VARCHAR2, value CLOB); PRAGMA INTERFACE(c, JSON_OBJECT_PUT_CLOB); - MEMBER PROCEDURE put(key VARCHAR2, value JSON); + MEMBER PROCEDURE put(SELF IN OUT NOCOPY JSON_OBJECT_T, key VARCHAR2, value JSON); PRAGMA INTERFACE(c, JSON_OBJECT_PUT_JSON); - MEMBER PROCEDURE put_Null(key VARCHAR2); + MEMBER PROCEDURE put_Null(SELF IN OUT NOCOPY JSON_OBJECT_T, key VARCHAR2); PRAGMA INTERFACE(c, JSON_OBJECT_PUT_NULL); - MEMBER PROCEDURE remove(key VARCHAR2); + MEMBER PROCEDURE remove(SELF IN OUT NOCOPY JSON_OBJECT_T, key VARCHAR2); PRAGMA INTERFACE(c, JSON_OBJECT_REMOVE); - MEMBER PROCEDURE rename_Key(keyOld VARCHAR2, keyNew VARCHAR2); + MEMBER PROCEDURE rename_Key(SELF IN OUT NOCOPY JSON_OBJECT_T, keyOld VARCHAR2, keyNew VARCHAR2); PRAGMA INTERFACE(c, JSON_OBJECT_RENAME_KEY); - MEMBER PROCEDURE on_Error(val NUMBER); + MEMBER PROCEDURE on_Error(SELF IN OUT NOCOPY JSON_OBJECT_T, val NUMBER); PRAGMA INTERFACE(c, JSON_OBJECT_ON_ERROR); MEMBER FUNCTION has(key VARCHAR2) return BOOLEAN; @@ -170,7 +170,7 @@ CREATE OR REPLACE TYPE BODY JSON_OBJECT_T AS MEMBER FUNCTION get_Type(key VARCHAR2) return VARCHAR2; PRAGMA INTERFACE(c, JSON_OBJECT_GET_TYPE); - MEMBER FUNCTION clone RETURN JSON_OBJECT_T; + MEMBER FUNCTION clone(self IN OUT NOCOPY JSON_OBJECT_T) RETURN JSON_OBJECT_T; PRAGMA INTERFACE(c, JSON_OBJECT_CLONE); END; // \ No newline at end of file diff --git a/src/sql/engine/expr/ob_expr_json_length.cpp b/src/sql/engine/expr/ob_expr_json_length.cpp index 58ca0d8937..3cb6602226 100644 --- a/src/sql/engine/expr/ob_expr_json_length.cpp +++ b/src/sql/engine/expr/ob_expr_json_length.cpp @@ -97,7 +97,7 @@ int ObExprJsonLength::calc(ObEvalCtx &ctx, const ObDatum &data1, ObDatumMeta met // handle data2(path text) if (OB_SUCC(ret) && OB_LIKELY(!is_null)) { if (OB_ISNULL(data2)) { // have no path - res_len = j_base->element_count(); + res_len = j_base->member_count(); } else { // handle json path ObObjType type2 = meta2.type_; if (type2 == ObNullType) { // null should display "NULL" @@ -116,7 +116,7 @@ int ObExprJsonLength::calc(ObEvalCtx &ctx, const ObDatum &data1, ObDatumMeta met } else if (hit.size() != 1) { // not found node by path, display "NULL" is_null = true; } else { - res_len = hit[0]->element_count(); + res_len = hit[0]->member_count(); } } } diff --git a/src/sql/engine/expr/ob_expr_left.cpp b/src/sql/engine/expr/ob_expr_left.cpp index db248556d5..994a18e2be 100644 --- a/src/sql/engine/expr/ob_expr_left.cpp +++ b/src/sql/engine/expr/ob_expr_left.cpp @@ -68,13 +68,9 @@ int ObExprLeft::calc_result_type2(ObExprResType &type, { int ret = OB_SUCCESS; ObSQLSessionInfo *session = const_cast(type_ctx.get_session()); - ObExecContext *exec_ctx = nullptr; if (OB_ISNULL(session)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("session is NULL", K(ret)); - } else if (OB_ISNULL(exec_ctx = session->get_cur_exec_ctx())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("exec context is NULL", K(ret)); } else if (session->is_varparams_sql_prepare()) { // the ps prepare stage does not do type deduction, and directly gives a default type. type.set_char(); diff --git a/src/sql/engine/expr/ob_expr_treat.cpp b/src/sql/engine/expr/ob_expr_treat.cpp index 569fb3ee8a..382cb4b932 100644 --- a/src/sql/engine/expr/ob_expr_treat.cpp +++ b/src/sql/engine/expr/ob_expr_treat.cpp @@ -110,7 +110,11 @@ static int treat_as_json_udt(const ObExpr &expr, ObEvalCtx &ctx, common::ObIAllo ret = OB_ERR_UNEXPECTED; LOG_WARN("get json doc is null", K(ret), K(jsontype)); } else { - if (OB_FAIL(pl::ObPlJsonUtil::transform_JsonBase_2_PLJsonType(ctx.exec_ctx_, json_doc, new_jsontype))) { + ObJsonNode * json_node_copy = nullptr; + if (OB_ISNULL(json_node_copy = json_doc->clone(&ctx.exec_ctx_.get_allocator()))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("failed to clone json node", K(ret)); + } else if (OB_FAIL(pl::ObPlJsonUtil::transform_JsonBase_2_PLJsonType(ctx.exec_ctx_, json_node_copy, new_jsontype))) { LOG_WARN("failed to transfrom ObJsonNode to ObPLJsonBaseType", K(ret)); } else if(OB_ISNULL(new_jsontype)) { ret = OB_ERR_UNEXPECTED; diff --git a/src/sql/resolver/expr/ob_raw_expr_util.cpp b/src/sql/resolver/expr/ob_raw_expr_util.cpp index e5c2cad7d2..ec4b4709be 100644 --- a/src/sql/resolver/expr/ob_raw_expr_util.cpp +++ b/src/sql/resolver/expr/ob_raw_expr_util.cpp @@ -1079,6 +1079,14 @@ int ObRawExprUtils::resolve_udf_param_exprs(ObResolverParams ¶ms, CK (OB_NOT_NULL(iparam)); OX (mode = static_cast(iparam->get_mode())); if (OB_SUCC(ret)) { +#ifdef OB_BUILD_ORACLE_PL + if (iparam->is_nocopy_param() + && pl::ObPLRoutineParamMode::PL_PARAM_INOUT == mode + && OB_NOT_NULL(udf_raw_expr->get_param_expr(i)) + && pl::ObPlJsonUtil::is_pl_jsontype(udf_raw_expr->get_param_expr(i)->get_udt_id())) { + OZ (udf_raw_expr->add_param_desc(ObUDFParamDesc())); + } else +#endif if (pl::ObPLRoutineParamMode::PL_PARAM_OUT == mode || pl::ObPLRoutineParamMode::PL_PARAM_INOUT == mode) { ObRawExpr* iexpr = udf_raw_expr->get_param_expr(i);