@SuppressWarnings("squid:S2095") // Suppress wrapper not closed warning
  @Override
  public SessionDataSetWrapper executeQueryStatement(String sql)
      throws IoTDBConnectionException, StatementExecutionException {
    for (int i = 0; i < RETRY; i++) {
      ISession session = getSession();
      try {
        SessionDataSet resp = session.executeQueryStatement(sql);
        SessionDataSetWrapper wrapper = new SessionDataSetWrapper(resp, session, this);
        occupy(session);
        return wrapper;
      } catch (IoTDBConnectionException e) {
        // TException means the connection is broken, remove it and get a new one.
        LOGGER.warn("executeQueryStatement failed", e);
        cleanSessionAndMayThrowConnectionException(session, i, e);
      } catch (StatementExecutionException | RuntimeException e) {
        putBack(session);
        throw e;
      } catch (Throwable e) {
        LOGGER.error("unexpected error in executeQueryStatement", e);
        putBack(session);
        throw new RuntimeException(e);
      }
    }
    // never go here
    return null;
  }
execure query sql users must call closeResultSet(SessionDataSetWrapper) if they do not use the
SessionDataSet any more. users do not need to call sessionDataSet.closeOpeationHandler() any
more.

@param sql query statement
@return result set Notice that you must get the result instance. Otherwise a data leakage will
    happen
iotdb-client/session/src/main/java/org/apache/iotdb/session/pool/SessionPool.java