GraphScope
GraphScope copied to clipboard
[BUG] Results Parsing Error When Label is None in Gremlin Queries
Describe the bug
When executing certain Gremlin queries that involve elementMap(), the labels that can be None if the element is None. For example:
g.V(1).union(outE().as('e'), out().as('middle').outE().as('e')).dedup().otherV().as('endv').select('endv', 'e', 'middle').by(elementMap()).by(elementMap()).by(elementMap()).limit(1)
In this query, the middle vertex can be None, and the elementMap() results for the middle vertex looks like (~id, ~label, and its properties are all None):
KeyValue { key: Some(Value { item: Some(Str("middle")) }), value: Some(Entry { inner: Some(Map(KeyValues { key_values: [KeyValue { key: Some(Value { item: Some(Str("~label")) }), value: Some(Entry { inner: Some(Element(Element { inner: Some(Object(Value { item: Some(None(None)) })) })) }) }, KeyValue { key: Some(Value { item: Some(Str("~id")) }), value: Some(Entry { inner: Some(Element(Element { inner: Some(Object(Value { item: Some(None(None)) })) })) }) }, KeyValue { key: Some(Value { item: Some(Str("user_email")) }), value: Some(Entry { inner: Some(Element(Element { inner: Some(Object(Value { item: Some(None(None)) })) })) }) }, KeyValue { key: Some(Value { item: Some(Str("entity_value")) }), value: Some(Entry { inner: Some(Element(Element { inner: Some(Object(Value { item: Some(None(None)) })) })) }) }, KeyValue { key: Some(Value { item: Some(Str("user_nick")) }), value: Some(Entry { inner: Some(Element(Element { inner: Some(Object(Value { item: Some(None(None)) })) })) }) }] })) }) }] })) }) }] }
However, in result parsing, the compiler returns error message:
ErrorCode: GREMLIN_INVALID_RESULT\nMessage: cannot parse label value with type=NONE\nEC: 03-0108\nstacktrace: java.lang.IllegalArgumentException: cannot parse label value with type=NONE\n\tat com.alibaba.graphscope.common.result.Utils.parseLabelValue(Utils.java:145)\n\tat com.alibaba.graphscope.gremlin.resultx.GremlinRecordParser.parseValue(GremlinRecordParser.java:267)\n\tat com.alibaba.graphscope.gremlin.resultx.GremlinRecordParser.parseElement(GremlinRecordParser.java:214)\n\tat com.alibaba.graphscope.gremlin.resultx.GremlinRecordParser.parseEntry(GremlinRecordParser.java:130)\n\tat com.alibaba.graphscope.gremlin.resultx.GremlinRecordParser.parseKeyValues(GremlinRecordParser.java:180)\n\tat com.alibaba.graphscope.gremlin.resultx.GremlinRecordParser.parseEntry(GremlinRecordParser.java:124)\n\tat com.alibaba.graphscope.gremlin.resultx.GremlinRecordParser.parseKeyValues(GremlinRecordParser.java:180)\n\tat com.alibaba.graphscope.gremlin.resultx.GremlinRecordParser.parseEntry(GremlinRecordParser.java:124)\n\tat com.alibaba.graphscope.gremlin.resultx.GremlinRecordParser.parseFrom(GremlinRecordParser.java:95)\n\tat com.alibaba.graphscope.gremlin.resultx.GremlinResultProcessor.lambda$processRecord$0(GremlinResultProcessor.java:134)\n\tat com.alibaba.graphscope.common.utils.ClassUtils.callExceptionWithDetails(ClassUtils.java:54)\n\tat com.alibaba.graphscope.common.utils.ClassUtils.callException(ClassUtils.java:48)\n\tat com.alibaba.graphscope.gremlin.resultx.GremlinResultProcessor.processRecord(GremlinResultProcessor.java:133)\n\tat com.alibaba.graphscope.gremlin.resultx.GremlinResultProcessor.request(GremlinResultProcessor.java:92)\n\tat com.alibaba.graphscope.gremlin.plugin.processor.LifeCycleSupplier.lambda$get$2(LifeCycleSupplier.java:136)\n\tat org.apache.tinkerpop.gremlin.groovy.engine.GremlinExecutor.lambda$eval$0(GremlinExecutor.java:283)\n\tat java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)\n\tat java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)\n\tat java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)\n\tat java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)\n\tat java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)\n\tat java.base/java.lang.Thread.run(Thread.java:829)\n\nQueryId: 4950820082035874898\n
Moreover, if we use valueMap() in the query instead of elementMap(), i.e.,
g.V(1).union(outE().as('e'), out().as('middle').outE().as('e')).dedup().otherV().as('endv').select('endv', 'e', 'middle').by(valueMap()).by(valueMap()).by(valueMap()).limit(1)
the query successfully returns results as expected (with valueMap of middle as a None value). The expectation is that the results of elementMap() and valueMap() should be consistent.