visitReference method

  1. @override
void visitReference(
  1. Reference e,
  2. ReferenceResolvingContext arg
)
override

Implementation

@override
void visitReference(Reference e, ReferenceResolvingContext arg) {
  if (e.resolved != null) {
    return super.visitReference(e, arg);
  }

  final scope = e.scope;

  if (e.entityName != null) {
    // first find the referenced table or view,
    // then use the column on that table or view.
    final entityResolver = scope.resolveResultSetForReference(e.entityName!);
    final resultSet = entityResolver?.resultSet.resultSet;

    if (resultSet == null) {
      context.reportError(AnalysisError(
        type: AnalysisErrorType.referencedUnknownTable,
        message: 'Unknown table or view: ${e.entityName}',
        relevantNode: e,
      ));
    } else {
      _resolveReferenceInTable(e, resultSet, source: entityResolver);
    }
  } else if (aliasesForRowId.contains(e.columnName.toLowerCase())) {
    // special case for aliases to a rowid
    final column = _resolveRowIdAlias(e);

    if (column == null) {
      _reportUnknownColumnError(e);
    } else {
      e.resolved = column;
    }
  } else {
    // find any column with the referenced name.
    // todo special case for USING (...) in joins?
    final found = scope.resolveUnqualifiedReference(
      e.columnName,
      allowReferenceToResultColumn: arg.canReferToColumnAlias,
    );

    if (found.isEmpty) {
      _reportUnknownColumnError(e);
    } else {
      if (found.length > 1) {
        final description =
            found.map((c) => c.humanReadableDescription()).join(', ');

        context.reportError(AnalysisError(
          type: AnalysisErrorType.ambiguousReference,
          relevantNode: e,
          message: 'Could refer to any of: $description',
        ));
      }

      e.resolved = found.first;
    }
  }

  visitChildren(e, arg);
}