public void write()

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


    public void write(DataOutput out) throws IOException {
        int numCol = colType.length;
        boolean[] nullBits = new boolean[numCol];
        int[] colLength = new int[numCol];
        byte[] enumType = new byte[numCol];
        int[] padLength = new int[numCol];
        byte[] padbytes = new byte[8];

        /*
         * Compute the total payload and header length
         * header = total length (4 byte), Version (2 byte), Error (1 byte), #col (2 byte)
         * col type array = #col * 1 byte
         * null bit array = ceil(#col/8)
         */
        int datlen = 4 + 2 + 1 + 2;
        datlen += numCol;
        datlen += getNullByteArraySize(numCol);

        for (int i = 0; i < numCol; i++) {
            /* Get the enum type */
            DBType coldbtype;
            switch (DataType.get(colType[i])) {
                case BIGINT:
                    coldbtype = DBType.BIGINT;
                    break;
                case BOOLEAN:
                    coldbtype = DBType.BOOLEAN;
                    break;
                case FLOAT8:
                    coldbtype = DBType.FLOAT8;
                    break;
                case INTEGER:
                    coldbtype = DBType.INTEGER;
                    break;
                case REAL:
                    coldbtype = DBType.REAL;
                    break;
                case SMALLINT:
                    coldbtype = DBType.SMALLINT;
                    break;
                case BYTEA:
                    coldbtype = DBType.BYTEA;
                    break;
                default:
                    coldbtype = DBType.TEXT;
            }
            enumType[i] = (byte) (coldbtype.ordinal());

            /* Get the actual value, and set the null bit */
            if (colValue[i] == null) {
                nullBits[i] = true;
                colLength[i] = 0;
            } else {
                nullBits[i] = false;

                /*
                 * For fixed length type, we get the fixed length.
                 * For var len binary format, the length is in the col value.
                 * For text format, we must convert encoding first.
                 */
                if (!coldbtype.isVarLength()) {
                    colLength[i] = coldbtype.getTypeLength();
                } else if (!isTextForm(colType[i])) {
                    colLength[i] = ((byte[]) colValue[i]).length;
                } else {
                    colLength[i] = ((String) colValue[i]).getBytes(databaseEncoding).length;
                }

                /* calculate and add the type alignment padding */
                padLength[i] = roundUpAlignment(datlen, coldbtype.getAlignment()) - datlen;
                datlen += padLength[i];

                /* for variable length type, we add a 4 byte length header */
                if (coldbtype.isVarLength()) {
                    datlen += 4;
                }
            }
            datlen += colLength[i];
        }

        /*
         * Add the final alignment padding for the next record
         */
        int endpadding = roundUpAlignment(datlen, 8) - datlen;
        datlen += endpadding;

        /* Construct the packet header */
        out.writeInt(datlen);
        out.writeShort(VERSION);
        out.writeByte(errorFlag);
        out.writeShort(numCol);

        /* Write col type */
        for (int i = 0; i < numCol; i++) {
            out.writeByte(enumType[i]);
        }

        /* Nullness */
        byte[] nullBytes = boolArrayToByteArray(nullBits);
        out.write(nullBytes);

        /* Column Value */
        for (int i = 0; i < numCol; i++) {
            if (!nullBits[i]) {
                /* Pad the alignment byte first */
                if (padLength[i] > 0) {
                    out.write(padbytes, 0, padLength[i]);
                }

                /* Now, write the actual column value */
                switch (DataType.get(colType[i])) {
                    case BIGINT:
                        out.writeLong(((Long) colValue[i]));
                        break;
                    case BOOLEAN:
                        out.writeBoolean(((Boolean) colValue[i]));
                        break;
                    case FLOAT8:
                        out.writeDouble(((Double) colValue[i]));
                        break;
                    case INTEGER:
                        out.writeInt(((Integer) colValue[i]));
                        break;
                    case REAL:
                        out.writeFloat(((Float) colValue[i]));
                        break;
                    case SMALLINT:
                        out.writeShort(((Short) colValue[i]));
                        break;

                    /* For BYTEA format, add 4byte length header at the beginning  */
                    case BYTEA:
                        out.writeInt(colLength[i]);
                        out.write((byte[]) colValue[i]);
                        break;

                    /* For text format, add 4byte length header. string is already '\0' terminated */
                    default: {
                        byte[] data = ((String) colValue[i]).getBytes(databaseEncoding);
                        out.writeInt(colLength[i]);
                        out.write(data);
                        break;
                    }
                }
            }
        }

        /* End padding */
        out.write(padbytes, 0, endpadding);
    }