typedb icon indicating copy to clipboard operation
typedb copied to clipboard

Strange query throws null pointer exception

Open james-whiteside opened this issue 2 years ago • 1 comments

Description

The following query throws a null pointer exception:

match
$x type entity;
$g isa gene, has official-gene-symbol $s;
not { $x type relation; $t isa tissue, has tissue-name "hello"; };
limit 10;

This is likely because of multiple type constraints on $x, as without them the query gives the expected response.

Environment

  1. OS (where TypeDB server runs): MacOS 12.6.1
  2. TypeDB version (and platform): TypeDB 2.18.0
  3. TypeDB client: Studio

Expected Output

Query either runs or throws a proper exception.

Actual Output

11:48:52.501 [typedb-service::0] ERROR com.vaticle.typedb.core.database.RocksStorage - 
java.lang.NullPointerException: null
	at java.base/java.util.AbstractCollection.addAll(AbstractCollection.java:351)
	at com.vaticle.typedb.core.pattern.variable.Variable.setInferredTypes(Variable.java:96)
	at com.vaticle.typedb.core.logic.tool.TypeInference$InferenceTraversal.lambda$applyTypes$13(TypeInference.java:238)
	at java.base/java.util.HashMap.forEach(HashMap.java:1337)
	at com.vaticle.typedb.core.logic.tool.TypeInference$InferenceTraversal.applyTypes(TypeInference.java:237)
	at com.vaticle.typedb.core.logic.tool.TypeInference$InferenceTraversal.applyCombination(TypeInference.java:225)
	at com.vaticle.typedb.core.logic.tool.TypeInference.applyCombination(TypeInference.java:110)
	at com.vaticle.typedb.core.logic.tool.TypeInference.lambda$applyCombination$0(TypeInference.java:94)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1541)
	at com.vaticle.typedb.core.logic.tool.TypeInference.applyCombination(TypeInference.java:94)
	at com.vaticle.typedb.core.logic.tool.TypeInference.lambda$applyCombination$1(TypeInference.java:113)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1541)
	at java.base/java.util.Collections$UnmodifiableCollection.forEach(Collections.java:1085)
	at com.vaticle.typedb.core.logic.tool.TypeInference.applyCombination(TypeInference.java:113)
	at com.vaticle.typedb.core.logic.tool.TypeInference.lambda$applyCombination$0(TypeInference.java:94)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1541)
	at com.vaticle.typedb.core.logic.tool.TypeInference.applyCombination(TypeInference.java:94)
	at com.vaticle.typedb.core.logic.tool.TypeInference.applyCombination(TypeInference.java:90)
	at com.vaticle.typedb.core.reasoner.Reasoner.inferAndValidateTypes(Reasoner.java:136)
	at com.vaticle.typedb.core.reasoner.Reasoner.execute(Reasoner.java:103)
	at com.vaticle.typedb.core.query.Matcher.execute(Matcher.java:110)
	at com.vaticle.typedb.core.query.Matcher.execute(Matcher.java:106)
	at com.vaticle.typedb.core.query.QueryManager.match(QueryManager.java:72)
	at com.vaticle.typedb.core.server.query.QueryService.match(QueryService.java:131)
	at com.vaticle.typedb.core.server.query.QueryService.execute(QueryService.java:84)
	at com.vaticle.typedb.core.server.TransactionService.executeRequest(TransactionService.java:178)
	at com.vaticle.typedb.core.server.TransactionService.execute(TransactionService.java:153)
	at com.vaticle.typedb.core.server.TransactionService.onNext(TransactionService.java:127)
	at com.vaticle.typedb.core.server.TransactionService.onNext(TransactionService.java:82)
	at io.grpc.stub.ServerCalls$StreamingServerCallHandler$StreamingServerCallListener.onMessage(ServerCalls.java:262)
	at io.grpc.internal.ServerCallImpl$ServerStreamListenerImpl.messagesAvailableInternal(ServerCallImpl.java:318)
	at io.grpc.internal.ServerCallImpl$ServerStreamListenerImpl.messagesAvailable(ServerCallImpl.java:301)
	at io.grpc.internal.ServerImpl$JumpToApplicationThreadServerStreamListener$1MessagesAvailable.runInContext(ServerImpl.java:834)
	at io.grpc.internal.ContextRunnable.run(ContextRunnable.java:37)
	at io.grpc.internal.SerializingExecutor.run(SerializingExecutor.java:133)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
	at java.base/java.lang.Thread.run(Thread.java:834)
11:48:52.507 [typedb-service::0] ERROR com.vaticle.typedb.core.server.TransactionService - java.lang.NullPointerException

james-whiteside avatar Jun 27 '23 11:06 james-whiteside

Looks like this is caused by type inference not adding the offending variable (The $x inside the not) to the traversal. The $x outside the not is added via restrictTypes in register(TypeVariable). The $x inside loses its inferredTypes when the bounds are applied in applyCombination, so restrictTypes is not called on it. Since it's not in the traversal, applyTypes fails.

This would be solved if we could enforce that a type variable can at most one type constraint (currently, we don't seem to if the second type constraint is inside a not - Maybe we don't want to?)

krishnangovindraj avatar Jun 27 '23 15:06 krishnangovindraj