diff --git a/community/cypher/cypher/src/main/java/org/neo4j/cypher/internal/javacompat/BaseToObjectValueWriter.java b/community/cypher/cypher/src/main/java/org/neo4j/cypher/internal/javacompat/BaseToObjectValueWriter.java index f3c3d5e998361..0859bc8df8c1c 100644 --- a/community/cypher/cypher/src/main/java/org/neo4j/cypher/internal/javacompat/BaseToObjectValueWriter.java +++ b/community/cypher/cypher/src/main/java/org/neo4j/cypher/internal/javacompat/BaseToObjectValueWriter.java @@ -94,7 +94,16 @@ public void writeNodeReference( long nodeId ) throws RuntimeException @Override public void writeNode( long nodeId, TextArray ignore, MapValue properties ) throws RuntimeException { - writeValue( newNodeProxyById( nodeId ) ); + if ( nodeId >= 0 ) + { + writeValue( newNodeProxyById( nodeId ) ); + } + } + + @Override + public void writeVirtualNodeHack( Object node ) + { + writeValue( node ); } @Override @@ -107,7 +116,16 @@ public void writeEdgeReference( long edgeId ) throws RuntimeException public void writeEdge( long edgeId, long startNodeId, long endNodeId, TextValue type, MapValue properties ) throws RuntimeException { - writeValue( newRelationshipProxyById( edgeId ) ); + if ( edgeId >= 0 ) + { + writeValue( newRelationshipProxyById( edgeId ) ); + } + } + + @Override + public void writeVirtualEdgeHack( Object relationship ) + { + writeValue( relationship ); } @Override diff --git a/community/cypher/cypher/src/main/java/org/neo4j/cypher/internal/javacompat/NodeProxyWrappingNodeValue.java b/community/cypher/cypher/src/main/java/org/neo4j/cypher/internal/javacompat/NodeProxyWrappingNodeValue.java index 59bb07fe00c51..93435480ed8a3 100644 --- a/community/cypher/cypher/src/main/java/org/neo4j/cypher/internal/javacompat/NodeProxyWrappingNodeValue.java +++ b/community/cypher/cypher/src/main/java/org/neo4j/cypher/internal/javacompat/NodeProxyWrappingNodeValue.java @@ -64,6 +64,12 @@ public void writeTo( AnyValueWriter writer ) throws E p = VirtualValues.EMPTY_MAP; } + + if ( id() < 0 ) + { + writer.writeVirtualNodeHack( node ); + } + writer.writeNode( node.getId(), l, p ); } diff --git a/community/cypher/cypher/src/main/java/org/neo4j/cypher/internal/javacompat/RelationshipProxyWrappingEdgeValue.java b/community/cypher/cypher/src/main/java/org/neo4j/cypher/internal/javacompat/RelationshipProxyWrappingEdgeValue.java index 1ba19a62b72c4..c7aea4341981e 100644 --- a/community/cypher/cypher/src/main/java/org/neo4j/cypher/internal/javacompat/RelationshipProxyWrappingEdgeValue.java +++ b/community/cypher/cypher/src/main/java/org/neo4j/cypher/internal/javacompat/RelationshipProxyWrappingEdgeValue.java @@ -61,6 +61,12 @@ public void writeTo( AnyValueWriter writer ) throws E p = VirtualValues.EMPTY_MAP; } + + if ( id() < 0 ) + { + writer.writeVirtualEdgeHack( relationship ); + } + writer.writeEdge( id(), startNode().id(), endNode().id(), type(), p ); } diff --git a/community/cypher/cypher/src/main/scala/org/neo4j/cypher/internal/compatibility/v3_3/runtime/helpers/RuntimeTextValueConverter.scala b/community/cypher/cypher/src/main/scala/org/neo4j/cypher/internal/compatibility/v3_3/runtime/helpers/RuntimeTextValueConverter.scala index 4a8331b81a257..7e19363a58de5 100644 --- a/community/cypher/cypher/src/main/scala/org/neo4j/cypher/internal/compatibility/v3_3/runtime/helpers/RuntimeTextValueConverter.scala +++ b/community/cypher/cypher/src/main/scala/org/neo4j/cypher/internal/compatibility/v3_3/runtime/helpers/RuntimeTextValueConverter.scala @@ -21,7 +21,7 @@ package org.neo4j.cypher.internal.compatibility.v3_3.runtime.helpers import org.neo4j.cypher.internal.compatibility.v3_3.runtime.commands.values.KeyToken import org.neo4j.cypher.internal.spi.v3_3.QueryContext -import org.neo4j.graphdb.{Node, Path, Relationship} +import org.neo4j.graphdb.{Entity, Node, Path, Relationship} import scala.collection.Map @@ -34,7 +34,7 @@ class RuntimeTextValueConverter(scalaValues: RuntimeScalaValueConverter)(implici def asTextValue(a: Any): String = { val scalaValue = scalaValues.asShallowScalaValue(a) scalaValue match { - case node: Node => s"$node${props(node)}" + case node: Node => s"Node[${node.getId}]${props(node)}" case relationship: Relationship => s":${relationship.getType.name()}[${relationship.getId}]${props(relationship)}" case path: Path => path.toString case map: Map[_, _] => makeString(map) @@ -52,15 +52,17 @@ class RuntimeTextValueConverter(scalaValues: RuntimeScalaValueConverter)(implici private def props(n: Node): String = { val ops = context.nodeOps - val properties = ops.propertyKeyIds(n.getId) + val properties = if (isVirtualEntityHack(n)) Iterator.empty else ops.propertyKeyIds(n.getId) val keyValStrings = properties.map(pkId => s"${context.getPropertyKeyName(pkId)}:${asTextValue(ops.getProperty(n.getId, pkId).asObject())}") keyValStrings.mkString("{", ",", "}") } private def props(r: Relationship): String = { val ops = context.relationshipOps - val properties = ops.propertyKeyIds(r.getId) + val properties = if (isVirtualEntityHack(r)) Iterator.empty else ops.propertyKeyIds(r.getId) val keyValStrings = properties.map(pkId => s"${context.getPropertyKeyName(pkId)}:${asTextValue(ops.getProperty(r.getId, pkId).asObject())}") keyValStrings.mkString("{", ",", "}") } + + private def isVirtualEntityHack(entity:Entity): Boolean = entity.getId < 0 } diff --git a/community/kernel/src/main/java/org/neo4j/kernel/builtinprocs/SchemaProcedure.java b/community/kernel/src/main/java/org/neo4j/kernel/builtinprocs/SchemaProcedure.java index 980a2265285ea..0bb0126422ada 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/builtinprocs/SchemaProcedure.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/builtinprocs/SchemaProcedure.java @@ -21,6 +21,7 @@ import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; @@ -63,8 +64,8 @@ public SchemaProcedure( final GraphDatabaseAPI graphDatabaseAPI, final KernelTra public GraphResult buildSchemaGraph() { - final Map nodes = new HashMap<>(); - final Map> relationships = new HashMap<>(); + final Map nodes = new HashMap<>(); + final Map> relationships = new HashMap<>(); try ( Statement statement = kernelTransaction.acquireStatement() ) { @@ -122,15 +123,15 @@ public GraphResult buildSchemaGraph() int relId = readOperations.relationshipTypeGetForName( relationshipTypeGetName ); try ( ResourceIterator