diff --git a/community/cypher/cypher/src/main/scala/org/neo4j/cypher/internal/spi/v2_3/TransactionBoundQueryContext.scala b/community/cypher/cypher/src/main/scala/org/neo4j/cypher/internal/spi/v2_3/TransactionBoundQueryContext.scala index 2a385cf49e793..28de721a91928 100644 --- a/community/cypher/cypher/src/main/scala/org/neo4j/cypher/internal/spi/v2_3/TransactionBoundQueryContext.scala +++ b/community/cypher/cypher/src/main/scala/org/neo4j/cypher/internal/spi/v2_3/TransactionBoundQueryContext.scala @@ -308,7 +308,7 @@ final class TransactionBoundQueryContext(tc: TransactionalContextWrapper) } def getProperty(id: Long, propertyKeyId: Int): Any = try { - tc.statement.readOperations().nodeGetProperty(id, propertyKeyId) + tc.statement.readOperations().nodeGetProperty(id, propertyKeyId).asPublic() } catch { case _: org.neo4j.kernel.api.exceptions.EntityNotFoundException => null.asInstanceOf[Int] } diff --git a/community/cypher/cypher/src/main/scala/org/neo4j/cypher/internal/spi/v3_1/TransactionBoundQueryContext.scala b/community/cypher/cypher/src/main/scala/org/neo4j/cypher/internal/spi/v3_1/TransactionBoundQueryContext.scala index 601c337f2c142..734fcced2a61d 100644 --- a/community/cypher/cypher/src/main/scala/org/neo4j/cypher/internal/spi/v3_1/TransactionBoundQueryContext.scala +++ b/community/cypher/cypher/src/main/scala/org/neo4j/cypher/internal/spi/v3_1/TransactionBoundQueryContext.scala @@ -304,7 +304,7 @@ final class TransactionBoundQueryContext(txContext: TransactionalContextWrapper) } override def getProperty(id: Long, propertyKeyId: Int): Any = try { - txContext.statement.readOperations().nodeGetProperty(id, propertyKeyId) + txContext.statement.readOperations().nodeGetProperty(id, propertyKeyId).asPublic() } catch { case e: org.neo4j.kernel.api.exceptions.EntityNotFoundException => if (isDeletedInThisTx(id)) diff --git a/community/cypher/cypher/src/main/scala/org/neo4j/cypher/internal/spi/v3_2/TransactionBoundQueryContext.scala b/community/cypher/cypher/src/main/scala/org/neo4j/cypher/internal/spi/v3_2/TransactionBoundQueryContext.scala index 4aec65ae5d59e..c810a84de63bc 100644 --- a/community/cypher/cypher/src/main/scala/org/neo4j/cypher/internal/spi/v3_2/TransactionBoundQueryContext.scala +++ b/community/cypher/cypher/src/main/scala/org/neo4j/cypher/internal/spi/v3_2/TransactionBoundQueryContext.scala @@ -311,7 +311,7 @@ final class TransactionBoundQueryContext(val transactionalContext: Transactional } override def getProperty(id: Long, propertyKeyId: Int): Any = try { - transactionalContext.statement.readOperations().nodeGetProperty(id, propertyKeyId) + transactionalContext.statement.readOperations().nodeGetProperty(id, propertyKeyId).asPublic() } catch { case e: org.neo4j.kernel.api.exceptions.EntityNotFoundException => if (isDeletedInThisTx(id)) diff --git a/community/cypher/cypher/src/main/scala/org/neo4j/cypher/internal/spi/v3_3/TransactionBoundQueryContext.scala b/community/cypher/cypher/src/main/scala/org/neo4j/cypher/internal/spi/v3_3/TransactionBoundQueryContext.scala index 5aff25a66dfb1..018e6f07f6ab0 100644 --- a/community/cypher/cypher/src/main/scala/org/neo4j/cypher/internal/spi/v3_3/TransactionBoundQueryContext.scala +++ b/community/cypher/cypher/src/main/scala/org/neo4j/cypher/internal/spi/v3_3/TransactionBoundQueryContext.scala @@ -311,7 +311,7 @@ final class TransactionBoundQueryContext(val transactionalContext: Transactional } override def getProperty(id: Long, propertyKeyId: Int): Any = try { - transactionalContext.statement.readOperations().nodeGetProperty(id, propertyKeyId) + transactionalContext.statement.readOperations().nodeGetProperty(id, propertyKeyId).asPublic() } catch { case e: org.neo4j.kernel.api.exceptions.EntityNotFoundException => if (isDeletedInThisTx(id)) diff --git a/community/kernel/src/main/java/org/neo4j/kernel/api/ReadOperations.java b/community/kernel/src/main/java/org/neo4j/kernel/api/ReadOperations.java index 278b6fe69b161..e54f2730930b9 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/api/ReadOperations.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/api/ReadOperations.java @@ -57,6 +57,7 @@ import org.neo4j.storageengine.api.Token; import org.neo4j.storageengine.api.lock.ResourceType; import org.neo4j.storageengine.api.schema.PopulationProgress; +import org.neo4j.values.Value; /** * Defines all types of read operations that can be done from the {@link KernelAPI}. @@ -190,15 +191,15 @@ long nodesCountIndexed( IndexDescriptor index, long nodeId, Object value ) boolean nodeHasProperty( long nodeId, int propertyKeyId ) throws EntityNotFoundException; - Object nodeGetProperty( long nodeId, int propertyKeyId ) throws EntityNotFoundException; + Value nodeGetProperty( long nodeId, int propertyKeyId ) throws EntityNotFoundException; boolean relationshipHasProperty( long relationshipId, int propertyKeyId ) throws EntityNotFoundException; - Object relationshipGetProperty( long relationshipId, int propertyKeyId ) throws EntityNotFoundException; + Value relationshipGetProperty( long relationshipId, int propertyKeyId ) throws EntityNotFoundException; boolean graphHasProperty( int propertyKeyId ); - Object graphGetProperty( int propertyKeyId ); + Value graphGetProperty( int propertyKeyId ); void relationshipVisit( long relId, RelationshipVisitor visitor ) throws EntityNotFoundException, EXCEPTION; diff --git a/community/kernel/src/main/java/org/neo4j/kernel/api/schema/IndexQuery.java b/community/kernel/src/main/java/org/neo4j/kernel/api/schema/IndexQuery.java index 29106fae5d4ec..045a696519463 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/api/schema/IndexQuery.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/api/schema/IndexQuery.java @@ -27,8 +27,6 @@ import java.util.function.Predicate; import org.neo4j.kernel.api.ReadOperations; -import org.neo4j.kernel.api.properties.DefinedProperty; -import org.neo4j.kernel.api.properties.Property; import org.neo4j.kernel.api.schema.index.IndexDescriptor; import org.neo4j.kernel.impl.api.PropertyValueComparison; import org.neo4j.values.Value; @@ -222,7 +220,8 @@ public IndexQueryType type() @Override public boolean test( Object value ) { - return exactValue.equals( Values.of( value ) ); + Value typed = value instanceof Value ? (Value)value : Values.of( value ); + return exactValue.equals( typed ); } public Object value() @@ -233,17 +232,17 @@ public Object value() public static final class NumberRangePredicate extends IndexQuery { - private final Number from; + private final Value from; private final boolean fromInclusive; - private final Number to; + private final Value to; private final boolean toInclusive; NumberRangePredicate( int propertyKeyId, Number from, boolean fromInclusive, Number to, boolean toInclusive ) { super( propertyKeyId ); - this.from = from; + this.from = Values.numberValue( from ); this.fromInclusive = fromInclusive; - this.to = to; + this.to = Values.numberValue( to ); this.toInclusive = toInclusive; } @@ -260,38 +259,61 @@ public boolean test( Object value ) { return false; } - if ( !(value instanceof Number) ) + if ( Values.isNumberValue( value ) ) { - return false; - } - Number number = (Number) value; - if ( from != null ) - { - int compare = PropertyValueComparison.COMPARE_NUMBERS.compare( number, from ); - if ( compare < 0 || !fromInclusive && compare == 0 ) + Value number = (Value) value; + if ( from != Values.NO_VALUE ) { - return false; + int compare = Values.VALUE_COMPARATOR.compare( number, from ); + if ( compare < 0 || !fromInclusive && compare == 0 ) + { + return false; + } + } + if ( to != Values.NO_VALUE ) + { + int compare = Values.VALUE_COMPARATOR.compare( number, to ); + if ( compare > 0 || !toInclusive && compare == 0 ) + { + return false; + } } + return true; } - if ( to != null ) + if ( value instanceof Number ) { - int compare = PropertyValueComparison.COMPARE_NUMBERS.compare( number, to ); - if ( compare > 0 || !toInclusive && compare == 0 ) + Number number = (Number) value; + if ( from != Values.NO_VALUE ) { - return false; + Number from = (Number) this.from.asPublic(); + int compare = PropertyValueComparison.COMPARE_NUMBERS.compare( number, from ); + if ( compare < 0 || !fromInclusive && compare == 0 ) + { + return false; + } } + if ( to != Values.NO_VALUE ) + { + Number to = (Number) this.to.asPublic(); + int compare = PropertyValueComparison.COMPARE_NUMBERS.compare( number, to ); + if ( compare > 0 || !toInclusive && compare == 0 ) + { + return false; + } + } + return true; } - return true; + return false; } public Number from() { - return from; + return (Number)from.asPublic(); } public Number to() { - return to; + return (Number)to.asPublic(); } public boolean fromInclusive() diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/api/ConstraintEnforcingEntityOperations.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/api/ConstraintEnforcingEntityOperations.java index 77929f9c046f3..88741ce944e44 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/api/ConstraintEnforcingEntityOperations.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/api/ConstraintEnforcingEntityOperations.java @@ -157,8 +157,8 @@ public Value nodeSetProperty( KernelStatement state, long nodeId, int propertyKe if ( propertyIds.contains( propertyKeyId ) ) { - Object previousValue = nodeGetProperty( state, node, propertyKeyId ); - if ( value.equals( Values.of( previousValue ) ) ) + Value previousValue = nodeGetProperty( state, node, propertyKeyId ); + if ( value.equals( previousValue ) ) { // since we are changing to the same value, there is no need to check return; @@ -434,7 +434,7 @@ public boolean graphHasProperty( KernelStatement state, int propertyKeyId ) } @Override - public Object graphGetProperty( KernelStatement state, int propertyKeyId ) + public Value graphGetProperty( KernelStatement state, int propertyKeyId ) { return entityReadOperations.graphGetProperty( state, propertyKeyId ); } @@ -496,7 +496,7 @@ public Cursor nodeGetProperties( KernelStatement statement, NodeIt } @Override - public Object nodeGetProperty( KernelStatement statement, NodeItem node, int propertyKeyId ) + public Value nodeGetProperty( KernelStatement statement, NodeItem node, int propertyKeyId ) { return entityReadOperations.nodeGetProperty( statement, node, propertyKeyId ); } @@ -520,7 +520,7 @@ public Cursor relationshipGetProperties( KernelStatement statement } @Override - public Object relationshipGetProperty( KernelStatement statement, RelationshipItem relationship, int propertyKeyId ) + public Value relationshipGetProperty( KernelStatement statement, RelationshipItem relationship, int propertyKeyId ) { return entityReadOperations.relationshipGetProperty( statement, relationship, propertyKeyId ); } diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/api/GuardingStatementOperations.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/api/GuardingStatementOperations.java index db9608420634c..1776dafeb8b57 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/api/GuardingStatementOperations.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/api/GuardingStatementOperations.java @@ -205,7 +205,7 @@ public boolean graphHasProperty( KernelStatement statement, int propertyKeyId ) } @Override - public Object graphGetProperty( KernelStatement statement, int propertyKeyId ) + public Value graphGetProperty( KernelStatement statement, int propertyKeyId ) { guard.check( statement ); return entityReadDelegate.graphGetProperty( statement, propertyKeyId ); @@ -287,7 +287,7 @@ public Cursor nodeGetProperties( KernelStatement statement, NodeIt } @Override - public Object nodeGetProperty( KernelStatement statement, NodeItem node, int propertyKeyId ) + public Value nodeGetProperty( KernelStatement statement, NodeItem node, int propertyKeyId ) { guard.check( statement ); return entityReadDelegate.nodeGetProperty( statement, node, propertyKeyId ); @@ -315,7 +315,7 @@ public Cursor relationshipGetProperties( KernelStatement statement } @Override - public Object relationshipGetProperty( KernelStatement statement, RelationshipItem relationship, int propertyKeyId ) + public Value relationshipGetProperty( KernelStatement statement, RelationshipItem relationship, int propertyKeyId ) { guard.check( statement ); return entityReadDelegate.relationshipGetProperty( statement, relationship, propertyKeyId ); diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/api/LookupFilter.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/api/LookupFilter.java index e121397132843..441cfd7d753b9 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/api/LookupFilter.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/api/LookupFilter.java @@ -30,6 +30,7 @@ import org.neo4j.kernel.api.schema.IndexQuery; import org.neo4j.kernel.impl.api.operations.EntityOperations; import org.neo4j.storageengine.api.NodeItem; +import org.neo4j.values.Value; /** * When looking up nodes by a property value, we have to do a two-stage check. @@ -116,8 +117,8 @@ public static PrimitiveLongIterator exactIndexMatches( EntityOperations operatio for ( IndexQuery predicate : numericPredicates ) { int propertyKeyId = predicate.propertyKeyId(); - Object value = operations.nodeGetProperty( state, nodeItem, propertyKeyId ); - if ( !predicate.test( value ) ) + Value value = operations.nodeGetProperty( state, nodeItem, propertyKeyId ); + if ( !predicate.test( value.asPublic() ) ) { return false; } diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/api/OperationsFacade.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/api/OperationsFacade.java index b3c97be709846..2619a0cb130cc 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/api/OperationsFacade.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/api/OperationsFacade.java @@ -111,6 +111,7 @@ import org.neo4j.storageengine.api.schema.PopulationProgress; import org.neo4j.storageengine.api.schema.SchemaRule; import org.neo4j.values.Value; +import org.neo4j.values.Values; import static java.lang.String.format; import static org.neo4j.collection.primitive.PrimitiveIntCollections.deduplicate; @@ -289,12 +290,12 @@ public boolean nodeHasProperty( long nodeId, int propertyKeyId ) throws EntityNo } @Override - public Object nodeGetProperty( long nodeId, int propertyKeyId ) throws EntityNotFoundException + public Value nodeGetProperty( long nodeId, int propertyKeyId ) throws EntityNotFoundException { statement.assertOpen(); if ( propertyKeyId == StatementConstants.NO_SUCH_PROPERTY_KEY ) { - return null; + return Values.NO_VALUE; } try ( Cursor node = dataRead().nodeCursorById( statement, nodeId ) ) { @@ -392,12 +393,12 @@ public boolean relationshipHasProperty( long relationshipId, int propertyKeyId ) } @Override - public Object relationshipGetProperty( long relationshipId, int propertyKeyId ) throws EntityNotFoundException + public Value relationshipGetProperty( long relationshipId, int propertyKeyId ) throws EntityNotFoundException { statement.assertOpen(); if ( propertyKeyId == StatementConstants.NO_SUCH_PROPERTY_KEY ) { - return null; + return Values.NO_VALUE; } try ( Cursor relationship = dataRead().relationshipCursorById( statement, relationshipId ) ) { @@ -417,7 +418,7 @@ public boolean graphHasProperty( int propertyKeyId ) } @Override - public Object graphGetProperty( int propertyKeyId ) + public Value graphGetProperty( int propertyKeyId ) { statement.assertOpen(); if ( propertyKeyId == StatementConstants.NO_SUCH_PROPERTY_KEY ) diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/api/StateHandlingStatementOperations.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/api/StateHandlingStatementOperations.java index d9631a04f06f7..14b52884124e6 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/api/StateHandlingStatementOperations.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/api/StateHandlingStatementOperations.java @@ -58,7 +58,6 @@ import org.neo4j.kernel.api.index.InternalIndexState; import org.neo4j.kernel.api.legacyindex.AutoIndexing; import org.neo4j.kernel.api.properties.DefinedProperty; -import org.neo4j.kernel.api.properties.Property; import org.neo4j.kernel.api.properties.PropertyKeyIdIterator; import org.neo4j.kernel.api.schema.IndexQuery; import org.neo4j.kernel.api.schema.LabelSchemaDescriptor; @@ -288,21 +287,21 @@ public PrimitiveIntCollection nodeGetPropertyKeys( KernelStatement statement, No } @Override - public Object nodeGetProperty( KernelStatement statement, NodeItem node, int propertyKeyId ) + public Value nodeGetProperty( KernelStatement statement, NodeItem node, int propertyKeyId ) { try ( Cursor cursor = nodeGetPropertyCursor( statement, node, propertyKeyId ) ) { if ( cursor.next() ) { - return cursor.get().value(); + return Values.of( cursor.get().value() ); } } catch ( NotFoundException e ) { - return null; + return Values.NO_VALUE; } - return null; + return Values.NO_VALUE; } @Override @@ -369,21 +368,21 @@ public PrimitiveIntCollection relationshipGetPropertyKeys( KernelStatement state } @Override - public Object relationshipGetProperty( KernelStatement statement, RelationshipItem relationship, int propertyKeyId ) + public Value relationshipGetProperty( KernelStatement statement, RelationshipItem relationship, int propertyKeyId ) { try ( Cursor cursor = relationshipGetPropertyCursor( statement, relationship, propertyKeyId ) ) { if ( cursor.next() ) { - return cursor.get().value(); + return Values.of( cursor.get().value() ); } } catch ( NotFoundException e ) { - return null; + return Values.NO_VALUE; } - return null; + return Values.NO_VALUE; } @Override @@ -1088,8 +1087,7 @@ public Value relationshipSetProperty( KernelStatement state, long relationshipId @Override public Value graphSetProperty( KernelStatement state, int propertyKeyId, Value value ) { - Object existingPropertyValue = graphGetProperty( state, propertyKeyId ); - Value existingValue = existingPropertyValue == null ? Values.NO_VALUE : Values.of( existingPropertyValue ); + Value existingValue = graphGetProperty( state, propertyKeyId ); if ( !value.equals( existingValue ) ) { @@ -1152,14 +1150,12 @@ public Value relationshipRemoveProperty( KernelStatement state, long relationshi @Override public Value graphRemoveProperty( KernelStatement state, int propertyKeyId ) { - Object existingPropertyValue = graphGetProperty( state, propertyKeyId ); - if ( existingPropertyValue != null ) + Value existingValue = graphGetProperty( state, propertyKeyId ); + if ( existingValue != Values.NO_VALUE ) { - Value existingValue = Values.of( existingPropertyValue ); state.txState().graphDoRemoveProperty( propertyKeyId, existingValue ); - return existingValue; } - return Values.NO_VALUE; + return existingValue; } @Override @@ -1176,11 +1172,11 @@ public PrimitiveIntIterator graphGetPropertyKeys( KernelStatement state ) @Override public boolean graphHasProperty( KernelStatement state, int propertyKeyId ) { - return graphGetProperty( state, propertyKeyId ) != null; + return graphGetProperty( state, propertyKeyId ) != Values.NO_VALUE; } @Override - public Object graphGetProperty( KernelStatement state, int propertyKeyId ) + public Value graphGetProperty( KernelStatement state, int propertyKeyId ) { Iterator properties = graphGetAllProperties( state ); while ( properties.hasNext() ) @@ -1188,10 +1184,10 @@ public Object graphGetProperty( KernelStatement state, int propertyKeyId ) DefinedProperty property = (DefinedProperty) properties.next(); if ( property.propertyKeyId() == propertyKeyId ) { - return property.value(); + return Values.of( property.value() ); } } - return null; + return Values.NO_VALUE; } private Iterator graphGetAllProperties( KernelStatement state ) diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/api/operations/EntityReadOperations.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/api/operations/EntityReadOperations.java index 97771b8b576ff..81ce6f2db2fde 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/api/operations/EntityReadOperations.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/api/operations/EntityReadOperations.java @@ -37,6 +37,7 @@ import org.neo4j.storageengine.api.NodeItem; import org.neo4j.storageengine.api.PropertyItem; import org.neo4j.storageengine.api.RelationshipItem; +import org.neo4j.values.Value; public interface EntityReadOperations { @@ -72,7 +73,7 @@ long nodesCountIndexed( KernelStatement statement, IndexDescriptor index, long n boolean graphHasProperty( KernelStatement state, int propertyKeyId ); - Object graphGetProperty( KernelStatement state, int propertyKeyId ); + Value graphGetProperty( KernelStatement state, int propertyKeyId ); /** * Return all property keys associated with a relationship. @@ -100,7 +101,7 @@ Cursor nodeGetRelationships( KernelStatement statement, NodeIt Cursor nodeGetProperties( KernelStatement statement, NodeItem node ); - Object nodeGetProperty( KernelStatement statement, NodeItem node, int propertyKeyId ); + Value nodeGetProperty( KernelStatement statement, NodeItem node, int propertyKeyId ); boolean nodeHasProperty( KernelStatement statement, NodeItem node, int propertyKeyId ); @@ -108,7 +109,7 @@ Cursor nodeGetRelationships( KernelStatement statement, NodeIt Cursor relationshipGetProperties( KernelStatement statement, RelationshipItem relationship ); - Object relationshipGetProperty( KernelStatement statement, RelationshipItem relationship, int propertyKeyId ); + Value relationshipGetProperty( KernelStatement statement, RelationshipItem relationship, int propertyKeyId ); boolean relationshipHasProperty( KernelStatement statement, RelationshipItem relationship, int propertyKeyId ); diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/api/state/IndexTxStateUpdater.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/api/state/IndexTxStateUpdater.java index 1bc25e9a927ae..beb904a21dc50 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/api/state/IndexTxStateUpdater.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/api/state/IndexTxStateUpdater.java @@ -159,7 +159,7 @@ public void onPropertyChange( KernelStatement state, NodeItem node, int property } else { - Object value = readOps.nodeGetProperty( state, node, indexPropertyId ); + Object value = readOps.nodeGetProperty( state, node, indexPropertyId ).asPublic(); valuesBefore[i] = value; valuesAfter[i] = value; } diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/core/GraphPropertiesProxy.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/core/GraphPropertiesProxy.java index b0b25393a92b4..15325eff6a303 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/core/GraphPropertiesProxy.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/core/GraphPropertiesProxy.java @@ -37,6 +37,7 @@ import org.neo4j.kernel.api.exceptions.schema.IllegalTokenNameException; import org.neo4j.kernel.impl.api.operations.KeyReadOperations; import org.neo4j.storageengine.api.EntityType; +import org.neo4j.values.Value; import org.neo4j.values.Values; import static java.lang.String.format; @@ -98,14 +99,14 @@ public Object getProperty( String key ) throw new NotFoundException( format( "No such property, '%s'.", key ) ); } - Object value = statement.readOperations().graphGetProperty( propertyKeyId ); + Value value = statement.readOperations().graphGetProperty( propertyKeyId ); - if ( value == null ) + if ( value == Values.NO_VALUE ) { throw new PropertyNotFoundException( propertyKeyId, EntityType.GRAPH, -1 ); } - return value; + return value.asPublic(); } catch ( PropertyNotFoundException e ) { @@ -126,8 +127,8 @@ public Object getProperty( String key, Object defaultValue ) try ( Statement statement = actions.statement() ) { int propertyKeyId = statement.readOperations().propertyKeyGetForName( key ); - Object value = statement.readOperations().graphGetProperty( propertyKeyId ); - return value == null ? defaultValue : value; + Value value = statement.readOperations().graphGetProperty( propertyKeyId ); + return value == Values.NO_VALUE ? defaultValue : value.asPublic(); } } diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/core/NodeProxy.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/core/NodeProxy.java index 81170d16ebbea..8087f890beccc 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/core/NodeProxy.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/core/NodeProxy.java @@ -56,6 +56,7 @@ import org.neo4j.storageengine.api.EntityType; import org.neo4j.storageengine.api.NodeItem; import org.neo4j.storageengine.api.PropertyItem; +import org.neo4j.values.Value; import org.neo4j.values.Values; import static java.lang.String.format; @@ -345,8 +346,8 @@ public Object getProperty( String key, Object defaultValue ) try ( Statement statement = actions.statement() ) { int propertyKeyId = statement.readOperations().propertyKeyGetForName( key ); - Object value = statement.readOperations().nodeGetProperty( nodeId, propertyKeyId ); - return value == null ? defaultValue : value; + Value value = statement.readOperations().nodeGetProperty( nodeId, propertyKeyId ); + return value == Values.NO_VALUE ? defaultValue : value.asPublic(); } catch ( EntityNotFoundException e ) { @@ -454,14 +455,14 @@ public Object getProperty( String key ) throws NotFoundException throw new NotFoundException( format( "No such property, '%s'.", key ) ); } - Object value = statement.readOperations().nodeGetProperty( nodeId, propertyKeyId ); + Value value = statement.readOperations().nodeGetProperty( nodeId, propertyKeyId ); - if ( value == null ) + if ( value == Values.NO_VALUE ) { throw new PropertyNotFoundException( propertyKeyId, EntityType.NODE, nodeId ); } - return value; + return value.asPublic(); } catch ( EntityNotFoundException | PropertyNotFoundException e ) diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/core/RelationshipProxy.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/core/RelationshipProxy.java index a63e8b43e4e3d..59168e016767a 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/core/RelationshipProxy.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/core/RelationshipProxy.java @@ -49,6 +49,7 @@ import org.neo4j.storageengine.api.EntityType; import org.neo4j.storageengine.api.PropertyItem; import org.neo4j.storageengine.api.RelationshipItem; +import org.neo4j.values.Value; import org.neo4j.values.Values; import static java.lang.String.format; @@ -336,14 +337,14 @@ public Object getProperty( String key ) throw new NotFoundException( String.format( "No such property, '%s'.", key ) ); } - Object value = statement.readOperations().relationshipGetProperty( getId(), propertyId ); + Value value = statement.readOperations().relationshipGetProperty( getId(), propertyId ); - if ( value == null ) + if ( value == Values.NO_VALUE ) { throw new PropertyNotFoundException( propertyId, EntityType.RELATIONSHIP, getId() ); } - return value; + return value.asPublic(); } catch ( EntityNotFoundException | PropertyNotFoundException e ) { @@ -364,8 +365,8 @@ public Object getProperty( String key, Object defaultValue ) try ( Statement statement = actions.statement() ) { int propertyId = statement.readOperations().propertyKeyGetForName( key ); - Object value = statement.readOperations().relationshipGetProperty( getId(), propertyId ); - return value == null ? defaultValue : value; + Value value = statement.readOperations().relationshipGetProperty( getId(), propertyId ); + return value == Values.NO_VALUE ? defaultValue : value.asPublic(); } catch ( EntityNotFoundException e ) { diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/factory/GraphDatabaseFacade.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/factory/GraphDatabaseFacade.java index 23645778c1541..287b6c57599a9 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/factory/GraphDatabaseFacade.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/factory/GraphDatabaseFacade.java @@ -103,6 +103,8 @@ import org.neo4j.kernel.impl.traversal.MonoDirectionalTraversalDescription; import org.neo4j.kernel.internal.GraphDatabaseAPI; import org.neo4j.storageengine.api.EntityType; +import org.neo4j.values.Value; +import org.neo4j.values.Values; import static java.lang.String.format; import static org.neo4j.collection.primitive.PrimitiveLongCollections.map; @@ -544,7 +546,7 @@ public TransactionEventHandler unregisterTransactionEventHandler( @Override public ResourceIterator findNodes( final Label myLabel, final String key, final Object value ) { - return nodesByLabelAndProperty( myLabel, key, value ); + return nodesByLabelAndProperty( myLabel, key, Values.of( value ) ); } @Override @@ -582,7 +584,7 @@ private InternalTransaction beginTransactionInternal( KernelTransaction.Type typ return new TopLevelTransaction( spi.beginTransaction( type, securityContext, timeoutMillis ), spi::currentStatement ); } - private ResourceIterator nodesByLabelAndProperty( Label myLabel, String key, Object value ) + private ResourceIterator nodesByLabelAndProperty( Label myLabel, String key, Value value ) { Statement statement = spi.currentStatement(); @@ -635,7 +637,7 @@ private IndexDescriptor findAnyIndexByLabelAndProperty( ReadOperations readOps, return null; } - private ResourceIterator getNodesByLabelAndPropertyWithoutIndex( int propertyId, Object value, + private ResourceIterator getNodesByLabelAndPropertyWithoutIndex( int propertyId, Value value, Statement statement, int labelId ) { return map2nodes( @@ -714,10 +716,10 @@ private static class PropertyValueFilteringNodeIdIterator extends PrimitiveLongC private final PrimitiveLongIterator nodesWithLabel; private final ReadOperations statement; private final int propertyKeyId; - private final Object value; + private final Value value; PropertyValueFilteringNodeIdIterator( PrimitiveLongIterator nodesWithLabel, ReadOperations statement, - int propertyKeyId, Object value ) + int propertyKeyId, Value value ) { this.nodesWithLabel = nodesWithLabel; this.statement = statement; @@ -733,10 +735,10 @@ protected boolean fetchNext() long nextValue = nodesWithLabel.next(); try { - Object propertyValue = statement.nodeGetProperty( nextValue, propertyKeyId ); + Value propertyValue = statement.nodeGetProperty( nextValue, propertyKeyId ); if ( propertyValue != null ) { - if ( Property.property( propertyKeyId, propertyValue ).valueEquals( value ) ) + if ( propertyValue.equals( value ) ) { return next( nextValue ); } diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/api/DataStatementArgumentVerificationTest.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/api/DataStatementArgumentVerificationTest.java index 6a0de5552fba7..63017e07d43c4 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/impl/api/DataStatementArgumentVerificationTest.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/api/DataStatementArgumentVerificationTest.java @@ -26,9 +26,13 @@ import org.neo4j.kernel.api.ReadOperations; import org.neo4j.kernel.api.StatementConstants; import org.neo4j.kernel.impl.proc.Procedures; +import org.neo4j.values.Value; +import org.neo4j.values.Values; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.mock; public class DataStatementArgumentVerificationTest @@ -41,10 +45,10 @@ public void shouldReturnNoPropertyFromNodeGetPropertyWithoutDelegatingForNoSuchP ReadOperations statement = stubStatement(); // when - Object value = statement.nodeGetProperty( 17, StatementConstants.NO_SUCH_PROPERTY_KEY ); + Value value = statement.nodeGetProperty( 17, StatementConstants.NO_SUCH_PROPERTY_KEY ); // then - assertNull( "should return NoProperty", value ); + assertTrue( "should return NoProperty", value == Values.NO_VALUE ); } @Test @@ -55,10 +59,10 @@ public void shouldReturnNoPropertyFromRelationshipGetPropertyWithoutDelegatingFo ReadOperations statement = stubStatement(); // when - Object value = statement.relationshipGetProperty( 17, StatementConstants.NO_SUCH_PROPERTY_KEY ); + Value value = statement.relationshipGetProperty( 17, StatementConstants.NO_SUCH_PROPERTY_KEY ); // then - assertNull( "should return NoProperty", value ); + assertEquals( "should return NoProperty", value, Values.NO_VALUE ); } @Test diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/api/integrationtest/PropertyIT.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/api/integrationtest/PropertyIT.java index 4efaebd2b2efa..36743a4987b98 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/impl/api/integrationtest/PropertyIT.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/api/integrationtest/PropertyIT.java @@ -36,6 +36,7 @@ import static junit.framework.TestCase.fail; import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.Matchers.not; import static org.hamcrest.Matchers.notNullValue; import static org.hamcrest.Matchers.nullValue; import static org.hamcrest.core.IsCollectionContaining.hasItems; @@ -71,14 +72,14 @@ public void shouldBeAbleToSetAndReadLargeByteArray() throws Exception public void shouldSetNodePropertyValue() throws Exception { // GIVEN - String value = "bozo"; + Value value = Values.of( "bozo" ); Statement statement = statementInNewTransaction( AnonymousContext.writeToken() ); long nodeId = statement.dataWriteOperations().nodeCreate(); // WHEN int propertyKeyId = statement.tokenWriteOperations().propertyKeyGetOrCreateForName( "clown" ); - statement.dataWriteOperations().nodeSetProperty( nodeId, propertyKeyId, Values.stringValue( value ) ); + statement.dataWriteOperations().nodeSetProperty( nodeId, propertyKeyId, value ); // THEN assertEquals( value, statement.readOperations().nodeGetProperty( nodeId, propertyKeyId ) ); @@ -105,14 +106,14 @@ public void shouldRemoveSetNodeProperty() throws Exception statement.dataWriteOperations().nodeRemoveProperty( nodeId, propertyKeyId ); // THEN - assertThat( statement.readOperations().nodeGetProperty( nodeId, propertyKeyId ), nullValue() ); + assertThat( statement.readOperations().nodeGetProperty( nodeId, propertyKeyId ), equalTo( Values.NO_VALUE ) ); // WHEN commit(); // THEN ReadOperations readOperations = readOperationsInNewTransaction(); - assertThat( readOperations.nodeGetProperty( nodeId, propertyKeyId ), nullValue() ); + assertThat( readOperations.nodeGetProperty( nodeId, propertyKeyId ), equalTo( Values.NO_VALUE ) ); } @Test @@ -136,7 +137,7 @@ public void shouldRemoveSetNodePropertyAcrossTransactions() throws Exception // THEN assertTrue( previous.equals( "bozo" ) ); - assertThat( statement.readOperations().nodeGetProperty( nodeId, propertyKeyId ), nullValue() ); + assertThat( statement.readOperations().nodeGetProperty( nodeId, propertyKeyId ), equalTo( Values.NO_VALUE ) ); // WHEN commit(); @@ -144,7 +145,7 @@ public void shouldRemoveSetNodePropertyAcrossTransactions() throws Exception // THEN ReadOperations readOperations = readOperationsInNewTransaction(); - assertThat( readOperations.nodeGetProperty( nodeId, propertyKeyId ), nullValue() ); + assertThat( readOperations.nodeGetProperty( nodeId, propertyKeyId ), equalTo( Values.NO_VALUE ) ); } @Test @@ -173,7 +174,7 @@ public void shouldRemoveSetExistingProperty() throws Exception statement.dataWriteOperations().nodeSetProperty( nodeId, propertyKeyId, newValue ); // THEN - assertThat( statement.readOperations().nodeGetProperty( nodeId, propertyKeyId ), equalTo( newValue.asPublic() ) ); + assertThat( statement.readOperations().nodeGetProperty( nodeId, propertyKeyId ), equalTo( newValue ) ); // WHEN commit(); @@ -182,7 +183,7 @@ public void shouldRemoveSetExistingProperty() throws Exception // THEN { ReadOperations readOperations = readOperationsInNewTransaction(); - assertThat( readOperations.nodeGetProperty( nodeId, propertyKeyId ), equalTo( newValue.asPublic() ) ); + assertThat( readOperations.nodeGetProperty( nodeId, propertyKeyId ), equalTo( newValue ) ); assertThat( toList( readOperations.nodeGetPropertyKeys( nodeId ) ), equalTo( Collections.singletonList( propertyKeyId ) ) ); } @@ -224,7 +225,8 @@ public void nodeHasPropertyIfSet() throws Exception // THEN assertThat( statement.readOperations().nodeHasProperty( nodeId, propertyKeyId ), is( true ) ); - assertThat( statement.readOperations().nodeGetProperty( nodeId, propertyKeyId ), notNullValue() ); + assertThat( statement.readOperations().nodeGetProperty( nodeId, propertyKeyId ), + not( equalTo( Values.NO_VALUE ) ) ); // WHEN commit(); @@ -232,7 +234,7 @@ public void nodeHasPropertyIfSet() throws Exception // THEN assertThat( readOperations.nodeHasProperty( nodeId, propertyKeyId ), is( true ) ); - assertThat( readOperations.nodeGetProperty( nodeId, propertyKeyId ), notNullValue() ); + assertThat( readOperations.nodeGetProperty( nodeId, propertyKeyId ), not( equalTo( Values.NO_VALUE ) ) ); } @Test @@ -247,7 +249,7 @@ public void nodeHasNotPropertyIfUnset() throws Exception // THEN assertThat( statement.readOperations().nodeHasProperty( nodeId, propertyKeyId ), is( false ) ); - assertThat( statement.readOperations().nodeGetProperty( nodeId, propertyKeyId ), nullValue() ); + assertThat( statement.readOperations().nodeGetProperty( nodeId, propertyKeyId ), equalTo( Values.NO_VALUE ) ); // WHEN commit(); @@ -256,7 +258,7 @@ public void nodeHasNotPropertyIfUnset() throws Exception // THEN assertThat( readOperations.nodeHasProperty( nodeId, propertyKeyId ), is( false ) ); - assertThat( readOperations.nodeGetProperty( nodeId, propertyKeyId ), nullValue() ); + assertThat( readOperations.nodeGetProperty( nodeId, propertyKeyId ), equalTo( Values.NO_VALUE ) ); } @Test @@ -276,7 +278,7 @@ public void shouldRollbackSetNodePropertyValue() throws Exception // THEN ReadOperations readOperations = readOperationsInNewTransaction(); assertThat( readOperations.nodeHasProperty( nodeId, propertyKeyId ), is( false ) ); - assertThat( readOperations.nodeGetProperty( nodeId, propertyKeyId ), nullValue() ); + assertThat( readOperations.nodeGetProperty( nodeId, propertyKeyId ), equalTo( Values.NO_VALUE ) ); } @Test @@ -296,7 +298,7 @@ public void shouldUpdateNodePropertyValue() throws Exception // THEN ReadOperations readOperations = readOperationsInNewTransaction(); - assertEquals( 42, readOperations.nodeGetProperty( nodeId, propertyId ) ); + assertEquals( 42, readOperations.nodeGetProperty( nodeId, propertyId ).asPublic() ); } @Test @@ -398,7 +400,7 @@ public void shouldBeAbleToRemoveResetAndTwiceRemovePropertyOnNode() throws Excep // then ReadOperations readOperations = readOperationsInNewTransaction(); - assertThat( readOperations.nodeGetProperty( node, prop ), nullValue() ); + assertThat( readOperations.nodeGetProperty( node, prop ), equalTo( Values.NO_VALUE ) ); } @Test @@ -427,7 +429,7 @@ public void shouldBeAbleToRemoveResetAndTwiceRemovePropertyOnRelationship() thro // then ReadOperations readOperations = readOperationsInNewTransaction(); - assertThat( readOperations.relationshipGetProperty( rel, prop ), nullValue() ); + assertThat( readOperations.relationshipGetProperty( rel, prop ), equalTo( Values.NO_VALUE ) ); } } diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/api/schema/NodeSchemaMatcherTest.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/api/schema/NodeSchemaMatcherTest.java index f3823d99041d9..8f42b4288efa4 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/impl/api/schema/NodeSchemaMatcherTest.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/api/schema/NodeSchemaMatcherTest.java @@ -35,6 +35,7 @@ import org.neo4j.kernel.impl.api.operations.EntityReadOperations; import org.neo4j.kernel.impl.api.state.StubCursors; import org.neo4j.storageengine.api.NodeItem; +import org.neo4j.values.Values; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.contains; @@ -84,9 +85,9 @@ public void setup() unIndexedPropId} ); EntityReadOperations readOps = mock( EntityReadOperations.class ); when( readOps.nodeGetPropertyKeys( state, node ) ).thenReturn( defaultPropertyIds ); - when( readOps.nodeGetProperty( state, node, propId1 ) ).thenReturn( "hi1" ); - when( readOps.nodeGetProperty( state, node, propId2 ) ).thenReturn( "hi2" ); - when( readOps.nodeGetProperty( state, node, unIndexedPropId ) ).thenReturn( "hi3" ); + when( readOps.nodeGetProperty( state, node, propId1 ) ).thenReturn( Values.of( "hi1" ) ); + when( readOps.nodeGetProperty( state, node, propId2 ) ).thenReturn( Values.of( "hi2" ) ); + when( readOps.nodeGetProperty( state, node, unIndexedPropId ) ).thenReturn( Values.of( "hi3" ) ); nodeSchemaMatcher = new NodeSchemaMatcher( readOps ); } diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/api/state/IndexTxStateUpdaterTest.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/api/state/IndexTxStateUpdaterTest.java index 744b7b93ea6fd..00dd7c308038b 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/impl/api/state/IndexTxStateUpdaterTest.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/api/state/IndexTxStateUpdaterTest.java @@ -111,9 +111,9 @@ public void setup() Property.property( propId1, "hi1" ), Property.property( propId2, "hi2" ), Property.property( propId3, "hi3" ) ) ); - when( readOps.nodeGetProperty( state, node, propId1 ) ).thenReturn( "hi1" ); - when( readOps.nodeGetProperty( state, node, propId2 ) ).thenReturn( "hi2" ); - when( readOps.nodeGetProperty( state, node, propId3 ) ).thenReturn( "hi3" ); + when( readOps.nodeGetProperty( state, node, propId1 ) ).thenReturn( Values.of( "hi1" ) ); + when( readOps.nodeGetProperty( state, node, propId2 ) ).thenReturn( Values.of( "hi2" ) ); + when( readOps.nodeGetProperty( state, node, propId3 ) ).thenReturn( Values.of( "hi3" ) ); indexTxUpdater = new IndexTxStateUpdater( storeReadLayer, readOps ); diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/event/ExpectedTransactionData.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/event/ExpectedTransactionData.java index 48bbeea91b7c8..89a89bdd771f8 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/impl/event/ExpectedTransactionData.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/event/ExpectedTransactionData.java @@ -32,6 +32,7 @@ import org.neo4j.graphdb.event.PropertyEntry; import org.neo4j.graphdb.event.TransactionData; import org.neo4j.kernel.impl.util.AutoCreatingHashMap; +import org.neo4j.values.Values; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; diff --git a/community/values/src/main/java/org/neo4j/values/ValueComparator.java b/community/values/src/main/java/org/neo4j/values/ValueComparator.java index a8426e6bec5cb..27ad7601c5521 100644 --- a/community/values/src/main/java/org/neo4j/values/ValueComparator.java +++ b/community/values/src/main/java/org/neo4j/values/ValueComparator.java @@ -26,7 +26,7 @@ /** * Comparator for values. Usable for sorting values, for example during index range scans. */ -class ValueComparator implements Comparator +public class ValueComparator implements Comparator { private final Comparator valueGroupComparator; private final Comparator virtualValueComparator; diff --git a/community/values/src/main/java/org/neo4j/values/Values.java b/community/values/src/main/java/org/neo4j/values/Values.java index 778101911f3f8..c2682d93a827c 100644 --- a/community/values/src/main/java/org/neo4j/values/Values.java +++ b/community/values/src/main/java/org/neo4j/values/Values.java @@ -60,6 +60,11 @@ public class ValueLoadException extends RuntimeException Comparator.comparingInt( VirtualValue::hashCode ) ); + public static boolean isNumberValue( Object value ) + { + return value instanceof NumberValue; + } + // DIRECT FACTORY METHODS public static final Value NO_VALUE = NoValue.NO_VALUE; @@ -145,6 +150,10 @@ public static Value numberValue( Number number ) { return shortValue( number.shortValue() ); } + if ( number == null ) + { + return NO_VALUE; + } throw new UnsupportedOperationException( "Unsupported type of Number " + number.toString() ); } diff --git a/enterprise/cypher/cypher/src/test/scala/org/neo4j/cypher/internal/compiled_runtime/v3_3/codegen/CodeGeneratorTest.scala b/enterprise/cypher/cypher/src/test/scala/org/neo4j/cypher/internal/compiled_runtime/v3_3/codegen/CodeGeneratorTest.scala index e1db17a6127cd..1a0820181c1ce 100644 --- a/enterprise/cypher/cypher/src/test/scala/org/neo4j/cypher/internal/compiled_runtime/v3_3/codegen/CodeGeneratorTest.scala +++ b/enterprise/cypher/cypher/src/test/scala/org/neo4j/cypher/internal/compiled_runtime/v3_3/codegen/CodeGeneratorTest.scala @@ -46,6 +46,7 @@ import org.neo4j.kernel.impl.api.RelationshipVisitor import org.neo4j.kernel.impl.api.store.RelationshipIterator import org.neo4j.kernel.impl.core.{NodeManager, NodeProxy, RelationshipProxy} import org.neo4j.time.Clocks +import org.neo4j.values.{Value, Values} import scala.collection.{JavaConverters, mutable} @@ -1759,10 +1760,10 @@ abstract class CodeGeneratorTest extends CypherFunSuite with LogicalPlanningTest when(queryContext.transactionalContext).thenReturn(transactionalContext) when(transactionalContext.readOperations).thenReturn(ro) when(queryContext.entityAccessor).thenReturn(nodeManager.asInstanceOf[queryContext.EntityAccessor]) - when(ro.nodeGetProperty(anyLong(), anyInt())).thenAnswer(new Answer[Object] { - override def answer(invocationOnMock: InvocationOnMock): Object = { + when(ro.nodeGetProperty(anyLong(), anyInt())).thenAnswer(new Answer[Value] { + override def answer(invocationOnMock: InvocationOnMock): Value = { val id = invocationOnMock.getArguments()(0).asInstanceOf[Long] - if (id < 3) "value" + if (id < 3) Values.stringValue("value") else null } })