class RowCountUndeterminedClientResult extends ClientResult {

    // 不能在这初始化为false，在super的构造函数中会调用fetchRows有可能把isEnd设为true了，
    // 如果初始化为false，相当于在调用完super(...)后再执行isEnd = false，这时前面的值就被覆盖了。
    private boolean isEnd;

    public RowCountUndeterminedClientResult(ClientSession session, TransferInputStream in, int resultId,
            int columnCount, int fetchSize) throws IOException {
        super(session, in, resultId, columnCount, -1, fetchSize);
    }

    @Override
    public boolean next() {
        if (isEnd && rowId - rowOffset >= result.size() - 1) {
            currentRow = null;
            return false;
        }

        rowId++;
        if (!isEnd) {
            remapIfOld();
            if (rowId - rowOffset >= result.size()) {
                fetchRows(true);
                if (isEnd && result.isEmpty()) {
                    currentRow = null;
                    return false;
                }
            }
        }
        currentRow = result.get(rowId - rowOffset);
        return true;

    }

    @Override
    public int getRowCount() {
        return Integer.MAX_VALUE; // 不能返回-1，JdbcResultSet那边会抛异常
    }

    @Override
    protected void fetchRows(boolean sendFetch) {<FILL_FUNCTION_BODY>}
}

        session.checkClosed();
        try {
            rowOffset += result.size();
            result.clear();
            if (sendFetch) {
                sendFetch(fetchSize);
            }
            for (int r = 0; r < fetchSize; r++) {
                boolean row = in.readBoolean();
                if (!row) {
                    isEnd = true;
                    break;
                }
                int len = columns.length;
                Value[] values = new Value[len];
                for (int i = 0; i < len; i++) {
                    Value v = in.readValue();
                    values[i] = v;
                }
                result.add(values);
            }

            if (isEnd)
                sendClose();
        } catch (IOException e) {
            throw DbException.convertIOException(e, null);
        }
    
<methods>public void <init>(com.lealone.client.session.ClientSession, com.lealone.net.TransferInputStream, int, int, int, int) throws java.io.IOException,public void close() ,public com.lealone.db.value.Value[] currentRow() ,public java.lang.String getAlias(int) ,public java.lang.String getColumnName(int) ,public long getColumnPrecision(int) ,public int getColumnScale(int) ,public int getColumnType(int) ,public int getCurrentRowCount() ,public int getDisplaySize(int) ,public int getFetchSize() ,public int getNullable(int) ,public int getRowCount() ,public int getRowId() ,public java.lang.String getSchemaName(int) ,public java.lang.String getTableName(int) ,public int getVisibleColumnCount() ,public boolean isAutoIncrement(int) ,public boolean needToClose() ,public abstract boolean next() ,public void reset() ,public void setFetchSize(int) ,public java.lang.String toString() <variables>protected final non-sealed com.lealone.client.result.ClientResultColumn[] columns,protected com.lealone.db.value.Value[] currentRow,protected int fetchSize,protected com.lealone.net.TransferInputStream in,protected ArrayList<com.lealone.db.value.Value[]> result,protected int resultId,protected final non-sealed int rowCount,protected int rowId,protected int rowOffset,protected com.lealone.client.session.ClientSession session