diff --git a/src/resolve.rs b/src/resolve.rs index 1f0d8069..06e2c8c7 100644 --- a/src/resolve.rs +++ b/src/resolve.rs @@ -4,8 +4,8 @@ use crate::omit::*; use crate::parser_util::*; use crate::transpile::{MutationEntrypoint, QueryEntrypoint}; use graphql_parser::query::{ - Definition, Document, FragmentDefinition, Mutation, OperationDefinition, Query, Selection, - SelectionSet, Text, + Definition, Document, FragmentDefinition, Mutation, OperationDefinition, Query, SelectionSet, + Text, }; use itertools::Itertools; use serde_json::{json, Value}; @@ -138,15 +138,21 @@ where let query_type = schema_type.query_type(); let map = query_type.field_map(); - let selections: Vec> = selection_set - .items - .into_iter() - .filter_map(|def| match def { - Selection::Field(field) => Some(field), - // TODO, handle fragments - _ => panic!("only Selections are supported"), - }) - .collect(); + let selections = match normalize_selection_set( + &selection_set, + &fragment_definitions, + &query_type.name().unwrap(), + ) { + Ok(selections) => selections, + Err(err) => { + return GraphQLResponse { + data: Omit::Omitted, + errors: Omit::Present(vec![ErrorMessage { + message: err.to_string(), + }]), + } + } + }; match selections[..] { [] => GraphQLResponse { @@ -319,15 +325,21 @@ where let map = mutation_type.field_map(); - let selections: Vec> = selection_set - .items - .into_iter() - .filter_map(|def| match def { - Selection::Field(field) => Some(field), - // TODO, handle fragments - _ => panic!("only Selections are supported"), - }) - .collect(); + let selections = match normalize_selection_set( + &selection_set, + &fragment_definitions, + &mutation_type.name().unwrap(), + ) { + Ok(selections) => selections, + Err(err) => { + return GraphQLResponse { + data: Omit::Omitted, + errors: Omit::Present(vec![ErrorMessage { + message: err.to_string(), + }]), + } + } + }; use pgx::prelude::*; use pgx_contrib_spiext::subtxn::*; diff --git a/test/expected/fragment_on_mutation.out b/test/expected/fragment_on_mutation.out new file mode 100644 index 00000000..efc16124 --- /dev/null +++ b/test/expected/fragment_on_mutation.out @@ -0,0 +1,34 @@ +begin; + create table blog_post( + id int primary key, + title text not null + ); + select graphql.resolve($$ + mutation { + ...blogPosts_insert + } + + fragment blogPosts_insert on Mutation { + insertIntoBlogPostCollection(objects: [ + { id: 1, title: "foo" } + ]) { + affectedCount + records { + id + title + } + } + } + $$); + resolve +---------------------------------------------------------------------------------------------------------- + {"data": {"insertIntoBlogPostCollection": {"records": [{"id": 1, "title": "foo"}], "affectedCount": 1}}} +(1 row) + + select * from blog_post; + id | title +----+------- + 1 | foo +(1 row) + +rollback; diff --git a/test/expected/fragment_on_query.out b/test/expected/fragment_on_query.out new file mode 100644 index 00000000..38ad3ed2 --- /dev/null +++ b/test/expected/fragment_on_query.out @@ -0,0 +1,28 @@ +begin; + create table blog_post( + id int primary key, + title text not null + ); + select graphql.resolve($$ + query { + ...blogPosts_query + } + + fragment blogPosts_query on Query { + blogPostCollection(first:2) { + edges + { + node { + id + title + } + } + } + } + $$); + resolve +------------------------------------------------- + {"data": {"blogPostCollection": {"edges": []}}} +(1 row) + +rollback; diff --git a/test/sql/fragment_on_mutation.sql b/test/sql/fragment_on_mutation.sql new file mode 100644 index 00000000..0bcb1c28 --- /dev/null +++ b/test/sql/fragment_on_mutation.sql @@ -0,0 +1,28 @@ +begin; + + create table blog_post( + id int primary key, + title text not null + ); + + select graphql.resolve($$ + mutation { + ...blogPosts_insert + } + + fragment blogPosts_insert on Mutation { + insertIntoBlogPostCollection(objects: [ + { id: 1, title: "foo" } + ]) { + affectedCount + records { + id + title + } + } + } + $$); + + select * from blog_post; + +rollback; diff --git a/test/sql/fragment_on_query.sql b/test/sql/fragment_on_query.sql new file mode 100644 index 00000000..1f84763b --- /dev/null +++ b/test/sql/fragment_on_query.sql @@ -0,0 +1,26 @@ +begin; + + create table blog_post( + id int primary key, + title text not null + ); + + select graphql.resolve($$ + query { + ...blogPosts_query + } + + fragment blogPosts_query on Query { + blogPostCollection(first:2) { + edges + { + node { + id + title + } + } + } + } + $$); + +rollback;