Skip to content

Commit

Permalink
Propagate types from the v3 schema into the v2 query request (#22)
Browse files Browse the repository at this point in the history
Co-authored-by: Jesse Hallett <jesse.hallett@hasura.io>
  • Loading branch information
daniel-chambers and hallettj authored Apr 2, 2024
1 parent b50094a commit 7ee4860
Show file tree
Hide file tree
Showing 25 changed files with 1,374 additions and 738 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions crates/configuration/src/schema/database.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ pub struct Collection {
/// The name of a type declared in `objectTypes` that describes the fields of this collection.
/// The type name may be the same as the collection name.
pub r#type: String,
#[serde(default)]
#[serde(default, skip_serializing_if = "Option::is_none")]
pub description: Option<String>,
}

Expand Down Expand Up @@ -65,7 +65,7 @@ impl Type {
#[serde(rename_all = "camelCase")]
pub struct ObjectType {
pub fields: BTreeMap<String, ObjectField>,
#[serde(default)]
#[serde(default, skip_serializing_if = "Option::is_none")]
pub description: Option<String>,
}

Expand All @@ -88,7 +88,7 @@ impl ObjectType {
#[serde(rename_all = "camelCase")]
pub struct ObjectField {
pub r#type: Type,
#[serde(default)]
#[serde(default, skip_serializing_if = "Option::is_none")]
pub description: Option<String>,
}

Expand Down
13 changes: 13 additions & 0 deletions crates/dc-api-test-helpers/src/field.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,19 @@ macro_rules! column {
};
}

#[macro_export]
macro_rules! relation_field {
($relationship:literal => $name:literal, $query:expr) => {
(
$name.into(),
dc_api_types::Field::Relationship {
relationship: $relationship.to_owned(),
query: Box::new($query.into()),
},
)
};
}

#[macro_export()]
macro_rules! nested_object_field {
($column:literal, $query:expr) => {
Expand Down
5 changes: 5 additions & 0 deletions crates/dc-api-test-helpers/src/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@ impl QueryBuilder {
self.predicate = Some(predicate);
self
}

pub fn order_by(mut self, order_by: OrderBy) -> Self {
self.order_by = Some(Some(order_by));
self
}
}

impl From<QueryBuilder> for Query {
Expand Down
5 changes: 5 additions & 0 deletions crates/dc-api-test-helpers/src/query_request.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@ impl QueryRequestBuilder {
self.query = Some(query.into());
self
}

pub fn relationships(mut self, relationships: impl Into<Vec<TableRelationships>>) -> Self {
self.relationships = Some(relationships.into());
self
}
}

impl From<QueryRequestBuilder> for QueryRequest {
Expand Down
12 changes: 8 additions & 4 deletions crates/mongodb-agent-common/src/query/column_ref.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use dc_api_types::comparison_column::ColumnSelector;
use dc_api_types::ComparisonColumn;

use crate::{
interface_types::MongoAgentError,
Expand All @@ -11,18 +11,22 @@ use crate::{
///
/// evaluating them as expressions.
pub fn column_ref(
column_name: &ColumnSelector,
column: &ComparisonColumn,
collection_name: Option<&str>,
) -> Result<String, MongoAgentError> {
if column.path.as_ref().map(|path| !path.is_empty()).unwrap_or(false) {
return Err(MongoAgentError::NotImplemented("comparisons against root query table columns"))
}

let reference = if let Some(collection) = collection_name {
// This assumes that a related collection has been brought into scope by a $lookup stage.
format!(
"{}.{}",
safe_name(collection)?,
safe_column_selector(column_name)?
safe_column_selector(&column.name)?
)
} else {
format!("{}", safe_column_selector(column_name)?)
format!("{}", safe_column_selector(&column.name)?)
};
Ok(reference)
}
8 changes: 4 additions & 4 deletions crates/mongodb-agent-common/src/query/make_selector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ fn make_selector_helper(
value,
} => {
let mongo_op = ComparisonFunction::try_from(operator)?;
let col = column_ref(&column.name, in_table)?;
let col = column_ref(column, in_table)?;
let comparison_value = match value {
ComparisonValue::AnotherColumnComparison { .. } => Err(
MongoAgentError::NotImplemented("comparisons between columns"),
Expand Down Expand Up @@ -117,7 +117,7 @@ fn make_selector_helper(
})
.collect::<Result<_, MongoAgentError>>()?;
Ok(doc! {
column_ref(&column.name, in_table)?: {
column_ref(column, in_table)?: {
mongo_op: values
}
})
Expand All @@ -129,11 +129,11 @@ fn make_selector_helper(
// value is null or is absent. Checking for type 10 returns true if the value is
// null, but false if it is absent.
Ok(doc! {
column_ref(&column.name, in_table)?: { "$type": 10 }
column_ref(column, in_table)?: { "$type": 10 }
})
}
UnaryComparisonOperator::CustomUnaryComparisonOperator(op) => {
let col = column_ref(&column.name, in_table)?;
let col = column_ref(column, in_table)?;
if op == "$exists" {
Ok(doc! { col: { "$exists": true } })
} else {
Expand Down
1 change: 1 addition & 0 deletions crates/mongodb-connector/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ futures = "^0.3"
http = "^0.2"
indexmap = { version = "2.1.0", features = ["serde"] }
itertools = "^0.10"
lazy_static = "^1.4.0"
mongodb = "2.8"
mongodb-agent-common = { path = "../mongodb-agent-common" }
mongodb-support = { path = "../mongodb-support" }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,21 @@ pub enum ConversionError {
#[error("Unknown scalar type, \"{0}\"")]
UnknownScalarType(String),

#[error("Unknown object type, \"{0}\"")]
UnknownObjectType(String),

#[error("Unknown field \"{field_name}\" in object type \"{object_type}\"")]
UnknownObjectTypeField { object_type: String, field_name: String },

#[error("Unknown collection, \"{0}\"")]
UnknownCollection(String),

#[error("Unknown relationship, \"{0}\"")]
UnknownRelationship(String),

#[error("Unknown aggregate function, \"{aggregate_function}\" in scalar type \"{scalar_type}\"")]
UnknownAggregateFunction { scalar_type: String, aggregate_function: String },

#[error("Query referenced a function, \"{0}\", but it has not been defined")]
UnspecifiedFunction(String),

Expand Down
17 changes: 1 addition & 16 deletions crates/mongodb-connector/src/api_type_conversions/helpers.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::collections::BTreeMap;

use ndc_sdk::models::{self as v3, ComparisonOperatorDefinition, ScalarType};
use ndc_sdk::models::{self as v3};

use super::ConversionError;

Expand All @@ -12,18 +12,3 @@ pub fn lookup_relationship<'a>(
.get(relationship)
.ok_or_else(|| ConversionError::UnspecifiedRelation(relationship.to_owned()))
}

pub fn lookup_operator_definition(
scalar_types: &BTreeMap<String, ScalarType>,
type_name: &str,
operator: &str,
) -> Result<ComparisonOperatorDefinition, ConversionError> {
let scalar_type = scalar_types
.get(type_name)
.ok_or_else(|| ConversionError::UnknownScalarType(type_name.to_owned()))?;
let operator = scalar_type
.comparison_operators
.get(operator)
.ok_or_else(|| ConversionError::UnknownComparisonOperator(operator.to_owned()))?;
Ok(operator.clone())
}
Loading

0 comments on commit 7ee4860

Please sign in to comment.