Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Propagate types from the v3 schema into the v2 query request #22

Merged
merged 7 commits into from
Apr 2, 2024

Conversation

daniel-chambers
Copy link
Contributor

@daniel-chambers daniel-chambers commented Mar 28, 2024

In v2 queries, the types of columns or scalar values were often inlined into the query. In v3, the types are omitted from the query and the connector is expected to remember the types from the schema stored in its state.

This PR updates the code that maps v3 queries into v2 queries to ensure all types are inlined into the v2 query from the v3 schema.

Some bugs were fixed along the way:

  • Queries with predicates that compare against columns in the root query table have been blocked as currently unsupported instead of incorrectly reading the column from the current table
  • Order by elements that involved relations were not correctly generating a relations (v2::OrderBy.relations) map. They now are.
  • v3 queries with predicates that involve comparisons against columns in other tables via the column path have been blocked as not supported. This was previously incorrectly mapped to the v2::ComparisonColumn.path property, but this property only ever supported the current table and the query root table, and never an arbitrary path of relationships like v3.

Also: v3 scalar types were being generated every time they were needed; however, this is static data, so they have been generated once and stored in a lazy static and are now reused everywhere.

Issue ticket number and link

JIRA: MDB-7

Copy link
Collaborator

@hallettj hallettj left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks Daniel, this is a great help! I appreciate all the improvements you've made here - it's a reassurance to have another set of eyes looking at this

Comment on lines 13 to +19
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"))
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good thinking! I reopened MDB-6 because I think we can support this, but that's a separate piece of work.

Comment on lines +96 to +101
fn v3_to_v2_query(
context: &QueryContext,
collection_relationships: &BTreeMap<String, v3::Relationship>,
root_collection_object_type: &WithNameRef<schema::ObjectType>,
query: v3::Query,
collection_object_type: &WithNameRef<schema::ObjectType>,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It could be helpful to move some of these arguments into QueryContext, especially since there are two arguments with the same type. But it's not something I'd hold the PR up for.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought about it but if we did that we'd need to stop the caller from being the one constructing and passing the QueryContext and make it internal use only. Right now, this struct is used for the caller to pass contextual information, not as a way for this module to have convenient access to "global" information.

I'm going to defer doing this, because frankly this whole module will be deleted when we eventually get rid of the v2 compat layer and go v3 native.

// v2 does not support navigating the same relationship more than once across multiple
// order by elements and having different predicates used on the same relationship in
// different order by elements. This appears to be technically supported by NDC.
return Err(ConversionError::NotImplemented("Relationships used in order by elements cannot contain different predicates when used more than once"))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, yes this seems like it would be a little tricky to fully support

.transpose()?,
})
}

fn merge_order_by_relations(rels1: &mut HashMap<String, v2::OrderByRelation>, rels2: HashMap<String, v2::OrderByRelation>) -> Result<(), ConversionError> {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice improvement - thanks!

let v3_relationship = lookup_relationship(collection_relationships, &relationship)?;
let v3_collection = context.find_collection(&v3_relationship.target_collection)?;
let collection_object_type = context.find_object_type(&v3_collection.r#type)?;
let in_table = v2::ExistsInTable::RelatedTable { relationship };
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe need to capture a predicate here? But that is beyond the scope of propagating types so just something to think about following up on.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think so. In v3 there's no predicate on the v3::ExistsInCollection::Related, and in v2 additional predicates are already inlined into the overall predicate expression.

It's different in order by because order by isn't a predicate structure, so it needed a place to put additional non-join predicates (ie permissions predicates). Where clause predicates are a predicate structure so the permissions predicates are inlined into the overall predicate expression.

Comment on lines +435 to +441
v2_relations.insert(
path_element.relationship,
v2::OrderByRelation {
r#where: where_expr,
subrelations,
}
);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok so you're hoisting the order_by predicates. Good thinking. I forget if we still need to do something similar for comparison targets. I'm not sure if my TODO comment still applies to that case.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, with comparison targets in predicates, and predicates from the permissions system (which is what these order by predicates are for) should already been inlined into the predicate body.

Comment on lines 12 to 13
#[macro_use]
extern crate lazy_static;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You don't need macro_use anymore. You can import macros in the modules where they are used, in this case with use lazy_static::lazy_static

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah nice one. Fixed.

Copy link
Collaborator

@hallettj hallettj left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry - I've got to change my review. I did a test query,

query MyQuery {
  artist {
    Name
    ArtistId
  }
}

and I'm getting an error,

Unknown collection, "Artist"

Copy link
Collaborator

@hallettj hallettj left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh sorry - it wasn't an issue with your changes. The connector configuration fixture hadn't been updated for the schema directory configuration change.

@daniel-chambers
Copy link
Contributor Author

@hallettj Thanks for fixing those integration tests. 🙏

@daniel-chambers daniel-chambers merged commit 7ee4860 into main Apr 2, 2024
1 check passed
@daniel-chambers daniel-chambers deleted the daniel/type-propagation branch April 2, 2024 01:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants