Skip to content

Commit

Permalink
Merge branch '3.6-dev'
Browse files Browse the repository at this point in the history
  • Loading branch information
kenhuuu committed Apr 14, 2023
2 parents a3e9cd4 + 055a946 commit 32b03cb
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 9 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,8 @@ image::https://raw.githubusercontent.com/apache/tinkerpop/master/docs/static/ima
=== TinkerPop 3.5.6 (Release Date: NOT OFFICIALLY RELEASED YET)
* Added `GraphFilter` support to `GraphSONRecordReader`.
* gremlin-python aiohttp dependency requirement upper bound relaxed to <4.0.0
* gremlin-python aiohttp dependency requirement upper bound relaxed to <4.0.0.
* Fixed bug in `CountStrategy` where `or()` and `and()` filters were not being rewritten properly for some patterns.
* Changed `PartitionStrategy` to force its filters to the end of the chain for `Vertex` and `Edge` read steps, thus preserving order of the `has()`.
* Added `RequestOptions` and `RequestOptionsBuilder` types to Go GLV to encapsulate per-request settings and bindings.
* Improved `addE()` error messaging when traverser is not a `Vertex`.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,14 +140,17 @@ public void apply(final Traversal.Admin<?, ?> traversal) {
traversal.asAdmin().removeStep(curr); // CountStep
size -= 2;
if (!dismissCountIs) {
final TraversalParent p;
if ((p = traversal.getParent()) instanceof FilterStep && !(p instanceof ConnectiveStep)) {
final Step<?, ?> filterStep = parent.asStep();
final Traversal.Admin parentTraversal = filterStep.getTraversal();
final Step notStep = new NotStep<>(parentTraversal,
traversal.getSteps().isEmpty() ? __.identity() : traversal);
filterStep.getLabels().forEach(notStep::addLabel);
TraversalHelper.replaceStep(filterStep, notStep, parentTraversal);
if (parent instanceof ConnectiveStep) {
// wrap the child of and()/or() in not().
final Step<?, ?> notStep = transformToNotStep(traversal, parent);
TraversalHelper.removeAllSteps(traversal);
traversal.addStep(notStep);
} else if (parent instanceof FilterStep) {
// converts entire where(<x>.count().is(0)) to not(<x>). that's why ConnectiveStep
// is handled differently above.
final Step filterStep = parent.asStep();
final Step<?, ?> notStep = transformToNotStep(traversal, parent);
TraversalHelper.replaceStep(filterStep, notStep, filterStep.getTraversal());
} else {
final Traversal.Admin inner;
if (prev != null) {
Expand Down Expand Up @@ -187,6 +190,19 @@ public void apply(final Traversal.Admin<?, ?> traversal) {
}
}

/**
* The {@code traversal} argument was marked as one that could be converted to {@code not()}, so wrap it inside
* that step and copy the labels.
*/
private Step<?, ?> transformToNotStep(final Traversal.Admin<?, ?> traversal, final TraversalParent parent) {
final Step<?, ?> filterStep = parent.asStep();
final Traversal.Admin<?,?> parentTraversal = filterStep.getTraversal();
final Step<?,?> notStep = new NotStep<>(parentTraversal,
traversal.getSteps().isEmpty() ? __.identity() : traversal.clone());
filterStep.getLabels().forEach(notStep::addLabel);
return notStep;
}

private boolean doStrategy(final Step step) {
if (!(step instanceof CountGlobalStep) ||
!(step.getNextStep() instanceof IsStep) ||
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ public static Iterable<Object[]> generateTestParameters() {
{__.filter(__.out().count().is(0)), __.not(__.out())},
{__.filter(__.outE().count().is(lt(1))), __.not(__.outE())},
{__.filter(__.both().count().is(lte(0))), __.not(__.both())},
{__.filter(__.out().out().count().is(0)), __.not(__.out().out())},
{__.store("x").count().is(0).as("a"), __.store("x").limit(1).count().is(0).as("a")},
{__.out().count().as("a").is(0), __.out().limit(1).count().as("a").is(0)},
{__.out().count().is(neq(4)), __.out().limit(5).count().is(neq(4))},
Expand All @@ -90,17 +91,23 @@ public static Iterable<Object[]> generateTestParameters() {
{__.branch(__.count().is(0)), __.branch(__.limit(1).count().is(0))},
{__.count().is(0).store("x"), __.limit(1).count().is(0).store("x")},
{__.repeat(__.out()).until(__.outE().count().is(0)), __.repeat(__.out()).until(__.not(__.outE()))},
{__.repeat(__.out()).until(__.out().out().values("name").count().is(0)), __.repeat(__.out()).until(__.out().out().not(__.values("name")))},
{__.repeat(__.out()).until(__.out().out().properties("age").has("x").count().is(0)), __.repeat(__.out()).until(__.out().out().not(__.properties("age").has("x")))},
{__.repeat(__.out()).emit(__.outE().count().is(0)), __.repeat(__.out()).emit(__.not(__.outE()))},
{__.where(__.outE().hasLabel("created").count().is(0)), __.not(__.outE().hasLabel("created"))},
{__.where(__.out().outE().hasLabel("created").count().is(0)), __.not(__.out().outE().hasLabel("created"))},
{__.where(__.out().outE().hasLabel("created").count().is(0).store("x")), __.where(__.out().outE().hasLabel("created").limit(1).count().is(0).store("x"))},
{__.where(__.or(__.out("none").out().count().is(0), __.has("none"))), __.where(__.or(__.not(__.out("none").out()), __.has("none"))) },
{__.where(__.or(__.out("none").out().count().is(0), __.has("none").count().is(0))), __.where(__.or(__.not(__.out("none").out()), __.not(__.has("none")))) },
{__.where(__.or(__.out("none").out(), __.has("none").count().is(0))), __.where(__.or(__.out("none").out(), __.not(__.has("none")))) },
{__.filter(__.bothE().count().is(gt(0))), __.filter(__.bothE())},
{__.filter(__.bothE().count().is(gte(1))), __.filter(__.bothE())},
{__.filter(__.bothE().count().is(gt(1))), __.filter(__.bothE().limit(2).count().is(gt(1)))},
{__.filter(__.bothE().count().is(gte(2))), __.filter(__.bothE().limit(2).count().is(gte(2)))},
{__.and(__.out().count().is(0), __.in().count().is(0)), __.and(__.not(__.out()), __.not(__.in()))},
{__.and(__.out().count().is(0), __.in().count().is(1)), __.and(__.not(__.out()), __.in().limit(2).count().is(1))},
{__.and(__.out().count().is(1), __.in().count().is(0)), __.and(__.out().limit(2).count().is(1), __.not(__.in()))},
{__.and(__.out().out().count().is(0), __.in().count().is(0)), __.and(__.not(__.out().out()), __.not(__.in()))},
{__.or(__.out().count().is(0), __.in().count().is(0)), __.or(__.not(__.out()), __.not(__.in()))},
{__.path().filter(__.count().is(gte(0.5))).limit(5), __.path().identity().limit(5)}, // unfortunately we can't just remove the filter step
{__.path().filter(__.unfold().count().is(gte(0.5))), __.path().filter(__.unfold())},
Expand Down

0 comments on commit 32b03cb

Please sign in to comment.