You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tinkerpop.apache.org by ke...@apache.org on 2023/11/16 22:20:34 UTC
(tinkerpop) branch string-null-update created (now 2bd909ba68)
This is an automated email from the ASF dual-hosted git repository.
kenhuuu pushed a change to branch string-null-update
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git
at 2bd909ba68 Update conjoin() and asString() null handling.
This branch includes the following new commits:
new 2bd909ba68 Update conjoin() and asString() null handling.
The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
(tinkerpop) 01/01: Update conjoin() and asString() null handling.
Posted by ke...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
kenhuuu pushed a commit to branch string-null-update
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git
commit 2bd909ba68ac2398211f0a71b3e07903ad35e0f4
Author: Ken Hu <10...@users.noreply.github.com>
AuthorDate: Thu Nov 16 14:18:13 2023 -0800
Update conjoin() and asString() null handling.
The handling of null values in some recently implemented Steps were
inconsistent. This addresses that issue by making conjoin() behave like
concat() and asString() like the other String functions.
---
docs/src/dev/provider/gremlin-semantics.asciidoc | 11 ++++++-----
docs/src/reference/the-traversal.asciidoc | 4 ++--
.../process/traversal/step/map/AsStringGlobalStep.java | 5 +++--
.../gremlin/process/traversal/step/map/AsStringLocalStep.java | 4 ++--
.../gremlin/process/traversal/step/map/ConjoinStep.java | 10 +++++++---
.../process/traversal/step/map/AsStringGlobalStepTest.java | 2 +-
.../process/traversal/step/map/AsStringLocalStepTest.java | 2 +-
.../gremlin/process/traversal/step/map/ConjoinStepTest.java | 3 +++
.../tinkerpop/gremlin/test/features/map/AsString.feature | 4 ++--
.../tinkerpop/gremlin/test/features/map/Conjoin.feature | 2 +-
10 files changed, 28 insertions(+), 19 deletions(-)
diff --git a/docs/src/dev/provider/gremlin-semantics.asciidoc b/docs/src/dev/provider/gremlin-semantics.asciidoc
index acec2f6c8c..f2167c75c0 100644
--- a/docs/src/dev/provider/gremlin-semantics.asciidoc
+++ b/docs/src/dev/provider/gremlin-semantics.asciidoc
@@ -632,8 +632,9 @@ incoming list traverser as string.
*Arguments:*
* `scope` - Determines the type of traverser it operates on. Both scopes will operate on the level of individual traversers.
-The `global` scope will operate on individual traverser, casting all to string. The `local` scope will behave like `global`
-for everything except lists, where it will cast individual elements inside the list into string and return a list of string instead.
+The `global` scope will operate on individual traverser, casting all (except null) to string. The `local` scope will behave like
+`global` for everything except lists, where it will cast individual non-null elements inside the list into string and return a
+list of string instead.
Null values from the incoming traverser are not processed and remain as null when returned.
@@ -1121,9 +1122,9 @@ None
*Considerations:*
-Every element in the list (including nulls) is converted to a String. The delimiter is inserted between neighboring
-elements to form the final result. This step only applies to list types which means that non-iterable types (including
-null) will cause exceptions to be thrown.
+Every element in the list (except null) is converted to a String. Null values are ignored. The delimiter is inserted
+between neighboring elements to form the final result. This step only applies to list types which means that
+non-iterable types (including null) will cause exceptions to be thrown.
*Exceptions*
diff --git a/docs/src/reference/the-traversal.asciidoc b/docs/src/reference/the-traversal.asciidoc
index c1f3c59dea..5acfe2d4c5 100644
--- a/docs/src/reference/the-traversal.asciidoc
+++ b/docs/src/reference/the-traversal.asciidoc
@@ -782,7 +782,7 @@ link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gre
[[asString-step]]
=== AsString Step
-The `asString()`-step (*map*) returns the value of incoming traverser as strings. Null values are returned as a string value "null".
+The `asString()`-step (*map*) returns the value of incoming traverser as strings. Null values are returned unchanged.
[gremlin-groovy,modern]
----
@@ -1215,7 +1215,7 @@ link:++https://tinkerpop.apache.org/docs/x.y.z/dev/provider/#concat-step++[`Sema
The `conjoin()`-step (*map*) joins together the elements in the incoming list traverser together with the provided argument
as a delimiter. The resulting `String` is added to the Traversal Stream. This step only expects list data (array or
Iterable) in the incoming traverser and will throw an `IllegalArgumentException` if any other type is encountered
-(including null). However, null is allowed as an element within the list and is converted to "null".
+(including null). Null values are skipped and not included in the result.
[gremlin-groovy,modern]
----
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AsStringGlobalStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AsStringGlobalStep.java
index 89782d4afe..eea78d853e 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AsStringGlobalStep.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AsStringGlobalStep.java
@@ -27,7 +27,7 @@ import java.util.Set;
/**
* Reference implementation for asString() step, a mid-traversal step which returns the incoming traverser value
- * as a string. Null values are returned as a string value "null".
+ * as a string. Null values are returned unchanged.
*
* @author David Bechberger (http://bechberger.com)
* @author Yang Xia (http://github.com/xiazcy)
@@ -40,7 +40,8 @@ public final class AsStringGlobalStep<S, E> extends ScalarMapStep<S, E> {
@Override
protected E map(final Traverser.Admin<S> traverser) {
- return (E) String.valueOf(traverser.get());
+ S traverserObject = traverser.get();
+ return (E) ((traverserObject == null) ? null : String.valueOf(traverserObject));
}
@Override
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AsStringLocalStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AsStringLocalStep.java
index bf354aad99..4a2120d238 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AsStringLocalStep.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AsStringLocalStep.java
@@ -31,7 +31,7 @@ import java.util.Set;
/**
* Reference implementation for asString() step, a mid-traversal step which returns the incoming traverser value
- * as a string. Null values are returned as a string value "null".
+ * as a string. Null values are returned unchanged.
*
* @author David Bechberger (http://bechberger.com)
* @author Yang Xia (http://github.com/xiazcy)
@@ -54,7 +54,7 @@ public final class AsStringLocalStep<S, E> extends ScalarMapStep<S, E> {
final Iterator<E> iterator = IteratorUtils.asIterator(item);
while (iterator.hasNext()) {
final E i = iterator.next();
- resList.add(String.valueOf(i));
+ resList.add((i == null) ? null : String.valueOf(i));
}
return (E) resList;
} else {
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/ConjoinStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/ConjoinStep.java
index f7b27ef1b6..0f38739f9b 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/ConjoinStep.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/ConjoinStep.java
@@ -48,18 +48,22 @@ public final class ConjoinStep<S> extends ScalarMapStep<S, String> implements Li
@Override
protected String map(Traverser.Admin<S> traverser) {
final Collection elements = convertTraverserToCollection(traverser);
+ if (elements.isEmpty()) { return ""; }
final StringBuilder joinResult = new StringBuilder();
for (Object elem : elements) {
- joinResult.append(String.valueOf(elem)).append(delimiter);
+ if (elem != null) {
+ joinResult.append(String.valueOf(elem)).append(delimiter);
+ }
}
if (joinResult.length() != 0) {
joinResult.delete(joinResult.length() - delimiter.length(), joinResult.length());
+ return joinResult.toString();
+ } else {
+ return null;
}
-
- return joinResult.toString();
}
@Override
diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AsStringGlobalStepTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AsStringGlobalStepTest.java
index b9a27e5c41..aa9097b173 100644
--- a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AsStringGlobalStepTest.java
+++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AsStringGlobalStepTest.java
@@ -49,7 +49,7 @@ public class AsStringGlobalStepTest extends StepTest {
assertEquals("1", __.__(Arrays.asList(1, 2)).unfold().asString().next());
assertArrayEquals(new String[]{"1", "2"}, __.inject(Arrays.asList(1, 2)).unfold().asString().toList().toArray());
- assertEquals("null", __.__(null).asString().next());
+ assertEquals(null, __.__(null).asString().next());
assertEquals("[1, 2]test", __.__(Arrays.asList(1, 2)).asString().concat("test").next());
assertEquals("1test", __.__(Arrays.asList(1, 2)).unfold().asString().concat("test").next());
diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AsStringLocalStepTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AsStringLocalStepTest.java
index ab844debb7..21dd03cfbb 100644
--- a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AsStringLocalStepTest.java
+++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AsStringLocalStepTest.java
@@ -46,7 +46,7 @@ public class AsStringLocalStepTest extends StepTest {
assertEquals("1", __.__(1).asString(Scope.local).next());
assertArrayEquals(new String[]{"1", "2"}, __.inject(1, 2).asString(Scope.local).toList().toArray());
assertArrayEquals(new String[]{}, ((List<?>) __.__(Collections.emptyList()).asString(Scope.local).next()).toArray());
- assertArrayEquals(new String[]{"1", "2", "null"}, ((List<?>) __.__(Arrays.asList(1, 2, null)).asString(Scope.local).next()).toArray());
+ assertArrayEquals(new String[]{"1", "2", null}, ((List<?>) __.__(Arrays.asList(1, 2, null)).asString(Scope.local).next()).toArray());
assertArrayEquals(new String[]{"1test", "2test"},
__.__(Arrays.asList(1, 2)).asString(Scope.local).unfold().concat("test").toList().toArray());
diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/ConjoinStepTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/ConjoinStepTest.java
index 300817de4d..a84c691182 100644
--- a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/ConjoinStepTest.java
+++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/ConjoinStepTest.java
@@ -23,12 +23,14 @@ 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.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
@@ -49,6 +51,7 @@ public class ConjoinStepTest extends StepTest {
assertEquals("5AA8AA10", __.__(new long[] {5L, 8L, 10L}).conjoin("AA").next());
assertEquals("715", __.__(1).constant(new Long[] {7L, 15L}).conjoin("").next());
assertEquals("5.5,8.0,10.1", __.__(new double[] {5.5, 8.0, 10.1}).conjoin(",").next());
+ assertNull(__.__(Arrays.asList(null, null)).conjoin(",").next());
final Set<Integer> set = new HashSet<>();
set.add(10); set.add(11); set.add(12);
diff --git a/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/AsString.feature b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/AsString.feature
index 187be9daa4..5d469cfc95 100644
--- a/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/AsString.feature
+++ b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/AsString.feature
@@ -72,7 +72,7 @@ Feature: Step - asString()
When iterated to list
Then the result should be unordered
| result |
- | str[null] |
+ | null |
| 1 |
@GraphComputerVerificationInjectionNotSupported
@@ -86,7 +86,7 @@ Feature: Step - asString()
When iterated to list
Then the result should be unordered
| result |
- | l[1,str[null]] |
+ | l[1,null] |
Scenario: g_V_valueMapXnameX_asString
Given the modern graph
diff --git a/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/Conjoin.feature b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/Conjoin.feature
index 0a326a53b8..9d9d54547e 100644
--- a/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/Conjoin.feature
+++ b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/Conjoin.feature
@@ -139,7 +139,7 @@ Feature: Step - conjoin()
When iterated to list
Then the result should be unordered
| result |
- | str[axyznullxyzb] |
+ | str[axyzb] |
@GraphComputerVerificationInjectionNotSupported
Scenario: g_injectX3_threeX_conjoinX_X