docs: @Nullable
    public ScanQuery toScanQuery()
    {
      if (grouping != null) {
        // Scan cannot GROUP BY.
        return null;
      }
      if (limitSpec != null &&
          (limitSpec.getColumns().size() > 1
           || (limitSpec.getColumns().size() == 1 && !Iterables.getOnlyElement(limitSpec.getColumns())
                                                               .getDimension()
                                                               .equals(ColumnHolder.TIME_COLUMN_NAME)))) {
        // Scan cannot ORDER BY non-time columns.
        return null;
      }
  
      if (outputRowSignature.getRowOrder().isEmpty()) {
        // Should never do a scan query without any columns that we're interested in. This is probably a planner bug.
        throw new ISE("WTF?! Attempting to convert to Scan query without any columns?");
      }
  
      final Filtration filtration = Filtration.create(filter).optimize(sourceQuerySignature);
  
      // DefaultLimitSpec (which we use to "remember" limits) is int typed, and Integer.MAX_VALUE means "no limit".
      final long scanLimit = limitSpec == null || limitSpec.getLimit() == Integer.MAX_VALUE
                             ? 0L
                             : (long) limitSpec.getLimit();
  
      ScanQuery.Order order;
      if (limitSpec == null || limitSpec.getColumns().size() == 0) {
        order = ScanQuery.Order.NONE;
      } else if (limitSpec.getColumns().get(0).getDirection() == OrderByColumnSpec.Direction.ASCENDING) {
        order = ScanQuery.Order.ASCENDING;
      } else {
        order = ScanQuery.Order.DESCENDING;
      }
  
      return new ScanQuery(
          dataSource,
          filtration.getQuerySegmentSpec(),
          getVirtualColumns(true),
          ScanQuery.ResultFormat.RESULT_FORMAT_COMPACTED_LIST,
          0,
          scanLimit,
          order, // Will default to "none"
          filtration.getDimFilter(),
          Ordering.natural().sortedCopy(ImmutableSet.copyOf(outputRowSignature.getRowOrder())),
          false,
          ImmutableSortedMap.copyOf(plannerContext.getQueryContext())
      );
    }