From 97487f88544e0aa11971bc265f03e00e7ef14795 Mon Sep 17 00:00:00 2001 From: "Norio Akagi (norakagi)" Date: Tue, 22 Aug 2023 13:39:47 -0700 Subject: [PATCH] [TINKERPOP-2972] ProjectStep does not allow keys specified in a query to be duplicate --- CHANGELOG.asciidoc | 1 + .../process/traversal/step/map/ProjectStep.java | 7 +++++++ .../traversal/step/map/ProjectStepTest.java | 17 +++++++++++++++++ .../gremlin/test/features/map/Project.feature | 11 ++++++++++- 4 files changed, 35 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc index 3a4a338a341..e59f334d21d 100644 --- a/CHANGELOG.asciidoc +++ b/CHANGELOG.asciidoc @@ -30,6 +30,7 @@ This release also includes changes from <>. * Deprecated the `HandshakeInterceptor` in favor of a more generic `RequestInterceptor`. * Fix a bug in `StarGraph` where `EdgeFilter` did not remove associated Edge Properties * Added translator to the Go GLV +* ProjectStep throws exception when a duplicate key is provided in a query. [[release-3-6-5]] === TinkerPop 3.6.5 (Release Date: July 31, 2023) diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/ProjectStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/ProjectStep.java index 78a24674ec3..c1f33910010 100644 --- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/ProjectStep.java +++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/ProjectStep.java @@ -29,10 +29,12 @@ import org.apache.tinkerpop.gremlin.structure.util.StringFactory; import java.util.Arrays; +import java.util.HashSet; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.stream.Collectors; /** * @author Marko A. Rodriguez (http://markorodriguez.com) @@ -48,6 +50,11 @@ public ProjectStep(final Traversal.Admin traversal, final String... projectKeys) public ProjectStep(final Traversal.Admin traversal, final TraversalRing traversalRing, final String... projectKeys) { super(traversal); + + if (Arrays.stream(projectKeys).collect(Collectors.toSet()).size() != projectKeys.length) { + throw new IllegalArgumentException("keys must be unique in ProjectStep"); + } + this.projectKeys = Arrays.asList(projectKeys); this.traversalRing = traversalRing; } diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/ProjectStepTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/ProjectStepTest.java index fb635267072..1755029480b 100644 --- a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/ProjectStepTest.java +++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/ProjectStepTest.java @@ -22,10 +22,16 @@ import org.apache.tinkerpop.gremlin.process.traversal.Traversal; import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__; import org.apache.tinkerpop.gremlin.process.traversal.step.StepTest; +import org.junit.Test; import java.util.Arrays; import java.util.List; +import static org.hamcrest.CoreMatchers.instanceOf; +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.Assert.fail; + /** * @author Marko A. Rodriguez (http://markorodriguez.com) */ @@ -44,4 +50,15 @@ protected List getTraversals() { __.project("y").by("name") ); } + + @Test + public void shouldThrowWhenDuplicateKeySupplied() { + try { + __.project("x", "x"); + fail("Should throw an exception."); + } catch (final Exception re) { + assertThat(re, instanceOf(IllegalArgumentException.class)); + assertThat(re.getMessage(), is("keys must be unique in ProjectStep")); + } + } } \ No newline at end of file diff --git a/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/Project.feature b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/Project.feature index 0e6e87567bb..e2cc6d3a733 100644 --- a/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/Project.feature +++ b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/Project.feature @@ -106,4 +106,13 @@ Feature: Step - project() | m[{"a":"d[0].l", "b":"d[29].i"}] | | m[{"a":"d[1].l", "b":"d[27].i"}] | | m[{"a":"d[1].l", "b":"d[32].i"}] | - | m[{"a":"d[0].l", "b":"d[35].i"}] | \ No newline at end of file + | m[{"a":"d[0].l", "b":"d[35].i"}] | + + + Scenario: g_V_projectXa_aX + Given the modern graph + And the traversal of + """ + g.V().project("a", "a") + """ + Then the traversal will raise an error with message containing text of "keys must be unique in ProjectStep" \ No newline at end of file