Skip to content

Commit ba6ff53

Browse files
committed
added a new validation phase
fixes update to latest run validations as soon as possible use specified rules instead of default set cleanup fix fmt added more rules move validation check to Query struct Added Leaf-Field-Selections rule fixes fixes Added an option to disable graphql validations: `DISABLE_GRAPHQL_VALIDATIONS` fixes use more rules! fixes fix cleanup trigger ci
1 parent 01a811e commit ba6ff53

File tree

7 files changed

+85
-11
lines changed

7 files changed

+85
-11
lines changed

Cargo.lock

+14-4
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

core/tests/interfaces.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -1424,7 +1424,7 @@ async fn recursive_fragment() {
14241424
.await
14251425
.unwrap();
14261426
let data = res.to_result().unwrap_err()[0].to_string();
1427-
assert_eq!(data, "query has fragment cycle including `FooFrag`");
1427+
assert_eq!(data, "Cannot spread fragment \"FooFrag\" within itself.");
14281428

14291429
let co_recursive = "
14301430
query {
@@ -1451,5 +1451,8 @@ async fn recursive_fragment() {
14511451
.await
14521452
.unwrap();
14531453
let data = res.to_result().unwrap_err()[0].to_string();
1454-
assert_eq!(data, "query has fragment cycle including `BarFrag`");
1454+
assert_eq!(
1455+
data,
1456+
"Cannot spread fragment \"BarFrag\" within itself via \"FooFrag\"."
1457+
);
14551458
}

graph/src/data/query/error.rs

+5
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ pub enum QueryExecutionError {
4141
AbstractTypeError(String),
4242
InvalidArgumentError(Pos, String, q::Value),
4343
MissingArgumentError(Pos, String),
44+
ValidationError(Option<Pos>, String),
4445
InvalidVariableTypeError(Pos, String),
4546
MissingVariableError(Pos, String),
4647
ResolveEntitiesError(String),
@@ -137,6 +138,7 @@ impl QueryExecutionError {
137138
| DeploymentReverted
138139
| SubgraphManifestResolveError(_)
139140
| InvalidSubgraphManifest
141+
| ValidationError(_, _)
140142
| ResultTooBig(_, _) => false,
141143
}
142144
}
@@ -161,6 +163,9 @@ impl fmt::Display for QueryExecutionError {
161163
OperationNotFound(s) => {
162164
write!(f, "Operation name not found `{}`", s)
163165
}
166+
ValidationError(_pos, message) => {
167+
write!(f, "{}", message)
168+
}
164169
NotSupported(s) => write!(f, "Not supported: {}", s),
165170
NoRootSubscriptionObjectType => {
166171
write!(f, "No root Subscription type defined in the schema")

graphql/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ crossbeam = "0.8"
88
futures01 = { package="futures", version="0.1.29" }
99
graph = { path = "../graph" }
1010
graphql-parser = "0.4.0"
11+
graphql-tools = "0.0.13"
1112
indexmap = "1.7"
1213
Inflector = "0.11.3"
1314
lazy_static = "1.2.0"

graphql/src/execution/query.rs

+58-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
use graphql_parser::Pos;
2+
use graphql_tools::validation::rules::*;
3+
use graphql_tools::validation::validate::{validate, ValidationPlan};
4+
use lazy_static::lazy_static;
25
use std::collections::{HashMap, HashSet};
36
use std::hash::{Hash, Hasher};
47
use std::sync::Arc;
@@ -9,11 +12,10 @@ use graph::data::graphql::{
912
ext::{DocumentExt, TypeExt},
1013
ObjectOrInterface,
1114
};
15+
use graph::data::query::QueryExecutionError;
1216
use graph::data::query::{Query as GraphDataQuery, QueryVariables};
1317
use graph::data::schema::ApiSchema;
14-
use graph::prelude::{
15-
info, o, q, r, s, BlockNumber, CheapClone, Logger, QueryExecutionError, TryFromValue,
16-
};
18+
use graph::prelude::{info, o, q, r, s, BlockNumber, CheapClone, Logger, TryFromValue};
1719

1820
use crate::introspection::introspection_schema;
1921
use crate::query::{ast as qast, ext::BlockConstraint};
@@ -23,6 +25,41 @@ use crate::{
2325
schema::api::ErrorPolicy,
2426
};
2527

28+
lazy_static! {
29+
static ref GRAPHQL_VALIDATION_PLAN: ValidationPlan = ValidationPlan::from(
30+
if std::env::var("DISABLE_GRAPHQL_VALIDATIONS")
31+
.unwrap_or_else(|_| "false".into())
32+
.parse::<bool>()
33+
.unwrap_or_else(|_| false)
34+
{
35+
vec![]
36+
} else {
37+
vec![
38+
Box::new(UniqueOperationNames {}),
39+
Box::new(LoneAnonymousOperation {}),
40+
Box::new(SingleFieldSubscriptions {}),
41+
Box::new(KnownTypeNames {}),
42+
Box::new(FragmentsOnCompositeTypes {}),
43+
Box::new(VariablesAreInputTypes {}),
44+
Box::new(LeafFieldSelections {}),
45+
Box::new(FieldsOnCorrectType {}),
46+
Box::new(UniqueFragmentNames {}),
47+
Box::new(KnownFragmentNames {}),
48+
Box::new(NoUnusedFragments {}),
49+
Box::new(OverlappingFieldsCanBeMerged {}),
50+
Box::new(NoFragmentsCycle {}),
51+
Box::new(PossibleFragmentSpreads {}),
52+
Box::new(NoUnusedVariables {}),
53+
Box::new(NoUndefinedVariables {}),
54+
Box::new(KnownArgumentNames {}),
55+
Box::new(UniqueArgumentNames {}),
56+
Box::new(UniqueVariableNames {}),
57+
Box::new(ProvidedRequiredArguments {}),
58+
]
59+
}
60+
);
61+
}
62+
2663
#[derive(Clone, Debug)]
2764
pub enum ComplexityError {
2865
TooDeep,
@@ -115,6 +152,24 @@ impl Query {
115152
max_complexity: Option<u64>,
116153
max_depth: u8,
117154
) -> Result<Arc<Self>, Vec<QueryExecutionError>> {
155+
let validation_errors = validate(
156+
&schema.document(),
157+
&query.document,
158+
&GRAPHQL_VALIDATION_PLAN,
159+
);
160+
161+
if validation_errors.len() > 0 {
162+
return Err(validation_errors
163+
.into_iter()
164+
.map(|e| {
165+
QueryExecutionError::ValidationError(
166+
e.locations.clone().into_iter().nth(0),
167+
e.message,
168+
)
169+
})
170+
.collect());
171+
}
172+
118173
let mut operation = None;
119174
let mut fragments = HashMap::new();
120175
for defn in query.document.definitions.into_iter() {

server/index-node/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,4 @@ graphql-parser = "0.4.0"
1313
http = "0.2"
1414
hyper = "0.14"
1515
serde = "1.0"
16-
either = "1.6.1"
16+
either = "1.6.1"

store/test-store/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,4 @@ graph-store-postgres = { path = "../postgres" }
1515
lazy_static = "1.1"
1616
hex-literal = "0.3"
1717
diesel = { version = "1.4.8", features = ["postgres", "serde_json", "numeric", "r2d2"] }
18-
graph-chain-ethereum = { path = "../../chain/ethereum" }
18+
graph-chain-ethereum = { path = "../../chain/ethereum" }

0 commit comments

Comments
 (0)