diff --git a/hugegraph-core/src/main/java/org/apache/hugegraph/StandardHugeGraph.java b/hugegraph-core/src/main/java/org/apache/hugegraph/StandardHugeGraph.java index e7039ba412..3cc1a83dd2 100644 --- a/hugegraph-core/src/main/java/org/apache/hugegraph/StandardHugeGraph.java +++ b/hugegraph-core/src/main/java/org/apache/hugegraph/StandardHugeGraph.java @@ -193,7 +193,7 @@ public StandardHugeGraph(HugeConfig config) { this.taskManager = TaskManager.instance(); - boolean supportsPersistence = this.backendStoreFeatures().supportsPersistence(); + boolean supportsPersistence = !"memory".equals(config.get(CoreOptions.BACKEND)); this.features = new HugeFeatures(this, supportsPersistence); this.name = config.get(CoreOptions.STORE); diff --git a/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/optimize/HugeGraphStepStrategy.java b/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/optimize/HugeGraphStepStrategy.java index bea1f19ae1..baa1946c5e 100644 --- a/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/optimize/HugeGraphStepStrategy.java +++ b/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/optimize/HugeGraphStepStrategy.java @@ -54,6 +54,9 @@ public void apply(Traversal.Admin traversal) { List steps = TraversalHelper.getStepsOfClass( GraphStep.class, traversal); for (GraphStep originStep : steps) { + TraversalUtil.trySetGraph(originStep, + TraversalUtil.tryGetGraph(steps.get(0))); + HugeGraphStep newStep = new HugeGraphStep<>(originStep); TraversalHelper.replaceStep(originStep, newStep, traversal); diff --git a/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/optimize/TraversalUtil.java b/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/optimize/TraversalUtil.java index d43dcb951c..5c76edc67a 100644 --- a/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/optimize/TraversalUtil.java +++ b/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/optimize/TraversalUtil.java @@ -25,6 +25,7 @@ import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.function.BiPredicate; import java.util.function.Function; import java.util.regex.Matcher; @@ -54,6 +55,7 @@ import org.apache.tinkerpop.gremlin.process.traversal.Traversal; import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal; import org.apache.tinkerpop.gremlin.process.traversal.step.HasContainerHolder; +import org.apache.tinkerpop.gremlin.process.traversal.step.TraversalParent; import org.apache.tinkerpop.gremlin.process.traversal.step.filter.FilterStep; import org.apache.tinkerpop.gremlin.process.traversal.step.filter.HasStep; import org.apache.tinkerpop.gremlin.process.traversal.step.filter.RangeGlobalStep; @@ -105,12 +107,71 @@ public static HugeGraph getGraph(Step step) { } public static HugeGraph tryGetGraph(Step step) { - Graph graph = step.getTraversal().getGraph().get(); - if (graph instanceof HugeGraph) { - return (HugeGraph) graph; + Optional graph = step.getTraversal() + .getGraph() + .filter(g -> { + return !(g instanceof EmptyGraph); + }); + if (!graph.isPresent()) { + TraversalParent parent = step.getTraversal().getParent(); + if (parent instanceof Traversal) { + Optional parentGraph = ((Traversal) parent) + .asAdmin() + .getGraph() + .filter(g -> { + return !(g instanceof EmptyGraph); + }); + if (parentGraph.isPresent()) { + step.getTraversal().setGraph(parentGraph.get()); + return (HugeGraph) parentGraph.get(); + } + } + + return null; } - assert graph == null || graph instanceof EmptyGraph; - return null; + + assert graph.get() instanceof HugeGraph; + return (HugeGraph) graph.get(); + } + + public static void trySetGraph(Step step, HugeGraph graph) { + if (graph == null || step == null || step.getTraversal() == null) { + return; + } + + Optional stepGraph = step.getTraversal() + .getGraph() + .filter(g -> { + return !(g instanceof EmptyGraph); + }); + + if (step instanceof TraversalParent) { + for (final Traversal.Admin local : ((TraversalParent) step).getLocalChildren()) { + if (local.getGraph() + .filter(g -> { + return !(g instanceof EmptyGraph); + }).isPresent()) { + continue; + } + local.setGraph(graph); + } + for (final Traversal.Admin global : ((TraversalParent) step).getGlobalChildren()) { + if (global.getGraph() + .filter(g -> { + return !(g instanceof EmptyGraph); + }).isPresent()) { + continue; + } + global.setGraph(graph); + } + } + + if (stepGraph.isPresent()) { + assert stepGraph.get() instanceof HugeGraph; + return; + } + + step.getTraversal().setGraph(graph); } public static void extractHasContainer(HugeGraphStep newStep, @@ -580,14 +641,34 @@ public static void convAllHasSteps(Traversal.Admin traversal) { List steps = TraversalHelper.getStepsOfAssignableClassRecursively( HasStep.class, traversal); + + if (steps.isEmpty()) { + return; + } + /* * The graph in traversal may be null, for example: * `g.V().hasLabel('person').union(__.has('name', 'tom'))` * Here `__.has()` will create a new traversal, but the graph is null */ - if (steps.isEmpty() || !traversal.getGraph().isPresent()) { - return; + if (!traversal.getGraph() + .filter(g -> { + return !(g instanceof EmptyGraph); + }).isPresent()) { + if (traversal.getParent() == null || !(traversal.getParent() instanceof Traversal)) { + return; + } + + Optional parentGraph = ((Traversal) traversal.getParent()) + .asAdmin() + .getGraph(); + if (parentGraph.filter(g -> { + return !(g instanceof EmptyGraph); + }).isPresent()) { + traversal.setGraph(parentGraph.get()); + } } + HugeGraph graph = (HugeGraph) traversal.getGraph().get(); for (HasStep step : steps) { TraversalUtil.convHasStep(graph, step);