This is an automated email from the ASF dual-hosted git repository.
eldenmoon pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/master by this push:
new d63f8db8648 [fix](json) Replace invalid JSONB with default JSONB null
value (#59007)
d63f8db8648 is described below
commit d63f8db86486c9c34cbf14fb725dd10b4709107f
Author: Sun Chenyang <[email protected]>
AuthorDate: Mon Dec 15 09:59:38 2025 +0800
[fix](json) Replace invalid JSONB with default JSONB null value (#59007)
This PR fixes the issue that was supposed to be resolved by
https://github.com/apache/doris/pull/58656
. We need to address it as soon as possible, so I am submitting this PR.
---
be/src/util/jsonb_document.cpp | 38 +++++++++++++++++++++++++++++++
be/src/util/jsonb_document.h | 25 --------------------
be/test/vec/jsonb/jsonb_document_test.cpp | 15 ++++++++++++
3 files changed, 53 insertions(+), 25 deletions(-)
diff --git a/be/src/util/jsonb_document.cpp b/be/src/util/jsonb_document.cpp
index 2cebd3f2221..55b12e0e9e6 100644
--- a/be/src/util/jsonb_document.cpp
+++ b/be/src/util/jsonb_document.cpp
@@ -18,12 +18,50 @@
#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,
+ const JsonbDocument** doc) {
+ *doc = nullptr;
+ if (!pb || size == 0) {
+ static const 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<const 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);
+ }
+
+ const auto* doc_ptr = (const JsonbDocument*)pb;
+ if (doc_ptr->header_.ver_ != JSONB_VER) {
+ return Status::InvalidArgument("Invalid JSONB document: invalid
version({})",
+ doc_ptr->header_.ver_);
+ }
+
+ const auto* val = (const 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();
+}
+
JsonbFindResult JsonbValue::findValue(JsonbPath& path) const {
JsonbFindResult result;
bool is_wildcard = false;
diff --git a/be/src/util/jsonb_document.h b/be/src/util/jsonb_document.h
index 9e3bdaed796..0220794a483 100644
--- a/be/src/util/jsonb_document.h
+++ b/be/src/util/jsonb_document.h
@@ -1003,31 +1003,6 @@ struct ArrayVal : public ContainerVal {
const_iterator end() const { return const_iterator((pointer)(payload +
size)); }
};
-inline Status JsonbDocument::checkAndCreateDocument(const char* pb, size_t
size,
- const JsonbDocument** doc)
{
- *doc = nullptr;
- if (!pb || size < sizeof(JsonbHeader) + sizeof(JsonbValue)) {
- return Status::InvalidArgument("Invalid JSONB document: too small
size({}) or null pointer",
- size);
- }
-
- const auto* doc_ptr = (const JsonbDocument*)pb;
- if (doc_ptr->header_.ver_ != JSONB_VER) {
- return Status::InvalidArgument("Invalid JSONB document: invalid
version({})",
- doc_ptr->header_.ver_);
- }
-
- const auto* val = (const 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 const JsonbValue* JsonbDocument::createValue(const char* pb, size_t
size) {
if (!pb || size < sizeof(JsonbHeader) + sizeof(JsonbValue)) {
return nullptr;
diff --git a/be/test/vec/jsonb/jsonb_document_test.cpp
b/be/test/vec/jsonb/jsonb_document_test.cpp
index 56d0f5fa960..e8bd380c883 100644
--- a/be/test/vec/jsonb/jsonb_document_test.cpp
+++ b/be/test/vec/jsonb/jsonb_document_test.cpp
@@ -279,4 +279,19 @@ TEST_F(JsonbDocumentTest, forobject) {
}
}
+TEST_F(JsonbDocumentTest, invaild_jsonb_document) {
+ const 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]