mirror of
https://github.com/hasura/graphql-engine.git
synced 2024-12-14 17:02:49 +03:00
1c5008df7c
This is Part 3 in a stacked PR set that delivers aggregate root field support. * Part 1: OpenDD: https://github.com/hasura/v3-engine/pull/683 * Part 2: Metadata Resolve: https://github.com/hasura/v3-engine/pull/684 JIRA: [V3ENGINE-159](https://hasurahq.atlassian.net/browse/V3ENGINE-159) ## Description This PR implements the GraphQL API for aggregate root fields. The GraphQL schema matches the design in the [Aggregate and Grouping RFC](https://github.com/hasura/v3-engine/blob/main/rfcs/aggregations.md#aggregations-walkthrough). ### Schema Generation The main new part of the GraphQL schema generation can be found in `crates/schema/src/aggregates.rs`. This is where we generate the new aggregate selection types. However, the root field generation can be found in `crates/schema/src/query_root/select_aggregate.rs`. The new `filter_input` type generation lives in `crates/schema/src/model_filter_input.rs`. As this type effectively encapsulates the existing field arguments used on the Select Many root field, the code to generate them has moved into `model_filter_input.rs` and `select_many.rs` simply reuses the functionality from there (without actually using the filter input type!). ### IR The main aggregates IR generation for the aggregate root field happens in `crates/execute/src/ir/query_root/select_aggregate.rs`. It reads all the input arguments to the root field and then kicks the selection logic over to `model_aggregate_selection_ir` from `crates/execute/src/ir/model_selection.rs`. `crates/execute/src/ir/model_selection.rs` has received some refactoring to facilitate that new `model_aggregate_selection_ir` function; it mostly shares functionality with the existing `model_selection_ir`, except instead of creating fields IR, it creates aggregates IR instead. The actual reading of the aggregate selection happens in `crates/execute/src/ir/aggregates.rs`. The aggregates selection IR captures the nested JSON structure of the aggregate selection, because NDC does not return aggregates in the same nested JSON structure as the GraphQL request. NDC takes a flat list of aggregate operations to run. This captured nested JSON structure is used during response rewriting to convert NDC's flat list into the nested structure that matches the GraphQL request. The aggregate selection IR is placed onto `ModelSelection` alongside the existing fields IR. Since both fields and aggregates can be put into the one NDC request (even though they are not right now), this made sense. They both translate onto one NDC `Query`. This necessitated making the field selection optional on the `ModelSelection` (`ModelSelection.selection`), since aggregate requests currently don't use them. ### Planning `crates/execute/src/plan/model_selection.rs` takes care of mapping the aggregates into the NDC request from the generated IR. There has been a new `ProcessResponseAs` variant added in `crates/execute/src/plan.rs` to capture how to read and reshape an NDC aggregates response. This is handled in `crates/execute/src/process_response.rs` where the captured JSON structure in the IR is used to restore NDC's flat aggregates list into the required nested JSON output structure. ### Testing The Custom Connector has been updated with functionality to allow aggregates over nested object fields (`crates/custom-connector/src/query.rs`). New execution and introspection tests have been added to `crates/engine/tests/execute/aggregates/` to test aggregates against Postgres and the Custom Connector. [V3ENGINE-159]: https://hasurahq.atlassian.net/browse/V3ENGINE-159?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ V3_GIT_ORIGIN_REV_ID: ff47f13eaca70d10de21e102a6667110f8f8af40 |
||
---|---|---|
.. | ||
benches | ||
bin/engine | ||
src | ||
tests | ||
build.rs | ||
Cargo.toml |