[Bug?] Updating and then removing the property in the same transaction leaves the property with an older value


Bharat Dighe <bdi...@...>
 

Is it a known bug? Any workaround?

Added a vertex
gremlin> v=graph.addVertex();
==>v[204804096]
gremlin> v.property("name", "name1");
==>vp[name->name1]
gremlin> v.property("p1", "v");
==>vp[p1->v]
gremlin> v.property("p2", "v");
==>vp[p2->v]
gremlin> graph.tx().commit();
==>null
gremlin> g.V(204804096).properties();
==>vp[name->name1]
==>vp[p1->v]
==>vp[p2->v]
gremlin> graph.tx().commit();
==>null

Updated propeties p1 and p2 to value x
gremlin> v=g.V().has("name", "name1").next();
==>v[204804096]
gremlin> v.property("p1", "x");
==>vp[p1->x]
gremlin> v.property("p2", "x")
==>vp[p2->x]
gremlin> graph.tx().commit();
==>null
gremlin> g.V(204804096).properties();
==>vp[name->name1]
==>vp[p1->x]
==>vp[p2->x]

Updated propeties p1 and p2 to value y and in the same transaction the properties are removed

gremlin> v=g.V().has("name", "name1").next();
==>v[204804096]
gremlin> v.property("p1", "y");
==>vp[p1->y]
gremlin> v.property("p2", "y");
==>vp[p2->y]
gremlin> v.property("p1").remove()
==>null
gremlin> v.property("p2").remove()
==>null
gremlin> g.V(204804096).properties();
==>vp[name->name1]
==>vp[p1->x]
==>vp[p2->x]
gremlin> graph.tx().commit();
==>null
gremlin> g.V(204804280).properties();
==>vp[name->v1]
==>vp[p1->x]
==>vp[p2->x]

Properties p1 and p2 are not removed. Their values are set to previous value of "x".





Oleksandr Porunov <alexand...@...>
 

I think this is a bug. You may raise an issue on GitHub about that.
Basically, when we updated a property and then removing this property in the same transaction, JanusGraph thinks that the property is new and remove it only from added relations inside the current transaction (i.e. remove the updated version of the property without marking it for deletion during the transaction closure). I think, we should mark the property as a modified property to resolve the issue.

As a temporary workaround, you may call "remove" 2 times for modified properties. In such case, the property will be marked for deletion and will be removed during the commit operation.
I.e. call  next 4 operations to remove 2 properties:
v.property("p1").remove()
v.property("p1").remove()
v.property("p2").remove()
v.property("p2").remove()

After the issue is fixed, you will need only 1 "remove" call per each modified property. Please open the issue on GitHub about that.

Thank you,
Oleksandr

On Tuesday, February 18, 2020 at 3:41:54 PM UTC-8, Bharat Dighe wrote:
Is it a known bug? Any workaround?

Added a vertex
gremlin> v=graph.addVertex();
==>v[204804096]
gremlin> v.property("name", "name1");
==>vp[name->name1]
gremlin> v.property("p1", "v");
==>vp[p1->v]
gremlin> v.property("p2", "v");
==>vp[p2->v]
gremlin> graph.tx().commit();
==>null
gremlin> g.V(204804096).properties();
==>vp[name->name1]
==>vp[p1->v]
==>vp[p2->v]
gremlin> graph.tx().commit();
==>null

Updated propeties p1 and p2 to value x
gremlin> v=g.V().has("name", "name1").next();
==>v[204804096]
gremlin> v.property("p1", "x");
==>vp[p1->x]
gremlin> v.property("p2", "x")
==>vp[p2->x]
gremlin> graph.tx().commit();
==>null
gremlin> g.V(204804096).properties();
==>vp[name->name1]
==>vp[p1->x]
==>vp[p2->x]

Updated propeties p1 and p2 to value y and in the same transaction the properties are removed

