in interactive_engine/compiler/src/main/java/com/alibaba/graphscope/gremlin/transform/TraversalParentTransform.java [50:224]
default ExprResult getSubTraversalAsExpr(ExprArg exprArg) {
int size = exprArg.size();
// return a result representing the traversal cannot be converted to expression
final ExprResult defaultNonExpr = (new ExprResult()).addTagExpr("", Optional.empty());
// the followings are considered as expressions instead of apply
if (size <= 1) {
if (exprArg.isEmpty()) { // by()
return (new ExprResult()).addTagExpr("", Optional.of("@"));
} else {
Step step = exprArg.getStartStep();
if (step instanceof PropertyMapStep) { // valueMap(..)
String[] mapKeys = ((PropertyMapStep) step).getPropertyKeys();
if (mapKeys.length > 0) {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("{");
for (int i = 0; i < mapKeys.length; ++i) {
if (i > 0) {
stringBuilder.append(", ");
}
stringBuilder.append("@." + mapKeys[i]);
}
stringBuilder.append("}");
return (new ExprResult())
.addTagExpr("", Optional.of(stringBuilder.toString()));
} else {
// valueMap() -> @.~all
return (new ExprResult())
.addTagExpr("", Optional.of("@." + ArgUtils.PROPERTY_ALL));
}
} else if (step instanceof PropertiesStep) { // values(..)
String[] mapKeys = ((PropertiesStep) step).getPropertyKeys();
if (mapKeys.length == 0) {
throw new OpArgIllegalException(
OpArgIllegalException.Cause.UNSUPPORTED_TYPE,
"values() is unsupported");
}
if (mapKeys.length > 1) {
throw new OpArgIllegalException(
OpArgIllegalException.Cause.UNSUPPORTED_TYPE,
"use valueMap(..) instead if there are multiple project keys");
}
return (new ExprResult()).addTagExpr("", Optional.of("@." + mapKeys[0]));
} else if (step instanceof LabelStep) {
return (new ExprResult())
.addTagExpr("", Optional.of("@." + T.label.getAccessor())); // @.~label
} else if (step instanceof IdStep) {
return (new ExprResult())
.addTagExpr("", Optional.of("@." + T.id.getAccessor())); // @.~id
} else if (step instanceof ElementMapStep) { // elementMap(..)
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("{");
// id
stringBuilder.append("@." + ArgUtils.ID + ",");
// label
stringBuilder.append("@." + ArgUtils.LABEL + ",");
// properties
String[] mapKeys = ((ElementMapStep) step).getPropertyKeys();
if (mapKeys.length > 0) {
for (int i = 0; i < mapKeys.length; ++i) {
if (i > 0) {
stringBuilder.append(",");
}
stringBuilder.append("@." + mapKeys[i]);
}
} else {
// elementMap() -> @.~all
stringBuilder.append("@." + ArgUtils.PROPERTY_ALL);
}
stringBuilder.append("}");
return (new ExprResult()).addTagExpr("", Optional.of(stringBuilder.toString()));
} else if (step instanceof SelectOneStep || step instanceof SelectStep) {
// select('a'), select('a').by()
// select('a').by('name'/values/valueMap)
// select('a', 'b'), select('a', 'b').by()
// select('a', 'b').by('name'/values/valueMap).by('name'/values/valueMap)
Map<String, Traversal.Admin> selectBys =
getProjectTraversals((TraversalParent) step);
ExprResult exprRes = new ExprResult();
for (Map.Entry<String, Traversal.Admin> entry : selectBys.entrySet()) {
String k = entry.getKey();
Traversal.Admin v = entry.getValue();
Optional<String> byExpr =
getSubTraversalAsExpr(new ExprArg(v)).getSingleExpr();
if (byExpr.isPresent()) {
String expr = byExpr.get().replace("@", "@" + k);
exprRes.addTagExpr(k, Optional.of(expr));
} else {
exprRes.addTagExpr(k, Optional.empty());
}
}
return exprRes;
} else if (step instanceof WhereTraversalStep.WhereStartStep) { // where(as('a'))
WhereTraversalStep.WhereStartStep startStep =
(WhereTraversalStep.WhereStartStep) step;
String selectKey = (String) startStep.getScopeKeys().iterator().next();
return (new ExprResult()).addTagExpr(selectKey, Optional.of("@" + selectKey));
} else if (step instanceof TraversalMapStep) { // select(keys), select(values)
ProjectOp mapOp =
(ProjectOp) StepTransformFactory.TRAVERSAL_MAP_STEP.apply(step);
List<Pair> pairs = (List<Pair>) mapOp.getExprWithAlias().get().applyArg();
String mapExpr = (String) pairs.get(0).getValue0();
String mapKey = mapExpr.substring(1);
return (new ExprResult()).addTagExpr(mapKey, Optional.of(mapExpr));
} else if (step instanceof DedupGlobalStep) {
// support the pattern of dedup by variables, i.e. dedup().by("name") or
// dedup("a").by("name")
ExprResult exprRes = new ExprResult();
DedupGlobalStep dedupStep = (DedupGlobalStep) step;
List<Traversal.Admin> traversals = dedupStep.getLocalChildren();
// get dedupTraversal nested in by() from dedup step
Traversal.Admin dedupTraversal =
traversals.isEmpty() ? new IdentityTraversal() : traversals.get(0);
// check whether the dedupTraversal can be represented as a expression or a
// apply,
// return string if it is a expression, i.e. dedup().by("name") or
// dedup("a").by("name"),
// return null if it is a apply, i.e. dedup().by(out().count())
Optional<String> exprOpt =
getSubTraversalAsExpr(new ExprArg(dedupTraversal)).getSingleExpr();
// get dedup keys from dedup step, i.e dedup() -> [""], dedup("a") -> ["a"],
// dedup("a", "b") ->
// ["a", "b"]
Set<String> dedupKeys =
dedupStep.getScopeKeys().isEmpty()
? Collections.singleton("")
: dedupStep.getScopeKeys();
for (String key : dedupKeys) {
if (exprOpt.isPresent()) { // dedup().by("name") or dedup("a").by("name")
String expr = exprOpt.get().replace("@", "@" + key);
exprRes.addTagExpr(key, Optional.of(expr));
} else { // dedup().by(out().count())
exprRes.addTagExpr(key, Optional.empty());
}
}
return exprRes;
} else {
return defaultNonExpr;
}
}
} else if (size == 2) {
Step startStep = exprArg.getStartStep();
Step endStep = exprArg.getEndStep();
if ((startStep instanceof SelectOneStep || startStep instanceof TraversalMapStep)
&& (endStep instanceof PropertiesStep || endStep instanceof PropertyMapStep)) {
Optional<String> propertyExpr =
getSubTraversalAsExpr((new ExprArg(Collections.singletonList(endStep))))
.getSingleExpr();
if (!propertyExpr.isPresent()) {
return defaultNonExpr;
}
String selectKey = null;
if (startStep
instanceof
SelectOneStep) { // select('a').values(..), select('a').valueMap(..)
selectKey =
(String) ((SelectOneStep) startStep).getScopeKeys().iterator().next();
} else if (startStep
instanceof
TraversalMapStep) { // select(keys).values(..), select(values).valueMap(..)
ProjectOp mapOp =
(ProjectOp) StepTransformFactory.TRAVERSAL_MAP_STEP.apply(startStep);
List<Pair> pairs = (List<Pair>) mapOp.getExprWithAlias().get().applyArg();
String mapExpr = (String) pairs.get(0).getValue0();
selectKey = mapExpr.substring(1);
}
String expr = propertyExpr.get().replace("@", "@" + selectKey);
return (new ExprResult()).addTagExpr(selectKey, Optional.of(expr));
} else {
return defaultNonExpr;
}
} else {
return defaultNonExpr;
}
}