private ListenableFuture<?> tryGetNext() {
    if (schemaReader == null) {
      schemaReader = createSchemaReader();
    }
    while (true) {
      try {
        final ListenableFuture<?> readerBlocked = schemaReader.isBlocked();
        if (!readerBlocked.isDone()) {
          final SettableFuture<?> settableFuture = SettableFuture.create();
          readerBlocked.addListener(
              () -> {
                next = tsBlockBuilder.build();
                tsBlockBuilder.reset();
                settableFuture.set(null);
              },
              directExecutor());
          return settableFuture;
        } else if (schemaReader.hasNext() && (limit < 0 || count < offset + limit)) {
          final T element = schemaReader.next();
          if (++count > offset) {
            setColumns(element, tsBlockBuilder);
            if (tsBlockBuilder.getRetainedSizeInBytes() >= MAX_SIZE) {
              next = tsBlockBuilder.build();
              tsBlockBuilder.reset();
              return NOT_BLOCKED;
            }
          }
        } else {
          if (tsBlockBuilder.isEmpty()) {
            next = null;
            isFinished = true;
          } else {
            next = tsBlockBuilder.build();
          }
          tsBlockBuilder.reset();
          return NOT_BLOCKED;
        }
      } catch (final Exception e) {
        throw new SchemaExecutionException(e);
      }
    }
  }
Try to get next {@link TsBlock}. If the next is not ready, return a future. After success,
{@link SchemaQueryScanOperator#next} will be set.
iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/schema/SchemaQueryScanOperator.java