Skip to content

Commit

Permalink
Fix neq and null condition query behavior
Browse files Browse the repository at this point in the history
Fixes JanusGraph#2205

Signed-off-by: Boxuan Li <[email protected]>
  • Loading branch information
li-boxuan committed Dec 6, 2020
1 parent 6a483bf commit 9d5b2c0
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,49 @@ public static void assertGraphOfTheGods(JanusGraph graphOfTheGods) {
graphOfTheGods.tx().commit();
}

@Test
public void testNeqQuery() {
makeKey("p2", String.class);
PropertyKey p3 = makeKey("p3", String.class);
PropertyKey p4 = makeKey("p4", String.class);
mgmt.buildIndex("composite", Vertex.class).addKey(p3).buildCompositeIndex();
mgmt.buildIndex("mixed", Vertex.class).addKey(p4, Mapping.STRING.asParameter()).buildMixedIndex(INDEX);
finishSchema();

tx.addVertex();

// property not registered in schema
assertFalse(tx.traversal().V().has("p1", P.neq("v")).hasNext());
// property registered in schema
assertFalse(tx.traversal().V().has("p2", P.neq("v")).hasNext());
// property registered in schema and has composite index
assertFalse(tx.traversal().V().has("p3", P.neq("v")).hasNext());
// property registered in schema and has mixed index
assertFalse(tx.traversal().V().has("p4", P.neq("v")).hasNext());
}

@Test
public void testNullHasConditionQuery() {
makeKey("name", String.class);
makeKey("p2", String.class);
PropertyKey p3 = makeKey("p3", String.class);
PropertyKey p4 = makeKey("p4", String.class);
mgmt.buildIndex("composite", Vertex.class).addKey(p3).buildCompositeIndex();
mgmt.buildIndex("mixed", Vertex.class).addKey(p4, Mapping.STRING.asParameter()).buildMixedIndex(INDEX);
finishSchema();

tx.addVertex();

// property not registered in schema
assertFalse(tx.traversal().V().has("p1", (Object) null).hasNext());
// property registered in schema
assertFalse(tx.traversal().V().has("p2", (Object) null).hasNext());
// property registered in schema and has composite index
assertFalse(tx.traversal().V().has("p3", (Object) null).hasNext());
// property registered in schema and has mixed index
assertFalse(tx.traversal().V().has("p4", (Object) null).hasNext());
}

/**
* Ensure clearing storage actually removes underlying graph and index databases.
* @throws Exception
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -160,10 +160,6 @@ public static <E extends JanusGraphElement> And<E> constraints2QNF(StandardJanus
final RelationType type = getType(tx, atom.getKey());

if (type == null) {
if (atom.getPredicate() == Cmp.EQUAL && atom.getValue() == null ||
(atom.getPredicate() == Cmp.NOT_EQUAL && atom.getValue() != null))
continue; //Ignore condition, its trivially satisfied

return null;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,9 @@ public boolean isValidCondition(Object condition) {

@Override
public boolean test(Object value, Object condition) {
if (condition==null) {
return value==null;
if (condition == null) {
// since JanusGraph does not support null value, has(p, null) should always evaluate to false
return false;
} else {
return condition.equals(value) || (condition.getClass().isArray() && ArrayUtils.isEquals(condition, value));
}
Expand Down Expand Up @@ -73,10 +74,13 @@ public boolean isValidCondition(Object condition) {

@Override
public boolean test(Object value, Object condition) {
if (condition==null) {
return value!=null;
if (value == null) {
// To align with TinkerPop behaviour, if an element does not have property p, then has(p, neq(anything))
// should always evaluate to false. Note that JanusGraph does not support null value, so the "value == null"
// here implies the element does not have such property.
return false;
} else {
return !condition.equals(value);
return !value.equals(condition);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
package org.janusgraph.graphdb.query;

import com.google.common.collect.Iterators;
import org.apache.tinkerpop.gremlin.process.traversal.P;
import org.apache.tinkerpop.gremlin.structure.Vertex;
import org.janusgraph.core.*;
import org.janusgraph.core.attribute.Contain;
Expand Down

0 comments on commit 9d5b2c0

Please sign in to comment.