visitInExpression method

  1. @override
void visitInExpression(
  1. InExpression e,
  2. void arg
)
override

Implementation

@override
void visitInExpression(InExpression e, void arg) {
  final expectedColumns = switch (e.left) {
    Tuple(:var expressions) => expressions.length,
    _ => 1,
  };

  switch (e.inside) {
    case Tuple tuple:
      for (final element in tuple.expressions) {
        final actualColumns = switch (element) {
          Tuple(:var expressions) => expressions.length,
          _ => 1,
        };

        if (expectedColumns != actualColumns) {
          context.reportError(AnalysisError(
            type: AnalysisErrorType.other,
            message: 'Expected $expectedColumns columns in this entry, got '
                '$actualColumns',
            relevantNode: element,
          ));
        }
      }
    case SubQuery subquery:
      final columns = subquery.select.resolvedColumns;
      if (columns != null && columns.length != expectedColumns) {
        context.reportError(AnalysisError(
          type: AnalysisErrorType.other,
          message: 'The subquery must return $expectedColumns columns, '
              'it returns ${columns.length}',
          relevantNode: subquery,
        ));
      }
    case TableOrSubquery table:
      final columns =
          table.availableResultSet?.resultSet.resultSet?.resolvedColumns;
      if (columns != null && columns.length != expectedColumns) {
        context.reportError(AnalysisError(
          type: AnalysisErrorType.other,
          message: 'To be used in this `IN` expression, this table must '
              'have $expectedColumns columns (it has ${columns.length}).',
          relevantNode: table,
        ));
      }
  }

  visitChildren(e, arg);
}