Skip to content

Commit cf092db

Browse files
committed
refactor(query): use jsonb_schema for JSONPath execution
1 parent 4f0b63a commit cf092db

File tree

3 files changed

+36
-79
lines changed

3 files changed

+36
-79
lines changed

Cargo.lock

Lines changed: 0 additions & 63 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ serde_json = "1.0"
1111
uuid = { version = "1.8.0", features = ["v7", "serde"] }
1212
chrono = { version = "0.4.43", features = ["serde"] }
1313
jsonb_schema = { git = "https://github.com/dataunitylab/jsonb", branch = "jsonb-schema" }
14-
jsonpath-rust = "1.0"
1514
tokio = { version = "1.49.0", features = ["full"] }
1615
async-trait = "0.1.89"
1716
futures = "0.3.31"

src/query.rs

Lines changed: 36 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
use crate::db::DB;
2-
use crate::{Value, jsonb_to_serde, serde_to_jsonb};
2+
use crate::{SerdeWrapper, Value, make_static};
33
use jsonb_schema::Number;
4-
use jsonpath_rust::query::js_path_vals;
54
use std::cmp::Ordering;
65
use std::collections::BTreeMap;
76
use tracing::{Level, span};
@@ -256,20 +255,41 @@ impl<'a> Iterator for OffsetOperator<'a> {
256255
fn evaluate_expression(expr: &Expression, doc: &Value) -> Value {
257256
match expr {
258257
Expression::FieldReference(path) => get_path(doc, path).unwrap_or(Value::Null),
259-
Expression::JsonPath(path) => {
260-
let serde_val = jsonb_to_serde(doc);
261-
if let Ok(nodes) = js_path_vals(path, &serde_val) {
262-
if nodes.is_empty() {
263-
Value::Null
264-
} else if nodes.len() == 1 {
265-
serde_to_jsonb(nodes[0].clone())
258+
Expression::JsonPath(path_str) => {
259+
let wrapper = SerdeWrapper(doc);
260+
if let Ok(blob) = jsonb_schema::to_owned_jsonb(&wrapper) {
261+
// Parse path
262+
if let Ok(json_path) = jsonb_schema::jsonpath::parse_json_path(path_str.as_bytes())
263+
{
264+
// Execute select_by_path on RawJsonb
265+
if let Ok(results) = blob.as_raw().select_by_path(&json_path) {
266+
if results.is_empty() {
267+
Value::Null
268+
} else if results.len() == 1 {
269+
// Extract single value
270+
let owned = results.into_iter().next().unwrap();
271+
let vec = owned.to_vec();
272+
if let Ok(val) = jsonb_schema::from_slice(&vec) {
273+
make_static(&val)
274+
} else {
275+
Value::Null
276+
}
277+
} else {
278+
// Array of values
279+
let mut arr = Vec::new();
280+
for owned in results {
281+
let vec = owned.to_vec();
282+
if let Ok(val) = jsonb_schema::from_slice(&vec) {
283+
arr.push(make_static(&val));
284+
}
285+
}
286+
Value::Array(arr)
287+
}
288+
} else {
289+
Value::Null
290+
}
266291
} else {
267-
Value::Array(
268-
nodes
269-
.into_iter()
270-
.map(|n| serde_to_jsonb(n.clone()))
271-
.collect(),
272-
)
292+
Value::Null
273293
}
274294
} else {
275295
Value::Null
@@ -517,6 +537,7 @@ pub fn execute_plan<'a>(
517537
#[cfg(test)]
518538
mod tests {
519539
use super::*;
540+
use crate::serde_to_jsonb;
520541
use jsonb_schema::Value as JsonbValue;
521542
use serde_json::json;
522543

0 commit comments

Comments
 (0)