csun5285 commented on code in PR #53843:
URL: https://github.com/apache/doris/pull/53843#discussion_r2244938953


##########
be/src/vec/functions/cast/cast_to_jsonb.h:
##########
@@ -364,94 +122,126 @@ inline bool can_cast_json_type(PrimitiveType pt) {
 WrapperType create_cast_from_jsonb_wrapper(const DataTypeJsonb& from_type,
                                            const DataTypePtr& to_type,
                                            bool jsonb_string_as_string) {
-    if (!can_cast_json_type(to_type->get_primitive_type())) {
-        return create_unsupport_wrapper(
-                fmt::format("CAST AS JSONB can only be performed between "
-                            "JSONB, String, Number, Boolean, Array, Struct 
types. "
-                            "Got {} to {}",
-                            from_type.get_name(), to_type->get_name())
+    if (is_string_type(to_type->get_primitive_type()) && 
jsonb_string_as_string) {
+        return ConvertImplGenericFromJsonb::execute;
+    }
+
+    return [](FunctionContext* context, Block& block, const ColumnNumbers& 
arguments,
+              uint32_t result, size_t input_rows_count, const 
NullMap::value_type*) {
+        CastParameters params;
+        params.is_strict = context->enable_strict_mode();
+        auto data_type_to = make_nullable(block.get_by_position(result).type);
+        auto serde_to = data_type_to->get_serde();
+        const auto& col_from_json =
+                assert_cast<const 
ColumnString&>(*block.get_by_position(arguments[0]).column);
+        size_t size = col_from_json.size();
+        auto col_to = data_type_to->create_column();
+        for (size_t i = 0; i < size; ++i) {
+            const auto& val = col_from_json.get_data_at(i);
+            JsonbDocument* doc = nullptr;
+            auto st = JsonbDocument::checkAndCreateDocument(val.data, 
val.size, &doc);
+            if (!st.ok() || !doc || !doc->getValue()) [[unlikely]] {
+                col_to->insert_default();

Review Comment:
   这里的严格模式下应该报错吧



##########
be/src/vec/data_types/serde/data_type_struct_serde.cpp:
##########
@@ -354,6 +354,40 @@ Status 
DataTypeStructSerDe::serialize_column_to_jsonb(const IColumn& from_column
     return Status::OK();
 }
 
+Status DataTypeStructSerDe::deserialize_column_from_jsonb(IColumn& column,
+                                                          const JsonbValue* 
jsonb_value,
+                                                          CastParameters& 
castParms) const {
+    if (jsonb_value->isString()) {
+        RETURN_IF_ERROR(parse_column_from_jsonb_string(column, jsonb_value, 
castParms));
+        return Status::OK();
+    }
+    auto& struct_column = assert_cast<ColumnStruct&>(column);
+    if (!jsonb_value->isObject()) {
+        return Status::InvalidArgument("jsonb_value is not an object");
+    }
+    const auto* jsonb_object = jsonb_value->unpack<ObjectVal>();
+
+    if (jsonb_object->numElem() != elem_names.size()) {
+        return Status::InvalidArgument("jsonb_value field size {} is not equal 
to struct size {}",
+                                       jsonb_object->numElem(), 
struct_column.tuple_size());
+    }
+
+    for (const auto& field_name : elem_names) {
+        if (!jsonb_object->find(field_name.data(), (int)field_name.size())) {

Review Comment:
   struct 的field 不区分大小写,这里也应该不区分



##########
fe/fe-common/src/main/java/org/apache/doris/catalog/Type.java:
##########
@@ -861,6 +861,9 @@ public static boolean canCastTo(Type sourceType, Type 
targetType) {
         if (targetType.isJsonbType() && sourceType.isComplexType()) {
             return true;
         }
+        if (sourceType.isJsonbType()) {

Review Comment:
   限制下 targetType,jsonb 不能转任意类型



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to