private Optional<ResolvedField> resolveField(Expression node, QualifiedName name, boolean local) { List<Field> matches = relation.resolveFields(name); if (matches.size() > 1) { throwAmbiguousAttributeException(node, name); } if (matches.isEmpty()) { if (isColumnReference(name, relation)) { return Optional.empty(); } Scope boundary = this; while (!boundary.queryBoundary) { if (boundary.parent.isPresent()) { boundary = boundary.parent.get(); } else { return Optional.empty(); } } if (boundary.parent.isPresent()) { // jump over the query boundary return boundary.parent.get().resolveField(node, name, false); } return Optional.empty(); } else { return Optional.of(asResolvedField(getOnlyElement(matches), local)); } }
private static boolean isColumnReference(QualifiedName name, RelationType relation) { while (name.getPrefix().isPresent()) { name = name.getPrefix().get(); if (!relation.resolveFields(name).isEmpty()) { return true; } } return false; }