Skip to content

Commit 6db75f7

Browse files
authored
Native translation of copyProperties (#281)
Signed-off-by: Dwitry dwitry@users.noreply.github.com
1 parent 7b42ab0 commit 6db75f7

File tree

12 files changed

+56
-35
lines changed

12 files changed

+56
-35
lines changed

testware/integration-tests/src/test/java/org/opencypher/gremlin/queries/SetTest.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -294,8 +294,7 @@ public void copyPropertiesRelationshipToNode() {
294294
public void copyPropertiesFromNull() {
295295
submitAndGet("CREATE (:TO {prop1: 'x', prop3: 'y'})");
296296

297-
assertThatThrownBy(() -> submitAndGet("OPTIONAL MATCH (x:NOT_EXISTING) WITH x MATCH (to:TO) SET to=x RETURN to"))
298-
.hasMessageContaining("Expected cypher.null to be Element");
297+
assertThatThrownBy(() -> submitAndGet("OPTIONAL MATCH (x:NOT_EXISTING) WITH x MATCH (to:TO) SET to=x RETURN to"));
299298
}
300299

301300
@Test

tinkerpop/cypher-gremlin-extensions/README.md

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -96,14 +96,6 @@ In Gremlin different steps are required for each type:
9696

9797
If type information is unknown (or on string concatenation) - custom function is used. If Gremlin Extensions for Cypher Support are not installed, translation falls back to number operator.
9898

99-
### Copying Properties from node to node
100-
101-
```cypher
102-
MATCH (n:FROM)-[r]->(m:TO) SET m=n RETURN m
103-
```
104-
105-
Gremlin [AddProperty step](http://tinkerpop.apache.org/docs/current/reference/#addproperty-step) only allows setting a single value, where the property name is constant. It is unknown how to copy all properties from one element to another.
106-
10799
## Translation Workarounds
108100

109101
### Null handling

tinkerpop/cypher-gremlin-extensions/src/main/java/org/opencypher/gremlin/traversal/CustomFunctions.java

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -464,20 +464,6 @@ public static Function<Traverser, Object> cypherReplace() {
464464
String.class, String.class, String.class);
465465
}
466466

467-
public static Function<Traverser, Object> cypherCopyProperties() {
468-
return traverser -> {
469-
List args = cast(traverser.get(), List.class);
470-
if (args.get(0) == Tokens.NULL) {
471-
return Tokens.NULL;
472-
}
473-
474-
Element to = cast(args.get(0), Element.class);
475-
Element from = cast(args.get(1), Element.class);
476-
from.properties().forEachRemaining(prop -> to.property(prop.key(), prop.value()));
477-
return to;
478-
};
479-
}
480-
481467
public static Function<Traverser, Object> cypherException() {
482468
return traverser -> {
483469
String message = CypherExceptions.messageByName(traverser.get());

translation/src/main/java/org/opencypher/gremlin/translation/GremlinSteps.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,8 @@ GremlinSteps<T, P> choose(GremlinSteps<T, P> traversalPredicate,
200200

201201
GremlinSteps<T, P> property(String key, GremlinSteps<T, P> traversal);
202202

203+
GremlinSteps<T, P> property(GremlinSteps<T, P> keyTraversal, GremlinSteps<T, P> valueTraversal);
204+
203205
GremlinSteps<T, P> property(Cardinality cardinality, String key, GremlinSteps<T, P> traversal);
204206

205207
GremlinSteps<T, P> project(String... keys);

translation/src/main/java/org/opencypher/gremlin/translation/bytecode/BytecodeGremlinSteps.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -484,6 +484,12 @@ public GremlinSteps<Bytecode, P> property(String key, GremlinSteps<Bytecode, P>
484484
return this;
485485
}
486486

487+
@Override
488+
public GremlinSteps<Bytecode, P> property(GremlinSteps<Bytecode, P> keyTraversal, GremlinSteps<Bytecode, P> valueTraversal) {
489+
bytecode.addStep(Symbols.property, keyTraversal.current(), valueTraversal.current());
490+
return this;
491+
}
492+
487493
@Override
488494
public GremlinSteps<Bytecode, P> property(Cardinality cardinality, String key, GremlinSteps<Bytecode, P> traversal) {
489495
bytecode.addStep(Symbols.property, cardinality, key, traversal.current());

translation/src/main/java/org/opencypher/gremlin/translation/groovy/GroovyGremlinSteps.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -493,6 +493,12 @@ public GremlinSteps<String, GroovyPredicate> property(String key, GremlinSteps<S
493493
return this;
494494
}
495495

496+
@Override
497+
public GremlinSteps<String, GroovyPredicate> property(GremlinSteps<String, GroovyPredicate> keyTraversal, GremlinSteps<String, GroovyPredicate> valueTraversal) {
498+
g.append(chain("property", traversal(keyTraversal), traversal(valueTraversal)));
499+
return this;
500+
}
501+
496502
@Override
497503
public GremlinSteps<String, GroovyPredicate> property(Cardinality cardinality, String key, GremlinSteps<String, GroovyPredicate> traversal) {
498504
g.append(chain("property", cardinality, key, traversal(traversal)));

translation/src/main/java/org/opencypher/gremlin/translation/traversal/TraversalGremlinSteps.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -520,6 +520,12 @@ public GremlinSteps<GraphTraversal, P> property(String key, GremlinSteps<GraphTr
520520
return property(key, traversal.current());
521521
}
522522

523+
@Override
524+
public GremlinSteps<GraphTraversal, P> property(GremlinSteps<GraphTraversal, P> keyTraversal, GremlinSteps<GraphTraversal, P> valueTraversal) {
525+
g.property(keyTraversal.current(), valueTraversal.current());
526+
return this;
527+
}
528+
523529
@Override
524530
public GremlinSteps<GraphTraversal, P> property(Cardinality cardinality, String key, GremlinSteps<GraphTraversal, P> traversal) {
525531
g.property(cardinality, key, traversal.current());

translation/src/main/java/org/opencypher/gremlin/traversal/CustomFunction.java

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -177,13 +177,6 @@ public static CustomFunction cypherReplace() {
177177
);
178178
}
179179

180-
public static CustomFunction cypherCopyProperties() {
181-
return new CustomFunction(
182-
"cypherCopyProperties",
183-
CustomFunctions.cypherCopyProperties()
184-
);
185-
}
186-
187180
@Override
188181
public boolean equals(Object o) {
189182
if (this == o) return true;

translation/src/main/scala/org/opencypher/gremlin/translation/ir/TranslationWriter.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,8 @@ sealed class TranslationWriter[T, P] private (translator: Translator[T, P], para
222222
g.property(cardinality, key, writeValue(value))
223223
case PropertyT(key, traversal) =>
224224
g.property(key, writeLocalSteps(traversal))
225+
case PropertyT2(keyTraversal, valueTraversal) =>
226+
g.property(writeLocalSteps(keyTraversal), writeLocalSteps(valueTraversal))
225227
case PropertyTC(cardinality, key, traversal) =>
226228
g.property(cardinality, key, writeLocalSteps(traversal))
227229
case Project(keys @ _*) =>

translation/src/main/scala/org/opencypher/gremlin/translation/ir/builder/IRGremlinSteps.scala

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -422,6 +422,14 @@ class IRGremlinSteps extends GremlinSteps[Seq[GremlinStep], GremlinPredicate] {
422422
this
423423
}
424424

425+
override def property(
426+
keyTraversal: GremlinSteps[Seq[GremlinStep], GremlinPredicate],
427+
valueTraversal: GremlinSteps[Seq[GremlinStep], GremlinPredicate])
428+
: GremlinSteps[Seq[GremlinStep], GremlinPredicate] = {
429+
buf += PropertyT2(keyTraversal.current(), valueTraversal.current())
430+
this
431+
}
432+
425433
override def property(
426434
cardinality: Cardinality,
427435
key: String,

0 commit comments

Comments
 (0)