code: public List<Query> shard(SortedSet<ByteString> splitPoints) {
      Preconditions.checkState(builder.getRowsLimit() == 0, "Can't shard a query with a row limit");
  
      List<RowSet> shardedRowSets = RowSetUtil.shard(builder.getRows(), splitPoints);
      List<Query> shards = Lists.newArrayListWithCapacity(shardedRowSets.size());
  
      for (RowSet rowSet : shardedRowSets) {
        Query queryShard = new Query(tableId);
        queryShard.builder.mergeFrom(this.builder.build());
        queryShard.builder.setRows(rowSet);
        shards.add(queryShard);
      }
  
      return shards;
    }
docs: Split this query into multiple queries that logically combine into this query. This is intended
  to be used by map reduce style frameworks like Beam to split a query across multiple workers.
  
  <p>Expected Usage:
  
  <pre>{@code
  List<ByteString> splitPoints = ...;
  List<Query> queryShards = myQuery.shard(splitPoints);
  List<ApiFuture<List<Row>>> futures = new ArrayList();
  for (Query subQuery : queryShards) {
  futures.add(dataClient.readRowsCallable().all().futureCall(subQuery));
  }
  List<List<Row>> results = ApiFutures.allAsList(futures).get();
  }</pre>