Skip to content

Commit

Permalink
Make EntityFilter::Child a struct
Browse files Browse the repository at this point in the history
  • Loading branch information
kamilkisiela committed Jun 20, 2022
1 parent bdc00dc commit 845b35e
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 30 deletions.
22 changes: 15 additions & 7 deletions graph/src/components/store/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,13 @@ fn key_stable_hash() {
"905b57035d6f98cff8281e7b055e10570a2bd31190507341c6716af2d3c1ad98",
);
}
#[derive(Clone, Debug, PartialEq)]
pub struct Child {
pub attr: Attribute,
pub entity_type: EntityType,
pub filter: Box<EntityFilter>,
pub derived: bool,
}

/// Supported types of store filters.
#[derive(Clone, Debug, PartialEq)]
Expand Down Expand Up @@ -206,12 +213,7 @@ pub enum EntityFilter {
NotEndsWith(Attribute, Value),
NotEndsWithNoCase(Attribute, Value),
ChangeBlockGte(BlockNumber),
Child(
Attribute,
EntityType,
Box<EntityFilter>,
EntityFilterDerivative,
),
Child(Child),
}

// A somewhat concise string representation of a filter
Expand Down Expand Up @@ -255,7 +257,13 @@ impl fmt::Display for EntityFilter {
NotEndsWith(a, v) => write!(f, "{a} !~ *{v}$"),
NotEndsWithNoCase(a, v) => write!(f, "{a} !~ *{v}$i"),
ChangeBlockGte(b) => write!(f, "block >= {b}"),
Child(a, et, cf, _) => write!(f, "join on {a} with {et}({})", cf.to_string()),
Child(child /* a, et, cf, _ */) => write!(
f,
"join on {} with {}({})",
child.attr,
child.entity_type,
child.filter.to_string()
),
}
}
}
Expand Down
11 changes: 5 additions & 6 deletions graph/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,13 +114,12 @@ pub mod prelude {
pub use crate::components::server::query::GraphQLServer;
pub use crate::components::server::subscription::SubscriptionServer;
pub use crate::components::store::{
AttributeNames, BlockNumber, CachedEthereumCall, ChainStore, ChildMultiplicity,
AttributeNames, BlockNumber, CachedEthereumCall, ChainStore, Child, ChildMultiplicity,
EntityCache, EntityChange, EntityChangeOperation, EntityCollection, EntityFilter,
EntityFilterDerivative, EntityKey, EntityLink, EntityModification, EntityOperation,
EntityOrder, EntityQuery, EntityRange, EntityWindow, EthereumCallCache, ParentLink,
PartialBlockPtr, PoolWaitStats, QueryStore, QueryStoreManager, StoreError, StoreEvent,
StoreEventStream, StoreEventStreamBox, SubgraphStore, UnfailOutcome, WindowAttribute,
BLOCK_NUMBER_MAX,
EntityKey, EntityLink, EntityModification, EntityOperation, EntityOrder, EntityQuery,
EntityRange, EntityWindow, EthereumCallCache, ParentLink, PartialBlockPtr, PoolWaitStats,
QueryStore, QueryStoreManager, StoreError, StoreEvent, StoreEventStream,
StoreEventStreamBox, SubgraphStore, UnfailOutcome, WindowAttribute, BLOCK_NUMBER_MAX,
};
pub use crate::components::subgraph::{
BlockState, DataSourceTemplateInfo, HostMetrics, RuntimeHost, RuntimeHostBuilder,
Expand Down
12 changes: 6 additions & 6 deletions graphql/src/store/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -271,12 +271,12 @@ fn build_child_filter_from_object(
.ok_or(QueryExecutionError::InvalidFilterError)?;
let filter = build_filter_from_object(child_entity, object, schema)?;

Ok(EntityFilter::Child(
field_name,
EntityType::new(type_name.to_string()),
Box::new(filter),
EntityFilterDerivative::new(field.is_derived()),
))
Ok(EntityFilter::Child(Child {
attr: field_name,
entity_type: EntityType::new(type_name.to_string()),
filter: Box::new(filter),
derived: field.is_derived(),
}))
}

/// Parses a list of GraphQL values into a vector of entity field values.
Expand Down
26 changes: 15 additions & 11 deletions store/postgres/src/relational_queries.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ use diesel::Connection;
use graph::data::value::Word;
use graph::prelude::{
anyhow, r, serde_json, Attribute, BlockNumber, ChildMultiplicity, Entity, EntityCollection,
EntityFilter, EntityFilterDerivative, EntityKey, EntityLink, EntityOrder, EntityRange,
EntityWindow, ParentLink, QueryExecutionError, StoreError, Value, ENV_VARS,
EntityFilter, EntityKey, EntityLink, EntityOrder, EntityRange, EntityWindow, ParentLink,
QueryExecutionError, StoreError, Value, ENV_VARS,
};
use graph::{
components::store::{AttributeNames, EntityType},
Expand Down Expand Up @@ -917,19 +917,19 @@ impl<'a> QueryFilter<'a> {
Self::valid_attributes(filter, table, layout, child_filter_ancestor)?;
}
}
Child(attr, entity, child_filter, _) => {
Child(child) => {
if child_filter_ancestor {
return Err(StoreError::QueryExecutionError(
"Only a single level sub filter is allowed".to_string(),
));
}

// Make sure that the attribute name is valid for the given table
table.column_for_field(attr)?;
table.column_for_field(child.attr.as_str())?;

Self::valid_attributes(
child_filter,
layout.table_for_entity(entity)?,
&child.filter,
layout.table_for_entity(&child.entity_type)?,
layout,
true,
)?;
Expand Down Expand Up @@ -978,7 +978,7 @@ impl<'a> QueryFilter<'a> {
attribute: &Attribute,
entity_type: &'a EntityType,
filter: &'a EntityFilter,
derivative: &'a EntityFilterDerivative,
derived: bool,
mut out: AstPass<Pg>,
) -> QueryResult<()> {
let child_table = self
Expand All @@ -998,7 +998,7 @@ impl<'a> QueryFilter<'a> {
out.push_sql(" where ");

// Join tables
if derivative.is_derived() {
if derived {
// If the parent is derived,
// the child column is picked based on the provided attribute
// and the parent column is the primary key of the parent table
Expand Down Expand Up @@ -1431,9 +1431,13 @@ impl<'a> QueryFragment<Pg> for QueryFilter<'a> {
self.starts_or_ends_with(attr, value, " not ilike ", false, out)?
}
ChangeBlockGte(block_number) => self.filter_block_gte(block_number, out)?,
Child(attr, entity_type, child_filter, derivative) => {
self.child(attr, entity_type, child_filter, derivative, out)?
}
Child(child) => self.child(
&child.attr,
&child.entity_type,
&child.filter,
child.derived,
out,
)?,
}
Ok(())
}
Expand Down

0 comments on commit 845b35e

Please sign in to comment.