docs: public ServerPrepareResult read(PacketInputStream reader, boolean eofDeprecated)
        throws IOException, SQLException {
      Buffer buffer = reader.getPacket(true);
      byte firstByte = buffer.getByteAt(buffer.position);
  
      if (firstByte == ERROR) {
        throw buildErrorException(buffer);
      }
  
      if (firstByte == OK) {
  
        /* Prepared Statement OK */
        buffer.readByte(); /* skip field count */
        final int statementId = buffer.readInt();
        final int numColumns = buffer.readShort() & 0xffff;
        final int numParams = buffer.readShort() & 0xffff;
  
        ColumnInformation[] params = new ColumnInformation[numParams];
        ColumnInformation[] columns = new ColumnInformation[numColumns];
  
        if (numParams > 0) {
          for (int i = 0; i < numParams; i++) {
            params[i] = new ColumnInformation(reader.getPacket(false));
          }
  
          if (numColumns > 0) {
            if (!eofDeprecated) {
              protocol.skipEofPacket();
            }
            for (int i = 0; i < numColumns; i++) {
              columns[i] = new ColumnInformation(reader.getPacket(false));
            }
          }
          if (!eofDeprecated) {
            protocol.readEofPacket();
          }
        } else {
          if (numColumns > 0) {
            for (int i = 0; i < numColumns; i++) {
              columns[i] = new ColumnInformation(reader.getPacket(false));
            }
            if (!eofDeprecated) {
              protocol.readEofPacket();
            }
          } else {
            //read warning only if no param / columns, because will be overwritten by EOF warning data
            buffer.readByte(); // reserved
            protocol.setHasWarnings(buffer.readShort() > 0);
          }
        }
  
        ServerPrepareResult serverPrepareResult = new ServerPrepareResult(sql, statementId, columns,
            params, protocol);
        if (protocol.getOptions().cachePrepStmts
            && protocol.getOptions().useServerPrepStmts
            && sql != null
            && sql.length() < protocol.getOptions().prepStmtCacheSqlLimit) {
          String key = protocol.getDatabase() + "-" + sql;
          ServerPrepareResult cachedServerPrepareResult = protocol
              .addPrepareInCache(key, serverPrepareResult);
          return cachedServerPrepareResult != null ? cachedServerPrepareResult : serverPrepareResult;
        }
        return serverPrepareResult;
  
      } else {
        throw new SQLException("Unexpected packet returned by server, first byte " + firstByte);
      }
    }