{
Iterable<List<Object>> data = getData(maxWaitTime);
// get the query info before returning
// force update if query manager is closed
QueryInfo queryInfo = queryManager.getQueryInfo(queryId);
// if we have received all of the output data and the query is not marked as done, wait for the query to finish
if (exchangeClient.isClosed() && !queryInfo.getState().isDone()) {
queryManager.waitForStateChange(queryId, queryInfo.getState(), maxWaitTime);
queryInfo = queryManager.getQueryInfo(queryId);
}
// close exchange client if the query has failed
if (queryInfo.getState().isDone()) {
if (queryInfo.getState() != QueryState.FINISHED) {
exchangeClient.close();
}
else if (queryInfo.getOutputStage() == null) {
// For simple executions (e.g. drop table), there will never be an output stage,
// so close the exchange as soon as the query is done.
exchangeClient.close();
// this is a hack to suppress the warn message in the client saying that there are no columns.
// The reason for this is that the current API definition assumes that everything is a query,
// so statements without results produce an error in the client otherwise.
//
// TODO: add support to the API for non-query statements.
columns = ImmutableList.of(new Column("result", "varchar"));
data = ImmutableSet.<List<Object>>of(ImmutableList.<Object>of("true"));
}
}
// only return a next if the query is not done or there is more data to send (due to buffering)
URI nextResultsUri = null;
if ((!queryInfo.getState().isDone()) || (!exchangeClient.isClosed())) {
nextResultsUri = createNextResultsUri(uriInfo);
}
// first time through, self is null
QueryResults queryResults = new QueryResults(
queryId.toString(),
uriInfo.getRequestUriBuilder().replaceQuery("").replacePath(queryInfo.getSelf().getPath()).build(),
findCancelableLeafStage(queryInfo),
nextResultsUri,
columns,
data,
toStatementStats(queryInfo),