Implemented JSON valid function

This commit is contained in:
Harin
2025-01-26 23:35:47 +05:30
parent 359576d910
commit 0903b9b019
6 changed files with 66 additions and 4 deletions

View File

@@ -375,7 +375,7 @@ Modifiers:
| jsonb_set(json,path,value,...) | | |
| json_type(json) | Yes | |
| json_type(json,path) | Yes | |
| json_valid(json) | | |
| json_valid(json) | Yes | |
| json_valid(json,flags) | | |
| json_quote(value) | | |
| json_group_array(value) | | |

View File

@@ -79,6 +79,7 @@ pub enum JsonFunc {
JsonObject,
JsonType,
JsonErrorPosition,
JsonValid,
}
#[cfg(feature = "json")]
@@ -97,6 +98,7 @@ impl Display for JsonFunc {
Self::JsonObject => "json_object".to_string(),
Self::JsonType => "json_type".to_string(),
Self::JsonErrorPosition => "json_error_position".to_string(),
Self::JsonValid => "json_valid".to_string(),
}
)
}
@@ -519,6 +521,8 @@ impl Func {
"json_type" => Ok(Func::Json(JsonFunc::JsonType)),
#[cfg(feature = "json")]
"json_error_position" => Ok(Self::Json(JsonFunc::JsonErrorPosition)),
#[cfg(feature = "json")]
"json_valid" => Ok(Self::Json(JsonFunc::JsonValid)),
"unixepoch" => Ok(Self::Scalar(ScalarFunc::UnixEpoch)),
"julianday" => Ok(Self::Scalar(ScalarFunc::JulianDay)),
"hex" => Ok(Self::Scalar(ScalarFunc::Hex)),

View File

@@ -984,3 +984,17 @@ mod tests {
}
}
}
pub fn is_json_valid(json_value: &OwnedValue) -> crate::Result<OwnedValue> {
match json_value {
OwnedValue::Text(ref t) => match from_str::<Val>(&t.value) {
Ok(_) => Ok(OwnedValue::Integer(1)),
Err(_) => Ok(OwnedValue::Integer(0)),
},
OwnedValue::Blob(b) => match jsonb::from_slice(b) {
Ok(_) => Ok(OwnedValue::Integer(1)),
Err(_) => Ok(OwnedValue::Integer(0)),
},
OwnedValue::Null => Ok(OwnedValue::Null),
_ => Ok(OwnedValue::Integer(1)),
}
}

View File

@@ -929,6 +929,14 @@ pub fn translate_expr(
func_ctx,
)
}
JsonFunc::JsonValid => translate_function(
program,
args.as_deref().unwrap_or_default(),
referenced_tables,
resolver,
target_register,
func_ctx,
),
},
Func::Scalar(srf) => {
match srf {

View File

@@ -40,9 +40,9 @@ use crate::vdbe::builder::CursorType;
use crate::vdbe::insn::Insn;
#[cfg(feature = "json")]
use crate::{
function::JsonFunc, json::get_json, json::json_array, json::json_array_length,
json::json_arrow_extract, json::json_arrow_shift_extract, json::json_error_position,
json::json_extract, json::json_object, json::json_type,
function::JsonFunc, json::get_json, json::is_json_valid, json::json_array,
json::json_array_length, json::json_arrow_extract, json::json_arrow_shift_extract,
json::json_error_position, json::json_extract, json::json_object, json::json_type,
};
use crate::{resolve_ext_path, Connection, Result, TransactionState, DATABASE_VERSION};
use datetime::{
@@ -1743,6 +1743,10 @@ impl Program {
Err(e) => return Err(e),
}
}
JsonFunc::JsonValid => {
let json_value = &state.registers[*start_reg];
state.registers[*dest] = is_json_valid(json_value)?;
}
},
crate::function::Func::Scalar(scalar_func) => match scalar_func {
ScalarFunc::Cast => {

View File

@@ -544,3 +544,35 @@ do_execsql_test json_from_json_object {
#do_execsql_test json_object_duplicated_keys {
# SELECT json_object('key', 'value', 'key', 'value2');
#} {{{"key":"value2"}}}
#
do_execsql_test json_valid_1 {
SELECT json_valid('{"a":55,"b":72}');
} {1}
do_execsql_test json_valid_2 {
SELECT json_valid('["a",55,"b",72]');
} {1}
do_execsql_test json_valid_3 {
SELECT json_valid( CAST('{"a":1}' AS BLOB) );
} {1}
do_execsql_test json_valid_4 {
SELECT json_valid(123);
} {1}
do_execsql_test json_valid_5 {
SELECT json_valid(12.3);
} {1}
do_execsql_test json_valid_6 {
SELECT json_valid('not a valid json');
} {0}
do_execsql_test json_valid_7 {
SELECT json_valid('{"a":"55,"b":72}');
} {0}
do_execsql_test json_valid_8 {
SELECT json_valid('{"a":55 "b":72}');
} {0}
do_execsql_test json_valid_3 {
SELECT json_valid( CAST('{"a":"1}' AS BLOB) );
} {0}
do_execsql_test json_valid_9 {
SELECT json_valid(NULL);
} {}