Skip to content

Commit d7aaafb

Browse files
fix(json): handle text-based JSON in json() blob arguments
1 parent 3b6d408 commit d7aaafb

File tree

3 files changed

+87
-14
lines changed

3 files changed

+87
-14
lines changed

core/json/mod.rs

Lines changed: 58 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,15 @@ pub fn get_json(json_value: &Value, indent: Option<&str>) -> crate::Result<Value
4949

5050
Ok(Value::Text(Text::json(json)))
5151
}
52-
Value::Blob(b) => {
53-
let jsonbin = Jsonb::new(b.len(), Some(b));
54-
jsonbin.element_type()?;
55-
Ok(Value::Text(Text::json(jsonbin.to_string())))
52+
Value::Blob(_) => {
53+
// Blobs can contain either text JSON or binary JSONB
54+
// Use convert_dbtype_to_jsonb to properly detect and parse both formats
55+
let json_val = convert_dbtype_to_jsonb(json_value, Conv::Strict)?;
56+
let json = match indent {
57+
Some(indent) => json_val.to_string_pretty(Some(indent))?,
58+
None => json_val.to_string(),
59+
};
60+
Ok(Value::Text(Text::json(json)))
5661
}
5762
Value::Null => Ok(Value::Null),
5863
_ => {
@@ -921,6 +926,54 @@ mod tests {
921926
}
922927
}
923928

929+
#[test]
930+
fn test_get_json_blob_text_json() {
931+
let true_blob = Value::Blob(b"true".to_vec());
932+
let result = get_json(&true_blob, None).unwrap();
933+
if let Value::Text(result_str) = result {
934+
assert_eq!(result_str.as_str(), "true");
935+
assert_eq!(result_str.subtype, TextSubtype::Json);
936+
} else {
937+
panic!("Expected Value::Text, got: {:?}", result);
938+
}
939+
940+
let false_blob = Value::Blob(b"false".to_vec());
941+
let result = get_json(&false_blob, None).unwrap();
942+
if let Value::Text(result_str) = result {
943+
assert_eq!(result_str.as_str(), "false");
944+
assert_eq!(result_str.subtype, TextSubtype::Json);
945+
} else {
946+
panic!("Expected Value::Text, got: {:?}", result);
947+
}
948+
949+
let null_blob = Value::Blob(b"null".to_vec());
950+
let result = get_json(&null_blob, None).unwrap();
951+
if let Value::Text(result_str) = result {
952+
assert_eq!(result_str.as_str(), "null");
953+
assert_eq!(result_str.subtype, TextSubtype::Json);
954+
} else {
955+
panic!("Expected Value::Text, got: {:?}", result);
956+
}
957+
958+
let number_blob = Value::Blob(b"123".to_vec());
959+
let result = get_json(&number_blob, None).unwrap();
960+
if let Value::Text(result_str) = result {
961+
assert_eq!(result_str.as_str(), "123");
962+
assert_eq!(result_str.subtype, TextSubtype::Json);
963+
} else {
964+
panic!("Expected Value::Text, got: {:?}", result);
965+
}
966+
967+
let string_blob = Value::Blob(b"\"hello\"".to_vec());
968+
let result = get_json(&string_blob, None).unwrap();
969+
if let Value::Text(result_str) = result {
970+
assert_eq!(result_str.as_str(), "\"hello\"");
971+
assert_eq!(result_str.subtype, TextSubtype::Json);
972+
} else {
973+
panic!("Expected Value::Text, got: {:?}", result);
974+
}
975+
}
976+
924977
#[test]
925978
fn test_get_json_non_text() {
926979
let input = Value::Null;
@@ -994,11 +1047,7 @@ mod tests {
9941047
let json_cache = JsonCacheCell::new();
9951048
let blob = Value::Blob("test".as_bytes().to_vec());
9961049
let result = json_set(
997-
&[
998-
Value::build_text("{}"),
999-
Value::build_text("$.field"),
1000-
blob,
1001-
],
1050+
&[Value::build_text("{}"), Value::build_text("$.field"), blob],
10021051
&json_cache,
10031052
);
10041053

core/json/ops.rs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -482,11 +482,7 @@ mod tests {
482482
fn test_json_insert_blob_invalid() {
483483
let json_cache = JsonCacheCell::new();
484484
let blob = Value::Blob("test".as_bytes().to_vec());
485-
let args = [
486-
create_json("{}"),
487-
create_text("$.field"),
488-
blob,
489-
];
485+
let args = [create_json("{}"), create_text("$.field"), blob];
490486

491487
let result = json_insert(&args, &json_cache);
492488

testing/json.test

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,34 @@ do_execsql_test json5-multi-comment-pretty {
148148
"aaa": 123
149149
}}}
150150

151+
do_execsql_test json-blob-text-true {
152+
SELECT json(x'74727565');
153+
} {true}
154+
155+
do_execsql_test json-blob-text-false {
156+
SELECT json(x'66616c7365');
157+
} {false}
158+
159+
do_execsql_test json-blob-text-null {
160+
SELECT json(x'6e756c6c');
161+
} {null}
162+
163+
do_execsql_test json-blob-text-number {
164+
SELECT json(x'313233');
165+
} {123}
166+
167+
do_execsql_test json-blob-text-string {
168+
SELECT json(x'2268656c6c6f22');
169+
} {{"hello"}}
170+
171+
do_execsql_test json-blob-text-array {
172+
SELECT json(x'5b312c322c335d');
173+
} {{[1,2,3]}}
174+
175+
do_execsql_test json-blob-text-object {
176+
SELECT json(x'7b226b6579223a2276616c7565227d');
177+
} {{{"key":"value"}}}
178+
151179
do_execsql_test json-pretty-ident-1 {
152180
SELECT json_pretty('{x: 1}', '');
153181
} {{{

0 commit comments

Comments
 (0)