From 1a52cbaca232b4967e543872ddfa970027b7a2b4 Mon Sep 17 00:00:00 2001 From: Jesse Hallett Date: Tue, 20 Aug 2024 14:10:08 -0700 Subject: [PATCH 01/10] enable all aggregation and comparison functions for extended json --- .../src/scalar_types_capabilities.rs | 43 ++++++++++++++++++- 1 file changed, 41 insertions(+), 2 deletions(-) diff --git a/crates/mongodb-agent-common/src/scalar_types_capabilities.rs b/crates/mongodb-agent-common/src/scalar_types_capabilities.rs index 34b08b12..c8942923 100644 --- a/crates/mongodb-agent-common/src/scalar_types_capabilities.rs +++ b/crates/mongodb-agent-common/src/scalar_types_capabilities.rs @@ -25,12 +25,51 @@ pub fn scalar_types() -> BTreeMap { } fn extended_json_scalar_type() -> (ndc_models::ScalarTypeName, ScalarType) { + // Extended JSON could be anything, so allow all aggregation functions + let aggregation_functions = enum_iterator::all::(); + + // Extended JSON could be anything, so allow all comparison operators + let comparison_operators = enum_iterator::all::(); + + let ext_json_type = Type::Named { + name: mongodb_support::EXTENDED_JSON_TYPE_NAME.into(), + }; + ( mongodb_support::EXTENDED_JSON_TYPE_NAME.into(), ScalarType { representation: Some(TypeRepresentation::JSON), - aggregate_functions: BTreeMap::new(), - comparison_operators: BTreeMap::new(), + aggregate_functions: aggregation_functions + .into_iter() + .map(|aggregation_function| { + let name = aggregation_function.graphql_name().into(); + let result_type = match aggregation_function { + AggregationFunction::Avg => ext_json_type.clone(), + AggregationFunction::Count => bson_to_named_type(S::Int), + AggregationFunction::Min => ext_json_type.clone(), + AggregationFunction::Max => ext_json_type.clone(), + AggregationFunction::Sum => ext_json_type.clone(), + }; + let definition = AggregateFunctionDefinition { result_type }; + (name, definition) + }) + .collect(), + comparison_operators: comparison_operators + .into_iter() + .map(|comparison_fn| { + let name = comparison_fn.graphql_name().into(); + let definition = match comparison_fn { + C::Equal => ComparisonOperatorDefinition::Equal, + C::Regex | C::IRegex => ComparisonOperatorDefinition::Custom { + argument_type: bson_to_named_type(S::String), + }, + _ => ComparisonOperatorDefinition::Custom { + argument_type: ext_json_type.clone(), + }, + }; + (name, definition) + }) + .collect(), }, ) } From ac5ee70e3bca207b31037e3449a252f7703586e4 Mon Sep 17 00:00:00 2001 From: Jesse Hallett Date: Tue, 20 Aug 2024 15:06:16 -0700 Subject: [PATCH 02/10] add ddn cli to dev shell --- flake.lock | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- flake.nix | 6 +++++ 2 files changed, 77 insertions(+), 2 deletions(-) diff --git a/flake.lock b/flake.lock index 5251bd59..e97caec5 100644 --- a/flake.lock +++ b/flake.lock @@ -116,6 +116,24 @@ "type": "indirect" } }, + "flake-utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1710146030, + "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, "graphql-engine-source": { "flake": false, "locked": { @@ -148,6 +166,25 @@ "type": "github" } }, + "hasura-ddn-cli": { + "inputs": { + "flake-utils": "flake-utils", + "nixpkgs": "nixpkgs" + }, + "locked": { + "lastModified": 1723539998, + "narHash": "sha256-9w9uF5JVPbIUXNf/HY+ug5yspXxVcLwFBE6KRgFhWZQ=", + "owner": "TheInnerLight", + "repo": "hasura-ddn-cli-nix", + "rev": "7e0bda12c484f08d194377389191c1a58920b2b1", + "type": "github" + }, + "original": { + "owner": "TheInnerLight", + "repo": "hasura-ddn-cli-nix", + "type": "github" + } + }, "hercules-ci-effects": { "inputs": { "flake-parts": "flake-parts_2", @@ -171,6 +208,22 @@ } }, "nixpkgs": { + "locked": { + "lastModified": 1723362943, + "narHash": "sha256-dFZRVSgmJkyM0bkPpaYRtG/kRMRTorUIDj8BxoOt1T4=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "a58bc8ad779655e790115244571758e8de055e3d", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_2": { "locked": { "lastModified": 1720542800, "narHash": "sha256-ZgnNHuKV6h2+fQ5LuqnUaqZey1Lqqt5dTUAiAnqH0QQ=", @@ -193,9 +246,10 @@ "crane": "crane", "flake-compat": "flake-compat", "graphql-engine-source": "graphql-engine-source", - "nixpkgs": "nixpkgs", + "hasura-ddn-cli": "hasura-ddn-cli", + "nixpkgs": "nixpkgs_2", "rust-overlay": "rust-overlay", - "systems": "systems" + "systems": "systems_2" } }, "rust-overlay": { @@ -232,6 +286,21 @@ "repo": "default", "type": "github" } + }, + "systems_2": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } } }, "root": "root", diff --git a/flake.nix b/flake.nix index fa8f28ec..e618073e 100644 --- a/flake.nix +++ b/flake.nix @@ -11,6 +11,8 @@ inputs.nixpkgs.follows = "nixpkgs"; }; + hasura-ddn-cli.url = "github:TheInnerLight/hasura-ddn-cli-nix"; + # Allows selecting arbitrary Rust toolchain configurations by editing # `rust-toolchain.toml` rust-overlay = { @@ -57,6 +59,7 @@ { self , nixpkgs , crane + , hasura-ddn-cli , rust-overlay , advisory-db , arion @@ -102,6 +105,8 @@ # compiled for Linux but with the same architecture as `localSystem`. # This is useful for building Docker images on Mac developer machines. pkgsCross.linux = mkPkgsLinux final.buildPlatform.system; + + ddn = hasura-ddn-cli.defaultPackage.${final.system}; }) ]; @@ -202,6 +207,7 @@ nativeBuildInputs = with pkgs; [ arion.packages.${pkgs.system}.default cargo-insta + ddn just mongosh pkg-config From 0499cb3cf9889f702f1b13e3105b2e0f2b611b36 Mon Sep 17 00:00:00 2001 From: Jesse Hallett Date: Tue, 20 Aug 2024 15:54:21 -0700 Subject: [PATCH 03/10] update metadata, add native query with extended json test data --- fixtures/hasura/chinook/metadata/chinook.hml | 61 ++++++++++- fixtures/hasura/chinook/subgraph.yaml | 2 +- .../metadata/scalar-types/ExtendedJSON.hml | 92 ++++++++++++++++ .../extended_json_test_data.json | 98 +++++++++++++++++ .../metadata/models/ExtendedJsonTestData.hml | 103 ++++++++++++++++++ .../sample_mflix/metadata/sample_mflix.hml | 79 +++++++++++++- fixtures/hasura/sample_mflix/subgraph.yaml | 2 +- 7 files changed, 431 insertions(+), 6 deletions(-) create mode 100644 fixtures/hasura/sample_mflix/connector/sample_mflix/native_queries/extended_json_test_data.json create mode 100644 fixtures/hasura/sample_mflix/metadata/models/ExtendedJsonTestData.hml diff --git a/fixtures/hasura/chinook/metadata/chinook.hml b/fixtures/hasura/chinook/metadata/chinook.hml index 04f844b0..d988caff 100644 --- a/fixtures/hasura/chinook/metadata/chinook.hml +++ b/fixtures/hasura/chinook/metadata/chinook.hml @@ -207,8 +207,65 @@ definition: ExtendedJSON: representation: type: json - aggregate_functions: {} - comparison_operators: {} + aggregate_functions: + avg: + result_type: + type: named + name: ExtendedJSON + count: + result_type: + type: named + name: Int + max: + result_type: + type: named + name: ExtendedJSON + min: + result_type: + type: named + name: ExtendedJSON + sum: + result_type: + type: named + name: ExtendedJSON + comparison_operators: + _eq: + type: equal + _gt: + type: custom + argument_type: + type: named + name: ExtendedJSON + _gte: + type: custom + argument_type: + type: named + name: ExtendedJSON + _iregex: + type: custom + argument_type: + type: named + name: String + _lt: + type: custom + argument_type: + type: named + name: ExtendedJSON + _lte: + type: custom + argument_type: + type: named + name: ExtendedJSON + _neq: + type: custom + argument_type: + type: named + name: ExtendedJSON + _regex: + type: custom + argument_type: + type: named + name: String Int: representation: type: int32 diff --git a/fixtures/hasura/chinook/subgraph.yaml b/fixtures/hasura/chinook/subgraph.yaml index fef4fcb2..26324e9c 100644 --- a/fixtures/hasura/chinook/subgraph.yaml +++ b/fixtures/hasura/chinook/subgraph.yaml @@ -1,5 +1,5 @@ kind: Subgraph -version: v1 +version: v2 definition: generator: rootPath: . diff --git a/fixtures/hasura/common/metadata/scalar-types/ExtendedJSON.hml b/fixtures/hasura/common/metadata/scalar-types/ExtendedJSON.hml index 37ced137..000dfda6 100644 --- a/fixtures/hasura/common/metadata/scalar-types/ExtendedJSON.hml +++ b/fixtures/hasura/common/metadata/scalar-types/ExtendedJSON.hml @@ -21,3 +21,95 @@ definition: dataConnectorName: sample_mflix dataConnectorScalarType: ExtendedJSON representation: ExtendedJSON + +--- +kind: BooleanExpressionType +version: v1 +definition: + name: ExtendedJsonComparisonExp + operand: + scalar: + type: ExtendedJSON + comparisonOperators: + - name: _eq + argumentType: ExtendedJSON + - name: _neq + argumentType: ExtendedJSON + - name: _gt + argumentType: ExtendedJSON + - name: _gte + argumentType: ExtendedJSON + - name: _lt + argumentType: ExtendedJSON + - name: _lte + argumentType: ExtendedJSON + - name: _regex + argumentType: String + - name: _iregex + argumentType: String + dataConnectorOperatorMapping: + - dataConnectorName: chinook + dataConnectorScalarType: ExtendedJSON + operatorMapping: + _eq: _eq + _neq: _neq + _gt: _gt + _gte: _gte + _lt: _lt + _lte: _lte + _regex: _regex + _iregex: _iregex + - dataConnectorName: sample_mflix + dataConnectorScalarType: ExtendedJSON + operatorMapping: + _eq: _eq + _neq: _neq + _gt: _gt + _gte: _gte + _lt: _lt + _lte: _lte + _regex: _regex + _iregex: _iregex + logicalOperators: + enable: true + isNull: + enable: true + graphql: + typeName: ExtendedJsonComparisonExp + +--- +kind: AggregateExpression +version: v1 +definition: + name: ExtendedJsonAggregateExp + operand: + scalar: + aggregatedType: ExtendedJSON + aggregationFunctions: + - name: _avg + returnType: ExtendedJSON + - name: _max + returnType: ExtendedJSON + - name: _min + returnType: ExtendedJSON + - name: _sum + returnType: ExtendedJSON + dataConnectorAggregationFunctionMapping: + - dataConnectorName: chinook + dataConnectorScalarType: ExtendedJSON + functionMapping: + _avg: { name: avg } + _max: { name: max } + _min: { name: min } + _sum: { name: sum } + - dataConnectorName: sample_mflix + dataConnectorScalarType: ExtendedJSON + functionMapping: + _avg: { name: avg } + _max: { name: max } + _min: { name: min } + _sum: { name: sum } + count: { enable: true } + countDistinct: { enable: true } + graphql: + selectTypeName: ExtendedJsonAggregateExp diff --git a/fixtures/hasura/sample_mflix/connector/sample_mflix/native_queries/extended_json_test_data.json b/fixtures/hasura/sample_mflix/connector/sample_mflix/native_queries/extended_json_test_data.json new file mode 100644 index 00000000..fd43809c --- /dev/null +++ b/fixtures/hasura/sample_mflix/connector/sample_mflix/native_queries/extended_json_test_data.json @@ -0,0 +1,98 @@ +{ + "name": "extended_json_test_data", + "representation": "collection", + "description": "various values that all have the ExtendedJSON type", + "resultDocumentType": "DocWithExtendedJsonValue", + "objectTypes": { + "DocWithExtendedJsonValue": { + "fields": { + "type": { + "type": { + "scalar": "string" + } + }, + "value": { + "type": "extendedJSON" + } + } + } + }, + "pipeline": [ + { + "$documents": [ + { + "type": "decimal", + "value": { + "$numberDecimal": "1" + } + }, + { + "type": "decimal", + "value": { + "$numberDecimal": "2" + } + }, + { + "type": "double", + "value": { + "$numberDouble": "3" + } + }, + { + "type": "double", + "value": { + "$numberDouble": "4" + } + }, + { + "type": "int", + "value": { + "$numberInt": "5" + } + }, + { + "type": "int", + "value": { + "$numberInt": "6" + } + }, + { + "type": "long", + "value": { + "$numberLong": "7" + } + }, + { + "type": "long", + "value": { + "$numberLong": "8" + } + }, + { + "type": "string", + "value": "foo" + }, + { + "type": "string", + "value": "hello, world!" + }, + { + "type": "date", + "value": { + "$date": "2024-08-20T14:38:00Z" + } + }, + { + "type": "date", + "value": { + "$date": "2021-11-22T09:00:00Z" + } + }, + { + "type": "null", + "value": null + } + ] + } + ] +} diff --git a/fixtures/hasura/sample_mflix/metadata/models/ExtendedJsonTestData.hml b/fixtures/hasura/sample_mflix/metadata/models/ExtendedJsonTestData.hml new file mode 100644 index 00000000..5e72c31f --- /dev/null +++ b/fixtures/hasura/sample_mflix/metadata/models/ExtendedJsonTestData.hml @@ -0,0 +1,103 @@ +--- +kind: ObjectType +version: v1 +definition: + name: DocWithExtendedJsonValue + fields: + - name: type + type: String! + - name: value + type: ExtendedJSON + graphql: + typeName: DocWithExtendedJsonValue + inputTypeName: DocWithExtendedJsonValueInput + dataConnectorTypeMapping: + - dataConnectorName: sample_mflix + dataConnectorObjectType: DocWithExtendedJsonValue + +--- +kind: TypePermissions +version: v1 +definition: + typeName: DocWithExtendedJsonValue + permissions: + - role: admin + output: + allowedFields: + - type + - value + +--- +kind: BooleanExpressionType +version: v1 +definition: + name: DocWithExtendedJsonValueComparisonExp + operand: + object: + type: DocWithExtendedJsonValue + comparableFields: + - fieldName: type + booleanExpressionType: StringComparisonExp + - fieldName: value + booleanExpressionType: ExtendedJsonComparisonExp + comparableRelationships: [] + logicalOperators: + enable: true + isNull: + enable: true + graphql: + typeName: DocWithExtendedJsonValueComparisonExp + +--- +kind: AggregateExpression +version: v1 +definition: + name: DocWithExtendedJsonValueAggregateExp + operand: + object: + aggregatedType: DocWithExtendedJsonValue + aggregatableFields: + - fieldName: value + aggregateExpression: ExtendedJsonAggregateExp + count: { enable: true } + graphql: + selectTypeName: DocWithExtendedJsonValueAggregateExp + +--- +kind: Model +version: v1 +definition: + name: ExtendedJsonTestData + objectType: DocWithExtendedJsonValue + source: + dataConnectorName: sample_mflix + collection: extended_json_test_data + aggregateExpression: DocWithExtendedJsonValueAggregateExp + filterExpressionType: DocWithExtendedJsonValueComparisonExp + orderableFields: + - fieldName: type + orderByDirections: + enableAll: true + - fieldName: value + orderByDirections: + enableAll: true + graphql: + aggregate: + queryRootField: extendedJsonTestDataAggregate + filterInputTypeName: ExtendedJsonTestDataFilterInput + selectMany: + queryRootField: extendedJsonTestData + selectUniques: [] + orderByExpressionType: ExtendedJsonTestDataOrderBy + description: various values that all have the ExtendedJSON type + +--- +kind: ModelPermissions +version: v1 +definition: + modelName: ExtendedJsonTestData + permissions: + - role: admin + select: + filter: null + diff --git a/fixtures/hasura/sample_mflix/metadata/sample_mflix.hml b/fixtures/hasura/sample_mflix/metadata/sample_mflix.hml index e552ce2f..020cf95a 100644 --- a/fixtures/hasura/sample_mflix/metadata/sample_mflix.hml +++ b/fixtures/hasura/sample_mflix/metadata/sample_mflix.hml @@ -207,8 +207,65 @@ definition: ExtendedJSON: representation: type: json - aggregate_functions: {} - comparison_operators: {} + aggregate_functions: + avg: + result_type: + type: named + name: ExtendedJSON + count: + result_type: + type: named + name: Int + max: + result_type: + type: named + name: ExtendedJSON + min: + result_type: + type: named + name: ExtendedJSON + sum: + result_type: + type: named + name: ExtendedJSON + comparison_operators: + _eq: + type: equal + _gt: + type: custom + argument_type: + type: named + name: ExtendedJSON + _gte: + type: custom + argument_type: + type: named + name: ExtendedJSON + _iregex: + type: custom + argument_type: + type: named + name: String + _lt: + type: custom + argument_type: + type: named + name: ExtendedJSON + _lte: + type: custom + argument_type: + type: named + name: ExtendedJSON + _neq: + type: custom + argument_type: + type: named + name: ExtendedJSON + _regex: + type: custom + argument_type: + type: named + name: String Int: representation: type: int32 @@ -517,6 +574,18 @@ definition: type: named name: Undefined object_types: + DocWithExtendedJsonValue: + fields: + type: + type: + type: named + name: String + value: + type: + type: nullable + underlying_type: + type: named + name: ExtendedJSON Hello: fields: __value: @@ -910,6 +979,12 @@ definition: unique_columns: - _id foreign_keys: {} + - name: extended_json_test_data + description: various values that all have the ExtendedJSON type + arguments: {} + type: DocWithExtendedJsonValue + uniqueness_constraints: {} + foreign_keys: {} - name: movies arguments: {} type: movies diff --git a/fixtures/hasura/sample_mflix/subgraph.yaml b/fixtures/hasura/sample_mflix/subgraph.yaml index 6b571d44..f91cd615 100644 --- a/fixtures/hasura/sample_mflix/subgraph.yaml +++ b/fixtures/hasura/sample_mflix/subgraph.yaml @@ -1,5 +1,5 @@ kind: Subgraph -version: v1 +version: v2 definition: generator: rootPath: . From 4f13450539719c93a001d26cfa7cb9251e2afa7b Mon Sep 17 00:00:00 2001 From: Jesse Hallett Date: Tue, 20 Aug 2024 16:12:26 -0700 Subject: [PATCH 04/10] wip: --- .../src/tests/aggregation.rs | 36 +++++++++++++++++++ flake.lock | 17 +++++---- flake.nix | 6 ++-- 3 files changed, 47 insertions(+), 12 deletions(-) diff --git a/crates/integration-tests/src/tests/aggregation.rs b/crates/integration-tests/src/tests/aggregation.rs index 299f68cf..6649f4fe 100644 --- a/crates/integration-tests/src/tests/aggregation.rs +++ b/crates/integration-tests/src/tests/aggregation.rs @@ -37,3 +37,39 @@ async fn runs_aggregation_over_top_level_fields() -> anyhow::Result<()> { ); Ok(()) } + +#[tokio::test] +async fn aggregates_extended_json_representing_mixture_of_numeric_types() -> anyhow::Result<()> { + assert_yaml_snapshot!( + graphql_query( + r#" + query { + + track(order_by: { id: Asc }, where: { albumId: { _eq: $albumId } }) { + milliseconds + unitPrice + } + trackAggregate( + filter_input: { order_by: { id: Asc }, where: { albumId: { _eq: $albumId } } } + ) { + _count + milliseconds { + _avg + _max + _min + _sum + } + unitPrice { + _count + _count_distinct + } + } + } + "# + ) + .variables(json!({ "albumId": 9 })) + .run() + .await? + ); + Ok(()) +} diff --git a/flake.lock b/flake.lock index e97caec5..d2b2fc52 100644 --- a/flake.lock +++ b/flake.lock @@ -172,17 +172,16 @@ "nixpkgs": "nixpkgs" }, "locked": { - "lastModified": 1723539998, - "narHash": "sha256-9w9uF5JVPbIUXNf/HY+ug5yspXxVcLwFBE6KRgFhWZQ=", - "owner": "TheInnerLight", - "repo": "hasura-ddn-cli-nix", - "rev": "7e0bda12c484f08d194377389191c1a58920b2b1", - "type": "github" + "dirtyRev": "deddc18875d3c691553f50b27dc9c249552fc545-dirty", + "dirtyShortRev": "deddc18-dirty", + "lastModified": 1724193024, + "narHash": "sha256-VU7JvulNSIfQoltHjaBhUD9uFOFiwshqi8h1Q0MM39Q=", + "type": "git", + "url": "file:///home/jesse/projects/hasura/hasura-ddn-cli-nix" }, "original": { - "owner": "TheInnerLight", - "repo": "hasura-ddn-cli-nix", - "type": "github" + "type": "git", + "url": "file:///home/jesse/projects/hasura/hasura-ddn-cli-nix" } }, "hercules-ci-effects": { diff --git a/flake.nix b/flake.nix index e618073e..21d21227 100644 --- a/flake.nix +++ b/flake.nix @@ -11,7 +11,8 @@ inputs.nixpkgs.follows = "nixpkgs"; }; - hasura-ddn-cli.url = "github:TheInnerLight/hasura-ddn-cli-nix"; + # hasura-ddn-cli.url = "github:TheInnerLight/hasura-ddn-cli-nix"; + hasura-ddn-cli.url = "git+file:///home/jesse/projects/hasura/hasura-ddn-cli-nix"; # Allows selecting arbitrary Rust toolchain configurations by editing # `rust-toolchain.toml` @@ -72,6 +73,7 @@ # packages or replace packages in that set. overlays = [ (import rust-overlay) + hasura-ddn-cli.overlays.default (final: prev: { # What's the deal with `pkgsBuildHost`? It has to do with # cross-compiling. @@ -105,8 +107,6 @@ # compiled for Linux but with the same architecture as `localSystem`. # This is useful for building Docker images on Mac developer machines. pkgsCross.linux = mkPkgsLinux final.buildPlatform.system; - - ddn = hasura-ddn-cli.defaultPackage.${final.system}; }) ]; From d67ba3c287db457cd03e875c94f947d2240e59cf Mon Sep 17 00:00:00 2001 From: Jesse Hallett Date: Thu, 22 Aug 2024 12:29:36 -0700 Subject: [PATCH 05/10] get cli from hasura repo --- flake.lock | 17 +++++++++-------- flake.nix | 6 +++--- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/flake.lock b/flake.lock index d2b2fc52..33c900d4 100644 --- a/flake.lock +++ b/flake.lock @@ -172,16 +172,17 @@ "nixpkgs": "nixpkgs" }, "locked": { - "dirtyRev": "deddc18875d3c691553f50b27dc9c249552fc545-dirty", - "dirtyShortRev": "deddc18-dirty", - "lastModified": 1724193024, - "narHash": "sha256-VU7JvulNSIfQoltHjaBhUD9uFOFiwshqi8h1Q0MM39Q=", - "type": "git", - "url": "file:///home/jesse/projects/hasura/hasura-ddn-cli-nix" + "lastModified": 1724197678, + "narHash": "sha256-yXS2S3nmHKur+pKgcg3imMz+xBKf211jUEHwtVbWhUk=", + "owner": "hasura", + "repo": "ddn-cli-nix", + "rev": "4a1279dbb2fe79f447cd409df710eee3a98fc16e", + "type": "github" }, "original": { - "type": "git", - "url": "file:///home/jesse/projects/hasura/hasura-ddn-cli-nix" + "owner": "hasura", + "repo": "ddn-cli-nix", + "type": "github" } }, "hercules-ci-effects": { diff --git a/flake.nix b/flake.nix index 21d21227..b5c2756b 100644 --- a/flake.nix +++ b/flake.nix @@ -11,8 +11,7 @@ inputs.nixpkgs.follows = "nixpkgs"; }; - # hasura-ddn-cli.url = "github:TheInnerLight/hasura-ddn-cli-nix"; - hasura-ddn-cli.url = "git+file:///home/jesse/projects/hasura/hasura-ddn-cli-nix"; + hasura-ddn-cli.url = "github:hasura/ddn-cli-nix"; # Allows selecting arbitrary Rust toolchain configurations by editing # `rust-toolchain.toml` @@ -73,7 +72,6 @@ # packages or replace packages in that set. overlays = [ (import rust-overlay) - hasura-ddn-cli.overlays.default (final: prev: { # What's the deal with `pkgsBuildHost`? It has to do with # cross-compiling. @@ -107,6 +105,8 @@ # compiled for Linux but with the same architecture as `localSystem`. # This is useful for building Docker images on Mac developer machines. pkgsCross.linux = mkPkgsLinux final.buildPlatform.system; + + ddn = hasura-ddn-cli.defaultPackage.${final.system}; }) ]; From 8b899fc8dd20906b0c7b8477722535d34b6bd104 Mon Sep 17 00:00:00 2001 From: Jesse Hallett Date: Thu, 22 Aug 2024 12:29:49 -0700 Subject: [PATCH 06/10] integration tests --- .../src/tests/aggregation.rs | 52 ++++++++++++++----- .../integration-tests/src/tests/filtering.rs | 24 +++++++++ crates/integration-tests/src/tests/mod.rs | 1 + ...representing_mixture_of_numeric_types.snap | 43 +++++++++++++++ ...es_mixture_of_numeric_and_null_values.snap | 27 ++++++++++ ...extended_json_using_string_comparison.snap | 9 ++++ 6 files changed, 144 insertions(+), 12 deletions(-) create mode 100644 crates/integration-tests/src/tests/filtering.rs create mode 100644 crates/integration-tests/src/tests/snapshots/integration_tests__tests__aggregation__aggregates_extended_json_representing_mixture_of_numeric_types.snap create mode 100644 crates/integration-tests/src/tests/snapshots/integration_tests__tests__aggregation__aggregates_mixture_of_numeric_and_null_values.snap create mode 100644 crates/integration-tests/src/tests/snapshots/integration_tests__tests__filtering__filters_on_extended_json_using_string_comparison.snap diff --git a/crates/integration-tests/src/tests/aggregation.rs b/crates/integration-tests/src/tests/aggregation.rs index 6649f4fe..6b35a1b3 100644 --- a/crates/integration-tests/src/tests/aggregation.rs +++ b/crates/integration-tests/src/tests/aggregation.rs @@ -43,31 +43,59 @@ async fn aggregates_extended_json_representing_mixture_of_numeric_types() -> any assert_yaml_snapshot!( graphql_query( r#" - query { - - track(order_by: { id: Asc }, where: { albumId: { _eq: $albumId } }) { - milliseconds - unitPrice - } - trackAggregate( - filter_input: { order_by: { id: Asc }, where: { albumId: { _eq: $albumId } } } + query ($types: String!) { + extendedJsonTestDataAggregate( + filter_input: { where: { type: { _regex: $types } } } ) { - _count - milliseconds { + value { _avg + _count _max _min _sum + _count_distinct } - unitPrice { + } + extendedJsonTestData(where: { type: { _regex: $types } }) { + type + value + } + } + "# + ) + .variables(json!({ "types": "decimal|double|int|long" })) + .run() + .await? + ); + Ok(()) +} + +#[tokio::test] +async fn aggregates_mixture_of_numeric_and_null_values() -> anyhow::Result<()> { + assert_yaml_snapshot!( + graphql_query( + r#" + query ($types: String!) { + extendedJsonTestDataAggregate( + filter_input: { where: { type: { _regex: $types } } } + ) { + value { + _avg _count + _max + _min + _sum _count_distinct } } + extendedJsonTestData(where: { type: { _regex: $types } }) { + type + value + } } "# ) - .variables(json!({ "albumId": 9 })) + .variables(json!({ "types": "double|null" })) .run() .await? ); diff --git a/crates/integration-tests/src/tests/filtering.rs b/crates/integration-tests/src/tests/filtering.rs new file mode 100644 index 00000000..ccc9698e --- /dev/null +++ b/crates/integration-tests/src/tests/filtering.rs @@ -0,0 +1,24 @@ +use insta::assert_yaml_snapshot; +use serde_json::json; + +use crate::graphql_query; + +#[tokio::test] +async fn filters_on_extended_json_using_string_comparison() -> anyhow::Result<()> { + assert_yaml_snapshot!( + graphql_query( + r#" + query Filtering { + extendedJsonTestData(where: { value: { _regex: "hello" } }) { + type + value + } + } + "# + ) + .variables(json!({ "types": "double|null" })) + .run() + .await? + ); + Ok(()) +} diff --git a/crates/integration-tests/src/tests/mod.rs b/crates/integration-tests/src/tests/mod.rs index 0b687af9..c1e59e22 100644 --- a/crates/integration-tests/src/tests/mod.rs +++ b/crates/integration-tests/src/tests/mod.rs @@ -9,6 +9,7 @@ mod aggregation; mod basic; +mod filtering; mod local_relationship; mod native_mutation; mod native_query; diff --git a/crates/integration-tests/src/tests/snapshots/integration_tests__tests__aggregation__aggregates_extended_json_representing_mixture_of_numeric_types.snap b/crates/integration-tests/src/tests/snapshots/integration_tests__tests__aggregation__aggregates_extended_json_representing_mixture_of_numeric_types.snap new file mode 100644 index 00000000..8cac9767 --- /dev/null +++ b/crates/integration-tests/src/tests/snapshots/integration_tests__tests__aggregation__aggregates_extended_json_representing_mixture_of_numeric_types.snap @@ -0,0 +1,43 @@ +--- +source: crates/integration-tests/src/tests/aggregation.rs +expression: "graphql_query(r#\"\n query ($types: String!) {\n extendedJsonTestDataAggregate(\n filter_input: { where: { type: { _regex: $types } } }\n ) {\n value {\n _avg\n _count\n _max\n _min\n _sum\n _count_distinct\n }\n }\n extendedJsonTestData(where: { type: { _regex: $types } }) {\n type\n value\n }\n }\n \"#).variables(json!({\n \"types\": \"decimal|double|int|long\"\n })).run().await?" +--- +data: + extendedJsonTestDataAggregate: + value: + _avg: + $numberDecimal: "4.5" + _count: 8 + _max: + $numberLong: "8" + _min: + $numberDecimal: "1" + _sum: + $numberDecimal: "36" + _count_distinct: 8 + extendedJsonTestData: + - type: decimal + value: + $numberDecimal: "1" + - type: decimal + value: + $numberDecimal: "2" + - type: double + value: + $numberDouble: "3.0" + - type: double + value: + $numberDouble: "4.0" + - type: int + value: + $numberInt: "5" + - type: int + value: + $numberInt: "6" + - type: long + value: + $numberLong: "7" + - type: long + value: + $numberLong: "8" +errors: ~ diff --git a/crates/integration-tests/src/tests/snapshots/integration_tests__tests__aggregation__aggregates_mixture_of_numeric_and_null_values.snap b/crates/integration-tests/src/tests/snapshots/integration_tests__tests__aggregation__aggregates_mixture_of_numeric_and_null_values.snap new file mode 100644 index 00000000..1a498f8b --- /dev/null +++ b/crates/integration-tests/src/tests/snapshots/integration_tests__tests__aggregation__aggregates_mixture_of_numeric_and_null_values.snap @@ -0,0 +1,27 @@ +--- +source: crates/integration-tests/src/tests/aggregation.rs +expression: "graphql_query(r#\"\n query ($types: String!) {\n extendedJsonTestDataAggregate(\n filter_input: { where: { type: { _regex: $types } } }\n ) {\n value {\n _avg\n _count\n _max\n _min\n _sum\n _count_distinct\n }\n }\n extendedJsonTestData(where: { type: { _regex: $types } }) {\n type\n value\n }\n }\n \"#).variables(json!({\n \"types\": \"double|null\"\n })).run().await?" +--- +data: + extendedJsonTestDataAggregate: + value: + _avg: + $numberDouble: "3.5" + _count: 2 + _max: + $numberDouble: "4.0" + _min: + $numberDouble: "3.0" + _sum: + $numberDouble: "7.0" + _count_distinct: 2 + extendedJsonTestData: + - type: double + value: + $numberDouble: "3.0" + - type: double + value: + $numberDouble: "4.0" + - type: "null" + value: ~ +errors: ~ diff --git a/crates/integration-tests/src/tests/snapshots/integration_tests__tests__filtering__filters_on_extended_json_using_string_comparison.snap b/crates/integration-tests/src/tests/snapshots/integration_tests__tests__filtering__filters_on_extended_json_using_string_comparison.snap new file mode 100644 index 00000000..88d6fa6a --- /dev/null +++ b/crates/integration-tests/src/tests/snapshots/integration_tests__tests__filtering__filters_on_extended_json_using_string_comparison.snap @@ -0,0 +1,9 @@ +--- +source: crates/integration-tests/src/tests/filtering.rs +expression: "graphql_query(r#\"\n query Filtering {\n extendedJsonTestData(where: { value: { _regex: \"hello\" } }) {\n type\n value\n }\n }\n \"#).variables(json!({\n \"types\": \"double|null\"\n })).run().await?" +--- +data: + extendedJsonTestData: + - type: string + value: "hello, world!" +errors: ~ From ae0ff4654e75b990cdebfb10389026808c5c8dfd Mon Sep 17 00:00:00 2001 From: Jesse Hallett Date: Thu, 22 Aug 2024 12:36:47 -0700 Subject: [PATCH 07/10] update changelog --- CHANGELOG.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4dde5ad7..690e64c5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,14 @@ This changelog documents the changes between release versions. ## [Unreleased] +### Added + +- Extended JSON fields no support all comparison and aggregation functions ([#99](https://github.com/hasura/ndc-mongodb/pull/99)) + +### Fixed + +### Changed + ## [1.1.0] - 2024-08-16 - Accept predicate arguments in native mutations and native queries ([#92](https://github.com/hasura/ndc-mongodb/pull/92)) From 24b555e619e1d738c1d1446c93c645904a449662 Mon Sep 17 00:00:00 2001 From: Jesse Hallett Date: Thu, 22 Aug 2024 13:12:40 -0700 Subject: [PATCH 08/10] skip tests in mongodb 5 --- .../src/tests/aggregation.rs | 22 +++++++++++++++++++ .../integration-tests/src/tests/filtering.rs | 11 ++++++++++ 2 files changed, 33 insertions(+) diff --git a/crates/integration-tests/src/tests/aggregation.rs b/crates/integration-tests/src/tests/aggregation.rs index 6b35a1b3..ac8c1503 100644 --- a/crates/integration-tests/src/tests/aggregation.rs +++ b/crates/integration-tests/src/tests/aggregation.rs @@ -40,6 +40,17 @@ async fn runs_aggregation_over_top_level_fields() -> anyhow::Result<()> { #[tokio::test] async fn aggregates_extended_json_representing_mixture_of_numeric_types() -> anyhow::Result<()> { + // Skip this test in MongoDB 5 because the example fails there. We're getting an error: + // + // > Kind: Command failed: Error code 5491300 (Location5491300): $documents' is not allowed in user requests, labels: {} + // + // This doesn't affect native queries that don't use the $documents stage. + if let Ok(image) = std::env::var("MONGODB_IMAGE") { + if image == "mongo:5" { + return Ok(()); + } + } + assert_yaml_snapshot!( graphql_query( r#" @@ -72,6 +83,17 @@ async fn aggregates_extended_json_representing_mixture_of_numeric_types() -> any #[tokio::test] async fn aggregates_mixture_of_numeric_and_null_values() -> anyhow::Result<()> { + // Skip this test in MongoDB 5 because the example fails there. We're getting an error: + // + // > Kind: Command failed: Error code 5491300 (Location5491300): $documents' is not allowed in user requests, labels: {} + // + // This doesn't affect native queries that don't use the $documents stage. + if let Ok(image) = std::env::var("MONGODB_IMAGE") { + if image == "mongo:5" { + return Ok(()); + } + } + assert_yaml_snapshot!( graphql_query( r#" diff --git a/crates/integration-tests/src/tests/filtering.rs b/crates/integration-tests/src/tests/filtering.rs index ccc9698e..b306087a 100644 --- a/crates/integration-tests/src/tests/filtering.rs +++ b/crates/integration-tests/src/tests/filtering.rs @@ -5,6 +5,17 @@ use crate::graphql_query; #[tokio::test] async fn filters_on_extended_json_using_string_comparison() -> anyhow::Result<()> { + // Skip this test in MongoDB 5 because the example fails there. We're getting an error: + // + // > Kind: Command failed: Error code 5491300 (Location5491300): $documents' is not allowed in user requests, labels: {} + // + // This doesn't affect native queries that don't use the $documents stage. + if let Ok(image) = std::env::var("MONGODB_IMAGE") { + if image == "mongo:5" { + return Ok(()); + } + } + assert_yaml_snapshot!( graphql_query( r#" From 9e31e5808e58c724e7a7a61a2f1fd3e040f9970e Mon Sep 17 00:00:00 2001 From: Jesse Hallett Date: Mon, 26 Aug 2024 12:03:13 -0700 Subject: [PATCH 09/10] fix typo in changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 690e64c5..758d546b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,7 @@ This changelog documents the changes between release versions. ### Added -- Extended JSON fields no support all comparison and aggregation functions ([#99](https://github.com/hasura/ndc-mongodb/pull/99)) +- Extended JSON fields now support all comparison and aggregation functions ([#99](https://github.com/hasura/ndc-mongodb/pull/99)) ### Fixed From a687aed791531e64aef2c909d6b30917cef7f9e5 Mon Sep 17 00:00:00 2001 From: Jesse Hallett Date: Mon, 26 Aug 2024 12:17:43 -0700 Subject: [PATCH 10/10] add filtering integration test --- .../integration-tests/src/tests/filtering.rs | 2 - crates/integration-tests/src/tests/mod.rs | 1 + ...ests__sorting__sorts_on_extended_json.snap | 45 +++++++++++++++++++ crates/integration-tests/src/tests/sorting.rs | 33 ++++++++++++++ 4 files changed, 79 insertions(+), 2 deletions(-) create mode 100644 crates/integration-tests/src/tests/snapshots/integration_tests__tests__sorting__sorts_on_extended_json.snap create mode 100644 crates/integration-tests/src/tests/sorting.rs diff --git a/crates/integration-tests/src/tests/filtering.rs b/crates/integration-tests/src/tests/filtering.rs index b306087a..e0684d97 100644 --- a/crates/integration-tests/src/tests/filtering.rs +++ b/crates/integration-tests/src/tests/filtering.rs @@ -1,5 +1,4 @@ use insta::assert_yaml_snapshot; -use serde_json::json; use crate::graphql_query; @@ -27,7 +26,6 @@ async fn filters_on_extended_json_using_string_comparison() -> anyhow::Result<() } "# ) - .variables(json!({ "types": "double|null" })) .run() .await? ); diff --git a/crates/integration-tests/src/tests/mod.rs b/crates/integration-tests/src/tests/mod.rs index c1e59e22..4ef6b7b9 100644 --- a/crates/integration-tests/src/tests/mod.rs +++ b/crates/integration-tests/src/tests/mod.rs @@ -15,3 +15,4 @@ mod native_mutation; mod native_query; mod permissions; mod remote_relationship; +mod sorting; diff --git a/crates/integration-tests/src/tests/snapshots/integration_tests__tests__sorting__sorts_on_extended_json.snap b/crates/integration-tests/src/tests/snapshots/integration_tests__tests__sorting__sorts_on_extended_json.snap new file mode 100644 index 00000000..fb3c1e49 --- /dev/null +++ b/crates/integration-tests/src/tests/snapshots/integration_tests__tests__sorting__sorts_on_extended_json.snap @@ -0,0 +1,45 @@ +--- +source: crates/integration-tests/src/tests/sorting.rs +expression: "graphql_query(r#\"\n query Sorting {\n extendedJsonTestData(order_by: { value: Desc }) {\n type\n value\n }\n }\n \"#).run().await?" +--- +data: + extendedJsonTestData: + - type: date + value: + $date: + $numberLong: "1724164680000" + - type: date + value: + $date: + $numberLong: "1637571600000" + - type: string + value: "hello, world!" + - type: string + value: foo + - type: long + value: + $numberLong: "8" + - type: long + value: + $numberLong: "7" + - type: int + value: + $numberInt: "6" + - type: int + value: + $numberInt: "5" + - type: double + value: + $numberDouble: "4.0" + - type: double + value: + $numberDouble: "3.0" + - type: decimal + value: + $numberDecimal: "2" + - type: decimal + value: + $numberDecimal: "1" + - type: "null" + value: ~ +errors: ~ diff --git a/crates/integration-tests/src/tests/sorting.rs b/crates/integration-tests/src/tests/sorting.rs new file mode 100644 index 00000000..9f399215 --- /dev/null +++ b/crates/integration-tests/src/tests/sorting.rs @@ -0,0 +1,33 @@ +use insta::assert_yaml_snapshot; + +use crate::graphql_query; + +#[tokio::test] +async fn sorts_on_extended_json() -> anyhow::Result<()> { + // Skip this test in MongoDB 5 because the example fails there. We're getting an error: + // + // > Kind: Command failed: Error code 5491300 (Location5491300): $documents' is not allowed in user requests, labels: {} + // + // This doesn't affect native queries that don't use the $documents stage. + if let Ok(image) = std::env::var("MONGODB_IMAGE") { + if image == "mongo:5" { + return Ok(()); + } + } + + assert_yaml_snapshot!( + graphql_query( + r#" + query Sorting { + extendedJsonTestData(order_by: { value: Desc }) { + type + value + } + } + "# + ) + .run() + .await? + ); + Ok(()) +}