@SuppressWarnings({"squid:S3776", "squid:S135"})
  @Override
  protected boolean calculateNextAggregationResult() throws Exception {

    // if needSkip is true, just get the tsBlock directly.
    while (needSkip || !calculateFromRawData()) {
      inputTsBlock = null;

      // NOTE: child.next() can only be invoked once
      if (child.hasNextWithTimer() && canCallNext) {
        inputTsBlock = child.nextWithTimer();
        canCallNext = false;
        if (needSkip) {
          break;
        }
      } else if (child.hasNextWithTimer()) {
        // if child still has next but can't be invoked now
        return false;
      } else {
        // If there are no points belong to last time window, the last time window will not
        // initialize window and aggregators. Specially for time window.
        if (windowManager.notInitializedLastTimeWindow()) {
          initWindowAndAggregators();
        }
        // If the window is not initialized, it just returns to avoid invoking
        // updateResultTsBlock()
        // but if it's skipping the last window, just break and keep skipping.
        if (needSkip || windowManager.isCurWindowInit()) {
          break;
        }
        return false;
      }
    }

    // Step into next window
    // if needSkip is true, don't need to enter next window again
    if (!needSkip) {
      windowManager.next();
    }
    // When some windows without cached endTime trying to output endTime,
    // they need to skip the points in lastWindow in advance to get endTime
    if (windowManager.needSkipInAdvance()) {
      needSkip = true;
      inputTsBlock = windowManager.skipPointsOutOfCurWindow(inputTsBlock);
      if ((inputTsBlock == null || inputTsBlock.isEmpty()) && child.hasNextWithTimer()) {
        return canCallNext;
      }
      needSkip = false;
    }

    updateResultTsBlock();
    // After updating, the data in aggregators is consumed.
    hasCachedDataInAggregator = false;

    return true;
  }
RawDataAggregationOperator is used to process raw data tsBlock input calculating using value
filter. It's possible that there is more than one tsBlock input in one time interval. And it's
also possible that one tsBlock can cover multiple time intervals too.

<p>Since raw data query with value filter is processed by FilterOperator above TimeJoinOperator,
there we can see RawDataAggregateOperator as a one-to-one(one input, ont output) operator.

<p>Return aggregation result in many time intervals once.
iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/process/RawDataAggregationOperator.java