gremlin> v=g.V().has("name", "name1").next();
==>v[204804096]
gremlin> v.property("p1", "y");
==>vp[p1->y]
gremlin> v.property("p2", "y");
==>vp[p2->y]
gremlin> v.property("p1").remove()
==>null
gremlin> v.property("p2").remove()
==>null
gremlin> g.V(204804096).properties();
==>vp[name->name1]
==>vp[p1->x]
==>vp[p2->x]
gremlin> graph.tx().commit();
==>null
gremlin> g.V(204804280).properties();
==>vp[name->v1]
==>vp[p1->x]
==>vp[p2->x]

Properties p1 and p2 are not removed. Their values are set to previous value of "x".





Pavel Ershov <owner...@...>
 

This bug introduced by optimization, when property changed - no one read query will be triggered, data just overwritten blindly, see https://github.com/JanusGraph/janusgraph/blob/100a2ee21351c24eedc0bd9533a49870ab16002a/janusgraph-core/src/main/java/org/janusgraph/graphdb/transaction/StandardJanusGraphTx.java#L796-L808

For fix that we need to read old property from db to mark it deleted

Or rewrite property explicitly

graph=JanusGraphFactory.open("inmemory")
g
=graph.traversal()
v
=graph.addVertex();
vid
=v.id();
v
.property("name", "name1");
v
.property("p1", "a");
graph
.tx().commit();
v
=g.V().has("name", "name1").next();
v
.property("p1").remove() // remove old property explicitly
v
.property("p1", "y");
v
.property("p1").remove()
g
.V(vid).properties();
graph
.tx().commit();
g
.V(vid).properties();



четверг, 20 февраля 2020 г., 20:14:12 UTC+3 пользователь Oleksandr Porunov написал:

I think this is a bug. You may raise an issue on GitHub about that.
Basically, when we updated a property and then removing this property in the same transaction, JanusGraph thinks that the property is new and remove it only from added relations inside the current transaction (i.e. remove the updated version of the property without marking it for deletion during the transaction closure). I think, we should mark the property as a modified property to resolve the issue.

As a temporary workaround, you may call "remove" 2 times for modified properties. In such case, the property will be marked for deletion and will be removed during the commit operation.
I.e. call  next 4 operations to remove 2 properties:
v.property("p1").remove()
v.property("p1").remove()
v.property("p2").remove()
v.property("p2").remove()

After the issue is fixed, you will need only 1 "remove" call per each modified property. Please open the issue on GitHub about that.

Thank you,
Oleksandr

On Tuesday, February 18, 2020 at 3:41:54 PM UTC-8, Bharat Dighe wrote:
Is it a known bug? Any workaround?

Added a vertex
gremlin> v=graph.addVertex();
==>v[204804096]
gremlin> v.property("name", "name1");
==>vp[name->name1]
gremlin> v.property("p1", "v");
==>vp[p1->v]
gremlin> v.property("p2", "v");
==>vp[p2->v]
gremlin> graph.tx().commit();
==>null
gremlin> g.V(204804096).properties();
==>vp[name->name1]
==>vp[p1->v]
==>vp[p2->v]
gremlin> graph.tx().commit();
==>null

Updated propeties p1 and p2 to value x
gremlin> v=g.V().has("name", "name1").next();
==>v[204804096]
gremlin> v.property("p1", "x");
==>vp[p1->x]
gremlin> v.property("p2", "x")
==>vp[p2->x]
gremlin> graph.tx().commit();
==>null
gremlin> g.V(204804096).properties();
==>vp[name->name1]
==>vp[p1->x]
==>vp[p2->x]

Updated propeties p1 and p2 to value y and in the same transaction the properties are removed

gremlin> v=g.V().has("name", "name1").next();
==>v[204804096]
gremlin> v.property("p1", "y");
==>vp[p1->y]
gremlin> v.property("p2", "y");
==>vp[p2->y]
gremlin> v.property("p1").remove()
==>null
gremlin> v.property("p2").remove()
==>null
gremlin> g.V(204804096).properties();
==>vp[name->name1]
==>vp[p1->x]
==>vp[p2->x]
gremlin> graph.tx().commit();
==>null
gremlin> g.V(204804280).properties();
==>vp[name->v1]
==>vp[p1->x]
==>vp[p2->x]

