Skip to content

Commit cc61383

Browse files
committed
graphql: Keep original field order when grouping by block constraint
1 parent dbd0054 commit cc61383

File tree

2 files changed

+22
-16
lines changed

2 files changed

+22
-16
lines changed

graphql/src/execution/query.rs

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -194,18 +194,21 @@ impl Query {
194194
Ok(Arc::new(query))
195195
}
196196

197-
/// Return the block constraint for the toplevel query field(s), merging the selection sets of
198-
/// fields that have the same block constraint.
197+
/// Return the block constraint for the toplevel query field(s), merging
198+
/// consecutive fields that have the same block constraint, while making
199+
/// sure that the fields appear in the same order as they did in the
200+
/// query
199201
///
200-
/// Also returns the combined error policy for those fields, which is `Deny` if any field is
201-
/// `Deny` and `Allow` otherwise.
202+
/// Also returns the combined error policy for those fields, which is
203+
/// `Deny` if any field is `Deny` and `Allow` otherwise.
202204
pub fn block_constraint(
203205
&self,
204-
) -> Result<HashMap<BlockConstraint, (a::SelectionSet, ErrorPolicy)>, Vec<QueryExecutionError>>
206+
) -> Result<Vec<(BlockConstraint, (a::SelectionSet, ErrorPolicy))>, Vec<QueryExecutionError>>
205207
{
206-
let mut bcs = HashMap::new();
208+
let mut bcs: Vec<(BlockConstraint, (a::SelectionSet, ErrorPolicy))> = Vec::new();
207209

208210
let root_type = self.schema.query_type.as_ref();
211+
let mut prev_bc: Option<BlockConstraint> = None;
209212
for field in self.selection_set.fields_for(root_type) {
210213
let bc = match field.argument_value("block") {
211214
Some(bc) => BlockConstraint::try_from_value(bc).map_err(|_| {
@@ -229,16 +232,19 @@ impl Query {
229232
None => ErrorPolicy::Deny,
230233
};
231234

232-
let (selection_set, error_policy) = bcs.entry(bc).or_insert_with(|| {
233-
(
234-
a::SelectionSet::empty_from(&self.selection_set),
235-
field_error_policy,
236-
)
237-
});
238-
selection_set.push(field);
239-
if field_error_policy == ErrorPolicy::Deny {
240-
*error_policy = ErrorPolicy::Deny;
235+
let next_bc = Some(bc.clone());
236+
if prev_bc == next_bc {
237+
let (selection_set, error_policy) = &mut bcs.last_mut().unwrap().1;
238+
selection_set.push(field);
239+
if field_error_policy == ErrorPolicy::Deny {
240+
*error_policy = ErrorPolicy::Deny;
241+
}
242+
} else {
243+
let mut selection_set = a::SelectionSet::empty_from(&self.selection_set);
244+
selection_set.push(field);
245+
bcs.push((bc, (selection_set, field_error_policy)))
241246
}
247+
prev_bc = next_bc;
242248
}
243249
Ok(bcs)
244250
}

graphql/src/query/ext.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ impl ValueExt for q::Value {
5454
}
5555
}
5656

57-
#[derive(PartialEq, Eq, Hash, Debug)]
57+
#[derive(Clone, PartialEq, Eq, Hash, Debug)]
5858
pub enum BlockConstraint {
5959
Hash(H256),
6060
Number(BlockNumber),

0 commit comments

Comments
 (0)