in sparql-gremlin/src/main/java/org/apache/tinkerpop/gremlin/sparql/SparqlToGremlinCompiler.java [94:205]
private GraphTraversal<Vertex, ?> compile(final Query query) {
final Op op = Algebra.compile(query);
OpWalker.walk(op, new GremlinOpVisitor());
int traversalIndex = 0;
final int numberOfTraversal = traversalList.size();
final int numberOfOptionalTraversal = optionalTraversals.size();
final Traversal[] arrayOfAllTraversals = (numberOfOptionalTraversal > 0) ?
new Traversal[numberOfTraversal - numberOfOptionalTraversal + 1] :
new Traversal[numberOfTraversal - numberOfOptionalTraversal];
final Traversal[] arrayOfOptionalTraversals = new Traversal[numberOfOptionalTraversal];
for (Traversal tempTrav : traversalList) {
arrayOfAllTraversals[traversalIndex++] = tempTrav;
}
traversalIndex = 0;
for (Traversal tempTrav : optionalTraversals)
arrayOfOptionalTraversals[traversalIndex++] = tempTrav;
// creates a map of ordering keys and their ordering direction
final Map<String, Order> orderingIndex = createOrderIndexFromQuery(query);
if (traversalList.size() > 0)
traversal = traversal.match(arrayOfAllTraversals);
if (optionalTraversals.size() > 0) {
traversal = traversal.coalesce(__.match(arrayOfOptionalTraversals), (Traversal) __.constant("N/A"));
for (int i = 0; i < optionalVariable.size(); i++) {
traversal = traversal.as(optionalVariable.get(i).substring(1));
}
}
final List<String> vars = query.getResultVars();
if (!query.isQueryResultStar() && !query.hasGroupBy()) {
final String[] all = new String[vars.size()];
vars.toArray(all);
if (query.isDistinct()) {
traversal = traversal.dedup(all);
}
// apply ordering from ORDER BY
orderingIndex.forEach((k, v) -> traversal = traversal.order().by(__.select(k), v));
// the result sizes have special handling to get the right signatures of select() called.
switch (all.length) {
case 0:
throw new IllegalStateException();
case 1:
traversal = traversal.select(all[0]);
break;
case 2:
traversal = traversal.select(all[0], all[1]);
break;
default:
final String[] others = Arrays.copyOfRange(all, 2, vars.size());
traversal = traversal.select(all[0], all[1], others);
break;
}
}
if (query.hasGroupBy()) {
final VarExprList lstExpr = query.getGroupBy();
String grpVar = "";
for (Var expr : lstExpr.getVars()) {
grpVar = expr.getName();
}
if (!grpVar.isEmpty())
traversal = traversal.select(grpVar);
if (query.hasAggregators()) {
final List<ExprAggregator> exprAgg = query.getAggregators();
for (ExprAggregator expr : exprAgg) {
if (expr.getAggregator().getName().contains("COUNT")) {
if (!query.toString().contains("GROUP")) {
if (expr.getAggregator().toString().contains("DISTINCT"))
traversal = traversal.dedup(expr.getAggregator().getExprList().get(0).toString().substring(1));
else
traversal = traversal.select(expr.getAggregator().getExprList().get(0).toString().substring(1));
traversal = traversal.count();
} else {
traversal = traversal.groupCount();
}
}
if (expr.getAggregator().getName().contains("MAX")) {
traversal = traversal.max();
}
}
} else {
traversal = traversal.group();
}
}
if (query.hasOrderBy() && query.hasGroupBy())
orderingIndex.forEach((k, v) -> traversal = traversal.order().by(__.select(k), v));
if (query.hasLimit()) {
long limit = query.getLimit(), offset = 0;
if (query.hasOffset())
offset = query.getOffset();
if (query.hasGroupBy() && query.hasOrderBy())
traversal = traversal.range(Scope.local, offset, offset + limit);
else
traversal = traversal.range(offset, offset + limit);
}
return traversal;
}