Skip to content

Commit 6ce4474

Browse files
committed
fix: ensure variables passed to subgraph requests
1 parent 7f11828 commit 6ce4474

File tree

1 file changed

+84
-2
lines changed

1 file changed

+84
-2
lines changed

lib/executor/src/execution/plan.rs

Lines changed: 84 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use std::collections::HashMap;
1+
use std::collections::{BTreeSet, HashMap};
22

33
use bytes::{BufMut, Bytes};
44
use futures::{future::BoxFuture, stream::FuturesUnordered, StreamExt};
@@ -522,6 +522,9 @@ impl<'exec> Executor<'exec> {
522522
node: &FetchNode,
523523
representations: Option<Vec<u8>>,
524524
) -> Result<ExecutionJob, PlanExecutionError> {
525+
let variable_refs =
526+
select_fetch_variables(self.variable_values, node.variable_usages.as_ref());
527+
525528
Ok(ExecutionJob::Fetch(FetchJob {
526529
fetch_node_id: node.id,
527530
response: self
@@ -532,7 +535,7 @@ impl<'exec> Executor<'exec> {
532535
query: node.operation.document_str.as_str(),
533536
dedupe: self.dedupe_subgraph_requests,
534537
operation_name: node.operation_name.as_deref(),
535-
variables: None,
538+
variables: variable_refs,
536539
representations,
537540
},
538541
)
@@ -555,3 +558,82 @@ fn condition_node_by_variables<'a>(
555558
condition_node.else_clause.as_deref()
556559
}
557560
}
561+
562+
fn select_fetch_variables<'a>(
563+
variable_values: &'a Option<HashMap<String, sonic_rs::Value>>,
564+
variable_usages: Option<&BTreeSet<String>>,
565+
) -> Option<HashMap<&'a str, &'a sonic_rs::Value>> {
566+
let values = variable_values.as_ref()?;
567+
568+
match variable_usages {
569+
Some(variable_usages) => Some(
570+
variable_usages
571+
.iter()
572+
.filter_map(|var_name| {
573+
values
574+
.get_key_value(var_name.as_str())
575+
.map(|(key, value)| (key.as_str(), value))
576+
})
577+
.collect(),
578+
),
579+
None => None,
580+
}
581+
}
582+
583+
#[cfg(test)]
584+
mod tests {
585+
use super::select_fetch_variables;
586+
use sonic_rs::Value;
587+
use std::collections::{BTreeSet, HashMap};
588+
589+
fn value_from_number(n: i32) -> Value {
590+
sonic_rs::from_str(&n.to_string()).unwrap()
591+
}
592+
593+
#[test]
594+
fn select_fetch_variables_only_used_variables() {
595+
let mut variable_values_map = HashMap::new();
596+
variable_values_map.insert("used".to_string(), value_from_number(1));
597+
variable_values_map.insert("unused".to_string(), value_from_number(2));
598+
let variable_values = Some(variable_values_map);
599+
600+
let mut usages = BTreeSet::new();
601+
usages.insert("used".to_string());
602+
603+
let selected = select_fetch_variables(&variable_values, Some(&usages)).unwrap();
604+
605+
assert_eq!(selected.len(), 1);
606+
assert!(selected.contains_key("used"));
607+
assert!(!selected.contains_key("unused"));
608+
}
609+
610+
#[test]
611+
fn select_fetch_variables_ignores_missing_usage_entries() {
612+
let mut variable_values_map = HashMap::new();
613+
variable_values_map.insert("present".to_string(), value_from_number(3));
614+
let variable_values = Some(variable_values_map);
615+
616+
let mut usages = BTreeSet::new();
617+
usages.insert("present".to_string());
618+
usages.insert("missing".to_string());
619+
620+
let selected = select_fetch_variables(&variable_values, Some(&usages)).unwrap();
621+
622+
assert_eq!(selected.len(), 1);
623+
assert!(selected.contains_key("present"));
624+
assert!(!selected.contains_key("missing"));
625+
}
626+
627+
#[test]
628+
fn select_fetch_variables_for_no_usage_entries() {
629+
let mut variable_values_map = HashMap::new();
630+
variable_values_map.insert("unused_1".to_string(), value_from_number(1));
631+
variable_values_map.insert("unused_2".to_string(), value_from_number(2));
632+
633+
let variable_values = Some(variable_values_map);
634+
635+
let selected = select_fetch_variables(&variable_values, None);
636+
637+
assert!(selected.is_none());
638+
}
639+
}

0 commit comments

Comments
 (0)