This is an automated email from the ASF dual-hosted git repository.

morrysnow pushed a commit to branch branch-3.1
in repository https://gitbox.apache.org/repos/asf/doris.git


The following commit(s) were added to refs/heads/branch-3.1 by this push:
     new 1922fabc749 branch-3.1: [fix](json) Replace invalid JSONB with default 
JSONB null value #59007 (#59067)
1922fabc749 is described below

commit 1922fabc749c5d2daf05c7fb4806ff7e46fc5d25
Author: Sun Chenyang <[email protected]>
AuthorDate: Wed Dec 17 17:14:12 2025 +0800

    branch-3.1: [fix](json) Replace invalid JSONB with default JSONB null value 
#59007 (#59067)
    
    pick from master #59007
---
 be/src/util/jsonb_document.cpp            | 64 +++++++++++++++++++++++++++++++
 be/src/util/jsonb_document.h              | 24 ------------
 be/test/vec/jsonb/jsonb_document_test.cpp | 54 ++++++++++++++++++++++++++
 3 files changed, 118 insertions(+), 24 deletions(-)

diff --git a/be/src/util/jsonb_document.cpp b/be/src/util/jsonb_document.cpp
new file mode 100644
index 00000000000..d6722791363
--- /dev/null
+++ b/be/src/util/jsonb_document.cpp
@@ -0,0 +1,64 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+#include "jsonb_document.h"
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "common/status.h"
+#include "util/jsonb_writer.h"
+
+namespace doris {
+
+Status JsonbDocument::checkAndCreateDocument(const char* pb, size_t size, 
JsonbDocument** doc) {
+    *doc = nullptr;
+    if (!pb || size == 0) {
+        static std::string buf = []() {
+            JsonbWriter writer;
+            (void)writer.writeNull();
+            auto* out = writer.getOutput();
+            return std::string(out->getBuffer(), out->getSize());
+        }();
+        // Treat empty input as a valid JSONB null document.
+        *doc = reinterpret_cast<JsonbDocument*>(buf.data());
+        return Status::OK();
+    }
+    if (!pb || size < sizeof(JsonbHeader) + sizeof(JsonbValue)) {
+        return Status::InvalidArgument("Invalid JSONB document: too small 
size({}) or null pointer",
+                                       size);
+    }
+
+    auto* doc_ptr = (JsonbDocument*)pb;
+    if (doc_ptr->header_.ver_ != JSONB_VER) {
+        return Status::InvalidArgument("Invalid JSONB document: invalid 
version({})",
+                                       doc_ptr->header_.ver_);
+    }
+
+    auto* val = (JsonbValue*)doc_ptr->payload_;
+    if (val->type() < JsonbType::T_Null || val->type() >= JsonbType::NUM_TYPES 
||
+        size != sizeof(JsonbHeader) + val->numPackedBytes()) {
+        return Status::InvalidArgument("Invalid JSONB document: invalid 
type({}) or size({})",
+                                       
static_cast<JsonbTypeUnder>(val->type()), size);
+    }
+
+    *doc = doc_ptr;
+    return Status::OK();
+}
+
+} // namespace doris
\ No newline at end of file
diff --git a/be/src/util/jsonb_document.h b/be/src/util/jsonb_document.h
index 6d269f6dd52..daf96bb215d 100644
--- a/be/src/util/jsonb_document.h
+++ b/be/src/util/jsonb_document.h
@@ -1100,30 +1100,6 @@ private:
     ArrayVal();
 };
 
-inline Status JsonbDocument::checkAndCreateDocument(const char* pb, size_t 
size,
-                                                    JsonbDocument** doc) {
-    *doc = nullptr;
-    if (!pb || size < sizeof(JsonbHeader) + sizeof(JsonbValue)) {
-        return Status::InvalidArgument("Invalid JSONB document: too small 
size({}) or null pointer",
-                                       size);
-    }
-
-    auto* doc_ptr = (JsonbDocument*)pb;
-    if (doc_ptr->header_.ver_ != JSONB_VER) {
-        return Status::InvalidArgument("Invalid JSONB document: invalid 
version({})",
-                                       doc_ptr->header_.ver_);
-    }
-
-    auto* val = (JsonbValue*)doc_ptr->payload_;
-    if (val->type() < JsonbType::T_Null || val->type() >= JsonbType::NUM_TYPES 
||
-        size != sizeof(JsonbHeader) + val->numPackedBytes()) {
-        return Status::InvalidArgument("Invalid JSONB document: invalid 
type({}) or size({})",
-                                       
static_cast<JsonbTypeUnder>(val->type()), size);
-    }
-
-    *doc = doc_ptr;
-    return Status::OK();
-}
 inline void JsonbDocument::setValue(const JsonbValue* value) {
     memcpy(payload_, value, value->numPackedBytes());
 }
diff --git a/be/test/vec/jsonb/jsonb_document_test.cpp 
b/be/test/vec/jsonb/jsonb_document_test.cpp
new file mode 100644
index 00000000000..0bfc9966f95
--- /dev/null
+++ b/be/test/vec/jsonb/jsonb_document_test.cpp
@@ -0,0 +1,54 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+#include "util/jsonb_document.h"
+
+#include <gtest/gtest.h>
+
+#include <cstdint>
+#include <limits>
+#include <string>
+#include <string_view>
+
+#include "util/jsonb_utils.h"
+#include "util/jsonb_writer.h"
+#include "vec/core/types.h"
+
+namespace doris {
+class JsonbDocumentTest : public testing::Test {
+protected:
+    void SetUp() override {}
+
+    void TearDown() override {}
+};
+
+TEST_F(JsonbDocumentTest, invaild_jsonb_document) {
+    JsonbDocument* doc = nullptr;
+    auto st = JsonbDocument::checkAndCreateDocument(nullptr, 0, &doc);
+    EXPECT_TRUE(st.ok());
+    EXPECT_TRUE(doc != nullptr);
+    EXPECT_TRUE(doc->getValue()->isNull());
+
+    JsonbToJson jsonb_to_json;
+    std::string json_null = jsonb_to_json.to_json_string(doc->getValue());
+    EXPECT_EQ(json_null, "null");
+
+    std::string json_string = JsonbToJson::jsonb_to_json_string(nullptr, 0);
+    EXPECT_EQ(json_null, json_string);
+}
+
+} // namespace doris
\ No newline at end of file


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

Reply via email to