Properties p1 and p2 are not removed. Their values are set to previous value of "x".





Oleksandr Porunov <alexand...@...>
 

I have opened the issue on GitHub regarding this bug: https://github.com/JanusGraph/janusgraph/issues/1981

Pavel, will you be able to check that issue?

On Friday, February 21, 2020 at 12:29:43 AM UTC-8, Pavel Ershov wrote:
This bug introduced by optimization, when property changed - no one read query will be triggered, data just overwritten blindly, see https://github.com/JanusGraph/janusgraph/blob/100a2ee21351c24eedc0bd9533a49870ab16002a/janusgraph-core/src/main/java/org/janusgraph/graphdb/transaction/StandardJanusGraphTx.java#L796-L808

For fix that we need to read old property from db to mark it deleted

Or rewrite property explicitly

graph=JanusGraphFactory.open("inmemory")
g
=graph.traversal()
v
=graph.addVertex();
vid
=v.id();
v
.property("name", "name1");
v
.property("p1", "a");
graph
.tx().commit();
v
=g.V().has("name", "name1").next();
v
.property("p1").remove() // remove old property explicitly
v
.property("p1", "y");
v
.property("p1").remove()
g
.V(vid).properties();
graph
.tx().commit();
g
.V(vid).properties();



четверг, 20 февраля 2020 г., 20:14:12 UTC+3 пользователь Oleksandr Porunov написал:
I think this is a bug. You may raise an issue on GitHub about that.
Basically, when we updated a property and then removing this property in the same transaction, JanusGraph thinks that the property is new and remove it only from added relations inside the current transaction (i.e. remove the updated version of the property without marking it for deletion during the transaction closure). I think, we should mark the property as a modified property to resolve the issue.

As a temporary workaround, you may call "remove" 2 times for modified properties. In such case, the property will be marked for deletion and will be removed during the commit operation.
I.e. call  next 4 operations to remove 2 properties:
v.property("p1").remove()
v.property("p1").remove()
v.property("p2").remove()
v.property("p2").remove()

After the issue is fixed, you will need only 1 "remove" call per each modified property. Please open the issue on GitHub about that.

Thank you,
Oleksandr

On Tuesday, February 18, 2020 at 3:41:54 PM UTC-8, Bharat Dighe wrote:
Is it a known bug? Any workaround?

Added a vertex
gremlin> v=graph.addVertex();
==>v[204804096]
gremlin> v.property("name", "name1");
==>vp[name->name1]
gremlin> v.property("p1", "v");
==>vp[p1->v]
gremlin> v.property("p2", "v");
==>vp[p2->v]
gremlin> graph.tx().commit();
==>null
gremlin> g.V(204804096).properties();
==>vp[name->name1]
==>vp[p1->v]
==>vp[p2->v]
gremlin> graph.tx().commit();
==>null

Updated propeties p1 and p2 to value x
gremlin> v=g.V().has("name", "name1").next();
==>v[204804096]
gremlin> v.property("p1", "x");
==>vp[p1->x]
gremlin> v.property("p2", "x")
==>vp[p2->x]
gremlin> graph.tx().commit();
==>null
gremlin> g.V(204804096).properties();
==>vp[name->name1]
==>vp[p1->x]
==>vp[p2->x]

Updated propeties p1 and p2 to value y and in the same transaction the properties are removed

gremlin> v=g.V().has("name", "name1").next();
==>v[204804096]
gremlin> v.property("p1", "y");
==>vp[p1->y]
gremlin> v.property("p2", "y");
==>vp[p2->y]
gremlin> v.property("p1").remove()
==>null
gremlin> v.property("p2").remove()
==>null
gremlin> g.V(204804096).properties();
==>vp[name->name1]
==>vp[p1->x]
==>vp[p2->x]
gremlin> graph.tx().commit();
==>null
gremlin> g.V(204804280).properties();
==>vp[name->v1]
==>vp[p1->x]
==>vp[p2->x]

Properties p1 and p2 are not removed. Their values are set to previous value of "x".





Boxuan Li <libo...@...>
 

