From 423fbb2b38d72f6523fd06a8fb6b89bd4838ba1d Mon Sep 17 00:00:00 2001 From: imbajin Date: Fri, 30 Dec 2022 16:34:03 +0800 Subject: [PATCH] fix(core): adapt HugeVertex.property() with null values --- .../apache/hugegraph/structure/HugeEdge.java | 2 +- .../hugegraph/structure/HugeVertex.java | 28 ++++++---- .../tinkerpop/ProcessStandardTest.java | 3 +- .../apache/hugegraph/tinkerpop/TestGraph.java | 55 +++++++------------ 4 files changed, 40 insertions(+), 48 deletions(-) diff --git a/hugegraph-core/src/main/java/org/apache/hugegraph/structure/HugeEdge.java b/hugegraph-core/src/main/java/org/apache/hugegraph/structure/HugeEdge.java index 8bfa67f2f..365b4d203 100644 --- a/hugegraph-core/src/main/java/org/apache/hugegraph/structure/HugeEdge.java +++ b/hugegraph-core/src/main/java/org/apache/hugegraph/structure/HugeEdge.java @@ -369,7 +369,7 @@ public class HugeEdge extends HugeElement implements Edge, Cloneable { if (ownerLabel.equals(this.label.sourceLabel())) { this.vertices(true, owner, other); } else { - // TODO: why when compare the label but ignore the result? + // TODO: why compare the label but ignore the result? ownerLabel.equals(this.label.targetLabel()); this.vertices(false, owner, other); } diff --git a/hugegraph-core/src/main/java/org/apache/hugegraph/structure/HugeVertex.java b/hugegraph-core/src/main/java/org/apache/hugegraph/structure/HugeVertex.java index 9fae700e6..3b1482b54 100644 --- a/hugegraph-core/src/main/java/org/apache/hugegraph/structure/HugeVertex.java +++ b/hugegraph-core/src/main/java/org/apache/hugegraph/structure/HugeVertex.java @@ -22,6 +22,7 @@ package org.apache.hugegraph.structure; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; +import java.util.HashSet; import java.util.Iterator; import java.util.LinkedList; import java.util.List; @@ -61,6 +62,9 @@ import org.apache.hugegraph.type.define.Directions; import org.apache.hugegraph.type.define.HugeKeys; import org.apache.hugegraph.type.define.IdStrategy; import org.apache.hugegraph.util.E; +import org.apache.tinkerpop.gremlin.structure.util.empty.EmptyProperty; +import org.apache.tinkerpop.gremlin.structure.util.empty.EmptyVertexProperty; + import com.google.common.collect.ImmutableList; public class HugeVertex extends HugeElement implements Vertex, Cloneable { @@ -164,8 +168,7 @@ public class HugeVertex extends HugeElement implements Vertex, Cloneable { } break; default: - throw new AssertionError(String.format( - "Unknown id strategy '%s'", strategy)); + throw new AssertionError(String.format("Unknown id strategy '%s'", strategy)); } this.checkIdLength(); } @@ -252,7 +255,7 @@ public class HugeVertex extends HugeElement implements Vertex, Cloneable { /** * Add one edge between this vertex and other vertex - * + *

* *** this method is not thread safe, must clone this vertex first before * multi thread access e.g. `vertex.copy().resetTx();` *** */ @@ -297,7 +300,7 @@ public class HugeVertex extends HugeElement implements Vertex, Cloneable { label, this.label(), vertex.label()); // Check sortKeys List keys = this.graph().mapPkName2Id(elemKeys.keys()); - E.checkArgument(keys.containsAll(edgeLabel.sortKeys()), + E.checkArgument(new HashSet<>(keys).containsAll(edgeLabel.sortKeys()), "The sort key(s) must be set for the edge " + "with label: '%s'", edgeLabel.name()); @@ -306,7 +309,7 @@ public class HugeVertex extends HugeElement implements Vertex, Cloneable { Collection nonNullKeys = CollectionUtils.subtract( edgeLabel.properties(), edgeLabel.nullableKeys()); - if (!keys.containsAll(nonNullKeys)) { + if (!new HashSet<>(keys).containsAll(nonNullKeys)) { @SuppressWarnings("unchecked") Collection missed = CollectionUtils.subtract(nonNullKeys, keys); E.checkArgument(false, "All non-null property keys: %s " + @@ -421,9 +424,8 @@ public class HugeVertex extends HugeElement implements Vertex, Cloneable { @Watched(prefix = "vertex") @Override - public VertexProperty property( - VertexProperty.Cardinality cardinality, - String key, V value, Object... objects) { + public VertexProperty property(VertexProperty.Cardinality cardinality, + String key, V value, Object... objects) { if (objects.length != 0 && objects[0].equals(T.id)) { throw VertexProperty.Exceptions.userSuppliedIdsNotSupported(); } @@ -439,7 +441,7 @@ public class HugeVertex extends HugeElement implements Vertex, Cloneable { * .property(list, "key2", val2) * * The cardinality single may be user supplied single, it may also be - * that user doesn't supplied cardinality, when it is latter situation, + * that user doesn't supply cardinality, when it is latter situation, * we shouldn't check it. Because of this reason, we are forced to * give up the check of user supplied cardinality single. * The cardinality not single must be user supplied, so should check it @@ -462,10 +464,14 @@ public class HugeVertex extends HugeElement implements Vertex, Cloneable { E.checkArgument(!this.hasProperty(propertyKey.id()), "Can't update primary key: '%s'", key); } + if (value == null) { + this.removeProperty(propertyKey.id()); + return EmptyVertexProperty.instance(); + } @SuppressWarnings("unchecked") - VertexProperty prop = (VertexProperty) this.addProperty( - propertyKey, value, !this.fresh()); + VertexProperty prop = (VertexProperty) this.addProperty(propertyKey, + value, !this.fresh()); return prop; } diff --git a/hugegraph-test/src/main/java/org/apache/hugegraph/tinkerpop/ProcessStandardTest.java b/hugegraph-test/src/main/java/org/apache/hugegraph/tinkerpop/ProcessStandardTest.java index 08a72dccb..b7ac99f91 100644 --- a/hugegraph-test/src/main/java/org/apache/hugegraph/tinkerpop/ProcessStandardTest.java +++ b/hugegraph-test/src/main/java/org/apache/hugegraph/tinkerpop/ProcessStandardTest.java @@ -23,7 +23,6 @@ import org.apache.tinkerpop.gremlin.GraphProviderClass; import org.junit.runner.RunWith; @RunWith(ProcessBasicSuite.class) -@GraphProviderClass(provider = ProcessTestGraphProvider.class, - graph = TestGraph.class) +@GraphProviderClass(provider = ProcessTestGraphProvider.class, graph = TestGraph.class) public class ProcessStandardTest { } diff --git a/hugegraph-test/src/main/java/org/apache/hugegraph/tinkerpop/TestGraph.java b/hugegraph-test/src/main/java/org/apache/hugegraph/tinkerpop/TestGraph.java index 21a82b3fe..1ac862fc4 100644 --- a/hugegraph-test/src/main/java/org/apache/hugegraph/tinkerpop/TestGraph.java +++ b/hugegraph-test/src/main/java/org/apache/hugegraph/tinkerpop/TestGraph.java @@ -47,6 +47,7 @@ import org.apache.hugegraph.task.TaskScheduler; import org.apache.hugegraph.testutil.Whitebox; import org.apache.hugegraph.type.define.IdStrategy; import org.apache.hugegraph.type.define.NodeRole; + import com.google.common.collect.ImmutableSet; @Graph.OptIn("org.apache.hugegraph.tinkerpop.StructureBasicSuite") @@ -57,8 +58,7 @@ public class TestGraph implements Graph { public static final String DEFAULT_VL = "vertex"; - public static final Set TRUNCATE_BACKENDS = - ImmutableSet.of("rocksdb", "mysql"); + public static final Set TRUNCATE_BACKENDS = ImmutableSet.of("rocksdb", "mysql"); private static volatile int id = 666; @@ -132,19 +132,19 @@ public class TestGraph implements Graph { // Clear schema and graph data will be cleared at same time SchemaManager schema = this.graph.schema(); - schema.getIndexLabels().stream().forEach(elem -> { + schema.getIndexLabels().forEach(elem -> { schema.indexLabel(elem.name()).remove(); }); - schema.getEdgeLabels().stream().forEach(elem -> { + schema.getEdgeLabels().forEach(elem -> { schema.edgeLabel(elem.name()).remove(); }); - schema.getVertexLabels().stream().forEach(elem -> { + schema.getVertexLabels().forEach(elem -> { schema.vertexLabel(elem.name()).remove(); }); - schema.getPropertyKeys().stream().forEach(elem -> { + schema.getPropertyKeys().forEach(elem -> { schema.propertyKey(elem.name()).remove(); }); @@ -157,7 +157,7 @@ public class TestGraph implements Graph { @Watched protected void clearVariables() { Variables variables = this.variables(); - variables.keys().forEach(key -> variables.remove(key)); + variables.keys().forEach(variables::remove); } protected boolean closed() { @@ -252,8 +252,7 @@ public class TestGraph implements Graph { @SuppressWarnings({ "unchecked", "rawtypes" }) @Override public I io(final Io.Builder builder) { - Whitebox.setInternalState(HugeGraphSONModule.class, - "OPTIMIZE_SERIALIZE", false); + Whitebox.setInternalState(HugeGraphSONModule.class, "OPTIMIZE_SERIALIZE", false); return (I) builder.graph(this).onMapper(mapper -> mapper.addRegistry(HugeGraphIoRegistry.instance()) ).create(); @@ -317,8 +316,7 @@ public class TestGraph implements Graph { case "regularLoad": return false; default: - throw new AssertionError(String.format( - "Wrong IO type %s", this.loadedGraph)); + throw new AssertionError(String.format("Wrong IO type %s", this.loadedGraph)); } } @@ -346,24 +344,19 @@ public class TestGraph implements Graph { schema.propertyKey(key).ifNotExist().create(); break; case "BooleanArray": - schema.propertyKey(key).asBoolean().valueList() - .ifNotExist().create(); + schema.propertyKey(key).asBoolean().valueList().ifNotExist().create(); break; case "IntegerArray": - schema.propertyKey(key).asInt().valueList() - .ifNotExist().create(); + schema.propertyKey(key).asInt().valueList().ifNotExist().create(); break; case "LongArray": - schema.propertyKey(key).asLong().valueList() - .ifNotExist().create(); + schema.propertyKey(key).asLong().valueList().ifNotExist().create(); break; case "FloatArray": - schema.propertyKey(key).asFloat().valueList() - .ifNotExist().create(); + schema.propertyKey(key).asFloat().valueList().ifNotExist().create(); break; case "DoubleArray": - schema.propertyKey(key).asDouble().valueList() - .ifNotExist().create(); + schema.propertyKey(key).asDouble().valueList().ifNotExist().create(); break; case "StringArray": schema.propertyKey(key).valueList().ifNotExist().create(); @@ -376,8 +369,7 @@ public class TestGraph implements Graph { case "Serializable": break; default: - throw new RuntimeException( - String.format("Wrong type %s for %s", type, key)); + throw new RuntimeException(String.format("Wrong type %s for %s", type, key)); } } @@ -413,8 +405,7 @@ public class TestGraph implements Graph { .useCustomizeStringId().ifNotExist().create(); break; default: - throw new AssertionError(String.format( - "Id strategy must be customize or automatic")); + throw new AssertionError("Id strategy must be customize or automatic"); } schema.edgeLabel("followedBy") @@ -509,8 +500,7 @@ public class TestGraph implements Graph { .useCustomizeStringId().ifNotExist().create(); break; default: - throw new AssertionError(String.format( - "Id strategy must be customize or automatic")); + throw new AssertionError("Id strategy must be customize or automatic"); } schema.edgeLabel("knows").link("person", "person") @@ -586,8 +576,7 @@ public class TestGraph implements Graph { .useCustomizeStringId().ifNotExist().create(); break; default: - throw new AssertionError(String.format( - "Id strategy must be customize or automatic")); + throw new AssertionError("Id strategy must be customize or automatic"); } schema.edgeLabel("knows").link("vertex", "vertex") @@ -675,8 +664,7 @@ public class TestGraph implements Graph { schema.propertyKey("new").ifNotExist().create(); schema.propertyKey("color").ifNotExist().create(); schema.propertyKey("every").ifNotExist().create(); - schema.propertyKey("gremlin.partitionGraphStrategy.partition") - .ifNotExist().create(); + schema.propertyKey("gremlin.partitionGraphStrategy.partition").ifNotExist().create(); schema.propertyKey("blah").asDouble().ifNotExist().create(); schema.propertyKey("bloop").asInt().ifNotExist().create(); @@ -695,8 +683,7 @@ public class TestGraph implements Graph { } @Watched - private void initBasicVertexLabelV(IdStrategy idStrategy, - String defaultVL) { + private void initBasicVertexLabelV(IdStrategy idStrategy, String defaultVL) { SchemaManager schema = this.graph.schema(); switch (idStrategy) { @@ -769,7 +756,7 @@ public class TestGraph implements Graph { private void initBasicVertexLabelAndEdgeLabelExceptV(String defaultVL) { SchemaManager schema = this.graph.schema(); - if (!defaultVL.equals("person")) { + if (!"person".equals(defaultVL)) { schema.vertexLabel("person") .properties("name", "age") .nullableKeys("name", "age")