public void readFields()

in server/pxf-api/src/main/java/org/greenplum/pxf/api/io/GPDBWritable.java [176:332]


    public void readFields(DataInput in) throws IOException {
        /*
         * extract pkt len.
         *
         * GPSQL-1107:
         * The DataInput might already be empty (EOF), but we can't check it beforehand.
         * If that's the case, pktlen is updated to -1, to mark that the object is still empty.
         * (can be checked with isEmpty()).
         */
        pktlen = readPktLen(in);
        if (isEmpty()) {
            return;
        }

        /* extract the version and col cnt */
        int version = in.readShort();
        int curOffset = 4 + 2;
        int colCnt;

        /* !!! Check VERSION !!! */
        if (version != GPDBWritable.VERSION && version != GPDBWritable.PREV_VERSION) {
            throw new IOException("Current GPDBWritable version(" +
                    GPDBWritable.VERSION + ") does not match input version(" +
                    version + ")");
        }

        if (version == GPDBWritable.VERSION) {
            errorFlag = in.readByte();
            curOffset += 1;
        }

        colCnt = in.readShort();
        curOffset += 2;

        /* Extract Column Type */
        colType = new int[colCnt];
        DBType[] coldbtype = new DBType[colCnt];
        for (int i = 0; i < colCnt; i++) {
            int enumType = (in.readByte());
            curOffset += 1;
            if (enumType == DBType.BIGINT.ordinal()) {
                colType[i] = DataType.BIGINT.getOID();
                coldbtype[i] = DBType.BIGINT;
            } else if (enumType == DBType.BOOLEAN.ordinal()) {
                colType[i] = DataType.BOOLEAN.getOID();
                coldbtype[i] = DBType.BOOLEAN;
            } else if (enumType == DBType.FLOAT8.ordinal()) {
                colType[i] = DataType.FLOAT8.getOID();
                coldbtype[i] = DBType.FLOAT8;
            } else if (enumType == DBType.INTEGER.ordinal()) {
                colType[i] = DataType.INTEGER.getOID();
                coldbtype[i] = DBType.INTEGER;
            } else if (enumType == DBType.REAL.ordinal()) {
                colType[i] = DataType.REAL.getOID();
                coldbtype[i] = DBType.REAL;
            } else if (enumType == DBType.SMALLINT.ordinal()) {
                colType[i] = DataType.SMALLINT.getOID();
                coldbtype[i] = DBType.SMALLINT;
            } else if (enumType == DBType.BYTEA.ordinal()) {
                colType[i] = DataType.BYTEA.getOID();
                coldbtype[i] = DBType.BYTEA;
            } else if (enumType == DBType.TEXT.ordinal()) {
                colType[i] = DataType.TEXT.getOID();
                coldbtype[i] = DBType.TEXT;
            } else {
                throw new IOException("Unknown GPDBWritable.DBType ordinal value");
            }
        }

        /* Extract null bit array */
        byte[] nullbytes = new byte[getNullByteArraySize(colCnt)];
        in.readFully(nullbytes);
        curOffset += nullbytes.length;
        boolean[] colIsNull = byteArrayToBooleanArray(nullbytes, colCnt);

        /* extract column value */
        colValue = new Object[colCnt];
        for (int i = 0; i < colCnt; i++) {
            if (!colIsNull[i]) {
                /* Skip the alignment padding */
                int skipbytes = roundUpAlignment(curOffset, coldbtype[i].getAlignment()) - curOffset;
                for (int j = 0; j < skipbytes; j++) {
                    in.readByte();
                }
                curOffset += skipbytes;

                /* For fixed length type, increment the offset according to type type length here.
                 * For var length type (BYTEA, TEXT), we'll read 4 byte length header and the
                 * actual payload.
                 */
                int varcollen = -1;
                if (coldbtype[i].isVarLength()) {
                    varcollen = in.readInt();
                    curOffset += 4 + varcollen;
                } else {
                    curOffset += coldbtype[i].getTypeLength();
                }

                switch (DataType.get(colType[i])) {
                    case BIGINT: {
                        colValue[i] = in.readLong();
                        break;
                    }
                    case BOOLEAN: {
                        colValue[i] = in.readBoolean();
                        break;
                    }
                    case FLOAT8: {
                        colValue[i] = in.readDouble();
                        break;
                    }
                    case INTEGER: {
                        colValue[i] = in.readInt();
                        break;
                    }
                    case REAL: {
                        colValue[i] = in.readFloat();
                        break;
                    }
                    case SMALLINT: {
                        colValue[i] = in.readShort();
                        break;
                    }

                    /* For BYTEA column, it has a 4 byte var length header. */
                    case BYTEA: {
                        colValue[i] = new byte[varcollen];
                        in.readFully((byte[]) colValue[i]);
                        break;
                    }
                    /* For text formatted column, it has a 4 byte var length header
                     * and it's always null terminated string.
                     * So, we can remove the last "\0" when constructing the string.
                     */
                    case TEXT: {
                        byte[] data = new byte[varcollen];
                        in.readFully(data, 0, varcollen);
                        colValue[i] = new String(data, 0, varcollen - 1, databaseEncoding);
                        break;
                    }

                    default:
                        throw new IOException("Unknown GPDBWritable ColType");
                }
            }
        }

        /* Skip the ending alignment padding */
        int skipbytes = roundUpAlignment(curOffset, 8) - curOffset;
        for (int j = 0; j < skipbytes; j++) {
            in.readByte();
        }

        if (errorFlag != 0) {
            throw new IOException("Received error value " + errorFlag + " from format");
        }
    }