diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/optimize/HugeCountStrategy.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/optimize/HugeCountStrategy.java index 5a8c468a44..ea6de76ac0 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/optimize/HugeCountStrategy.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/optimize/HugeCountStrategy.java @@ -190,19 +190,17 @@ public void apply(final Traversal.Admin traversal) { traversal.asAdmin().removeStep(curr); 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); + if (parent instanceof ConnectiveStep) { + final Step notStep = this.transformToNotStep( + traversal, parent); + TraversalHelper.removeAllSteps(traversal); + traversal.addStep(notStep); + } else if (parent instanceof FilterStep) { + final Step filterStep = parent.asStep(); + final Step notStep = this.transformToNotStep( + traversal, parent); TraversalHelper.replaceStep(filterStep, notStep, - parentTraversal); + filterStep.getTraversal()); } else { final Traversal.Admin inner; if (prev != null) { @@ -256,6 +254,17 @@ public void apply(final Traversal.Admin traversal) { } } + 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) || diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/CountStrategyCoreTest.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/CountStrategyCoreTest.java index fdfc9d2e44..97e56d1b9a 100644 --- a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/CountStrategyCoreTest.java +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/CountStrategyCoreTest.java @@ -30,10 +30,11 @@ public class CountStrategyCoreTest extends BaseCoreTest { private void initSchema() { SchemaManager schema = graph().schema(); schema.propertyKey("name").asText().create(); - schema.vertexLabel("person").properties("name") - .nullableKeys("name").create(); - schema.vertexLabel("software").properties("name") - .nullableKeys("name").create(); + schema.propertyKey("none").asText().create(); + schema.vertexLabel("person").properties("name", "none") + .nullableKeys("name", "none").create(); + schema.vertexLabel("software").properties("name", "none") + .nullableKeys("name", "none").create(); schema.edgeLabel("knows").link("person", "person").create(); schema.edgeLabel("created").link("person", "software").create(); } @@ -125,4 +126,58 @@ public void testWhereCountGteNegativeDoesNotBuildInvalidRange() { Assert.assertEquals(4L, count); } + + @Test + public void testConnectiveAndCountIsZero() { + this.initSchema(); + this.initGraph(); + + long count = graph().traversal().V() + .filter(__.and(__.out().count().is(0), + __.in().count().is(0))) + .count().next(); + + Assert.assertEquals(0L, count); + } + + @Test + public void testConnectiveOrCountIsZero() { + this.initSchema(); + this.initGraph(); + + long count = graph().traversal().V() + .filter(__.or(__.out().count().is(0), + __.in().count().is(0))) + .count().next(); + + Assert.assertEquals(3L, count); + } + + @Test + public void testWhereOrWithMultiStepCountIsZero() { + this.initSchema(); + this.initGraph(); + + long count = graph().traversal().V() + .where(__.or(__.out("created").out("knows") + .count().is(0), + __.has("none"))) + .count().next(); + + Assert.assertEquals(3L, count); + } + + @Test + public void testWhereOrWithMultipleCountIsZero() { + this.initSchema(); + this.initGraph(); + + long count = graph().traversal().V() + .where(__.or(__.out("created").out("knows") + .count().is(0), + __.has("none").count().is(0))) + .count().next(); + + Assert.assertEquals(3L, count); + } }