Skip to content

Commit a80ac83

Browse files
committed
graphql: Refactor handling of multiple block constraints
1 parent da55e55 commit a80ac83

File tree

2 files changed

+25
-24
lines changed

2 files changed

+25
-24
lines changed

graphql/src/runner.rs

Lines changed: 18 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -137,36 +137,32 @@ where
137137
},
138138
)
139139
};
140-
let by_block_constraint = query.block_constraint()?;
141-
142-
// We want to optimize for the common case of a single block constraint,
143-
// where we can avoid cloning the result.
144-
match by_block_constraint.len() {
145-
0 => Ok(Arc::new(QueryResult::empty())),
146-
1 => {
147-
let (bc, selection_set) = by_block_constraint.into_iter().next().unwrap();
140+
141+
// Unwrap: There is always at least one block constraint, even if it
142+
// is an implicit 'BlockContraint::Latest'.
143+
let mut by_block_constraint = query.block_constraint()?.into_iter();
144+
let (bc, selection_set) = by_block_constraint.next().unwrap();
145+
let (resolver, block_ptr) =
146+
StoreResolver::at_block(&self.logger, self.store.clone(), bc, &query.schema.id)?;
147+
let mut result = execute(selection_set, block_ptr, resolver);
148+
149+
// We want to optimize for the common case of a single block constraint, where we can avoid
150+
// cloning the result. If there are multiple constraints we have to clone.
151+
if by_block_constraint.len() > 0 {
152+
let mut partial_res = result.as_ref().clone();
153+
for (bc, selection_set) in by_block_constraint {
148154
let (resolver, block_ptr) = StoreResolver::at_block(
149155
&self.logger,
150156
self.store.clone(),
151157
bc,
152158
&query.schema.id,
153159
)?;
154-
Ok(execute(selection_set, block_ptr, resolver))
155-
}
156-
_ => {
157-
let mut result = QueryResult::empty();
158-
for (bc, selection_set) in query.block_constraint()? {
159-
let (resolver, block_ptr) = StoreResolver::at_block(
160-
&self.logger,
161-
self.store.clone(),
162-
bc,
163-
&query.schema.id,
164-
)?;
165-
result.append(execute(selection_set, block_ptr, resolver).as_ref().clone());
166-
}
167-
Ok(Arc::new(result))
160+
partial_res.append(execute(selection_set, block_ptr, resolver).as_ref().clone());
168161
}
162+
result = Arc::new(partial_res);
169163
}
164+
165+
Ok(result)
170166
}
171167
}
172168

tests/integration-tests/value-roundtrip/test/test.js

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,13 +76,18 @@ contract("Contract", (accounts) => {
7676
await waitForSubgraphToBeSynced();
7777
});
7878

79-
it("all overloads of the contract function are called", async () => {
79+
it("test query", async () => {
80+
// Also test that multiple block constraints do not result in a graphql error.
8081
let result = await fetchSubgraph({
81-
query: `{ foos(orderBy: id) { id value } }`,
82+
query: `{
83+
foos_0: foos(orderBy: id, block: { number: 0 }) { id }
84+
foos(orderBy: id) { id value }
85+
}`,
8286
});
8387

8488
expect(result.errors).to.be.undefined;
8589
expect(result.data).to.deep.equal({
90+
foos_0: [],
8691
foos: [
8792
{
8893
id: "0",

0 commit comments

Comments
 (0)