@Override
  public void performAction(Connection connection, OperationObserver observer)
      throws SQLException, Exception {

    ProcedureTranslator transl = createTranslator(connection);
    CallableStatement statement = (CallableStatement) transl.createStatement();

    try {
      // stored procedure may contain a mixture of update counts and result sets,
      // and out parameters. Read out parameters first, then
      // iterate until we exhaust all results
      boolean hasResultSet = statement.execute();

      // local observer to cache results and provide them to the external observer
      // in the order consistent with other adapters.

      Observer localObserver = new Observer(observer);

      // read query, using local observer

      while (true) {
        if (hasResultSet) {
          ResultSet rs = statement.getResultSet();
          try {
            RowDescriptor descriptor = describeResultSet(rs, processedResultSets++);
            readResultSet(rs, descriptor, query, localObserver);
          } finally {
            try {
              rs.close();
            } catch (SQLException ex) {
            }
          }
        } else {
          int updateCount = statement.getUpdateCount();
          if (updateCount == -1) {
            break;
          }
          dataNode.getJdbcEventLogger().logUpdateCount(updateCount);
          localObserver.nextCount(query, updateCount);
        }

        hasResultSet = statement.getMoreResults();
      }

      // read out parameters to the main observer ... AFTER the main result set
      // TODO: I hope SQLServer does not support ResultSets as OUT parameters,
      // otherwise
      // the order of custom result descriptors will be messed up
      readProcedureOutParameters(statement, observer);

      // add results back to main observer
      localObserver.flushResults(query);
    } finally {
      try {
        statement.close();
      } catch (SQLException ex) {

      }
    }
  }