docs: public void cancelCopy(CopyOperationImpl op) throws SQLException {
      if (!hasLock(op)) {
        throw new PSQLException(GT.tr("Tried to cancel an inactive copy operation"),
            PSQLState.OBJECT_NOT_IN_STATE);
      }
  
      SQLException error = null;
      int errors = 0;
  
      try {
        if (op instanceof CopyIn) {
          synchronized (this) {
            LOGGER.log(Level.FINEST, "FE => CopyFail");
            final byte[] msg = Utils.encodeUTF8("Copy cancel requested");
            pgStream.sendChar('f'); // CopyFail
            pgStream.sendInteger4(5 + msg.length);
            pgStream.send(msg);
            pgStream.sendChar(0);
            pgStream.flush();
            do {
              try {
                processCopyResults(op, true); // discard rest of input
              } catch (SQLException se) { // expected error response to failing copy
                errors++;
                if (error != null) {
                  SQLException e = se;
                  SQLException next;
                  while ((next = e.getNextException()) != null) {
                    e = next;
                  }
                  e.setNextException(error);
                }
                error = se;
              }
            } while (hasLock(op));
          }
        } else if (op instanceof CopyOut) {
          sendQueryCancel();
        }
  
      } catch (IOException ioe) {
        throw new PSQLException(GT.tr("Database connection failed when canceling copy operation"),
            PSQLState.CONNECTION_FAILURE, ioe);
      } finally {
        // Need to ensure the lock isn't held anymore, or else
        // future operations, rather than failing due to the
        // broken connection, will simply hang waiting for this
        // lock.
        synchronized (this) {
          if (hasLock(op)) {
            unlock(op);
          }
        }
      }
  
      if (op instanceof CopyIn) {
        if (errors < 1) {
          throw new PSQLException(GT.tr("Missing expected error response to copy cancel request"),
              PSQLState.COMMUNICATION_ERROR);
        } else if (errors > 1) {
          throw new PSQLException(
              GT.tr("Got {0} error responses to single copy cancel request", String.valueOf(errors)),
              PSQLState.COMMUNICATION_ERROR, error);
        }
      }
    }