This is an automated email from the ASF dual-hosted git repository.
Cole-Greer pushed a commit to branch 3.8-dev
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git
The following commit(s) were added to refs/heads/3.8-dev by this push:
new 673fcd609a Fix doFinalReduction to remove keys when post-barrier steps
produce nothing (#3513)
673fcd609a is described below
commit 673fcd609a1104a4243b5d000bcb4b5e2d406aaa
Author: theneelshah <[email protected]>
AuthorDate: Thu Jul 16 16:15:40 2026 -0700
Fix doFinalReduction to remove keys when post-barrier steps produce nothing
(#3513)
Co-authored-by: Neel Shah <[email protected]>
---
CHANGELOG.asciidoc | 1 +
.../gremlin/process/traversal/step/Grouping.java | 8 +++++++-
.../gremlin/test/features/sideEffect/Group.feature | 22 ++++++++++++++++++++++
3 files changed, 30 insertions(+), 1 deletion(-)
diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc
index 340aa2b2b2..a5ecd33da3 100644
--- a/CHANGELOG.asciidoc
+++ b/CHANGELOG.asciidoc
@@ -31,6 +31,7 @@ This release also includes changes from prior 3.7.x releases.
* Bumped to Groovy 4.0.32 which adds support for parsing Java 25 bytecode.
* Bumped Hadoop to 3.4.3 (and Kerby to 2.0.3) to enable `hadoop-gremlin` to
build and run on Java 25.
* Add missing `Configuring` interface to `GraphStepPlaceholder` and
`VertexStepPlaceholder`
+* Fixed bug in `group()` value traversal where keys were retained with stale
barrier state instead of being filtered when steps following a `Barrier` in the
second `by()` produced no output (e.g. `by(values("age").fold().unfold())` or
`by(__.out().fold().count(local).is(P.gt(0)))` for vertices with no out-edges).
[[release-3-8-1]]
=== TinkerPop 3.8.1 (Release Date: April 1, 2026)
diff --git
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/Grouping.java
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/Grouping.java
index 62cc816e8c..18f5309737 100644
---
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/Grouping.java
+++
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/Grouping.java
@@ -31,6 +31,7 @@ import
org.apache.tinkerpop.gremlin.process.traversal.step.map.LambdaMapStep;
import
org.apache.tinkerpop.gremlin.process.traversal.step.sideEffect.GroupSideEffectStep;
import org.apache.tinkerpop.gremlin.process.traversal.step.util.ProfileStep;
+import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@@ -106,12 +107,17 @@ public interface Grouping<S, K, V> {
public default Map<K, V> doFinalReduction(final Map<K, Object> map, final
Traversal.Admin<S, V> valueTraversal) {
final Barrier barrierStep = determineBarrierStep(valueTraversal);
if (barrierStep != null) {
+ final List<K> keysToRemove = new ArrayList<>();
for (final K key : map.keySet()) {
valueTraversal.reset();
barrierStep.addBarrier(map.get(key));
- if (valueTraversal.hasNext())
+ if (valueTraversal.hasNext()) {
map.put(key, valueTraversal.next());
+ } else {
+ keysToRemove.add(key);
+ }
}
+ keysToRemove.forEach(map::remove);
}
return (Map<K, V>) map;
}
diff --git
a/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/sideEffect/Group.feature
b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/sideEffect/Group.feature
index bdcd871c10..c20af59cb5 100644
---
a/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/sideEffect/Group.feature
+++
b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/sideEffect/Group.feature
@@ -259,6 +259,28 @@ Feature: Step - group()
| result |
| m[{"v[peter]":"v[lop]"}] |
+ Scenario: g_V_group_byXvaluesXnameXX_byXvaluesXageX_fold_unfoldX
+ Given the modern graph
+ And the traversal of
+ """
+ g.V().group().by(values("name")).by(values("age").fold().unfold())
+ """
+ When iterated to list
+ Then the result should be unordered
+ | result |
+ | m[{"marko":"d[29].i", "vadas":"d[27].i", "josh":"d[32].i",
"peter":"d[35].i"}] |
+
+ Scenario: g_V_group_byXvaluesXnameXX_byXout_fold_countXlocalX_isXgtX0XXX
+ Given the modern graph
+ And the traversal of
+ """
+
g.V().group().by(values("name")).by(__.out().fold().count(local).is(P.gt(0)))
+ """
+ When iterated to list
+ Then the result should be unordered
+ | result |
+ | m[{"marko":"d[3].l", "josh":"d[2].l", "peter":"d[1].l"}] |
+
Scenario:
g_V_hasXperson_name_withinXvadas_peterXX_group_by_byXout_order_countX
Given the modern graph
And the traversal of