From 8009a58fe2e3c360bf0d664637c366b61b0d150c Mon Sep 17 00:00:00 2001 From: Tim Diekmann <21277928+TimDiekmann@users.noreply.github.com> Date: Wed, 15 Jan 2025 12:56:07 +0100 Subject: [PATCH 1/2] Return error instead of `panic` in `SelectCompiler` --- Cargo.lock | 1 + apps/hash-graph/src/subcommand/server.rs | 2 +- libs/@local/graph/api/src/rest/entity.rs | 2 +- libs/@local/graph/postgres-store/Cargo.toml | 1 + .../postgres-store/src/store/postgres/crud.rs | 20 ++-- .../store/postgres/knowledge/entity/mod.rs | 8 +- .../store/postgres/ontology/entity_type.rs | 4 +- .../src/store/postgres/ontology/mod.rs | 16 ++-- .../src/store/postgres/ontology/read.rs | 2 +- .../src/store/postgres/query/compile.rs | 93 +++++++++++-------- .../postgres/query/expression/where_clause.rs | 24 ++++- .../src/store/postgres/query/mod.rs | 12 ++- 12 files changed, 114 insertions(+), 71 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 06d04c7924b..fc0e8694f99 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2907,6 +2907,7 @@ dependencies = [ "deadpool", "deadpool-postgres", "derive-where", + "derive_more", "dotenv-flow", "error-stack", "futures", diff --git a/apps/hash-graph/src/subcommand/server.rs b/apps/hash-graph/src/subcommand/server.rs index 875c0244b14..38ec35de118 100644 --- a/apps/hash-graph/src/subcommand/server.rs +++ b/apps/hash-graph/src/subcommand/server.rs @@ -294,7 +294,7 @@ pub async fn server(args: ServerArgs) -> Result<(), Report> { let mut zanzibar_client = ZanzibarClient::new(spicedb_client); zanzibar_client.seed().await.change_context(GraphError)?; - let temporal_client_fn = async |host: Option, port: u16| { + let temporal_client_fn = |host: Option, port: u16| async move { if let Some(host) = host { TemporalClientConfig::new( Url::from_str(&format!("{host}:{port}")).change_context(GraphError)?, diff --git a/libs/@local/graph/api/src/rest/entity.rs b/libs/@local/graph/api/src/rest/entity.rs index 5912f0fe932..2a801ddf7c0 100644 --- a/libs/@local/graph/api/src/rest/entity.rs +++ b/libs/@local/graph/api/src/rest/entity.rs @@ -661,7 +661,7 @@ impl<'q, 's, 'p: 'q> From> for GetEntitiesParams< #[tracing::instrument( level = "info", skip_all, - fields(actor=%actor_id, %request) + fields(actor=%actor_id) )] async fn get_entities( AuthenticatedUserHeader(actor_id): AuthenticatedUserHeader, diff --git a/libs/@local/graph/postgres-store/Cargo.toml b/libs/@local/graph/postgres-store/Cargo.toml index 48a9ef5b501..3bd420d7ac1 100644 --- a/libs/@local/graph/postgres-store/Cargo.toml +++ b/libs/@local/graph/postgres-store/Cargo.toml @@ -34,6 +34,7 @@ async-scoped = { workspace = true, features = ["use-tokio"] } bytes = { workspace = true } clap = { workspace = true, optional = true, features = ["derive", "env"] } derive-where = { workspace = true } +derive_more = { workspace = true } dotenv-flow = { workspace = true } futures = { workspace = true } postgres-types = { workspace = true, features = ["derive", "with-serde_json-1"] } diff --git a/libs/@local/graph/postgres-store/src/store/postgres/crud.rs b/libs/@local/graph/postgres-store/src/store/postgres/crud.rs index c4927b9624e..9216a94f992 100644 --- a/libs/@local/graph/postgres-store/src/store/postgres/crud.rs +++ b/libs/@local/graph/postgres-store/src/store/postgres/crud.rs @@ -94,13 +94,15 @@ where compiler.set_limit(limit); } - compiler.add_filter(filter); - - let cursor_indices = sorting.compile( - &mut compiler, - cursor_parameters.as_ref(), - temporal_axes.expect("To use a cursor, temporal axes has to be specified"), - ); + compiler.add_filter(filter).change_context(QueryError)?; + + let cursor_indices = sorting + .compile( + &mut compiler, + cursor_parameters.as_ref(), + temporal_axes.expect("To use a cursor, temporal axes has to be specified"), + ) + .change_context(QueryError)?; let record_artifacts = R::parameters(); let record_indices = R::compile(&mut compiler, &record_artifacts); @@ -145,7 +147,7 @@ where let record_artifacts = R::parameters(); let record_indices = R::compile(&mut compiler, &record_artifacts); - compiler.add_filter(filter); + compiler.add_filter(filter).change_context(QueryError)?; let (statement, parameters) = compiler.compile(); Ok(self @@ -170,7 +172,7 @@ where let record_artifacts = R::parameters(); let record_indices = R::compile(&mut compiler, &record_artifacts); - compiler.add_filter(filter); + compiler.add_filter(filter).change_context(QueryError)?; let (statement, parameters) = compiler.compile(); let rows = self diff --git a/libs/@local/graph/postgres-store/src/store/postgres/knowledge/entity/mod.rs b/libs/@local/graph/postgres-store/src/store/postgres/knowledge/entity/mod.rs index d47634ee74c..67d1c71185c 100644 --- a/libs/@local/graph/postgres-store/src/store/postgres/knowledge/entity/mod.rs +++ b/libs/@local/graph/postgres-store/src/store/postgres/knowledge/entity/mod.rs @@ -532,7 +532,9 @@ where ) }); - compiler.add_filter(¶ms.filter); + compiler + .add_filter(¶ms.filter) + .change_context(QueryError)?; let (statement, parameters) = compiler.compile(); @@ -643,7 +645,9 @@ where }, ParameterList::EntityTypeIds(&type_uuids), ); - type_compiler.add_filter(&filter); + type_compiler + .add_filter(&filter) + .change_context(QueryError)?; let (statement, parameters) = type_compiler.compile(); diff --git a/libs/@local/graph/postgres-store/src/store/postgres/ontology/entity_type.rs b/libs/@local/graph/postgres-store/src/store/postgres/ontology/entity_type.rs index 914e4e332a2..6c418f2c317 100644 --- a/libs/@local/graph/postgres-store/src/store/postgres/ontology/entity_type.rs +++ b/libs/@local/graph/postgres-store/src/store/postgres/ontology/entity_type.rs @@ -387,7 +387,9 @@ where compiler.add_selection_path(&EntityTypeQueryPath::EditionProvenance(None)) }); - compiler.add_filter(¶ms.filter); + compiler + .add_filter(¶ms.filter) + .change_context(QueryError)?; let (statement, parameters) = compiler.compile(); diff --git a/libs/@local/graph/postgres-store/src/store/postgres/ontology/mod.rs b/libs/@local/graph/postgres-store/src/store/postgres/ontology/mod.rs index f99897f9ea4..9dddc1a2eaa 100644 --- a/libs/@local/graph/postgres-store/src/store/postgres/ontology/mod.rs +++ b/libs/@local/graph/postgres-store/src/store/postgres/ontology/mod.rs @@ -35,7 +35,7 @@ use crate::store::{ postgres::{ AsClient as _, PostgresStore, crud::QueryRecordDecode, - query::{Distinctness, PostgresSorting, SelectCompiler}, + query::{Distinctness, PostgresSorting, SelectCompiler, SelectCompilerError}, }, }; @@ -153,29 +153,29 @@ macro_rules! impl_ontology_cursor { compiler: &mut SelectCompiler<'p, 'q, $ty>, parameters: Option<&'p Self::CompilationParameters>, _: &QueryTemporalAxes, - ) -> Self::Indices { + ) -> Result> { if let Some(parameters) = parameters { let base_url_expression = compiler.compile_parameter(¶meters.base_url).0; let version_expression = compiler.compile_parameter(¶meters.version).0; - VersionedUrlIndices { + Ok(VersionedUrlIndices { base_url: compiler.add_cursor_selection( &<$query_path>::BaseUrl, identity, Some(base_url_expression), Ordering::Ascending, None, - ), + )?, version: compiler.add_cursor_selection( &<$query_path>::Version, identity, Some(version_expression), Ordering::Descending, None, - ), - } + )?, + }) } else { - VersionedUrlIndices { + Ok(VersionedUrlIndices { base_url: compiler.add_distinct_selection_with_ordering( &<$query_path>::BaseUrl, Distinctness::Distinct, @@ -186,7 +186,7 @@ macro_rules! impl_ontology_cursor { Distinctness::Distinct, Some((Ordering::Descending, None)), ), - } + }) } } } diff --git a/libs/@local/graph/postgres-store/src/store/postgres/ontology/read.rs b/libs/@local/graph/postgres-store/src/store/postgres/ontology/read.rs index 377dc5b2d55..40f8c082cd3 100644 --- a/libs/@local/graph/postgres-store/src/store/postgres/ontology/read.rs +++ b/libs/@local/graph/postgres-store/src/store/postgres/ontology/read.rs @@ -76,7 +76,7 @@ impl PostgresStore { let closed_schema_index = compiler.add_selection_path(&EntityTypeQueryPath::ClosedSchema(None)); - compiler.add_filter(filter); + compiler.add_filter(filter).change_context(QueryError)?; let (statement, parameters) = compiler.compile(); Ok(self diff --git a/libs/@local/graph/postgres-store/src/store/postgres/query/compile.rs b/libs/@local/graph/postgres-store/src/store/postgres/query/compile.rs index b58bacc8355..97065941ce8 100644 --- a/libs/@local/graph/postgres-store/src/store/postgres/query/compile.rs +++ b/libs/@local/graph/postgres-store/src/store/postgres/query/compile.rs @@ -2,6 +2,7 @@ use alloc::borrow::Cow; use core::{iter::once, mem}; use std::collections::{HashMap, HashSet}; +use error_stack::{Report, bail, ensure}; use hash_graph_store::{ filter::{ Filter, FilterExpression, Parameter, ParameterList, ParameterType, PathToken, QueryRecord, @@ -47,7 +48,7 @@ pub struct CompilerArtifacts<'p> { condition_index: usize, required_tables: HashSet, table_info: TableInfo, - uses_cursor: bool, + cursor_disallowed_reason: Option<&'static str>, } struct PathSelection { @@ -66,6 +67,22 @@ pub struct SelectCompiler<'p, 'q: 'p, T: QueryRecord> { selections: HashMap<&'p T::QueryPath<'q>, PathSelection>, } +#[derive(Debug, derive_more::Display, derive_more::Error)] +pub enum SelectCompilerError { + #[display("Cannot convert parameter for distance function")] + ConvertDistanceParameter, + #[display("Only a single embedding for the same path is allowed")] + MultipleEmbeddings, + #[display("Only embeddings are supported for cosine distance")] + UnsupportedEmbeddingPath, + #[display( + "Cosine distance is only supported with exactly one `path` and one `parameter` expression." + )] + UnsupportedDistanceExpression, + #[display("Cannot add a cursor: {reason}")] + CursorDisallowed { reason: &'static str }, +} + impl<'p, 'q: 'p, R: PostgresRecord> SelectCompiler<'p, 'q, R> { /// Creates a new, empty compiler. pub fn new(temporal_axes: Option<&'p QueryTemporalAxes>, include_drafts: bool) -> Self { @@ -109,7 +126,7 @@ impl<'p, 'q: 'p, R: PostgresRecord> SelectCompiler<'p, 'q, R> { pinned_timestamp_index: None, variable_interval_index: None, }, - uses_cursor: false, + cursor_disallowed_reason: None, }, temporal_axes, table_hooks, @@ -343,30 +360,36 @@ impl<'p, 'q: 'p, R: PostgresRecord> SelectCompiler<'p, 'q, R> { rhs: Option, ordering: Ordering, null_ordering: Option, - ) -> usize + ) -> Result> where R::QueryPath<'q>: PostgresQueryPath, { + if let Some(reason) = self.artifacts.cursor_disallowed_reason { + bail!(SelectCompilerError::CursorDisallowed { reason }); + } let column = self.compile_path_column(path); self.statement .where_expression .add_cursor(lhs(column), rhs, ordering, null_ordering); - self.artifacts.uses_cursor = true; - self.add_distinct_selection_with_ordering( + Ok(self.add_distinct_selection_with_ordering( path, Distinctness::Distinct, Some((ordering, null_ordering)), - ) + )) } /// Adds a new filter to the selection. - pub fn add_filter(&mut self, filter: &'p Filter<'q, R>) + pub fn add_filter( + &mut self, + filter: &'p Filter<'q, R>, + ) -> Result<(), Report> where R::QueryPath<'q>: PostgresQueryPath, { - let condition = self.compile_filter(filter); + let condition = self.compile_filter(filter)?; self.artifacts.condition_index += 1; self.statement.where_expression.add_condition(condition); + Ok(()) } /// Transpiles the statement into SQL and the parameter to be passed to a prepared statement. @@ -380,28 +403,31 @@ impl<'p, 'q: 'p, R: PostgresRecord> SelectCompiler<'p, 'q, R> { /// Compiles a [`Filter`] to a `Condition`. #[expect(clippy::too_many_lines)] - pub fn compile_filter(&mut self, filter: &'p Filter<'q, R>) -> Condition + pub fn compile_filter( + &mut self, + filter: &'p Filter<'q, R>, + ) -> Result> where R::QueryPath<'q>: PostgresQueryPath, { if let Some(condition) = self.compile_special_filter(filter) { - return condition; + return Ok(condition); } - match filter { + Ok(match filter { Filter::All(filters) => Condition::All( filters .iter() .map(|filter| self.compile_filter(filter)) - .collect(), + .collect::>()?, ), Filter::Any(filters) => Condition::Any( filters .iter() .map(|filter| self.compile_filter(filter)) - .collect(), + .collect::>()?, ), - Filter::Not(filter) => Condition::Not(Box::new(self.compile_filter(filter))), + Filter::Not(filter) => Condition::Not(Box::new(self.compile_filter(filter)?)), Filter::Equal(lhs, rhs) => Condition::Equal( lhs.as_ref() .map(|expression| self.compile_filter_expression(expression).0), @@ -442,16 +468,15 @@ impl<'p, 'q: 'p, R: PostgresRecord> SelectCompiler<'p, 'q, R> { // We don't support custom sorting yet and limit/cursor implicitly set an order. // We special case the distance function to allow sorting by distance, so we // need to make sure that we don't have a limit or cursor. - assert!( - self.statement.limit.is_none() && !self.artifacts.uses_cursor, - "Cannot use distance function with limit or cursor", - ); + + self.artifacts.cursor_disallowed_reason = + Some("Cannot use distance function with cursor"); // `convert` should be `None` as we don't support parameter conversion at this // stage, yet. - assert!( + ensure!( convert.is_none(), - "Cannot convert parameter for distance function" + SelectCompilerError::ConvertDistanceParameter ); let path_alias = self.add_join_statements(path); @@ -459,7 +484,7 @@ impl<'p, 'q: 'p, R: PostgresRecord> SelectCompiler<'p, 'q, R> { let maximum_expression = self.compile_filter_expression(max).0; let (embeddings_column, None) = path.terminating_column() else { - panic!("Only embeddings are supported for cosine distance"); + bail!(SelectCompilerError::UnsupportedEmbeddingPath); }; let embeddings_table = embeddings_column.table(); let embeddings_alias = Alias { @@ -481,13 +506,13 @@ impl<'p, 'q: 'p, R: PostgresRecord> SelectCompiler<'p, 'q, R> { Table::EntityEmbeddings => { Column::EntityEmbeddings(EntityEmbeddings::Distance) } - _ => panic!("Only embeddings are supported for cosine distance"), + _ => bail!(SelectCompilerError::UnsupportedEmbeddingPath), }, table_alias: Some(path_alias), }; if let Some(last_join) = self.statement.joins.last_mut() { - assert!( + ensure!( matches!( last_join.table.table, Table::DataTypeEmbeddings @@ -495,13 +520,12 @@ impl<'p, 'q: 'p, R: PostgresRecord> SelectCompiler<'p, 'q, R> { | Table::EntityTypeEmbeddings | Table::EntityEmbeddings ) || last_join.statement.is_some(), - "Only a single embedding for the same path is allowed" + SelectCompilerError::MultipleEmbeddings ); - let select_columns = match embeddings_table { + let select_columns: &[_] = match embeddings_table { Table::DataTypeEmbeddings => { &[Column::DataTypeEmbeddings(DataTypeEmbeddings::OntologyId)] - as &[_] } Table::PropertyTypeEmbeddings => &[Column::PropertyTypeEmbeddings( PropertyTypeEmbeddings::OntologyId, @@ -574,10 +598,7 @@ impl<'p, 'q: 'p, R: PostgresRecord> SelectCompiler<'p, 'q, R> { self.statement.distinct.push(distance_expression.clone()); Condition::LessOrEqual(distance_expression, maximum_expression) } - _ => panic!( - "Cosine distance is only supported with exactly one `path` and one \ - `parameter` expression." - ), + _ => bail!(SelectCompilerError::UnsupportedDistanceExpression), }, Filter::In(lhs, rhs) => Condition::In( self.compile_filter_expression(lhs).0, @@ -634,14 +655,10 @@ impl<'p, 'q: 'p, R: PostgresRecord> SelectCompiler<'p, 'q, R> { Condition::ContainsSegment(left_filter, right_filter) } - } + }) } /// Compiles the `path` to a condition, which is searching for the latest version. - /// - /// # Panics - /// - /// This function will panic if the statement has a limit or uses a cursor. // Warning: This adds a CTE to the statement, which is overwriting the `ontology_ids` table. // When more CTEs are needed, a test should be added to cover both CTEs in one // statement to ensure compatibility @@ -655,10 +672,8 @@ impl<'p, 'q: 'p, R: PostgresRecord> SelectCompiler<'p, 'q, R> { where R::QueryPath<'q>: PostgresQueryPath, { - assert!( - self.statement.limit.is_none() && !self.artifacts.uses_cursor, - "Cannot use latest version filter with limit or cursor", - ); + self.artifacts.cursor_disallowed_reason = + Some("Cannot use latest version filter with cursor"); let version_column = Column::OntologyIds(OntologyIds::Version); let alias = Alias { diff --git a/libs/@local/graph/postgres-store/src/store/postgres/query/expression/where_clause.rs b/libs/@local/graph/postgres-store/src/store/postgres/query/expression/where_clause.rs index c98905bdac5..1c8df8ea207 100644 --- a/libs/@local/graph/postgres-store/src/store/postgres/query/expression/where_clause.rs +++ b/libs/@local/graph/postgres-store/src/store/postgres/query/expression/where_clause.rs @@ -150,7 +150,11 @@ mod tests { convert: None, }), ); - where_clause.add_condition(compiler.compile_filter(&filter_a)); + where_clause.add_condition( + compiler + .compile_filter(&filter_a) + .expect("Failed to compile filter"), + ); assert_eq!( where_clause.transpile_to_string(), @@ -179,7 +183,11 @@ mod tests { }), ), ]); - where_clause.add_condition(compiler.compile_filter(&filter_b)); + where_clause.add_condition( + compiler + .compile_filter(&filter_b) + .expect("Failed to compile filter"), + ); assert_eq!( trim_whitespace(&where_clause.transpile_to_string()), @@ -196,7 +204,11 @@ mod tests { }), None, ); - where_clause.add_condition(compiler.compile_filter(&filter_c)); + where_clause.add_condition( + compiler + .compile_filter(&filter_c) + .expect("Failed to compile filter"), + ); assert_eq!( trim_whitespace(&where_clause.transpile_to_string()), @@ -228,7 +240,11 @@ mod tests { }), ), ]); - where_clause.add_condition(compiler.compile_filter(&filter_d)); + where_clause.add_condition( + compiler + .compile_filter(&filter_d) + .expect("Failed to compile filter"), + ); assert_eq!( trim_whitespace(&where_clause.transpile_to_string()), diff --git a/libs/@local/graph/postgres-store/src/store/postgres/query/mod.rs b/libs/@local/graph/postgres-store/src/store/postgres/query/mod.rs index b5a235d19cd..acbb583dd09 100644 --- a/libs/@local/graph/postgres-store/src/store/postgres/query/mod.rs +++ b/libs/@local/graph/postgres-store/src/store/postgres/query/mod.rs @@ -19,6 +19,7 @@ use core::{ fmt::{self, Display, Formatter}, }; +use error_stack::Report; use hash_graph_store::{ entity::{EntityQueryCursor, EntityQuerySorting}, filter::{ParameterConversionError, QueryRecord}, @@ -30,7 +31,7 @@ use serde_json::Value; use tokio_postgres::Row; pub use self::{ - compile::SelectCompiler, + compile::{SelectCompiler, SelectCompilerError}, condition::{Condition, EqualityOperator}, expression::{ Constant, Expression, Function, JoinExpression, OrderByExpression, SelectExpression, @@ -105,7 +106,7 @@ pub trait PostgresSorting<'s, R: QueryRecord>: compiler: &mut SelectCompiler<'p, 'q, R>, parameters: Option<&'p Self::CompilationParameters>, temporal_axes: &QueryTemporalAxes, - ) -> Self::Indices + ) -> Result> where 's: 'q; } @@ -137,7 +138,7 @@ where compiler: &mut SelectCompiler<'p, 'q, Entity>, _: Option<&'p Self::CompilationParameters>, _: &QueryTemporalAxes, - ) -> Self::Indices + ) -> Result> where 's: 'q, { @@ -158,7 +159,8 @@ where }) .collect() } else { - self.paths + Ok(self + .paths .iter() .map(|sorting_record| { compiler.add_distinct_selection_with_ordering( @@ -167,7 +169,7 @@ where Some((sorting_record.ordering, sorting_record.nulls)), ) }) - .collect() + .collect()) } } } From dce7e4e08d422c2bc5602b73c71fe7e78fdde5b4 Mon Sep 17 00:00:00 2001 From: Tim Diekmann <21277928+TimDiekmann@users.noreply.github.com> Date: Wed, 15 Jan 2025 13:24:15 +0100 Subject: [PATCH 2/2] Satisfy clippy --- .../store/postgres/knowledge/entity/mod.rs | 1 - .../src/store/postgres/query/condition.rs | 4 +- .../store/postgres/query/statement/select.rs | 128 ++++++++++-------- 3 files changed, 71 insertions(+), 62 deletions(-) diff --git a/libs/@local/graph/postgres-store/src/store/postgres/knowledge/entity/mod.rs b/libs/@local/graph/postgres-store/src/store/postgres/knowledge/entity/mod.rs index 67d1c71185c..a638fb1e9bb 100644 --- a/libs/@local/graph/postgres-store/src/store/postgres/knowledge/entity/mod.rs +++ b/libs/@local/graph/postgres-store/src/store/postgres/knowledge/entity/mod.rs @@ -622,7 +622,6 @@ where .count(); let type_ids = type_ids.map(HashMap::from); - #[expect(clippy::if_then_some_else_none)] let type_titles = if params.include_type_titles { let type_uuids = type_ids .as_ref() diff --git a/libs/@local/graph/postgres-store/src/store/postgres/query/condition.rs b/libs/@local/graph/postgres-store/src/store/postgres/query/condition.rs index 2ea71541e0c..93182b67c74 100644 --- a/libs/@local/graph/postgres-store/src/store/postgres/query/condition.rs +++ b/libs/@local/graph/postgres-store/src/store/postgres/query/condition.rs @@ -164,7 +164,9 @@ mod tests { parameters: &[&'p dyn ToSql], ) { let mut compiler = SelectCompiler::new(None, false); - let condition = compiler.compile_filter(filter); + let condition = compiler + .compile_filter(filter) + .expect("failed to compile filter"); assert_eq!(condition.transpile_to_string(), rendered); diff --git a/libs/@local/graph/postgres-store/src/store/postgres/query/statement/select.rs b/libs/@local/graph/postgres-store/src/store/postgres/query/statement/select.rs index 0f471a5824d..94365b4084a 100644 --- a/libs/@local/graph/postgres-store/src/store/postgres/query/statement/select.rs +++ b/libs/@local/graph/postgres-store/src/store/postgres/query/statement/select.rs @@ -180,17 +180,19 @@ mod tests { let pinned_timestamp = temporal_axes.pinned_timestamp(); let mut compiler = SelectCompiler::::with_asterisk(Some(&temporal_axes), false); - compiler.add_filter(&Filter::Equal( - Some(FilterExpression::Path { - path: DataTypeQueryPath::VersionedUrl, - }), - Some(FilterExpression::Parameter { - parameter: Parameter::Text(Cow::Borrowed( - "https://blockprotocol.org/@blockprotocol/types/data-type/text/v/1", - )), - convert: None, - }), - )); + compiler + .add_filter(&Filter::Equal( + Some(FilterExpression::Path { + path: DataTypeQueryPath::VersionedUrl, + }), + Some(FilterExpression::Parameter { + parameter: Parameter::Text(Cow::Borrowed( + "https://blockprotocol.org/@blockprotocol/types/data-type/text/v/1", + )), + convert: None, + }), + )) + .expect("Failed to add filter"); test_compilation( &compiler, r#" @@ -221,7 +223,7 @@ mod tests { convert: None, }), ); - compiler.add_filter(&filter); + compiler.add_filter(&filter).expect("Failed to add filter"); test_compilation( &compiler, r#" @@ -252,7 +254,7 @@ mod tests { convert: None, }), ); - compiler.add_filter(&filter); + compiler.add_filter(&filter).expect("Failed to add filter"); test_compilation( &compiler, r#" @@ -294,7 +296,7 @@ mod tests { }), ), ]); - compiler.add_filter(&filter); + compiler.add_filter(&filter).expect("Failed to add filter"); test_compilation( &compiler, @@ -321,15 +323,17 @@ mod tests { let mut compiler = SelectCompiler::::with_asterisk(Some(&temporal_axes), false); - compiler.add_filter(&Filter::Equal( - Some(FilterExpression::Path { - path: DataTypeQueryPath::Version, - }), - Some(FilterExpression::Parameter { - parameter: Parameter::Text(Cow::Borrowed("latest")), - convert: None, - }), - )); + compiler + .add_filter(&Filter::Equal( + Some(FilterExpression::Path { + path: DataTypeQueryPath::Version, + }), + Some(FilterExpression::Parameter { + parameter: Parameter::Text(Cow::Borrowed("latest")), + convert: None, + }), + )) + .expect("Failed to add filter"); test_compilation( &compiler, @@ -353,15 +357,17 @@ mod tests { let mut compiler = SelectCompiler::::with_asterisk(Some(&temporal_axes), false); - compiler.add_filter(&Filter::NotEqual( - Some(FilterExpression::Path { - path: DataTypeQueryPath::Version, - }), - Some(FilterExpression::Parameter { - parameter: Parameter::Text(Cow::Borrowed("latest")), - convert: None, - }), - )); + compiler + .add_filter(&Filter::NotEqual( + Some(FilterExpression::Path { + path: DataTypeQueryPath::Version, + }), + Some(FilterExpression::Parameter { + parameter: Parameter::Text(Cow::Borrowed("latest")), + convert: None, + }), + )) + .expect("Failed to add filter"); test_compilation( &compiler, @@ -385,18 +391,20 @@ mod tests { let mut compiler = SelectCompiler::::with_asterisk(Some(&temporal_axes), false); - compiler.add_filter(&Filter::Equal( - Some(FilterExpression::Path { - path: PropertyTypeQueryPath::DataTypeEdge { - edge_kind: OntologyEdgeKind::ConstrainsValuesOn, - path: DataTypeQueryPath::Title, - }, - }), - Some(FilterExpression::Parameter { - parameter: Parameter::Text(Cow::Borrowed("Text")), - convert: None, - }), - )); + compiler + .add_filter(&Filter::Equal( + Some(FilterExpression::Path { + path: PropertyTypeQueryPath::DataTypeEdge { + edge_kind: OntologyEdgeKind::ConstrainsValuesOn, + path: DataTypeQueryPath::Title, + }, + }), + Some(FilterExpression::Parameter { + parameter: Parameter::Text(Cow::Borrowed("Text")), + convert: None, + }), + )) + .expect("Failed to add filter"); test_compilation( &compiler, @@ -444,7 +452,7 @@ mod tests { }), ), ]); - compiler.add_filter(&filter); + compiler.add_filter(&filter).expect("Failed to add filter"); test_compilation( &compiler, @@ -498,7 +506,7 @@ mod tests { convert: None, }), ); - compiler.add_filter(&filter); + compiler.add_filter(&filter).expect("Failed to add filter"); test_compilation( &compiler, @@ -539,7 +547,7 @@ mod tests { convert: None, }), ); - compiler.add_filter(&filter); + compiler.add_filter(&filter).expect("Failed to add filter"); test_compilation( &compiler, @@ -587,7 +595,7 @@ mod tests { convert: None, }), ); - compiler.add_filter(&filter); + compiler.add_filter(&filter).expect("Failed to add filter"); test_compilation( &compiler, @@ -639,7 +647,7 @@ mod tests { convert: None, }), ); - compiler.add_filter(&filter); + compiler.add_filter(&filter).expect("Failed to add filter"); test_compilation( &compiler, @@ -679,7 +687,7 @@ mod tests { convert: None, }), ); - compiler.add_filter(&filter); + compiler.add_filter(&filter).expect("Failed to add filter"); test_compilation( &compiler, @@ -725,7 +733,7 @@ mod tests { convert: None, }), ); - compiler.add_filter(&filter); + compiler.add_filter(&filter).expect("Failed to add filter"); test_compilation( &compiler, @@ -770,7 +778,7 @@ mod tests { convert: None, }), ); - compiler.add_filter(&filter); + compiler.add_filter(&filter).expect("Failed to add filter"); test_compilation( &compiler, @@ -808,7 +816,7 @@ mod tests { }), None, ); - compiler.add_filter(&filter); + compiler.add_filter(&filter).expect("Failed to add filter"); test_compilation( &compiler, @@ -853,7 +861,7 @@ mod tests { convert: None, }), ); - compiler.add_filter(&filter); + compiler.add_filter(&filter).expect("Failed to add filter"); test_compilation( &compiler, @@ -914,7 +922,7 @@ mod tests { convert: None, }), ); - compiler.add_filter(&filter); + compiler.add_filter(&filter).expect("Failed to add filter"); test_compilation( &compiler, @@ -1012,7 +1020,7 @@ mod tests { }), ), ]); - compiler.add_filter(&filter); + compiler.add_filter(&filter).expect("Failed to add filter"); test_compilation( &compiler, @@ -1090,7 +1098,7 @@ mod tests { }), ), ]); - compiler.add_filter(&filter); + compiler.add_filter(&filter).expect("Failed to add filter"); test_compilation( &compiler, @@ -1163,7 +1171,7 @@ mod tests { convert: None, }, ); - compiler.add_filter(&filter); + compiler.add_filter(&filter).expect("Failed to add filter"); test_compilation( &compiler, @@ -1215,7 +1223,7 @@ mod tests { SelectCompiler::::with_asterisk(Some(&temporal_axes), false); let filter = Filter::for_versioned_url(&url); - compiler.add_filter(&filter); + compiler.add_filter(&filter).expect("Failed to add filter"); test_compilation( &compiler, @@ -1244,7 +1252,7 @@ mod tests { let mut compiler = SelectCompiler::::with_asterisk(Some(&temporal_axes), false); let filter = Filter::for_entity_by_entity_id(entity_id); - compiler.add_filter(&filter); + compiler.add_filter(&filter).expect("Failed to add filter"); test_compilation( &compiler,