mirror of
https://github.com/hasura/graphql-engine.git
synced 2024-12-14 17:02:49 +03:00
fix relationship collection of filter and order by clauses (#323)
This fixes a bug with collection_relationships not being populated by relationships constructed from where and/or order by clauses. We fix this by not only collecting relationships from field selection, but also considering relationships introduced by order by and where clauses. V3_GIT_ORIGIN_REV_ID: c612ceed8b3831257ca2c7d23ec9ed23261efedf
This commit is contained in:
parent
d4740a08a1
commit
8071b11194
@ -1,5 +1,6 @@
|
||||
mod commands;
|
||||
mod model_selection;
|
||||
mod relationships;
|
||||
pub(crate) mod selection_set;
|
||||
|
||||
use gql::normalized_ast;
|
||||
|
@ -61,7 +61,7 @@ pub(crate) fn ndc_query_ir<'s, 'ir>(
|
||||
|
||||
let (query, jl) = ndc_query(&ir.command_info, join_id_counter)?;
|
||||
let mut collection_relationships = BTreeMap::new();
|
||||
selection_set::collect_relationships(
|
||||
selection_set::collect_relationships_from_selection(
|
||||
&ir.command_info.selection,
|
||||
&mut collection_relationships,
|
||||
)?;
|
||||
@ -96,7 +96,7 @@ pub(crate) fn ndc_mutation_ir<'s, 'ir>(
|
||||
)),
|
||||
};
|
||||
let mut collection_relationships = BTreeMap::new();
|
||||
selection_set::collect_relationships(
|
||||
selection_set::collect_relationships_from_selection(
|
||||
&ir.command_info.selection,
|
||||
&mut collection_relationships,
|
||||
)?;
|
||||
|
@ -3,6 +3,7 @@
|
||||
use ndc_client as ndc;
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
use super::relationships;
|
||||
use super::selection_set;
|
||||
use crate::execute::error;
|
||||
use crate::execute::ir::model_selection::ModelSelection;
|
||||
@ -43,7 +44,8 @@ pub(crate) fn ndc_ir<'s, 'ir>(
|
||||
error::Error,
|
||||
> {
|
||||
let mut collection_relationships = BTreeMap::new();
|
||||
selection_set::collect_relationships(&ir.selection, &mut collection_relationships)?;
|
||||
relationships::collect_relationships(ir, &mut collection_relationships)?;
|
||||
|
||||
let (query, join_locations) = ndc_query(ir, join_id_counter)?;
|
||||
let query_request = ndc::models::QueryRequest {
|
||||
query,
|
||||
|
70
v3/engine/src/execute/query_plan/relationships.rs
Normal file
70
v3/engine/src/execute/query_plan/relationships.rs
Normal file
@ -0,0 +1,70 @@
|
||||
//! NDC query generation from 'ModelSelection' IR for relationships.
|
||||
|
||||
use ndc_client as ndc;
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
use super::selection_set;
|
||||
use crate::execute::error;
|
||||
use crate::execute::ir::model_selection::ModelSelection;
|
||||
use crate::execute::ir::relationship;
|
||||
use crate::execute::ir::selection_set::FieldSelection;
|
||||
|
||||
/// collect relationships recursively from IR components containing relationships,
|
||||
/// and create NDC relationship definitions which will be added to the `relationships`
|
||||
/// variable.
|
||||
pub(crate) fn collect_relationships(
|
||||
ir: &ModelSelection<'_>,
|
||||
relationships: &mut BTreeMap<String, ndc::models::Relationship>,
|
||||
) -> Result<(), error::Error> {
|
||||
// from selection fields
|
||||
for field in ir.selection.fields.values() {
|
||||
match field {
|
||||
FieldSelection::Column { .. } => (),
|
||||
FieldSelection::ModelRelationshipLocal {
|
||||
query,
|
||||
name,
|
||||
relationship_info,
|
||||
} => {
|
||||
relationships.insert(
|
||||
name.to_string(),
|
||||
relationship::process_model_relationship_definition(relationship_info)?,
|
||||
);
|
||||
collect_relationships(query, relationships)?;
|
||||
}
|
||||
FieldSelection::CommandRelationshipLocal {
|
||||
ir,
|
||||
name,
|
||||
relationship_info,
|
||||
} => {
|
||||
relationships.insert(
|
||||
name.to_string(),
|
||||
relationship::process_command_relationship_definition(relationship_info)?,
|
||||
);
|
||||
selection_set::collect_relationships_from_selection(
|
||||
&ir.command_info.selection,
|
||||
relationships,
|
||||
)?;
|
||||
}
|
||||
// we ignore remote relationships as we are generating relationship
|
||||
// definition for one data connector
|
||||
FieldSelection::ModelRelationshipRemote { .. } => (),
|
||||
FieldSelection::CommandRelationshipRemote { .. } => (),
|
||||
};
|
||||
}
|
||||
|
||||
// from filter clause
|
||||
for (name, relationship) in ir.filter_clause.relationships.iter() {
|
||||
let result = relationship::process_model_relationship_definition(relationship)?;
|
||||
relationships.insert(name.to_string(), result);
|
||||
}
|
||||
|
||||
// from order by clause
|
||||
if let Some(order_by) = &ir.order_by {
|
||||
for (name, relationship) in order_by.relationships.iter() {
|
||||
let result = relationship::process_model_relationship_definition(relationship)?;
|
||||
relationships.insert(name.to_string(), result);
|
||||
}
|
||||
};
|
||||
|
||||
Ok(())
|
||||
}
|
@ -4,6 +4,7 @@ use std::collections::{BTreeMap, HashMap};
|
||||
|
||||
use super::commands;
|
||||
use super::model_selection;
|
||||
use super::relationships;
|
||||
use super::ProcessResponseAs;
|
||||
use crate::execute::error;
|
||||
use crate::execute::ir::relationship;
|
||||
@ -202,7 +203,7 @@ fn make_hasura_phantom_field(field_name: &str) -> String {
|
||||
|
||||
/// From the fields in `ResultSelectionSet`, collect relationships recursively
|
||||
/// and create NDC relationship definitions
|
||||
pub(crate) fn collect_relationships(
|
||||
pub(crate) fn collect_relationships_from_selection(
|
||||
selection: &ResultSelectionSet,
|
||||
relationships: &mut BTreeMap<String, ndc::models::Relationship>,
|
||||
) -> Result<(), error::Error> {
|
||||
@ -218,7 +219,7 @@ pub(crate) fn collect_relationships(
|
||||
name.to_string(),
|
||||
relationship::process_model_relationship_definition(relationship_info)?,
|
||||
);
|
||||
collect_relationships(&query.selection, relationships)?;
|
||||
relationships::collect_relationships(query, relationships)?;
|
||||
}
|
||||
FieldSelection::CommandRelationshipLocal {
|
||||
ir,
|
||||
@ -229,7 +230,7 @@ pub(crate) fn collect_relationships(
|
||||
name.to_string(),
|
||||
relationship::process_command_relationship_definition(relationship_info)?,
|
||||
);
|
||||
collect_relationships(&ir.command_info.selection, relationships)?;
|
||||
collect_relationships_from_selection(&ir.command_info.selection, relationships)?;
|
||||
}
|
||||
// we ignore remote relationships as we are generating relationship
|
||||
// definition for one data connector
|
||||
|
@ -21,6 +21,17 @@
|
||||
}
|
||||
}
|
||||
],
|
||||
"TrackOrderByWithoutRelationshipField": [
|
||||
{
|
||||
"Name": "Koyaanisqatsi"
|
||||
},
|
||||
{
|
||||
"Name": "Quintet for Horn, Violin, 2 Violas, and Cello in E Flat Major, K. 407/386c: III. Allegro"
|
||||
},
|
||||
{
|
||||
"Name": "L'orfeo, Act 3, Sinfonia (Orchestra)"
|
||||
}
|
||||
],
|
||||
"TrackOrderByWithFilter": [
|
||||
{
|
||||
"TrackId": 5,
|
||||
@ -83,6 +94,17 @@
|
||||
}
|
||||
}
|
||||
],
|
||||
"TrackOrderByWithoutRelationshipField": [
|
||||
{
|
||||
"Name": "Koyaanisqatsi"
|
||||
},
|
||||
{
|
||||
"Name": "Quintet for Horn, Violin, 2 Violas, and Cello in E Flat Major, K. 407/386c: III. Allegro"
|
||||
},
|
||||
{
|
||||
"Name": "L'orfeo, Act 3, Sinfonia (Orchestra)"
|
||||
}
|
||||
],
|
||||
"TrackOrderByWithFilter": [
|
||||
{
|
||||
"TrackId": 5,
|
||||
|
@ -5,6 +5,9 @@ query MyQuery {
|
||||
Title
|
||||
}
|
||||
}
|
||||
TrackOrderByWithoutRelationshipField: Track(order_by: [{Album: {ArtistId: Desc}}, {Name: Asc}], limit: 3) {
|
||||
Name
|
||||
}
|
||||
TrackOrderByWithFilter: Track(
|
||||
order_by: [{Album: {ArtistId: Asc}}, {TrackId: Desc}]
|
||||
where: {Album: {Artist: {ArtistId: {_eq: 2}}}}
|
||||
|
@ -24,6 +24,17 @@
|
||||
}
|
||||
}
|
||||
],
|
||||
"TrackWithoutRelationshipField": [
|
||||
{
|
||||
"Name": "Fast As a Shark"
|
||||
},
|
||||
{
|
||||
"Name": "Restless and Wild"
|
||||
},
|
||||
{
|
||||
"Name": "Princess of the Dawn"
|
||||
}
|
||||
],
|
||||
"TrackAnd": [
|
||||
{
|
||||
"AlbumId": 3,
|
||||
@ -104,6 +115,17 @@
|
||||
}
|
||||
}
|
||||
],
|
||||
"TrackWithoutRelationshipField": [
|
||||
{
|
||||
"Name": "Fast As a Shark"
|
||||
},
|
||||
{
|
||||
"Name": "Restless and Wild"
|
||||
},
|
||||
{
|
||||
"Name": "Princess of the Dawn"
|
||||
}
|
||||
],
|
||||
"TrackAnd": [
|
||||
{
|
||||
"AlbumId": 3,
|
||||
|
@ -6,6 +6,9 @@ query MyQuery {
|
||||
Title
|
||||
}
|
||||
}
|
||||
TrackWithoutRelationshipField: Track(where: {Album: {Title: {_eq: "Restless and Wild"}}}) {
|
||||
Name
|
||||
}
|
||||
TrackAnd: Track(where: {_and: [{Album: {Title: {_eq: "Restless and Wild"}}}, {AlbumId: {_eq: 3}} ]} ) {
|
||||
AlbumId
|
||||
Name
|
||||
|
Loading…
Reference in New Issue
Block a user