presto-main/src/main/java/io/prestosql/sql/analyzer/Scope.java/Scope/resolveAsteriskedIdentifierChainBasis
class Scope:    public Optional<AsteriskedIdentifierChainBasis> resolveAsteriskedIdentifierChainBasis(QualifiedName identifierChain, AllColumns selectItem)
    {
        int length = identifierChain.getParts().size();

        Optional<Scope> scopeForTableReference = Optional.empty();
        Optional<Scope> scopeForFieldReference = Optional.empty();

        if (length <= 3) {
            scopeForTableReference = findLocally(scope -> scope.getRelationType()
                    .getAllFields().stream()
                    .anyMatch(field -> field.matchesPrefix(Optional.of(identifierChain))));
        }

        if (length >= 2) {
            scopeForFieldReference = findLocally(scope -> scope.getRelationType()
                    .getAllFields().stream()
                    .anyMatch(field -> field.matchesPrefix(Optional.of(QualifiedName.of(identifierChain.getParts().get(0))))
                            && field.getName().isPresent()
                            && field.getName().get().equals(identifierChain.getParts().get(1))
                            && field.getType() instanceof RowType));
        }

        if (scopeForTableReference.isPresent() && scopeForFieldReference.isPresent()) {
            throw semanticException(AMBIGUOUS_NAME, selectItem, "Reference '%s' is ambiguous", identifierChain);
        }

        if (scopeForTableReference.isPresent()) {
            return Optional.of(new AsteriskedIdentifierChainBasis(TABLE, scopeForTableReference, Optional.of(scopeForTableReference.get().getRelationType())));
        }

        if (scopeForFieldReference.isPresent()) {
            return Optional.of(new AsteriskedIdentifierChainBasis(FIELD, Optional.empty(), Optional.empty()));
        }

        return getOuterQueryParent()
                .map(parent -> parent.resolveAsteriskedIdentifierChainBasis(identifierChain, selectItem))
                .orElse(Optional.empty());
    }