Created a PR to fix this bug: https://github.com/JanusGraph/janusgraph/pull/2244
Appreciate any review!

On Saturday, February 22, 2020 at 2:00:09 PM UTC+8 alex...@... wrote:
I have opened the issue on GitHub regarding this bug: https://github.com/JanusGraph/janusgraph/issues/1981

Pavel, will you be able to check that issue?

On Friday, February 21, 2020 at 12:29:43 AM UTC-8, Pavel Ershov wrote:
This bug introduced by optimization, when property changed - no one read query will be triggered, data just overwritten blindly, see https://github.com/JanusGraph/janusgraph/blob/100a2ee21351c24eedc0bd9533a49870ab16002a/janusgraph-core/src/main/java/org/janusgraph/graphdb/transaction/StandardJanusGraphTx.java#L796-L808

For fix that we need to read old property from db to mark it deleted

Or rewrite property explicitly

graph=JanusGraphFactory.open("inmemory")
g
=graph.traversal()
v
=graph.addVertex();
vid
=v.id();
v
.property("name", "name1");
v
.property("p1", "a");
graph
.tx().commit();
v
=g.V().has("name", "name1").next();
v
.property("p1").remove() // remove old property explicitly
v
.property("p1", "y");
v
.property("p1").remove()
g
.V(vid).properties();
graph
.tx().commit();
g
.V(vid).properties();



четверг, 20 февраля 2020 г., 20:14:12 UTC+3 пользователь Oleksandr Porunov написал:
I think this is a bug. You may raise an issue on GitHub about that.
Basically, when we updated a property and then removing this property in the same transaction, JanusGraph thinks that the property is new and remove it only from added relations inside the current transaction (i.e. remove the updated version of the property without marking it for deletion during the transaction closure). I think, we should mark the property as a modified property to resolve the issue.

As a temporary workaround, you may call "remove" 2 times for modified properties. In such case, the property will be marked for deletion and will be removed during the commit operation.
I.e. call  next 4 operations to remove 2 properties:
v.property("p1").remove()
v.property("p1").remove()
v.property("p2").remove()
v.property("p2").remove()

After the issue is fixed, you will need only 1 "remove" call per each modified property. Please open the issue on GitHub about that.

Thank you,
Oleksandr

On Tuesday, February 18, 2020 at 3:41:54 PM UTC-8, Bharat Dighe wrote:
Is it a known bug? Any workaround?

Added a vertex
gremlin> v=graph.addVertex();
==>v[204804096]
gremlin> v.property("name", "name1");
==>vp[name->name1]
gremlin> v.property("p1", "v");
==>vp[p1->v]
gremlin> v.property("p2", "v");
==>vp[p2->v]
gremlin> graph.tx().commit();
==>null
gremlin> g.V(204804096).properties();
==>vp[name->name1]
==>vp[p1->v]
==>vp[p2->v]
gremlin> graph.tx().commit();
==>null

Updated propeties p1 and p2 to value x
gremlin> v=g.V().has("name", "name1").next();
==>v[204804096]
gremlin> v.property("p1", "x");
==>vp[p1->x]
gremlin> v.property("p2", "x")
==>vp[p2->x]
gremlin> graph.tx().commit();
==>null
gremlin> g.V(204804096).properties();
==>vp[name->name1]
==>vp[p1->x]
==>vp[p2->x]

Updated propeties p1 and p2 to value y and in the same transaction the properties are removed

gremlin> v=g.V().has("name", "name1").next();
==>v[204804096]
gremlin> v.property("p1", "y");
==>vp[p1->y]
gremlin> v.property("p2", "y");
==>vp[p2->y]
gremlin> v.property("p1").remove()
==>null
gremlin> v.property("p2").remove()
==>null
gremlin> g.V(204804096).properties();
==>vp[name->name1]
==>vp[p1->x]
==>vp[p2->x]
gremlin> graph.tx().commit();
==>null
gremlin> g.V(204804280).properties();
==>vp[name->v1]
==>vp[p1->x]
==>vp[p2->x]

Properties p1 and p2 are not removed. Their values are set to previous value of "x".