diff --git a/.changeset/few-sloths-battle.md b/.changeset/few-sloths-battle.md new file mode 100644 index 0000000000..f302ec4d5d --- /dev/null +++ b/.changeset/few-sloths-battle.md @@ -0,0 +1,7 @@ +--- +"@neo4j/graphql": major +--- + +Changes the result projection where there are multiple relationships between two nodes. + +In the case of using the connection API then multiple relationships will still be represented, as there is the ability to select the relationship properties. In the non-connection API case, the duplicate results will only return distinct results. diff --git a/packages/graphql/src/translate/queryAST/ast/operations/ReadOperation.ts b/packages/graphql/src/translate/queryAST/ast/operations/ReadOperation.ts index d6e8526604..3c8bb62a21 100644 --- a/packages/graphql/src/translate/queryAST/ast/operations/ReadOperation.ts +++ b/packages/graphql/src/translate/queryAST/ast/operations/ReadOperation.ts @@ -92,20 +92,13 @@ export class ReadOperation extends Operation { return filterTruthy(this.authFilters.map((f) => f.getPredicate(context))); } - protected getProjectionClause( - context: QueryASTContext, - returnVariable: Cypher.Variable, - isArray: boolean - ): Cypher.Return { + protected getProjectionClause(context: QueryASTContext, returnVariable: Cypher.Variable): Cypher.Return { if (!hasTarget(context)) { throw new Error("No parent node found!"); } const projection = this.getProjectionMap(context); - let aggregationExpr: Cypher.Expr = Cypher.collect(context.target); - if (!isArray) { - aggregationExpr = Cypher.head(aggregationExpr); - } + const aggregationExpr = Cypher.collect(context.target); const withClause = new Cypher.With([projection, context.target]); if (this.sortFields.length > 0 || this.pagination) { @@ -148,7 +141,7 @@ export class ReadOperation extends Operation { const authFiltersPredicate = this.getAuthFilterPredicate(nestedContext); const ret: Cypher.Return = this.relationship - ? this.getProjectionClause(nestedContext, context.returnVariable, this.relationship.isList) + ? this.getProjectionClause(nestedContext, context.returnVariable) : this.getReturnStatement( isCreateSelection || isUpdateSelection ? context : nestedContext, nestedContext.returnVariable @@ -215,6 +208,11 @@ export class ReadOperation extends Operation { } matchBlock.push(...extraMatches, extraMatchesWith); + if (this.relationship) { + const distinctTargetWith = new Cypher.With(nestedContext.target).distinct(); + matchBlock.push(distinctTargetWith); + } + clause = Cypher.utils.concat( ...matchBlock, ...authFilterSubqueries, diff --git a/packages/graphql/tests/integration/directives/relationship/duplicate-relationship/duplicate-relationship-create.int.test.ts b/packages/graphql/tests/integration/directives/relationship/duplicate-relationship/duplicate-relationship-create.int.test.ts new file mode 100644 index 0000000000..7de165176f --- /dev/null +++ b/packages/graphql/tests/integration/directives/relationship/duplicate-relationship/duplicate-relationship-create.int.test.ts @@ -0,0 +1,158 @@ +/* + * Copyright (c) "Neo4j" + * Neo4j Sweden AB [http://neo4j.com] + * + * This file is part of Neo4j. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { UniqueType } from "../../../../utils/graphql-types"; +import { TestHelper } from "../../../../utils/tests-helper"; + +describe("Create: Multiple relationships results difference between Connection API and Simple API", () => { + const testHelper: TestHelper = new TestHelper(); + const Movie: UniqueType = testHelper.createUniqueType("Movie"); + const Actor: UniqueType = testHelper.createUniqueType("Actor"); + + beforeEach(async () => { + const typeDefs = /* GraphQL */ ` + type ${Movie} @node { + title: String! + actors: [${Actor}!]! @relationship(type: "ACTED_IN", properties: "ActedIn", direction: IN) + } + + type ${Actor} @node { + name: String! + movies: [${Movie}!]! @relationship(type: "ACTED_IN", properties: "ActedIn", direction: OUT) + } + + type ActedIn @relationshipProperties { + role: String! + } + `; + await testHelper.initNeo4jGraphQL({ typeDefs }); + }); + + afterEach(async () => { + await testHelper.close(); + }); + + test("should return multiple relationship results for connection API", async () => { + const source = /* GraphQL */ ` + mutation { + ${Movie.operations.create}( + input: [ + { + title: "Movie One" + actors: { + create: [{ edge: { role: "Role One" }, node: { name: "Actor One" } }] + connect: [{ edge: { role: "Role Two" } }] + } + } + ] + ) { + ${Movie.plural} { + title + actorsConnection { + edges { + properties { + role + } + node { + name + } + } + } + } + } + } + `; + + const gqlResult = await testHelper.executeGraphQL(source); + + expect(gqlResult.errors).toBeFalsy(); + expect(gqlResult.data).toEqual({ + [Movie.operations.create]: { + [Movie.plural]: [ + { + title: "Movie One", + actorsConnection: { + edges: expect.toIncludeSameMembers([ + { + node: { + name: "Actor One", + }, + properties: { + role: "Role One", + }, + }, + { + node: { + name: "Actor One", + }, + properties: { + role: "Role Two", + }, + }, + ]), + }, + }, + ], + }, + }); + }); + + test("should only return a single relationship result for simple API", async () => { + const source = /* GraphQL */ ` + mutation { + ${Movie.operations.create}( + input: [ + { + title: "Movie One" + actors: { + create: [{ edge: { role: "Role One" }, node: { name: "Actor One" } }] + connect: [{ edge: { role: "Role Two" } }] + } + } + ] + ) { + ${Movie.plural} { + title + actors { + name + } + } + } + } + `; + + const gqlResult = await testHelper.executeGraphQL(source); + + expect(gqlResult.errors).toBeFalsy(); + expect(gqlResult.data).toEqual({ + [Movie.operations.create]: { + [Movie.plural]: [ + { + title: "Movie One", + actors: [ + { + name: "Actor One", + }, + ], + }, + ], + }, + }); + }); +}); diff --git a/packages/graphql/tests/integration/directives/relationship/duplicate-relationship/duplicate-relationship-read-interface.int.test.ts b/packages/graphql/tests/integration/directives/relationship/duplicate-relationship/duplicate-relationship-read-interface.int.test.ts new file mode 100644 index 0000000000..d701b2ec9a --- /dev/null +++ b/packages/graphql/tests/integration/directives/relationship/duplicate-relationship/duplicate-relationship-read-interface.int.test.ts @@ -0,0 +1,220 @@ +/* + * Copyright (c) "Neo4j" + * Neo4j Sweden AB [http://neo4j.com] + * + * This file is part of Neo4j. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { UniqueType } from "../../../../utils/graphql-types"; +import { TestHelper } from "../../../../utils/tests-helper"; + +describe("Interface: Multiple relationships results difference between Connection API and Simple API", () => { + const testHelper: TestHelper = new TestHelper(); + + const Production: UniqueType = testHelper.createUniqueType("Production"); + const Movie: UniqueType = testHelper.createUniqueType("Movie"); + const Series: UniqueType = testHelper.createUniqueType("Series"); + const Actor: UniqueType = testHelper.createUniqueType("Actor"); + + beforeAll(async () => { + const typeDefs = /* GraphQL */ ` + interface ${Production} { + title: String! + } + + type ${Movie} implements ${Production} @node { + title: String! + actors: [${Actor}!]! @relationship(type: "ACTED_IN", properties: "ActedIn", direction: IN) + } + + type ${Series} implements ${Production} @node { + title: String! + actors: [${Actor}!]! @relationship(type: "ACTED_IN", properties: "ActedIn", direction: IN) + } + + type ${Actor} @node { + name: String! + productions: [${Production}!]! @relationship(type: "ACTED_IN", properties: "ActedIn", direction: OUT) + } + + type ActedIn @relationshipProperties { + role: String! + } + `; + await testHelper.initNeo4jGraphQL({ typeDefs }); + + // Create duplicate relationships + await testHelper.executeCypher(` + CREATE (m:${Movie} {title: "Movie One"}) + + CREATE (s:${Series} {title: "Series One"}) + + CREATE (a:${Actor} {name: "Actor One"}) + CREATE (a)-[:ACTED_IN {role: "Movie role one"}]->(m) + CREATE (a)-[:ACTED_IN {role: "Movie role two"}]->(m) + + CREATE (a)-[:ACTED_IN {role: "Series role one"}]->(s) + CREATE (a)-[:ACTED_IN {role: "Series role two"}]->(s) + `); + }); + + afterAll(async () => { + await testHelper.close(); + }); + + test("should return multiple relationship results for connection API", async () => { + const source = /* GraphQL */ ` + query { + ${Production.operations.connection} { + edges { + node { + ...on ${Movie} { + title + actorsConnection { + edges { + node { + name + } + properties { + role + } + } + } + } + ...on ${Series} { + title + actorsConnection { + edges { + node { + name + } + properties { + role + } + } + } + } + } + } + } + } + `; + + const gqlResult = await testHelper.executeGraphQL(source); + + expect(gqlResult.errors).toBeFalsy(); + expect(gqlResult.data).toEqual({ + [Production.operations.connection]: { + edges: expect.toIncludeSameMembers([ + { + node: { + title: "Movie One", + actorsConnection: { + edges: expect.toIncludeSameMembers([ + { + node: { + name: "Actor One", + }, + properties: { + role: "Movie role one", + }, + }, + { + node: { + name: "Actor One", + }, + properties: { + role: "Movie role two", + }, + }, + ]), + }, + }, + }, + { + node: { + title: "Series One", + actorsConnection: { + edges: expect.toIncludeSameMembers([ + { + node: { + name: "Actor One", + }, + properties: { + role: "Series role one", + }, + }, + { + node: { + name: "Actor One", + }, + properties: { + role: "Series role two", + }, + }, + ]), + }, + }, + }, + ]), + }, + }); + }); + + test("should only return a single relationship result for simple API", async () => { + const source = /* GraphQL */ ` + query { + ${Production.plural} { + ...on ${Movie} { + title + actors { + name + } + } + ...on ${Series} { + title + actors { + name + } + } + } + } + `; + + const gqlResult = await testHelper.executeGraphQL(source); + + expect(gqlResult.errors).toBeFalsy(); + expect(gqlResult.data).toEqual({ + [Production.plural]: expect.toIncludeSameMembers([ + { + title: "Movie One", + actors: [ + { + name: "Actor One", + }, + ], + }, + { + title: "Series One", + actors: [ + { + name: "Actor One", + }, + ], + }, + ]), + }); + }); +}); diff --git a/packages/graphql/tests/integration/directives/relationship/duplicate-relationship/duplicate-relationship-read-union.int.test.ts b/packages/graphql/tests/integration/directives/relationship/duplicate-relationship/duplicate-relationship-read-union.int.test.ts new file mode 100644 index 0000000000..e22c21be5a --- /dev/null +++ b/packages/graphql/tests/integration/directives/relationship/duplicate-relationship/duplicate-relationship-read-union.int.test.ts @@ -0,0 +1,189 @@ +/* + * Copyright (c) "Neo4j" + * Neo4j Sweden AB [http://neo4j.com] + * + * This file is part of Neo4j. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { UniqueType } from "../../../../utils/graphql-types"; +import { TestHelper } from "../../../../utils/tests-helper"; + +describe("Union: Multiple relationships results difference between Connection API and Simple API", () => { + const testHelper: TestHelper = new TestHelper(); + + const Production: UniqueType = testHelper.createUniqueType("Production"); + const Movie: UniqueType = testHelper.createUniqueType("Movie"); + const Series: UniqueType = testHelper.createUniqueType("Series"); + const Actor: UniqueType = testHelper.createUniqueType("Actor"); + + beforeAll(async () => { + const typeDefs = /* GraphQL */ ` + type ${Movie} @node { + title: String! + actors: [${Actor}!]! @relationship(type: "ACTED_IN", properties: "ActedIn", direction: IN) + } + + type ${Series} @node { + title: String! + actors: [${Actor}!]! @relationship(type: "ACTED_IN", properties: "ActedIn", direction: IN) + } + + union ${Production} = ${Movie} | ${Series} + + type ${Actor} @node { + name: String! + productions: [${Production}!]! @relationship(type: "ACTED_IN", properties: "ActedIn", direction: OUT) + } + + type ActedIn @relationshipProperties { + role: String! + } + `; + await testHelper.initNeo4jGraphQL({ typeDefs }); + + // Deliberately create duplicate relationships + await testHelper.executeCypher(` + CREATE (m:${Movie} {title: "Movie One"}) + + CREATE (s:${Series} {title: "Series One"}) + + CREATE (a:${Actor} {name: "Actor One"}) + CREATE (a)-[:ACTED_IN {role: "Movie role one"}]->(m) + CREATE (a)-[:ACTED_IN {role: "Movie role two"}]->(m) + + CREATE (a)-[:ACTED_IN {role: "Series role one"}]->(s) + CREATE (a)-[:ACTED_IN {role: "Series role two"}]->(s) + `); + }); + + afterAll(async () => { + await testHelper.close(); + }); + + test("should return multiple relationship results for connection API", async () => { + const source = /* GraphQL */ ` + query { + ${Actor.operations.connection} { + edges { + node { + productionsConnection { + edges { + node { + ... on ${Movie} { + title + } + ... on ${Series} { + title + } + } + properties { + role + } + } + } + } + } + } + } + `; + + const gqlResult = await testHelper.executeGraphQL(source); + + expect(gqlResult.errors).toBeFalsy(); + expect(gqlResult.data).toEqual({ + [Actor.operations.connection]: { + edges: [ + { + node: { + productionsConnection: { + edges: [ + { + node: { + title: "Movie One", + }, + properties: { + role: "Movie role one", + }, + }, + { + node: { + title: "Movie One", + }, + properties: { + role: "Movie role two", + }, + }, + { + node: { + title: "Series One", + }, + properties: { + role: "Series role one", + }, + }, + { + node: { + title: "Series One", + }, + properties: { + role: "Series role two", + }, + }, + ], + }, + }, + }, + ], + }, + }); + }); + + test("should only return a single relationship result for simple API", async () => { + const source = /* GraphQL */ ` + query { + ${Actor.plural} { + productions { + ...on ${Movie} { + title + } + ...on ${Series} { + title + } + } + name + } + } + `; + + const gqlResult = await testHelper.executeGraphQL(source); + + expect(gqlResult.errors).toBeFalsy(); + expect(gqlResult.data).toEqual({ + [Actor.plural]: [ + { + productions: expect.toIncludeSameMembers([ + { + title: "Movie One", + }, + { + title: "Series One", + }, + ]), + name: "Actor One", + }, + ], + }); + }); +}); diff --git a/packages/graphql/tests/integration/directives/relationship/duplicate-relationship/duplicate-relationship-read.int.test.ts b/packages/graphql/tests/integration/directives/relationship/duplicate-relationship/duplicate-relationship-read.int.test.ts new file mode 100644 index 0000000000..86d087aa2b --- /dev/null +++ b/packages/graphql/tests/integration/directives/relationship/duplicate-relationship/duplicate-relationship-read.int.test.ts @@ -0,0 +1,138 @@ +/* + * Copyright (c) "Neo4j" + * Neo4j Sweden AB [http://neo4j.com] + * + * This file is part of Neo4j. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { UniqueType } from "../../../../utils/graphql-types"; +import { TestHelper } from "../../../../utils/tests-helper"; + +describe("Multiple relationships results difference between Connection API and Simple API", () => { + const testHelper: TestHelper = new TestHelper(); + const Movie: UniqueType = testHelper.createUniqueType("Movie"); + const Actor: UniqueType = testHelper.createUniqueType("Actor"); + + beforeAll(async () => { + const typeDefs = /* GraphQL */ ` + type ${Movie} @node { + title: String! + actors: [${Actor}!]! @relationship(type: "ACTED_IN", properties: "ActedIn", direction: IN) + } + + type ${Actor} @node { + name: String! + movies: [${Movie}!]! @relationship(type: "ACTED_IN", properties: "ActedIn", direction: OUT) + } + + type ActedIn @relationshipProperties { + role: String! + } + `; + await testHelper.initNeo4jGraphQL({ typeDefs }); + + // Deliberately create duplicate relationships + await testHelper.executeCypher(` + CREATE (m:${Movie} {title: "Movie One"}) + CREATE (a:${Actor} {name: "Actor One"}) + CREATE (a)-[:ACTED_IN {role: "Role One"}]->(m) + CREATE (a)-[:ACTED_IN {role: "Role Two"}]->(m) + `); + }); + + afterAll(async () => { + await testHelper.close(); + }); + + test("should return multiple relationship results for connection API", async () => { + const source = /* GraphQL */ ` + query { + ${Movie.plural} { + title + actorsConnection { + edges { + node { + name + } + properties { + role + } + } + } + } + } + `; + + const gqlResult = await testHelper.executeGraphQL(source); + + expect(gqlResult.errors).toBeFalsy(); + expect(gqlResult.data).toEqual({ + [Movie.plural]: [ + { + title: "Movie One", + actorsConnection: { + edges: expect.toIncludeSameMembers([ + { + node: { + name: "Actor One", + }, + properties: { + role: "Role One", + }, + }, + { + node: { + name: "Actor One", + }, + properties: { + role: "Role Two", + }, + }, + ]), + }, + }, + ], + }); + }); + + test("should only return a single relationship result for simple API", async () => { + const source = /* GraphQL */ ` + query { + ${Movie.plural} { + title + actors { + name + } + } + } + `; + + const gqlResult = await testHelper.executeGraphQL(source); + + expect(gqlResult.errors).toBeFalsy(); + expect(gqlResult.data).toEqual({ + [Movie.plural]: [ + { + title: "Movie One", + actors: [ + { + name: "Actor One", + }, + ], + }, + ], + }); + }); +}); diff --git a/packages/graphql/tests/integration/directives/relationship/duplicate-relationship/duplicate-relationship-update.int.test.ts b/packages/graphql/tests/integration/directives/relationship/duplicate-relationship/duplicate-relationship-update.int.test.ts new file mode 100644 index 0000000000..b4c96e9462 --- /dev/null +++ b/packages/graphql/tests/integration/directives/relationship/duplicate-relationship/duplicate-relationship-update.int.test.ts @@ -0,0 +1,173 @@ +/* + * Copyright (c) "Neo4j" + * Neo4j Sweden AB [http://neo4j.com] + * + * This file is part of Neo4j. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { UniqueType } from "../../../../utils/graphql-types"; +import { TestHelper } from "../../../../utils/tests-helper"; + +describe("Update: Multiple relationships results difference between Connection API and Simple API", () => { + const testHelper: TestHelper = new TestHelper(); + const Movie: UniqueType = testHelper.createUniqueType("Movie"); + const Actor: UniqueType = testHelper.createUniqueType("Actor"); + + beforeEach(async () => { + const typeDefs = /* GraphQL */ ` + type ${Movie} @node { + title: String! + actors: [${Actor}!]! @relationship(type: "ACTED_IN", properties: "ActedIn", direction: IN) + } + + type ${Actor} @node { + name: String! + movies: [${Movie}!]! @relationship(type: "ACTED_IN", properties: "ActedIn", direction: OUT) + } + + type ActedIn @relationshipProperties { + role: String! + } + `; + await testHelper.initNeo4jGraphQL({ typeDefs }); + + // Deliberately create duplicate relationships + await testHelper.executeCypher(` + CREATE (m:${Movie} {title: "Movie One"}) + CREATE (a:${Actor} {name: "Actor One"}) + CREATE (a)-[:ACTED_IN {role: "Role One"}]->(m) + `); + }); + + afterEach(async () => { + await testHelper.close(); + }); + + test("should return multiple relationship results for connection API", async () => { + const source = /* GraphQL */ ` + mutation { + ${Movie.operations.update}( + where: { title: { eq: "Movie One" } } + update: { + actors: [ + { + connect: [ + { + where: { node: { name: { eq: "Actor One" } } } + edge: { role: "Role Two" } + } + ] + } + ] + } + ) { + ${Movie.plural} { + title + actorsConnection { + edges { + properties { + role + } + node { + name + } + } + } + } + } + } + `; + + const gqlResult = await testHelper.executeGraphQL(source); + + expect(gqlResult.errors).toBeFalsy(); + expect(gqlResult.data).toEqual({ + [Movie.operations.update]: { + [Movie.plural]: [ + { + title: "Movie One", + actorsConnection: { + edges: expect.toIncludeSameMembers([ + { + node: { + name: "Actor One", + }, + properties: { + role: "Role One", + }, + }, + { + node: { + name: "Actor One", + }, + properties: { + role: "Role Two", + }, + }, + ]), + }, + }, + ], + }, + }); + }); + + test("should only return a single relationship result for simple API", async () => { + const source = /* GraphQL */ ` + mutation { + ${Movie.operations.update}( + where: { title: { eq: "Movie One" } } + update: { + actors: [ + { + connect: [ + { + where: { node: { name: { eq: "Actor One" } } } + edge: { role: "Role Two" } + } + ] + } + ] + } + ) { + ${Movie.plural} { + title + actors { + name + } + } + } + } + `; + + const gqlResult = await testHelper.executeGraphQL(source); + + expect(gqlResult.errors).toBeFalsy(); + expect(gqlResult.data).toEqual({ + [Movie.operations.update]: { + [Movie.plural]: [ + { + title: "Movie One", + actors: [ + { + name: "Actor One", + }, + ], + }, + ], + }, + }); + }); +}); diff --git a/packages/graphql/tests/integration/interfaces/relationships/create/connect.int.test.ts b/packages/graphql/tests/integration/interfaces/relationships/create/connect.int.test.ts index 012b4a17ce..19b23fe110 100644 --- a/packages/graphql/tests/integration/interfaces/relationships/create/connect.int.test.ts +++ b/packages/graphql/tests/integration/interfaces/relationships/create/connect.int.test.ts @@ -243,11 +243,7 @@ describe("interface relationships", () => { { runtime: movieRuntime, title: movieTitle, - actors: expect.toIncludeSameMembers([ - { name: actorName2 }, - { name: actorName1 }, - { name: actorName2 }, - ]), + actors: expect.toIncludeSameMembers([{ name: actorName2 }, { name: actorName1 }]), }, ], name: actorName1, diff --git a/packages/graphql/tests/tck/alias.test.ts b/packages/graphql/tests/tck/alias.test.ts index f7369db85b..6b937e9cd6 100644 --- a/packages/graphql/tests/tck/alias.test.ts +++ b/packages/graphql/tests/tck/alias.test.ts @@ -86,6 +86,7 @@ describe("Cypher Alias", () => { CALL { WITH this MATCH (this)<-[this2:ACTED_IN]-(this3:Actor) + WITH DISTINCT this3 WITH this3 { aliasActorsName: this3.name } AS this3 RETURN collect(this3) AS var4 } diff --git a/packages/graphql/tests/tck/array-methods.test.ts b/packages/graphql/tests/tck/array-methods.test.ts index 0934899eca..ea58e50c3e 100644 --- a/packages/graphql/tests/tck/array-methods.test.ts +++ b/packages/graphql/tests/tck/array-methods.test.ts @@ -499,6 +499,7 @@ describe("Arrays Methods", () => { CALL { WITH this MATCH (this)-[update_this0:ACTED_IN]->(update_this1:Movie) + WITH DISTINCT update_this1 WITH update_this1 { .title } AS update_this1 RETURN collect(update_this1) AS update_var2 } @@ -601,6 +602,7 @@ describe("Arrays Methods", () => { CALL { WITH this MATCH (this)-[update_this0:ACTED_IN]->(update_this1:Movie) + WITH DISTINCT update_this1 WITH update_this1 { .title } AS update_this1 RETURN collect(update_this1) AS update_var2 } diff --git a/packages/graphql/tests/tck/connections/mixed-nesting.test.ts b/packages/graphql/tests/tck/connections/mixed-nesting.test.ts index a67c53160e..1326d6fa2e 100644 --- a/packages/graphql/tests/tck/connections/mixed-nesting.test.ts +++ b/packages/graphql/tests/tck/connections/mixed-nesting.test.ts @@ -87,6 +87,7 @@ describe("Mixed nesting", () => { WITH this1 MATCH (this1)-[this2:ACTED_IN]->(this3:Movie) WHERE NOT (this3.title = $param2) + WITH DISTINCT this3 WITH this3 { .title } AS this3 RETURN collect(this3) AS var4 } @@ -164,6 +165,7 @@ describe("Mixed nesting", () => { WITH this3 MATCH (this3)<-[this4:ACTED_IN]-(this5:Actor) WHERE NOT (this5.name = $param3) + WITH DISTINCT this5 WITH this5 { .name } AS this5 RETURN collect(this5) AS var6 } @@ -219,6 +221,7 @@ describe("Mixed nesting", () => { WITH this MATCH (this)<-[this0:ACTED_IN]-(this1:Actor) WHERE this1.name = $param1 + WITH DISTINCT this1 CALL { WITH this1 MATCH (this1)-[this2:ACTED_IN]->(this3:Movie) diff --git a/packages/graphql/tests/tck/deprecated/cypher-sort-deprecated.test.ts b/packages/graphql/tests/tck/deprecated/cypher-sort-deprecated.test.ts index 1a3057db4d..9ee8cc21d8 100644 --- a/packages/graphql/tests/tck/deprecated/cypher-sort-deprecated.test.ts +++ b/packages/graphql/tests/tck/deprecated/cypher-sort-deprecated.test.ts @@ -338,6 +338,7 @@ describe("Cypher sort deprecated", () => { CALL { WITH this MATCH (this)-[this0:HAS_GENRE]->(this1:Genre) + WITH DISTINCT this1 WITH this1 { .name } AS this1 ORDER BY this1.name DESC RETURN collect(this1) AS var2 @@ -366,6 +367,7 @@ describe("Cypher sort deprecated", () => { CALL { WITH this MATCH (this)-[this0:HAS_GENRE]->(this1:Genre) + WITH DISTINCT this1 WITH this1 { .name } AS this1 ORDER BY this1.name ASC RETURN collect(this1) AS var2 @@ -395,6 +397,7 @@ describe("Cypher sort deprecated", () => { CALL { WITH this MATCH (this)-[this0:HAS_GENRE]->(this1:Genre) + WITH DISTINCT this1 CALL { WITH this1 CALL { diff --git a/packages/graphql/tests/tck/deprecated/generic-filtering/cypher-filtering-one-to-one-relationship-deprecated.test.ts b/packages/graphql/tests/tck/deprecated/generic-filtering/cypher-filtering-one-to-one-relationship-deprecated.test.ts index 3e8f5dc8ca..9e32a87e1c 100644 --- a/packages/graphql/tests/tck/deprecated/generic-filtering/cypher-filtering-one-to-one-relationship-deprecated.test.ts +++ b/packages/graphql/tests/tck/deprecated/generic-filtering/cypher-filtering-one-to-one-relationship-deprecated.test.ts @@ -1453,9 +1453,11 @@ describe("cypher directive filtering - One To One Relationship - deprecated", () CALL { WITH this2 MATCH (this2)<-[this3:ACTED_IN]-(this4:Person) + WITH DISTINCT this4 CALL { WITH this4 MATCH (this4)-[this5:ACTED_IN]->(this6:Movie) + WITH DISTINCT this6 CALL { WITH this6 CALL { diff --git a/packages/graphql/tests/tck/directives/alias.test.ts b/packages/graphql/tests/tck/directives/alias.test.ts index 962bc4056f..d77517ee93 100644 --- a/packages/graphql/tests/tck/directives/alias.test.ts +++ b/packages/graphql/tests/tck/directives/alias.test.ts @@ -69,6 +69,7 @@ describe("Cypher alias directive", () => { CALL { WITH this MATCH (this)-[this0:ACTED_IN]->(this1:Movie) + WITH DISTINCT this1 WITH this1 { .title, rating: this1.ratingPropInDb } AS this1 RETURN collect(this1) AS var2 } @@ -193,6 +194,7 @@ describe("Cypher alias directive", () => { CALL { WITH create_this1 MATCH (create_this1)-[create_this6:ACTED_IN]->(create_this7:Movie) + WITH DISTINCT create_this7 WITH create_this7 { .title, rating: create_this7.ratingPropInDb } AS create_this7 RETURN collect(create_this7) AS create_var8 } diff --git a/packages/graphql/tests/tck/directives/authorization/arguments/allow/allow.test.ts b/packages/graphql/tests/tck/directives/authorization/arguments/allow/allow.test.ts index e79cbf0be4..264f4289b4 100644 --- a/packages/graphql/tests/tck/directives/authorization/arguments/allow/allow.test.ts +++ b/packages/graphql/tests/tck/directives/authorization/arguments/allow/allow.test.ts @@ -197,6 +197,7 @@ describe("Cypher Auth Allow", () => { CALL { WITH this MATCH (this)-[this0:HAS_POST]->(this1:Post) + WITH DISTINCT this1 WITH * WHERE apoc.util.validatePredicate(NOT ($isAuthenticated = true AND EXISTS { MATCH (this1)<-[:HAS_POST]-(this2:User) @@ -247,6 +248,7 @@ describe("Cypher Auth Allow", () => { CALL { WITH this MATCH (this)<-[this1:HAS_POST]-(this2:User) + WITH DISTINCT this2 WITH * WHERE (apoc.util.validatePredicate(NOT ($isAuthenticated = true AND ($jwt.sub IS NOT NULL AND this2.id = $jwt.sub)), \\"@neo4j/graphql/FORBIDDEN\\", [0]) AND apoc.util.validatePredicate(NOT ($isAuthenticated = true AND ($jwt.sub IS NOT NULL AND this2.id = $jwt.sub)), \\"@neo4j/graphql/FORBIDDEN\\", [0])) WITH this2 { .password } AS this2 @@ -294,6 +296,7 @@ describe("Cypher Auth Allow", () => { CALL { WITH this MATCH (this)-[this0:HAS_POST]->(this1:Post) + WITH DISTINCT this1 WITH * WHERE (this1.id = $param3 AND apoc.util.validatePredicate(NOT ($isAuthenticated = true AND EXISTS { MATCH (this1)<-[:HAS_POST]-(this2:User) @@ -302,6 +305,7 @@ describe("Cypher Auth Allow", () => { CALL { WITH this1 MATCH (this1)-[this3:HAS_COMMENT]->(this4:Comment) + WITH DISTINCT this4 WITH * WHERE (this4.id = $param4 AND apoc.util.validatePredicate(NOT ($isAuthenticated = true AND EXISTS { MATCH (this4)<-[:HAS_COMMENT]-(this5:User) diff --git a/packages/graphql/tests/tck/directives/authorization/arguments/allow/interface-relationships/implementation-allow.test.ts b/packages/graphql/tests/tck/directives/authorization/arguments/allow/interface-relationships/implementation-allow.test.ts index 20d5533faf..26b376be31 100644 --- a/packages/graphql/tests/tck/directives/authorization/arguments/allow/interface-relationships/implementation-allow.test.ts +++ b/packages/graphql/tests/tck/directives/authorization/arguments/allow/interface-relationships/implementation-allow.test.ts @@ -174,6 +174,7 @@ describe("@auth allow on specific interface implementation", () => { WITH this4 MATCH (this4)-[this6:HAS_COMMENT]->(this7:Comment) WHERE this7.id = $param5 + WITH DISTINCT this7 WITH this7 { .content } AS this7 RETURN collect(this7) AS var8 } diff --git a/packages/graphql/tests/tck/directives/authorization/arguments/roles-where.test.ts b/packages/graphql/tests/tck/directives/authorization/arguments/roles-where.test.ts index 7590e1b741..bfb580596b 100644 --- a/packages/graphql/tests/tck/directives/authorization/arguments/roles-where.test.ts +++ b/packages/graphql/tests/tck/directives/authorization/arguments/roles-where.test.ts @@ -186,6 +186,7 @@ describe("Cypher Auth Where with Roles", () => { CALL { WITH this MATCH (this)-[this0:HAS_POST]->(this1:Post) + WITH DISTINCT this1 WITH * WHERE apoc.util.validatePredicate(NOT (($isAuthenticated = true AND EXISTS { MATCH (this1)<-[:HAS_POST]-(this2:User) @@ -363,6 +364,7 @@ describe("Cypher Auth Where with Roles", () => { CALL { WITH this MATCH (this)-[this0:HAS_POST]->(this1:Post) + WITH DISTINCT this1 WITH * WHERE (this1.content = $param4 AND apoc.util.validatePredicate(NOT (($isAuthenticated = true AND EXISTS { MATCH (this1)<-[:HAS_POST]-(this2:User) @@ -722,6 +724,7 @@ describe("Cypher Auth Where with Roles", () => { CALL { WITH this MATCH (this)-[update_this0:HAS_POST]->(update_this1:Post) + WITH DISTINCT update_this1 WITH * WHERE apoc.util.validatePredicate(NOT (($isAuthenticated = true AND EXISTS { MATCH (update_this1)<-[:HAS_POST]-(update_this2:User) diff --git a/packages/graphql/tests/tck/directives/authorization/arguments/where/connection-auth-filter.test.ts b/packages/graphql/tests/tck/directives/authorization/arguments/where/connection-auth-filter.test.ts index 896b578a94..a6c989fafa 100644 --- a/packages/graphql/tests/tck/directives/authorization/arguments/where/connection-auth-filter.test.ts +++ b/packages/graphql/tests/tck/directives/authorization/arguments/where/connection-auth-filter.test.ts @@ -200,6 +200,7 @@ describe("Connection auth filter", () => { CALL { WITH this0 MATCH (this0)-[this1:HAS_POST]->(this2:Post) + WITH DISTINCT this2 WITH * WHERE ($isAuthenticated = true AND EXISTS { MATCH (this2)<-[:HAS_POST]-(this3:User) @@ -398,6 +399,7 @@ describe("Connection auth filter", () => { CALL { WITH this0 MATCH (this0)-[this1:HAS_POST]->(this2:Post) + WITH DISTINCT this2 WITH * WHERE (this2.content = $param2 AND ($isAuthenticated = true AND EXISTS { MATCH (this2)<-[:HAS_POST]-(this3:User) diff --git a/packages/graphql/tests/tck/directives/authorization/arguments/where/where.test.ts b/packages/graphql/tests/tck/directives/authorization/arguments/where/where.test.ts index 6ff9c36a1e..3b65a5ac24 100644 --- a/packages/graphql/tests/tck/directives/authorization/arguments/where/where.test.ts +++ b/packages/graphql/tests/tck/directives/authorization/arguments/where/where.test.ts @@ -169,6 +169,7 @@ describe("Cypher Auth Where", () => { CALL { WITH this MATCH (this)-[this0:HAS_POST]->(this1:Post) + WITH DISTINCT this1 WITH * WHERE ($isAuthenticated = true AND EXISTS { MATCH (this1)<-[:HAS_POST]-(this2:User) @@ -334,6 +335,7 @@ describe("Cypher Auth Where", () => { CALL { WITH this MATCH (this)-[this0:HAS_POST]->(this1:Post) + WITH DISTINCT this1 WITH * WHERE (this1.content = $param2 AND ($isAuthenticated = true AND EXISTS { MATCH (this1)<-[:HAS_POST]-(this2:User) @@ -654,6 +656,7 @@ describe("Cypher Auth Where", () => { CALL { WITH this MATCH (this)-[update_this0:HAS_POST]->(update_this1:Post) + WITH DISTINCT update_this1 WITH * WHERE ($isAuthenticated = true AND EXISTS { MATCH (update_this1)<-[:HAS_POST]-(update_this2:User) diff --git a/packages/graphql/tests/tck/directives/cypher/cypher-interface.test.ts b/packages/graphql/tests/tck/directives/cypher/cypher-interface.test.ts index e9eab72e7c..4ff33bc2ba 100644 --- a/packages/graphql/tests/tck/directives/cypher/cypher-interface.test.ts +++ b/packages/graphql/tests/tck/directives/cypher/cypher-interface.test.ts @@ -288,6 +288,7 @@ describe("Cypher directive on interface", () => { WITH this0 MATCH (this0)<-[this6:ACTED_IN]-(this7:Actor) WHERE this7.name = $param2 + WITH DISTINCT this7 WITH this7 { .name } AS this7 RETURN collect(this7) AS var8 } @@ -471,6 +472,7 @@ describe("Cypher directive on interface", () => { WITH this0 MATCH (this0)<-[this6:ACTED_IN]-(this7:Actor) WHERE this7.name = $param2 + WITH DISTINCT this7 WITH this7 { .name } AS this7 RETURN collect(this7) AS var8 } @@ -569,6 +571,7 @@ describe("Cypher directive on interface", () => { WITH this0 MATCH (this0)<-[this6:ACTED_IN]-(this7:Actor) WHERE this7.name = $param2 + WITH DISTINCT this7 WITH this7 { .name } AS this7 RETURN collect(this7) AS var8 } diff --git a/packages/graphql/tests/tck/directives/cypher/cypher-union.test.ts b/packages/graphql/tests/tck/directives/cypher/cypher-union.test.ts index bbd6a56806..10b9556831 100644 --- a/packages/graphql/tests/tck/directives/cypher/cypher-union.test.ts +++ b/packages/graphql/tests/tck/directives/cypher/cypher-union.test.ts @@ -262,6 +262,7 @@ describe("Cypher directive on union", () => { WITH this0 MATCH (this0)<-[this1:ACTED_IN]-(this2:Actor) WHERE this2.name = $param1 + WITH DISTINCT this2 WITH this2 { .name } AS this2 RETURN collect(this2) AS var3 } @@ -451,6 +452,7 @@ describe("Cypher directive on union", () => { WITH this0 MATCH (this0)<-[this1:ACTED_IN]-(this2:Actor) WHERE this2.name = $param1 + WITH DISTINCT this2 WITH this2 { .name } AS this2 RETURN collect(this2) AS var3 } @@ -550,6 +552,7 @@ describe("Cypher directive on union", () => { WITH this0 MATCH (this0)<-[this1:ACTED_IN]-(this2:Actor) WHERE this2.name = $param1 + WITH DISTINCT this2 WITH this2 { .name } AS this2 RETURN collect(this2) AS var3 } diff --git a/packages/graphql/tests/tck/directives/cypher/cypher.test.ts b/packages/graphql/tests/tck/directives/cypher/cypher.test.ts index 88445a264b..26947aa7d3 100644 --- a/packages/graphql/tests/tck/directives/cypher/cypher.test.ts +++ b/packages/graphql/tests/tck/directives/cypher/cypher.test.ts @@ -477,6 +477,7 @@ describe("Cypher directive", () => { CALL { WITH this0 MATCH (this0)<-[this1:ACTED_IN]-(this2:Actor) + WITH DISTINCT this2 WITH this2 { .name } AS this2 RETURN collect(this2) AS var3 } @@ -539,6 +540,7 @@ describe("Cypher directive", () => { CALL { WITH this0 MATCH (this0)<-[this1:ACTED_IN]-(this2:Actor) + WITH DISTINCT this2 WITH this2 { .name } AS this2 RETURN collect(this2) AS var3 } @@ -605,6 +607,7 @@ describe("Cypher directive", () => { CALL { WITH this0 MATCH (this0)<-[this1:ACTED_IN]-(this2:Actor) + WITH DISTINCT this2 WITH this2 { .name } AS this2 RETURN collect(this2) AS var3 } diff --git a/packages/graphql/tests/tck/directives/cypher/filtering/cypher-filtering-connect.test.ts b/packages/graphql/tests/tck/directives/cypher/filtering/cypher-filtering-connect.test.ts index 766bf9897c..3adfa54f1e 100644 --- a/packages/graphql/tests/tck/directives/cypher/filtering/cypher-filtering-connect.test.ts +++ b/packages/graphql/tests/tck/directives/cypher/filtering/cypher-filtering-connect.test.ts @@ -123,6 +123,7 @@ describe("cypher directive filtering", () => { CALL { WITH this0 MATCH (this0)<-[create_this0:ACTED_IN]-(create_this1:Actor) + WITH DISTINCT create_this1 WITH create_this1 { .name } AS create_this1 RETURN collect(create_this1) AS create_var2 } diff --git a/packages/graphql/tests/tck/directives/cypher/filtering/cypher-filtering-misc.test.ts b/packages/graphql/tests/tck/directives/cypher/filtering/cypher-filtering-misc.test.ts index d8f84df1e1..5a79ecf763 100644 --- a/packages/graphql/tests/tck/directives/cypher/filtering/cypher-filtering-misc.test.ts +++ b/packages/graphql/tests/tck/directives/cypher/filtering/cypher-filtering-misc.test.ts @@ -91,6 +91,7 @@ describe("cypher directive filtering - Auth", () => { CALL { WITH this MATCH (this)<-[this5:ACTED_IN]-(this6:Actor) + WITH DISTINCT this6 WITH this6 { .name } AS this6 RETURN collect(this6) AS var7 } @@ -147,6 +148,7 @@ describe("cypher directive filtering - Auth", () => { CALL { WITH this MATCH (this)-[this0:ACTED_IN]->(this1:Movie) + WITH DISTINCT this1 CALL { WITH this1 CALL { @@ -227,6 +229,7 @@ describe("cypher directive filtering - Auth", () => { WITH this MATCH (this)<-[this2:ACTED_IN]-(this3:Actor) WHERE this3.name = $param1 + WITH DISTINCT this3 WITH this3 { .name } AS this3 RETURN collect(this3) AS var4 } @@ -319,6 +322,7 @@ describe("cypher directive filtering - Auth", () => { CALL { WITH this MATCH (this)<-[this4:ACTED_IN]-(this5:Actor) + WITH DISTINCT this5 WITH this5 { .name } AS this5 RETURN collect(this5) AS var6 } @@ -397,6 +401,7 @@ describe("cypher directive filtering - Auth", () => { CALL { WITH this MATCH (this)<-[this2:ACTED_IN]-(this3:Actor) + WITH DISTINCT this3 CALL { WITH this3 CALL { diff --git a/packages/graphql/tests/tck/directives/cypher/filtering/cypher-filtering-one-to-one-relationship.test.ts b/packages/graphql/tests/tck/directives/cypher/filtering/cypher-filtering-one-to-one-relationship.test.ts index bfe3a32575..f83b927439 100644 --- a/packages/graphql/tests/tck/directives/cypher/filtering/cypher-filtering-one-to-one-relationship.test.ts +++ b/packages/graphql/tests/tck/directives/cypher/filtering/cypher-filtering-one-to-one-relationship.test.ts @@ -1465,9 +1465,11 @@ describe("cypher directive filtering - One To One Relationship", () => { CALL { WITH this2 MATCH (this2)<-[this3:ACTED_IN]-(this4:Person) + WITH DISTINCT this4 CALL { WITH this4 MATCH (this4)-[this5:ACTED_IN]->(this6:Movie) + WITH DISTINCT this6 CALL { WITH this6 CALL { diff --git a/packages/graphql/tests/tck/directives/cypher/filtering/cypher-filtering-sorting.test.ts b/packages/graphql/tests/tck/directives/cypher/filtering/cypher-filtering-sorting.test.ts index c9d2fbfdaf..8b445d42bf 100644 --- a/packages/graphql/tests/tck/directives/cypher/filtering/cypher-filtering-sorting.test.ts +++ b/packages/graphql/tests/tck/directives/cypher/filtering/cypher-filtering-sorting.test.ts @@ -90,6 +90,7 @@ describe("cypher directive filtering", () => { CALL { WITH this MATCH (this)<-[this4:ACTED_IN]-(this5:Actor) + WITH DISTINCT this5 WITH this5 { .name } AS this5 RETURN collect(this5) AS var6 } @@ -159,6 +160,7 @@ describe("cypher directive filtering", () => { CALL { WITH this MATCH (this)<-[this2:ACTED_IN]-(this3:Actor) + WITH DISTINCT this3 WITH this3 { .name } AS this3 RETURN collect(this3) AS var4 } diff --git a/packages/graphql/tests/tck/directives/node/node-additional-labels.test.ts b/packages/graphql/tests/tck/directives/node/node-additional-labels.test.ts index b0c891a2f5..e75afe9686 100644 --- a/packages/graphql/tests/tck/directives/node/node-additional-labels.test.ts +++ b/packages/graphql/tests/tck/directives/node/node-additional-labels.test.ts @@ -81,6 +81,7 @@ describe("Node directive with additionalLabels", () => { CALL { WITH this MATCH (this)<-[this0:ACTED_IN]-(this1:Actor:Person) + WITH DISTINCT this1 WITH this1 { .name } AS this1 RETURN collect(this1) AS var2 } diff --git a/packages/graphql/tests/tck/directives/node/node-label-jwt.test.ts b/packages/graphql/tests/tck/directives/node/node-label-jwt.test.ts index 9bfdbd2ea9..0c836b2f8e 100644 --- a/packages/graphql/tests/tck/directives/node/node-label-jwt.test.ts +++ b/packages/graphql/tests/tck/directives/node/node-label-jwt.test.ts @@ -89,6 +89,7 @@ describe("Label in Node directive", () => { WITH this MATCH (this)-[this0:ACTED_IN]->(this1:Film) WHERE this1.title = $param1 + WITH DISTINCT this1 WITH this1 { .title } AS this1 RETURN collect(this1) AS var2 } diff --git a/packages/graphql/tests/tck/directives/node/node-label.test.ts b/packages/graphql/tests/tck/directives/node/node-label.test.ts index b467a87dbd..4473bb6139 100644 --- a/packages/graphql/tests/tck/directives/node/node-label.test.ts +++ b/packages/graphql/tests/tck/directives/node/node-label.test.ts @@ -81,6 +81,7 @@ describe("Label in Node directive", () => { CALL { WITH this MATCH (this)<-[this0:ACTED_IN]-(this1:Person) + WITH DISTINCT this1 WITH this1 { .name } AS this1 RETURN collect(this1) AS var2 } diff --git a/packages/graphql/tests/tck/directives/relationship.test.ts b/packages/graphql/tests/tck/directives/relationship.test.ts index e4c4d781d4..be5798be3b 100644 --- a/packages/graphql/tests/tck/directives/relationship.test.ts +++ b/packages/graphql/tests/tck/directives/relationship.test.ts @@ -68,6 +68,7 @@ describe("Cypher relationship", () => { CALL { WITH this MATCH (this)<-[this0:ACTED_IN]-(this1:Actor) + WITH DISTINCT this1 WITH this1 { .name } AS this1 RETURN collect(this1) AS var2 } diff --git a/packages/graphql/tests/tck/issues/1249.test.ts b/packages/graphql/tests/tck/issues/1249.test.ts index ff0748c599..3c0ba3704e 100644 --- a/packages/graphql/tests/tck/issues/1249.test.ts +++ b/packages/graphql/tests/tck/issues/1249.test.ts @@ -85,6 +85,7 @@ describe("https://github.com/neo4j/graphql/issues/1249", () => { CALL { WITH this MATCH (this)-[this0:MATERIAL_BULK]->(this1:Material) + WITH DISTINCT this1 CALL { WITH this1 MATCH (this1)-[this2:MATERIAL_SUPPLIER]->(this3:Supplier) diff --git a/packages/graphql/tests/tck/issues/1628.test.ts b/packages/graphql/tests/tck/issues/1628.test.ts index c245c53591..92cc2fcd27 100644 --- a/packages/graphql/tests/tck/issues/1628.test.ts +++ b/packages/graphql/tests/tck/issues/1628.test.ts @@ -70,6 +70,7 @@ describe("https://github.com/neo4j/graphql/issues/1628", () => { WITH this MATCH (this)-[this1:dcterms__title]->(this2:dcterms_title:property) WHERE this2.value CONTAINS $param2 + WITH DISTINCT this2 WITH this2 { .value } AS this2 RETURN collect(this2) AS var3 } diff --git a/packages/graphql/tests/tck/issues/1779.test.ts b/packages/graphql/tests/tck/issues/1779.test.ts index bee880b256..c287a61dee 100644 --- a/packages/graphql/tests/tck/issues/1779.test.ts +++ b/packages/graphql/tests/tck/issues/1779.test.ts @@ -69,6 +69,7 @@ describe("https://github.com/neo4j/graphql/issues/1779", () => { MATCH (this1)<-[:attends]-(this2:Person) WHERE NOT (this2.age > $param0) })) + WITH DISTINCT this1 WITH this1 { .name } AS this1 RETURN collect(this1) AS var3 } diff --git a/packages/graphql/tests/tck/issues/190.test.ts b/packages/graphql/tests/tck/issues/190.test.ts index a18b48fb6f..6351d00472 100644 --- a/packages/graphql/tests/tck/issues/190.test.ts +++ b/packages/graphql/tests/tck/issues/190.test.ts @@ -69,6 +69,7 @@ describe("#190", () => { CALL { WITH this MATCH (this)-[this1:HAS_DEMOGRAPHIC]->(this2:UserDemographics) + WITH DISTINCT this2 WITH this2 { .type, .value } AS this2 RETURN collect(this2) AS var3 } @@ -119,6 +120,7 @@ describe("#190", () => { CALL { WITH this MATCH (this)-[this1:HAS_DEMOGRAPHIC]->(this2:UserDemographics) + WITH DISTINCT this2 WITH this2 { .type, .value } AS this2 RETURN collect(this2) AS var3 } diff --git a/packages/graphql/tests/tck/issues/2022.test.ts b/packages/graphql/tests/tck/issues/2022.test.ts index 7af996860f..6a8a8281e0 100644 --- a/packages/graphql/tests/tck/issues/2022.test.ts +++ b/packages/graphql/tests/tck/issues/2022.test.ts @@ -98,9 +98,11 @@ describe("https://github.com/neo4j/graphql/issues/2022", () => { CALL { WITH this0 MATCH (this0)-[this1:SOLD_AT_AUCTION_AS]->(this2:AuctionItem) + WITH DISTINCT this2 CALL { WITH this2 MATCH (this2)<-[this3:BOUGHT_ITEM_AT_AUCTION]-(this4:Organization) + WITH DISTINCT this4 WITH this4 { .name, dbId: this4.id } AS this4 RETURN collect(this4) AS var5 } @@ -110,6 +112,7 @@ describe("https://github.com/neo4j/graphql/issues/2022", () => { CALL { WITH this0 MATCH (this0)-[this7:OWNED_BY]->(this8:Organization) + WITH DISTINCT this8 WITH this8 { .name, dbId: this8.id } AS this8 RETURN collect(this8) AS var9 } diff --git a/packages/graphql/tests/tck/issues/2100.test.ts b/packages/graphql/tests/tck/issues/2100.test.ts index cfa285a3f4..57a5b37da8 100644 --- a/packages/graphql/tests/tck/issues/2100.test.ts +++ b/packages/graphql/tests/tck/issues/2100.test.ts @@ -120,6 +120,7 @@ describe("https://github.com/neo4j/graphql/issues/2100", () => { CALL { WITH this0 MATCH (this0)-[this1:BUSSED_ON]->(this2:TimeGraph) + WITH DISTINCT this2 WITH this2 { .date } AS this2 RETURN collect(this2) AS var3 } diff --git a/packages/graphql/tests/tck/issues/2189.test.ts b/packages/graphql/tests/tck/issues/2189.test.ts index 8955274591..bd6e32f600 100644 --- a/packages/graphql/tests/tck/issues/2189.test.ts +++ b/packages/graphql/tests/tck/issues/2189.test.ts @@ -284,6 +284,7 @@ describe("https://github.com/neo4j/graphql/issues/2189", () => { CALL { WITH create_this1 MATCH (create_this1)<-[create_this8:TEST_RELATIONSHIP]-(create_this9:Test_Feedback) + WITH DISTINCT create_this9 WITH create_this9 { .uuid, .int, .str, .bool } AS create_this9 RETURN collect(create_this9) AS create_var10 } @@ -378,6 +379,7 @@ describe("https://github.com/neo4j/graphql/issues/2189", () => { CALL { WITH create_this1 MATCH (create_this1)<-[create_this6:TEST_RELATIONSHIP]-(create_this7:Test_Feedback) + WITH DISTINCT create_this7 WITH create_this7 { .uuid, .int, .str, .bool } AS create_this7 RETURN collect(create_this7) AS create_var8 } diff --git a/packages/graphql/tests/tck/issues/2396.test.ts b/packages/graphql/tests/tck/issues/2396.test.ts index a14cc9acdc..aa9db71aad 100644 --- a/packages/graphql/tests/tck/issues/2396.test.ts +++ b/packages/graphql/tests/tck/issues/2396.test.ts @@ -168,11 +168,13 @@ describe("https://github.com/neo4j/graphql/issues/2396", () => { CALL { WITH this MATCH (this)-[this2:HAS_VALUATION]->(this3:Valuation) + WITH DISTINCT this3 WITH * WHERE ($isAuthenticated = true AND this3.archivedAt IS NULL) CALL { WITH this3 MATCH (this3)-[this4:VALUATION_FOR]->(this5:Estate) + WITH DISTINCT this5 WITH * WHERE ($isAuthenticated = true AND this5.archivedAt IS NULL) WITH this5 { .uuid } AS this5 @@ -244,11 +246,13 @@ describe("https://github.com/neo4j/graphql/issues/2396", () => { CALL { WITH this MATCH (this)-[this2:HAS_VALUATION]->(this3:Valuation) + WITH DISTINCT this3 WITH * WHERE ($isAuthenticated = true AND this3.archivedAt IS NULL) CALL { WITH this3 MATCH (this3)-[this4:VALUATION_FOR]->(this5:Estate) + WITH DISTINCT this5 WITH * WHERE ($isAuthenticated = true AND this5.archivedAt IS NULL) WITH this5 { .uuid } AS this5 @@ -338,11 +342,13 @@ describe("https://github.com/neo4j/graphql/issues/2396", () => { CALL { WITH this MATCH (this)-[this4:HAS_VALUATION]->(this5:Valuation) + WITH DISTINCT this5 WITH * WHERE ($isAuthenticated = true AND this5.archivedAt IS NULL) CALL { WITH this5 MATCH (this5)-[this6:VALUATION_FOR]->(this7:Estate) + WITH DISTINCT this7 WITH * WHERE ($isAuthenticated = true AND this7.archivedAt IS NULL) WITH this7 { .uuid } AS this7 @@ -442,11 +448,13 @@ describe("https://github.com/neo4j/graphql/issues/2396", () => { CALL { WITH this MATCH (this)-[this4:HAS_VALUATION]->(this5:Valuation) + WITH DISTINCT this5 WITH * WHERE ($isAuthenticated = true AND this5.archivedAt IS NULL) CALL { WITH this5 MATCH (this5)-[this6:VALUATION_FOR]->(this7:Estate) + WITH DISTINCT this7 WITH * WHERE ($isAuthenticated = true AND this7.archivedAt IS NULL) WITH this7 { .uuid } AS this7 @@ -554,11 +562,13 @@ describe("https://github.com/neo4j/graphql/issues/2396", () => { CALL { WITH this MATCH (this)-[this4:HAS_VALUATION]->(this5:Valuation) + WITH DISTINCT this5 WITH * WHERE ($isAuthenticated = true AND this5.archivedAt IS NULL) CALL { WITH this5 MATCH (this5)-[this6:VALUATION_FOR]->(this7:Estate) + WITH DISTINCT this7 WITH * WHERE ($isAuthenticated = true AND this7.archivedAt IS NULL) WITH this7 { .uuid } AS this7 diff --git a/packages/graphql/tests/tck/issues/2766.test.ts b/packages/graphql/tests/tck/issues/2766.test.ts index 19cbbec9dc..c96f25d55f 100644 --- a/packages/graphql/tests/tck/issues/2766.test.ts +++ b/packages/graphql/tests/tck/issues/2766.test.ts @@ -82,6 +82,7 @@ describe("https://github.com/neo4j/graphql/issues/2766", () => { CALL { WITH this0 MATCH (this0)<-[this1:ACTED_IN]-(this2:Actor) + WITH DISTINCT this2 CALL { WITH this2 CALL { diff --git a/packages/graphql/tests/tck/issues/2812.test.ts b/packages/graphql/tests/tck/issues/2812.test.ts index ffcac79f7e..701e0bb632 100644 --- a/packages/graphql/tests/tck/issues/2812.test.ts +++ b/packages/graphql/tests/tck/issues/2812.test.ts @@ -114,6 +114,7 @@ describe("https://github.com/neo4j/graphql/issues/2812", () => { WITH create_this1 MATCH (create_this1)<-[create_this6:ACTED_IN]-(create_this7:Actor) WHERE apoc.util.validatePredicate(NOT ($isAuthenticated = true AND ($jwt.sub IS NOT NULL AND create_this7.nodeCreatedBy = $jwt.sub)), \\"@neo4j/graphql/FORBIDDEN\\", [0]) + WITH DISTINCT create_this7 WITH create_this7 { .name } AS create_this7 RETURN collect(create_this7) AS create_var8 } @@ -224,6 +225,7 @@ describe("https://github.com/neo4j/graphql/issues/2812", () => { WITH create_this1 MATCH (create_this1)<-[create_this6:ACTED_IN]-(create_this7:Actor) WHERE apoc.util.validatePredicate(NOT ($isAuthenticated = true AND ($jwt.sub IS NOT NULL AND create_this7.nodeCreatedBy = $jwt.sub)), \\"@neo4j/graphql/FORBIDDEN\\", [0]) + WITH DISTINCT create_this7 WITH create_this7 { .name } AS create_this7 RETURN collect(create_this7) AS create_var8 } @@ -330,6 +332,7 @@ describe("https://github.com/neo4j/graphql/issues/2812", () => { WITH create_this1 MATCH (create_this1)<-[create_this6:ACTED_IN]-(create_this7:Actor) WHERE apoc.util.validatePredicate(NOT ($isAuthenticated = true AND ($jwt.sub IS NOT NULL AND create_this7.nodeCreatedBy = $jwt.sub)), \\"@neo4j/graphql/FORBIDDEN\\", [0]) + WITH DISTINCT create_this7 WITH create_this7 { .name } AS create_this7 RETURN collect(create_this7) AS create_var8 } diff --git a/packages/graphql/tests/tck/issues/3394.test.ts b/packages/graphql/tests/tck/issues/3394.test.ts index 8e9d175f66..99e4047676 100644 --- a/packages/graphql/tests/tck/issues/3394.test.ts +++ b/packages/graphql/tests/tck/issues/3394.test.ts @@ -84,6 +84,7 @@ describe("https://github.com/neo4j/graphql/issues/3394", () => { CALL { WITH this MATCH (this)-[this0:CAN_ACCESS]->(this1:Product) + WITH DISTINCT this1 WITH this1 { .description, id: this1.fg_item_id, partNumber: this1.fg_item } AS this1 ORDER BY this1.partNumber DESC RETURN collect(this1) AS var2 diff --git a/packages/graphql/tests/tck/issues/4170.test.ts b/packages/graphql/tests/tck/issues/4170.test.ts index efbb89860c..3c250ece8a 100644 --- a/packages/graphql/tests/tck/issues/4170.test.ts +++ b/packages/graphql/tests/tck/issues/4170.test.ts @@ -222,6 +222,7 @@ describe("https://github.com/neo4j/graphql/issues/4170", () => { WITH this0 MATCH (this0)<-[create_this0:ADMIN_IN]-(create_this1:User) WHERE apoc.util.validatePredicate(NOT ($isAuthenticated = true AND ($jwt.id IS NOT NULL AND create_this1.userId = $jwt.id)), \\"@neo4j/graphql/FORBIDDEN\\", [0]) + WITH DISTINCT create_this1 WITH create_this1 { .userId } AS create_this1 RETURN collect(create_this1) AS create_var2 } diff --git a/packages/graphql/tests/tck/issues/4214.test.ts b/packages/graphql/tests/tck/issues/4214.test.ts index 14b77d629f..2c12b1a224 100644 --- a/packages/graphql/tests/tck/issues/4214.test.ts +++ b/packages/graphql/tests/tck/issues/4214.test.ts @@ -229,9 +229,11 @@ describe("https://github.com/neo4j/graphql/issues/4214", () => { MATCH (create_this1)-[:TRANSACTION]->(create_this2:Store) WHERE ($jwt.store IS NOT NULL AND create_this2.id = $jwt.store) })) + WITH DISTINCT create_this1 CALL { WITH create_this1 MATCH (create_this1)-[create_this3:TRANSACTION]->(create_this4:Store) + WITH DISTINCT create_this4 WITH create_this4 { .name } AS create_this4 RETURN collect(create_this4) AS create_var5 } diff --git a/packages/graphql/tests/tck/issues/4223.test.ts b/packages/graphql/tests/tck/issues/4223.test.ts index 4473b1eddc..3bc7d628ac 100644 --- a/packages/graphql/tests/tck/issues/4223.test.ts +++ b/packages/graphql/tests/tck/issues/4223.test.ts @@ -264,6 +264,7 @@ describe("https://github.com/neo4j/graphql/issues/4223", () => { WITH this0 MATCH (this0)<-[create_this0:ADMIN_IN]-(create_this1:User) WHERE apoc.util.validatePredicate(NOT ($isAuthenticated = true AND ($jwt.id IS NOT NULL AND create_this1.userId = $jwt.id)), \\"@neo4j/graphql/FORBIDDEN\\", [0]) + WITH DISTINCT create_this1 WITH create_this1 { .userId } AS create_this1 RETURN collect(create_this1) AS create_var2 } diff --git a/packages/graphql/tests/tck/issues/4292.test.ts b/packages/graphql/tests/tck/issues/4292.test.ts index 480b75d06f..99f681850b 100644 --- a/packages/graphql/tests/tck/issues/4292.test.ts +++ b/packages/graphql/tests/tck/issues/4292.test.ts @@ -215,6 +215,7 @@ describe("https://github.com/neo4j/graphql/issues/4292", () => { CALL { WITH this MATCH (this)<-[this0:MEMBER_OF]-(this1:Person) + WITH DISTINCT this1 WITH * WHERE apoc.util.validatePredicate(NOT ($isAuthenticated = true AND (EXISTS { MATCH (this1)<-[:CREATOR_OF]-(this2:User) diff --git a/packages/graphql/tests/tck/issues/4838.test.ts b/packages/graphql/tests/tck/issues/4838.test.ts index 89171b2853..c29973f46f 100644 --- a/packages/graphql/tests/tck/issues/4838.test.ts +++ b/packages/graphql/tests/tck/issues/4838.test.ts @@ -116,6 +116,7 @@ describe("https://github.com/neo4j/graphql/issues/4838", () => { CALL { WITH create_this1 MATCH (create_this1)-[create_this6:REL]->(create_this7:Test) + WITH DISTINCT create_this7 CALL { WITH create_this7 CALL { diff --git a/packages/graphql/tests/tck/issues/487.test.ts b/packages/graphql/tests/tck/issues/487.test.ts index 6942c2360e..7cc2b7069f 100644 --- a/packages/graphql/tests/tck/issues/487.test.ts +++ b/packages/graphql/tests/tck/issues/487.test.ts @@ -103,6 +103,7 @@ describe("https://github.com/neo4j/graphql/issues/487", () => { CALL { WITH this0 MATCH (this0)<-[this1:WROTE]-(this2:Author) + WITH DISTINCT this2 WITH this2 { .id } AS this2 RETURN collect(this2) AS var3 } @@ -115,6 +116,7 @@ describe("https://github.com/neo4j/graphql/issues/487", () => { CALL { WITH this0 MATCH (this0)<-[this5:DIRECTED]-(this6:Director) + WITH DISTINCT this6 WITH this6 { .id } AS this6 RETURN collect(this6) AS var7 } @@ -212,6 +214,7 @@ describe("https://github.com/neo4j/graphql/issues/487", () => { CALL { WITH this0 MATCH (this0)<-[this1:WROTE]-(this2:Author) + WITH DISTINCT this2 WITH this2 { .id } AS this2 RETURN collect(this2) AS var3 } @@ -224,6 +227,7 @@ describe("https://github.com/neo4j/graphql/issues/487", () => { CALL { WITH this0 MATCH (this0)<-[this5:DIRECTED]-(this6:Director) + WITH DISTINCT this6 WITH this6 { .id } AS this6 RETURN collect(this6) AS var7 } diff --git a/packages/graphql/tests/tck/issues/5023.test.ts b/packages/graphql/tests/tck/issues/5023.test.ts index 8041e527cc..a3cc93f876 100644 --- a/packages/graphql/tests/tck/issues/5023.test.ts +++ b/packages/graphql/tests/tck/issues/5023.test.ts @@ -200,6 +200,7 @@ describe("https://github.com/neo4j/graphql/issues/5023", () => { CALL { WITH this MATCH (this)-[update_this1:HAS_SETTINGS]->(update_this2:Settings) + WITH DISTINCT update_this2 WITH * WHERE apoc.util.validatePredicate(NOT ($isAuthenticated = true AND EXISTS { MATCH (update_this2)<-[:HAS_SETTINGS]-(update_this3:Tenant) @@ -211,6 +212,7 @@ describe("https://github.com/neo4j/graphql/issues/5023", () => { CALL { WITH update_this2 MATCH (update_this2)-[update_this5:HAS_OPENING_HOURS]->(update_this6:OpeningDay) + WITH DISTINCT update_this6 WITH * WHERE apoc.util.validatePredicate(NOT ($isAuthenticated = true AND EXISTS { MATCH (update_this6)<-[:HAS_OPENING_HOURS]-(update_this7:Settings) @@ -225,6 +227,7 @@ describe("https://github.com/neo4j/graphql/issues/5023", () => { CALL { WITH update_this6 MATCH (update_this6)-[update_this10:HAS_OPEN_INTERVALS]->(update_this11:OpeningHoursInterval) + WITH DISTINCT update_this11 WITH * WHERE apoc.util.validatePredicate(NOT ($isAuthenticated = true AND EXISTS { MATCH (update_this11)<-[:HAS_OPEN_INTERVALS]-(update_this12:OpeningDay) diff --git a/packages/graphql/tests/tck/issues/505.test.ts b/packages/graphql/tests/tck/issues/505.test.ts index 4d5bffecaa..bb82a31b02 100644 --- a/packages/graphql/tests/tck/issues/505.test.ts +++ b/packages/graphql/tests/tck/issues/505.test.ts @@ -125,6 +125,7 @@ describe("https://github.com/neo4j/graphql/issues/505", () => { CALL { WITH this MATCH (this)-[this0:CREATED_PAGE]->(this1:Page) + WITH DISTINCT this1 WITH * WHERE ($isAuthenticated = true AND (EXISTS { MATCH (this1)<-[:CREATED_PAGE]-(this2:User) @@ -191,6 +192,7 @@ describe("https://github.com/neo4j/graphql/issues/505", () => { CALL { WITH this MATCH (this)-[this2:HAS_PAGE]->(this3:Page) + WITH DISTINCT this3 WITH * WHERE ($isAuthenticated = true AND (EXISTS { MATCH (this3)<-[:CREATED_PAGE]-(this4:User) diff --git a/packages/graphql/tests/tck/issues/901.test.ts b/packages/graphql/tests/tck/issues/901.test.ts index cb40e4fcb0..777f83b1b3 100644 --- a/packages/graphql/tests/tck/issues/901.test.ts +++ b/packages/graphql/tests/tck/issues/901.test.ts @@ -104,12 +104,14 @@ describe("https://github.com/neo4j/graphql/issues/901", () => { CALL { WITH this MATCH (this)-[this4:HAS_BRAND]->(this5:Series) + WITH DISTINCT this5 WITH this5 { .name } AS this5 RETURN collect(this5) AS var6 } CALL { WITH this MATCH (this)-[this7:HAS_MANUFACTURER]->(this8:Series) + WITH DISTINCT this8 WITH this8 { .name } AS this8 RETURN collect(this8) AS var9 } diff --git a/packages/graphql/tests/tck/math.test.ts b/packages/graphql/tests/tck/math.test.ts index 33c054d587..fa1065efd9 100644 --- a/packages/graphql/tests/tck/math.test.ts +++ b/packages/graphql/tests/tck/math.test.ts @@ -166,6 +166,7 @@ describe("Math operators", () => { CALL { WITH this MATCH (this)-[update_this0:ACTED_IN]->(update_this1:Movie) + WITH DISTINCT update_this1 WITH update_this1 { .viewers } AS update_this1 RETURN collect(update_this1) AS update_var2 } @@ -225,6 +226,7 @@ describe("Math operators", () => { CALL { WITH this MATCH (this)-[update_this0:ACTED_IN]->(update_this1:Movie) + WITH DISTINCT update_this1 WITH update_this1 { .title } AS update_this1 RETURN collect(update_this1) AS update_var2 } diff --git a/packages/graphql/tests/tck/operations/batch/batch-create-auth.test.ts b/packages/graphql/tests/tck/operations/batch/batch-create-auth.test.ts index 05f27d8ca2..a711738178 100644 --- a/packages/graphql/tests/tck/operations/batch/batch-create-auth.test.ts +++ b/packages/graphql/tests/tck/operations/batch/batch-create-auth.test.ts @@ -165,6 +165,7 @@ describe("Batch Create, Auth", () => { WITH create_this1 MATCH (create_this1)<-[create_this6:ACTED_IN]-(create_this7:Actor) WHERE apoc.util.validatePredicate(NOT ($isAuthenticated = true AND ($jwt.sub IS NOT NULL AND create_this7.id = $jwt.sub)), \\"@neo4j/graphql/FORBIDDEN\\", [0]) + WITH DISTINCT create_this7 WITH create_this7 { .name } AS create_this7 RETURN collect(create_this7) AS create_var8 } diff --git a/packages/graphql/tests/tck/operations/batch/batch-create-fields.test.ts b/packages/graphql/tests/tck/operations/batch/batch-create-fields.test.ts index da45410aad..028a86b0fc 100644 --- a/packages/graphql/tests/tck/operations/batch/batch-create-fields.test.ts +++ b/packages/graphql/tests/tck/operations/batch/batch-create-fields.test.ts @@ -294,6 +294,7 @@ describe("Batch Create, Scalar types", () => { CALL { WITH create_this1 MATCH (create_this1)<-[create_this6:ACTED_IN]-(create_this7:Actor) + WITH DISTINCT create_this7 WITH create_this7 { .name } AS create_this7 RETURN collect(create_this7) AS create_var8 } diff --git a/packages/graphql/tests/tck/operations/batch/batch-create-interface.test.ts b/packages/graphql/tests/tck/operations/batch/batch-create-interface.test.ts index f32546e9a9..0a81cb2f4e 100644 --- a/packages/graphql/tests/tck/operations/batch/batch-create-interface.test.ts +++ b/packages/graphql/tests/tck/operations/batch/batch-create-interface.test.ts @@ -335,6 +335,7 @@ describe("Batch Create, Interface", () => { CALL { WITH this0 MATCH (this0)-[create_this0:HAS_WEBSITE]->(create_this1:Website) + WITH DISTINCT create_this1 WITH create_this1 { .address } AS create_this1 RETURN collect(create_this1) AS create_var2 } @@ -361,6 +362,7 @@ describe("Batch Create, Interface", () => { CALL { WITH this1 MATCH (this1)-[create_this9:HAS_WEBSITE]->(create_this10:Website) + WITH DISTINCT create_this10 WITH create_this10 { .address } AS create_this10 RETURN collect(create_this10) AS create_var11 } @@ -387,6 +389,7 @@ describe("Batch Create, Interface", () => { CALL { WITH this2 MATCH (this2)-[create_this18:HAS_WEBSITE]->(create_this19:Website) + WITH DISTINCT create_this19 WITH create_this19 { .address } AS create_this19 RETURN collect(create_this19) AS create_var20 } @@ -413,6 +416,7 @@ describe("Batch Create, Interface", () => { CALL { WITH this3 MATCH (this3)-[create_this27:HAS_WEBSITE]->(create_this28:Website) + WITH DISTINCT create_this28 WITH create_this28 { .address } AS create_this28 RETURN collect(create_this28) AS create_var29 } diff --git a/packages/graphql/tests/tck/operations/batch/batch-create.test.ts b/packages/graphql/tests/tck/operations/batch/batch-create.test.ts index 1030c77e24..6f221193ad 100644 --- a/packages/graphql/tests/tck/operations/batch/batch-create.test.ts +++ b/packages/graphql/tests/tck/operations/batch/batch-create.test.ts @@ -261,6 +261,7 @@ describe("Batch Create", () => { CALL { WITH create_this1 MATCH (create_this1)<-[create_this6:ACTED_IN]-(create_this7:Actor) + WITH DISTINCT create_this7 WITH create_this7 { .name } AS create_this7 RETURN collect(create_this7) AS create_var8 } @@ -384,6 +385,7 @@ describe("Batch Create", () => { CALL { WITH this0 MATCH (this0)<-[create_this0:ACTED_IN]-(create_this1:Actor) + WITH DISTINCT create_this1 WITH create_this1 { .name } AS create_this1 RETURN collect(create_this1) AS create_var2 } @@ -394,6 +396,7 @@ describe("Batch Create", () => { CALL { WITH this1 MATCH (this1)<-[create_this4:ACTED_IN]-(create_this5:Actor) + WITH DISTINCT create_this5 WITH create_this5 { .name } AS create_this5 RETURN collect(create_this5) AS create_var6 } diff --git a/packages/graphql/tests/tck/operations/create.test.ts b/packages/graphql/tests/tck/operations/create.test.ts index bb6f739a04..d78ff5753b 100644 --- a/packages/graphql/tests/tck/operations/create.test.ts +++ b/packages/graphql/tests/tck/operations/create.test.ts @@ -404,6 +404,7 @@ describe("Cypher Create", () => { CALL { WITH this0 MATCH (this0)-[create_this0:ACTED_IN]->(create_this1:Movie) + WITH DISTINCT create_this1 CALL { WITH create_this1 MATCH (create_this1)<-[create_this2:ACTED_IN]-(create_this3:Actor) diff --git a/packages/graphql/tests/tck/operations/update.test.ts b/packages/graphql/tests/tck/operations/update.test.ts index 4dfa2cb3d1..792f828e50 100644 --- a/packages/graphql/tests/tck/operations/update.test.ts +++ b/packages/graphql/tests/tck/operations/update.test.ts @@ -566,6 +566,7 @@ describe("Cypher Update", () => { CALL { WITH this MATCH (this)-[update_this0:ACTED_IN]->(update_this1:Movie) + WITH DISTINCT update_this1 WITH update_this1 { .id, .title } AS update_this1 RETURN collect(update_this1) AS update_var2 } @@ -614,6 +615,7 @@ describe("Cypher Update", () => { CALL { WITH this MATCH (this)-[update_this0:ACTED_IN]->(update_this1:Movie) + WITH DISTINCT update_this1 WITH update_this1 { .id, .title } AS update_this1 RETURN collect(update_this1) AS update_var2 } @@ -673,6 +675,7 @@ describe("Cypher Update", () => { CALL { WITH this MATCH (this)-[update_this0:ACTED_IN]->(update_this1:Movie) + WITH DISTINCT update_this1 WITH update_this1 { .id, .title } AS update_this1 RETURN collect(update_this1) AS update_var2 } diff --git a/packages/graphql/tests/tck/pagination/cypher-pagination.test.ts b/packages/graphql/tests/tck/pagination/cypher-pagination.test.ts index 0f09b63402..24a5292498 100644 --- a/packages/graphql/tests/tck/pagination/cypher-pagination.test.ts +++ b/packages/graphql/tests/tck/pagination/cypher-pagination.test.ts @@ -262,6 +262,7 @@ describe("Cypher Sort tests", () => { CALL { WITH this MATCH (this)-[this0:HAS_GENRE]->(this1:Genre) + WITH DISTINCT this1 CALL { WITH this1 CALL { diff --git a/packages/graphql/tests/tck/pagination/sort.test.ts b/packages/graphql/tests/tck/pagination/sort.test.ts index b5fb16d493..3b8cf0e8b7 100644 --- a/packages/graphql/tests/tck/pagination/sort.test.ts +++ b/packages/graphql/tests/tck/pagination/sort.test.ts @@ -163,6 +163,7 @@ describe("Sort", () => { CALL { WITH this MATCH (this)-[this0:HAS_GENRE]->(this1:Genre) + WITH DISTINCT this1 WITH this1 { .name } AS this1 ORDER BY this1.name ASC RETURN collect(this1) AS var2 @@ -191,6 +192,7 @@ describe("Sort", () => { CALL { WITH this MATCH (this)-[this0:HAS_GENRE]->(this1:Genre) + WITH DISTINCT this1 WITH this1 { .name } AS this1 ORDER BY this1.name DESC RETURN collect(this1) AS var2 diff --git a/packages/graphql/tests/tck/projection.test.ts b/packages/graphql/tests/tck/projection.test.ts index 2f8ff2289b..4cba7243b1 100644 --- a/packages/graphql/tests/tck/projection.test.ts +++ b/packages/graphql/tests/tck/projection.test.ts @@ -99,6 +99,7 @@ describe("Cypher Projection", () => { WITH create_this1 MATCH (create_this1)-[create_this2:HAS_PHOTO]->(create_this3:Photo) WHERE create_this3.url = $create_param1 + WITH DISTINCT create_this3 WITH create_this3 { .url, .location } AS create_this3 RETURN collect(create_this3) AS create_var4 } @@ -106,6 +107,7 @@ describe("Cypher Projection", () => { WITH create_this1 MATCH (create_this1)-[create_this5:HAS_COLOR]->(create_this6:Color) WHERE create_this6.id = $create_param2 + WITH DISTINCT create_this6 WITH create_this6 { .id } AS create_this6 RETURN collect(create_this6) AS create_var7 } @@ -113,6 +115,7 @@ describe("Cypher Projection", () => { WITH create_this1 MATCH (create_this1)-[create_this8:HAS_SIZE]->(create_this9:Size) WHERE create_this9.name = $create_param3 + WITH DISTINCT create_this9 WITH create_this9 { .name } AS create_this9 RETURN collect(create_this9) AS create_var10 } diff --git a/packages/graphql/tests/tck/rfcs/query-limits.test.ts b/packages/graphql/tests/tck/rfcs/query-limits.test.ts index 46d0fb5015..684b291ba1 100644 --- a/packages/graphql/tests/tck/rfcs/query-limits.test.ts +++ b/packages/graphql/tests/tck/rfcs/query-limits.test.ts @@ -158,6 +158,7 @@ describe("tck/rfcs/query-limits", () => { CALL { WITH this MATCH (this)<-[this0:ACTED_IN]-(this1:Person) + WITH DISTINCT this1 WITH this1 { .id } AS this1 LIMIT $param1 RETURN collect(this1) AS var2 @@ -356,6 +357,7 @@ describe("tck/rfcs/query-limits", () => { CALL { WITH this MATCH (this)<-[this0:ACTED_IN]-(this1:Person) + WITH DISTINCT this1 WITH this1 { .id } AS this1 LIMIT $param1 RETURN collect(this1) AS var2 diff --git a/packages/graphql/tests/tck/rfcs/rfc-022.test.ts b/packages/graphql/tests/tck/rfcs/rfc-022.test.ts index 8766f0e673..cb3eafdff5 100644 --- a/packages/graphql/tests/tck/rfcs/rfc-022.test.ts +++ b/packages/graphql/tests/tck/rfcs/rfc-022.test.ts @@ -72,6 +72,7 @@ describe("tck/rfs/022 subquery projection", () => { WITH this MATCH (this)<-[this0:ACTED_IN]-(this1:Person) WHERE this1.name = $param1 + WITH DISTINCT this1 WITH this1 { .name } AS this1 RETURN collect(this1) AS var2 } @@ -114,9 +115,11 @@ describe("tck/rfs/022 subquery projection", () => { WITH this MATCH (this)<-[this0:ACTED_IN]-(this1:Person) WHERE this1.name = $param1 + WITH DISTINCT this1 CALL { WITH this1 MATCH (this1)-[this2:DIRECTED]->(this3:Movie) + WITH DISTINCT this3 WITH this3 { .title, .released } AS this3 RETURN collect(this3) AS var4 } @@ -202,6 +205,7 @@ describe("tck/rfs/022 subquery projection", () => { CALL { WITH this MATCH (this)<-[this0:ACTED_IN]-(this1:Person) + WITH DISTINCT this1 WITH * WHERE (this1.name = $param1 AND ($isAuthenticated = true AND ($param3 IS NOT NULL AND this1.name = $param3)) AND apoc.util.validatePredicate(NOT ($isAuthenticated = true AND ($jwt.test IS NOT NULL AND this1.name = $jwt.test) AND ($jwt.roles IS NOT NULL AND $param5 IN $jwt.roles)), \\"@neo4j/graphql/FORBIDDEN\\", [0])) WITH this1 { .name } AS this1 diff --git a/packages/graphql/tests/tck/subscriptions/create.test.ts b/packages/graphql/tests/tck/subscriptions/create.test.ts index 5d5c3cc8aa..b74a41a104 100644 --- a/packages/graphql/tests/tck/subscriptions/create.test.ts +++ b/packages/graphql/tests/tck/subscriptions/create.test.ts @@ -654,6 +654,7 @@ describe("Subscriptions metadata on create", () => { CALL { WITH create_this4 MATCH (create_this4)-[create_this5:ACTED_IN]->(create_this6:Movie) + WITH DISTINCT create_this6 WITH create_this6 { .title } AS create_this6 RETURN collect(create_this6) AS create_var7 } @@ -803,6 +804,7 @@ describe("Subscriptions metadata on create", () => { CALL { WITH create_this1 MATCH (create_this1)<-[create_this6:ACTED_IN]-(create_this7:Actor) + WITH DISTINCT create_this7 WITH create_this7 { .name } AS create_this7 RETURN collect(create_this7) AS create_var8 } @@ -884,6 +886,7 @@ describe("Subscriptions metadata on create", () => { CALL { WITH create_this1 MATCH (create_this1)<-[create_this10:ACTED_IN]-(create_this11:Actor) + WITH DISTINCT create_this11 WITH create_this11 { .name } AS create_this11 RETURN collect(create_this11) AS create_var12 } @@ -1001,12 +1004,15 @@ describe("Subscriptions metadata on create", () => { CALL { WITH create_this1 MATCH (create_this1)<-[create_this14:ACTED_IN]-(create_this15:Actor) + WITH DISTINCT create_this15 CALL { WITH create_this15 MATCH (create_this15)-[create_this16:ACTED_IN]->(create_this17:Movie) + WITH DISTINCT create_this17 CALL { WITH create_this17 MATCH (create_this17)<-[create_this18:ACTED_IN]-(create_this19:Actor) + WITH DISTINCT create_this19 WITH create_this19 { .name } AS create_this19 RETURN collect(create_this19) AS create_var20 } diff --git a/packages/graphql/tests/tck/undirected-relationships/query-direction.test.ts b/packages/graphql/tests/tck/undirected-relationships/query-direction.test.ts index 3843383439..fa31929550 100644 --- a/packages/graphql/tests/tck/undirected-relationships/query-direction.test.ts +++ b/packages/graphql/tests/tck/undirected-relationships/query-direction.test.ts @@ -56,6 +56,7 @@ describe("queryDirection in relationships", () => { CALL { WITH this MATCH (this)-[this0:FRIENDS_WITH]->(this1:User) + WITH DISTINCT this1 WITH this1 { .name } AS this1 RETURN collect(this1) AS var2 } @@ -88,6 +89,7 @@ describe("queryDirection in relationships", () => { CALL { WITH this MATCH (this)-[this1:FRIENDS_WITH]->(this2:User) + WITH DISTINCT this2 WITH this2 { .name } AS this2 RETURN collect(this2) AS var3 } @@ -143,6 +145,7 @@ describe("queryDirection in relationships", () => { CALL { WITH this MATCH (this)-[update_this0:FRIENDS_WITH]->(update_this1:User) + WITH DISTINCT update_this1 WITH update_this1 { .name } AS update_this1 RETURN collect(update_this1) AS update_var2 } @@ -220,6 +223,7 @@ describe("queryDirection in relationships", () => { CALL { WITH this MATCH (this)-[update_this0:FRIENDS_WITH]->(update_this1:User) + WITH DISTINCT update_this1 WITH update_this1 { .name } AS update_this1 RETURN collect(update_this1) AS update_var2 } @@ -298,6 +302,7 @@ describe("queryDirection in relationships", () => { CALL { WITH this MATCH (this)-[update_this0:FRIENDS_WITH]->(update_this1:User) + WITH DISTINCT update_this1 WITH update_this1 { .name } AS update_this1 RETURN collect(update_this1) AS update_var2 } @@ -416,6 +421,7 @@ describe("queryDirection in relationships", () => { CALL { WITH this MATCH (this)-[this0:FRIENDS_WITH]-(this1:User) + WITH DISTINCT this1 WITH this1 { .name } AS this1 RETURN collect(this1) AS var2 } @@ -448,6 +454,7 @@ describe("queryDirection in relationships", () => { CALL { WITH this MATCH (this)-[this1:FRIENDS_WITH]-(this2:User) + WITH DISTINCT this2 WITH this2 { .name } AS this2 RETURN collect(this2) AS var3 } @@ -503,6 +510,7 @@ describe("queryDirection in relationships", () => { CALL { WITH this MATCH (this)-[update_this0:FRIENDS_WITH]-(update_this1:User) + WITH DISTINCT update_this1 WITH update_this1 { .name } AS update_this1 RETURN collect(update_this1) AS update_var2 } @@ -580,6 +588,7 @@ describe("queryDirection in relationships", () => { CALL { WITH this MATCH (this)-[update_this0:FRIENDS_WITH]-(update_this1:User) + WITH DISTINCT update_this1 WITH update_this1 { .name } AS update_this1 RETURN collect(update_this1) AS update_var2 } @@ -658,6 +667,7 @@ describe("queryDirection in relationships", () => { CALL { WITH this MATCH (this)-[update_this0:FRIENDS_WITH]-(update_this1:User) + WITH DISTINCT update_this1 WITH update_this1 { .name } AS update_this1 RETURN collect(update_this1) AS update_var2 }