JanusGraph / janusgraph

JanusGraph: an open-source, distributed graph database
https://janusgraph.org
Other
5.26k stars 1.16k forks source link

Float property comparison fails #487

Open pluradj opened 7 years ago

pluradj commented 7 years ago

Reported on janusgraph-users thread

It is reproducible from the Gremlin Console.

gremlin> graph = JanusGraphFactory.open('inmemory')
==>standardjanusgraph[inmemory:[127.0.0.1]]
gremlin> mgmt = graph.openManagement()
==>org.janusgraph.graphdb.database.management.ManagementSystem@2938127d
gremlin> float_prop = mgmt.makePropertyKey('float_prop').dataType(Float.class).cardinality(Cardinality.LIST).make()
==>float_prop
gremlin> mgmt.commit()
==>null
gremlin> g = graph.traversal()
==>graphtraversalsource[standardjanusgraph[inmemory:[127.0.0.1]], standard]
gremlin> v = g.addV().property(VertexProperty.Cardinality.list, 'float_prop', 1.1f).next()
==>v[4176]
gremlin> g.V(v).has('float_prop', 1.1).toList()
==>v[4176]
gremlin> g.V(v).properties('float_prop').hasValue(1.1).toList()
Property value [1.1] is of type class java.math.BigDecimal is not supported
Type ':help' or ':h' for help.
Display stack trace? [yN]y
java.lang.IllegalArgumentException: Property value [1.1] is of type class java.math.BigDecimal is not supported
    at org.apache.tinkerpop.gremlin.structure.Property$Exceptions.dataTypeOfPropertyValueNotSupported(Property.java:163)
    at org.apache.tinkerpop.gremlin.structure.Property$Exceptions.dataTypeOfPropertyValueNotSupported(Property.java:159)
    at org.janusgraph.graphdb.transaction.StandardJanusGraphTx.verifyAttribute(StandardJanusGraphTx.java:578)
    at org.janusgraph.graphdb.query.QueryUtil.addConstraint(QueryUtil.java:206)
    at org.janusgraph.graphdb.query.QueryUtil.constraints2QNF(QueryUtil.java:196)
    at org.janusgraph.graphdb.query.vertex.BasicVertexCentricQueryBuilder.constructQueryWithoutProfile(BasicVertexCentricQueryBuilder.java:422)
    at org.janusgraph.graphdb.query.vertex.BasicVertexCentricQueryBuilder.constructQuery(BasicVertexCentricQueryBuilder.java:399)
    at org.janusgraph.graphdb.query.vertex.VertexCentricQueryBuilder.execute(VertexCentricQueryBuilder.java:68)
    at org.janusgraph.graphdb.query.vertex.VertexCentricQueryBuilder.properties(VertexCentricQueryBuilder.java:100)
    at org.janusgraph.graphdb.tinkerpop.optimize.JanusGraphPropertiesStep.flatMap(JanusGraphPropertiesStep.java:117)
    at org.apache.tinkerpop.gremlin.process.traversal.step.map.FlatMapStep.processNextStart(FlatMapStep.java:49)
    at org.janusgraph.graphdb.tinkerpop.optimize.JanusGraphPropertiesStep.processNextStart(JanusGraphPropertiesStep.java:107)
    at org.apache.tinkerpop.gremlin.process.traversal.step.util.AbstractStep.next(AbstractStep.java:128)
    at org.apache.tinkerpop.gremlin.process.traversal.step.util.AbstractStep.next(AbstractStep.java:38)
    at org.apache.tinkerpop.gremlin.process.traversal.Traversal.fill(Traversal.java:177)
    at org.apache.tinkerpop.gremlin.process.traversal.Traversal.toList(Traversal.java:115)
    at org.apache.tinkerpop.gremlin.process.traversal.Traversal$toList$0.call(Unknown Source)

Unlike the HasStep, the JanusGraphPropertiesStep doesn't appear to handle Float vs Double vs BigDecimal comparison gracefully -- Final Traversal [GraphStep(vertex,[v[4176]]), JanusGraphPropertiesStep([~value.eq(1.1)])]

robertdale commented 7 years ago

Let alone the fact that equals should not be used on floating point...

The issue is that property step predicate values are not converted (to a supported type). In other words, an unsupported type is being passed (e.g. 1.1 unqualified becomes BigDecimal in groovy - one must use f or d to specify another type). Had the query used the same type as the underlying type, there would be no error: g.V(v).properties('float_prop').hasValue(1.1f).toList()

So, how do we solve this? 1) throw an error on any unsupported type (as-is), 2) ignore the error and just filter out any traversers, 3) have a special conversion from BigDecimal to Float or Double, 4) ??

robertdale commented 7 years ago

This fails as expected:

gremlin> g.addV().property('float_prop',1.4)
Property value [1.4] is of type class java.math.BigDecimal is not supported