in core/src/main/java/com/jetbrains/youtrackdb/internal/core/sql/functions/graph/SQLFunctionShortestPath.java [77:231]
public List<RID> execute(
Object iThis,
final Result iCurrentRecord,
final Object iCurrentResult,
final Object[] iParams,
final CommandContext iContext) {
var session = iContext.getDatabaseSession();
var record =
iCurrentRecord != null && iCurrentRecord.isEntity() ? iCurrentRecord.asEntity() : null;
final var ctx = new ShortestPathContext();
var source = iParams[0];
source = getSingleItem(source);
if (source == null) {
throw new IllegalArgumentException("Only one sourceVertex is allowed");
}
source = SQLHelper.getValue(source, record, iContext);
if (source instanceof Identifiable) {
var transaction = session.getActiveTransaction();
Entity elem = transaction.load(((Identifiable) source));
if (!elem.isVertex()) {
throw new IllegalArgumentException("The sourceVertex must be a vertex record");
}
ctx.sourceVertex = elem.asVertex();
} else {
throw new IllegalArgumentException("The sourceVertex must be a vertex record");
}
var dest = iParams[1];
dest = getSingleItem(dest);
if (dest == null) {
throw new IllegalArgumentException("Only one destinationVertex is allowed");
}
dest = SQLHelper.getValue(dest, record, iContext);
if (dest instanceof Identifiable) {
var transaction = session.getActiveTransaction();
Entity elem = transaction.load(((Identifiable) dest));
if (elem == null || !elem.isVertex()) {
throw new IllegalArgumentException("The destinationVertex must be a vertex record");
}
ctx.destinationVertex = elem.asVertex();
} else {
throw new IllegalArgumentException("The destinationVertex must be a vertex record");
}
if (ctx.sourceVertex.equals(ctx.destinationVertex)) {
final List<RID> result = new ArrayList<RID>(1);
result.add(ctx.destinationVertex.getIdentity());
return result;
}
if (iParams.length > 2 && iParams[2] != null) {
ctx.directionLeft = Direction.valueOf(iParams[2].toString().toUpperCase(Locale.ENGLISH));
}
if (ctx.directionLeft == Direction.OUT) {
ctx.directionRight = Direction.IN;
} else if (ctx.directionLeft == Direction.IN) {
ctx.directionRight = Direction.OUT;
}
ctx.edgeType = null;
if (iParams.length > 3) {
var param = iParams[3];
if (param instanceof Collection
&& ((Collection) param).stream().allMatch(x -> x instanceof String)) {
ctx.edgeType = ((Collection<String>) param).stream().collect(Collectors.joining(","));
ctx.edgeTypeParam = (String[]) ((Collection) param).toArray(new String[0]);
} else {
ctx.edgeType = param == null ? null : "" + param;
ctx.edgeTypeParam = new String[]{ctx.edgeType};
}
} else {
ctx.edgeTypeParam = new String[]{null};
}
if (iParams.length > 4) {
bindAdditionalParams(session, iParams[4], ctx);
}
ctx.queueLeft.add(ctx.sourceVertex);
ctx.leftVisited.add(ctx.sourceVertex.getIdentity());
ctx.queueRight.add(ctx.destinationVertex);
ctx.rightVisited.add(ctx.destinationVertex.getIdentity());
var depth = 1;
while (true) {
if (ctx.maxDepth != null && ctx.maxDepth <= depth) {
break;
}
if (ctx.queueLeft.isEmpty() || ctx.queueRight.isEmpty()) {
break;
}
if (Thread.interrupted()) {
throw new CommandExecutionException(session,
"The shortestPath() function has been interrupted");
}
if (!CommandExecutorAbstract.checkInterruption(iContext)) {
break;
}
List<RID> neighborIdentity;
if (ctx.queueLeft.size() <= ctx.queueRight.size()) {
// START EVALUATING FROM LEFT
neighborIdentity = walkLeft(ctx);
if (neighborIdentity != null) {
return neighborIdentity;
}
depth++;
if (ctx.maxDepth != null && ctx.maxDepth <= depth) {
break;
}
if (ctx.queueLeft.isEmpty()) {
break;
}
neighborIdentity = walkRight(ctx);
if (neighborIdentity != null) {
return neighborIdentity;
}
} else {
// START EVALUATING FROM RIGHT
neighborIdentity = walkRight(ctx);
if (neighborIdentity != null) {
return neighborIdentity;
}
depth++;
if (ctx.maxDepth != null && ctx.maxDepth <= depth) {
break;
}
if (ctx.queueRight.isEmpty()) {
break;
}
neighborIdentity = walkLeft(ctx);
if (neighborIdentity != null) {
return neighborIdentity;
}
}
depth++;
}
return new ArrayList<RID>();
}