Search in sources :

Example 1 with FormatIdInputStream

use of org.apache.derby.iapi.services.io.FormatIdInputStream in project derby by apache.

the class SQLChar method getString.

/**
 * If possible, use getCharArray() if you don't really
 * need a string.  getString() will cause an extra
 * char array to be allocated when it calls the the String()
 * constructor (the first time through), so may be
 * cheaper to use getCharArray().
 *
 * @exception StandardException     Thrown on error
 */
public String getString() throws StandardException {
    if (value == null) {
        int len = rawLength;
        if (len != -1) {
            // data is stored in the char[] array
            value = new String(rawData, 0, len);
            if (len > RETURN_SPACE_THRESHOLD) {
                // free up this char[] array to reduce memory usage
                rawData = null;
                rawLength = -1;
                cKey = null;
            }
        } else if (_clobValue != null) {
            try {
                value = _clobValue.getSubString(1L, getClobLength());
                _clobValue = null;
            } catch (SQLException se) {
                throw StandardException.plainWrapException(se);
            }
        } else if (stream != null) {
            // data stored as a stream
            try {
                if (stream instanceof FormatIdInputStream) {
                    readExternal((FormatIdInputStream) stream);
                } else {
                    readExternal(new FormatIdInputStream(stream));
                }
                stream = null;
                // so call again to convert to a String
                return getString();
            } catch (IOException ioe) {
                throw StandardException.newException(SQLState.LANG_STREAMING_COLUMN_I_O_EXCEPTION, ioe, String.class.getName());
            }
        }
    }
    return value;
}
Also used : FormatIdInputStream(org.apache.derby.iapi.services.io.FormatIdInputStream) SQLException(java.sql.SQLException) IOException(java.io.IOException)

Example 2 with FormatIdInputStream

use of org.apache.derby.iapi.services.io.FormatIdInputStream in project derby by apache.

the class SQLClob method readExternal.

/**
 * Reads and materializes the CLOB value from the stream.
 *
 * @param in source stream
 * @throws java.io.UTFDataFormatException if an encoding error is detected
 * @throws IOException if reading from the stream fails, or the content of
 *      the stream header is invalid
 */
public void readExternal(ObjectInput in) throws IOException {
    HeaderInfo hdrInfo;
    if (csd != null) {
        int hdrLen = (int) csd.getDataOffset();
        int valueLength = (hdrLen == 5) ? (int) csd.getCharLength() : (int) csd.getByteLength();
        hdrInfo = new HeaderInfo(hdrLen, valueLength);
        // Make sure the stream is correctly positioned.
        rewindStream((InputStream) in, hdrLen);
    } else {
        final InputStream srcIn = (InputStream) in;
        final boolean markSet = srcIn.markSupported();
        if (markSet) {
            srcIn.mark(MAX_STREAM_HEADER_LENGTH);
        }
        byte[] header = new byte[MAX_STREAM_HEADER_LENGTH];
        int read = in.read(header);
        // Expect at least two header bytes.
        if (SanityManager.DEBUG) {
            SanityManager.ASSERT(read > 1, "Too few header bytes: " + read);
        }
        hdrInfo = investigateHeader(header, read);
        if (read > hdrInfo.headerLength()) {
            // in step three if the stream isn't resetable.
            if (markSet) {
                // 1) Reset the stream to the previously set mark.
                srcIn.reset();
                InputStreamUtil.skipFully(srcIn, hdrInfo.headerLength());
            } else if (in instanceof FormatIdInputStream) {
                // 2) Add a push back stream on top of the underlying
                // source, and unread the surplus bytes we read. Set the
                // push back stream to be the source of the data input obj.
                final int surplus = read - hdrInfo.headerLength();
                FormatIdInputStream formatIn = (FormatIdInputStream) in;
                PushbackInputStream pushbackIn = new PushbackInputStream(formatIn.getInputStream(), surplus);
                pushbackIn.unread(header, hdrInfo.headerLength(), surplus);
                formatIn.setInput(pushbackIn);
            } else {
                // 3) Assume we have a store stream.
                rewindStream(srcIn, hdrInfo.headerLength());
            }
        }
    }
    // The data will be materialized in memory, in a char array.
    // Subtract the header length from the byte length if there is a byte
    // encoded in the header, otherwise the decode routine will try to read
    // too many bytes.
    // zero is interpreted as unknown / unset
    int byteLength = 0;
    if (hdrInfo.byteLength() != 0) {
        byteLength = hdrInfo.byteLength() - hdrInfo.headerLength();
    }
    super.readExternal(in, byteLength, hdrInfo.charLength());
}
Also used : FormatIdInputStream(org.apache.derby.iapi.services.io.FormatIdInputStream) PushbackInputStream(java.io.PushbackInputStream) FormatIdInputStream(org.apache.derby.iapi.services.io.FormatIdInputStream) PushbackInputStream(java.io.PushbackInputStream) ArrayInputStream(org.apache.derby.iapi.services.io.ArrayInputStream) InputStream(java.io.InputStream)

Example 3 with FormatIdInputStream

use of org.apache.derby.iapi.services.io.FormatIdInputStream in project derby by apache.

the class StoredPage method readOneColumnFromPage.

/**
 * Read just one column from stream into row.
 * <p>
 * The routine reads just one column from the row, it is mostly code
 * taken from readRecordFromStream, but highly optimized to just get
 * one column from a non-overflow row.  It can only be called to read
 * a row from the pageData array as it directly accesses the page array
 * to avoid the Stream overhead while processing non-user data which
 * does not need the limit functionality.
 * <p>
 * It is expected that this code will be called to read in a column
 * associated with a qualifiers which are applied one column at a time,
 * and has been specialized to proved the greatest peformance for
 * processing qualifiers.  This kind of access is done when scanning
 * large datasets while applying qualifiers and thus any performance
 * gain at this low level is multiplied by the large number of rows that
 * may be iterated over.
 * <p>
 * The column is read into the object located in row[qual_colid].
 *
 * @param row                   col is read into object in row[qual_colid].
 * @param offset_to_field_data  offset in bytes from top of page to field
 * @param colid                 the column id to read, colid N is row[N]
 * @param recordHeader          record header of row to read column from.
 * @param recordToLock          record handle to lock,
 *                              used by overflow column code.
 *
 * @exception  StandardException  Standard exception policy.
 */
private final void readOneColumnFromPage(Object[] row, int colid, int offset_to_field_data, StoredRecordHeader recordHeader, RecordHandle recordToLock) throws StandardException, IOException {
    ErrorObjectInput inUserCode = null;
    // Reads in this routine are always against the raw data in the
    // pageData array, thus it can assume array access to page data array.
    ArrayInputStream lrdi = rawDataIn;
    try {
        if (SanityManager.DEBUG) {
            if (colid >= row.length)
                SanityManager.THROWASSERT("colid = " + colid + ";row length = " + row.length);
            // currently this routine will not work on long rows.
            if (recordHeader.getFirstField() != 0) {
                SanityManager.THROWASSERT("recordHeader.getFirstField() = " + recordHeader.getFirstField());
            }
        }
        Object column = row[colid];
        // if the column id exists on this page.
        if (colid <= (recordHeader.getNumberFields() - 1)) {
            for (int columnId = colid; columnId > 0; columnId--) {
                offset_to_field_data += StoredFieldHeader.readTotalFieldLength(pageData, offset_to_field_data);
            }
            // read the field header
            // read the status byte.
            int fieldStatus = StoredFieldHeader.readStatus(pageData, offset_to_field_data);
            // read the field data length, and position on 1st byte of data.
            int fieldDataLength = StoredFieldHeader.readFieldLengthAndSetStreamPosition(pageData, offset_to_field_data + StoredFieldHeader.STORED_FIELD_HEADER_STATUS_SIZE, fieldStatus, slotFieldSize, lrdi);
            if (SanityManager.DEBUG) {
                SanityManager.ASSERT(!StoredFieldHeader.isExtensible(fieldStatus), "extensible fields not supported yet");
            }
            if (!StoredFieldHeader.isNonexistent(fieldStatus)) {
                boolean isOverflow = StoredFieldHeader.isOverflow(fieldStatus);
                OverflowInputStream overflowIn = null;
                if (isOverflow) {
                    // A fetched long column is returned as a stream
                    long overflowPage = CompressedNumber.readLong((InputStream) lrdi);
                    int overflowId = CompressedNumber.readInt((InputStream) lrdi);
                    // Prepare the stream for results...
                    // create the byteHolder the size of a page, so, that it
                    // will fit the field Data that would fit on a page.
                    MemByteHolder byteHolder = new MemByteHolder(pageData.length);
                    overflowIn = new OverflowInputStream(byteHolder, owner, overflowPage, overflowId, recordToLock);
                }
                // Deal with Storable columns
                if (column instanceof DataValueDescriptor) {
                    DataValueDescriptor sColumn = (DataValueDescriptor) column;
                    // is the column null ?
                    if (StoredFieldHeader.isNull(fieldStatus)) {
                        sColumn.restoreToNull();
                    } else {
                        // set the limit for the user read
                        if (!isOverflow) {
                            // normal, non-overflow column case.
                            lrdi.setLimit(fieldDataLength);
                            inUserCode = lrdi;
                            sColumn.readExternalFromArray(lrdi);
                            inUserCode = null;
                            int unread = lrdi.clearLimit();
                            if (unread != 0)
                                DataInputUtil.skipFully(lrdi, unread);
                        } else {
                            // fetched column is a Storable long column.
                            FormatIdInputStream newIn = new FormatIdInputStream(overflowIn);
                            if ((sColumn instanceof StreamStorable)) {
                                ((StreamStorable) sColumn).setStream(newIn);
                            } else {
                                inUserCode = newIn;
                                sColumn.readExternal(newIn);
                                inUserCode = null;
                            }
                        }
                    }
                } else {
                    if (StoredFieldHeader.isNull(fieldStatus)) {
                        throw StandardException.newException(SQLState.DATA_NULL_STORABLE_COLUMN, Integer.toString(colid));
                    }
                    // This is a non-extensible field, which means the
                    // caller must know the correct type and thus the
                    // element in row is the correct type or null. It must
                    // be Serializable.
                    // 
                    // We do not support Externalizable here.
                    lrdi.setLimit(fieldDataLength);
                    inUserCode = lrdi;
                    // RESOLVE (no non-storables?)
                    row[colid] = (Object) lrdi.readObject();
                    inUserCode = null;
                    int unread = lrdi.clearLimit();
                    if (unread != 0)
                        DataInputUtil.skipFully(lrdi, unread);
                }
            } else {
                if (column instanceof DataValueDescriptor) {
                    // RESOLVE - This is in place for 1.2. In the future
                    // we may want to return this column as non-existent
                    // even if it is a storable column, or maybe use a
                    // supplied default.
                    ((DataValueDescriptor) column).restoreToNull();
                } else {
                    row[colid] = null;
                }
            }
        } else {
            if (column instanceof DataValueDescriptor) {
                // RESOLVE - This is in place for 1.2. In the future
                // we may want to return this column as non-existent
                // even if it is a storable column, or maybe use a
                // supplied default.
                ((DataValueDescriptor) column).restoreToNull();
            } else {
                row[colid] = null;
            }
        }
    } catch (IOException ioe) {
        if (inUserCode != null) {
            lrdi.clearLimit();
            if (ioe instanceof EOFException) {
                if (SanityManager.DEBUG) {
                    SanityManager.DEBUG_PRINT("DEBUG_TRACE", "StoredPage.readOneColumnFromPage - EOF while restoring record: " + recordHeader + "Page dump = " + this);
                    SanityManager.showTrace(ioe);
                }
                // an EOFException when it sees the -1 from a read
                throw StandardException.newException(SQLState.DATA_STORABLE_READ_MISMATCH, ioe, inUserCode.getErrorInfo());
            }
            // some SQLData error reporting
            Exception ne = inUserCode.getNestedException();
            if (ne != null) {
                if (ne instanceof InstantiationException) {
                    throw StandardException.newException(SQLState.DATA_SQLDATA_READ_INSTANTIATION_EXCEPTION, ne, inUserCode.getErrorInfo());
                }
                if (ne instanceof IllegalAccessException) {
                    throw StandardException.newException(SQLState.DATA_SQLDATA_READ_ILLEGAL_ACCESS_EXCEPTION, ne, inUserCode.getErrorInfo());
                }
                if (ne instanceof StandardException) {
                    throw (StandardException) ne;
                }
            }
            throw StandardException.newException(SQLState.DATA_STORABLE_READ_EXCEPTION, ioe, inUserCode.getErrorInfo());
        }
        // re-throw to higher levels so they can put it in correct context.
        throw ioe;
    } catch (ClassNotFoundException cnfe) {
        lrdi.clearLimit();
        // make the database corrupt, just that this field is inaccessable
        throw StandardException.newException(SQLState.DATA_STORABLE_READ_MISSING_CLASS, cnfe, inUserCode.getErrorInfo());
    } catch (LinkageError le) {
        // Some error during the link of a user class
        if (inUserCode != null) {
            lrdi.clearLimit();
            throw StandardException.newException(SQLState.DATA_STORABLE_READ_EXCEPTION, le, inUserCode.getErrorInfo());
        }
        throw le;
    }
}
Also used : ErrorObjectInput(org.apache.derby.iapi.services.io.ErrorObjectInput) IOException(java.io.IOException) StandardException(org.apache.derby.shared.common.error.StandardException) IOException(java.io.IOException) EOFException(java.io.EOFException) FormatIdInputStream(org.apache.derby.iapi.services.io.FormatIdInputStream) StandardException(org.apache.derby.shared.common.error.StandardException) StreamStorable(org.apache.derby.iapi.services.io.StreamStorable) EOFException(java.io.EOFException) ByteArrayInputStream(java.io.ByteArrayInputStream) ArrayInputStream(org.apache.derby.iapi.services.io.ArrayInputStream) DataValueDescriptor(org.apache.derby.iapi.types.DataValueDescriptor)

Example 4 with FormatIdInputStream

use of org.apache.derby.iapi.services.io.FormatIdInputStream in project derby by apache.

the class StoredPage method readRecordFromArray.

private final boolean readRecordFromArray(Object[] row, int max_colid, int[] vCols, int[] mCols, ArrayInputStream dataIn, StoredRecordHeader recordHeader, RecordHandle recordToLock) throws StandardException, IOException {
    ErrorObjectInput inUserCode = null;
    try {
        // Get the number of columns in the row.
        int numberFields = recordHeader.getNumberFields();
        int startColumn = recordHeader.getFirstField();
        if (startColumn > max_colid) {
            // done if the startColumn is higher than highest column.
            return true;
        }
        // For each column in the row, restore the column from
        // the corresponding field in the record.  If the field
        // is missing or not set, set the column to null.
        int highestColumnOnPage = numberFields + startColumn;
        int vColsSize = (vCols == null) ? 0 : vCols.length;
        int offset_to_field_data = dataIn.getPosition();
        for (int columnId = startColumn; columnId <= max_colid; columnId++) {
            // that have already been read.
            if (((vCols != null) && (!(vColsSize > columnId && (vCols[columnId] != 0)))) || ((mCols != null) && (mCols[columnId] != 0))) {
                if (columnId < highestColumnOnPage) {
                    // If the field exists in the row on the page, but the
                    // partial row being returned does not include it,
                    // skip the field ...
                    offset_to_field_data += StoredFieldHeader.readTotalFieldLength(pageData, offset_to_field_data);
                }
                continue;
            } else if (columnId < highestColumnOnPage) {
                // the column is on this page.
                // read the field header
                // read the status byte.
                int fieldStatus = StoredFieldHeader.readStatus(pageData, offset_to_field_data);
                // read the field data length, position on 1st byte of data
                int fieldDataLength = StoredFieldHeader.readFieldLengthAndSetStreamPosition(pageData, offset_to_field_data + StoredFieldHeader.STORED_FIELD_HEADER_STATUS_SIZE, fieldStatus, slotFieldSize, dataIn);
                if (SanityManager.DEBUG) {
                    SanityManager.ASSERT(!StoredFieldHeader.isExtensible(fieldStatus), "extensible fields not supported yet");
                }
                Object column = row[columnId];
                OverflowInputStream overflowIn = null;
                if ((fieldStatus & StoredFieldHeader.FIELD_NONEXISTENT) != StoredFieldHeader.FIELD_NONEXISTENT) {
                    // normal path - field exists.
                    boolean isOverflow = ((fieldStatus & StoredFieldHeader.FIELD_OVERFLOW) != 0);
                    if (isOverflow) {
                        // A fetched long column is returned as a stream
                        long overflowPage = CompressedNumber.readLong((InputStream) dataIn);
                        int overflowId = CompressedNumber.readInt((InputStream) dataIn);
                        // Prepare the stream for results...
                        // create the byteHolder the size of a page, so,
                        // that it will fit the field Data that would fit
                        // on a page.
                        MemByteHolder byteHolder = new MemByteHolder(pageData.length);
                        overflowIn = new OverflowInputStream(byteHolder, owner, overflowPage, overflowId, recordToLock);
                    }
                    // Deal with Object columns
                    if (column instanceof DataValueDescriptor) {
                        DataValueDescriptor sColumn = (DataValueDescriptor) column;
                        // is the column null ?
                        if ((fieldStatus & StoredFieldHeader.FIELD_NULL) == 0) {
                            // set the limit for the user read
                            if (!isOverflow) {
                                // normal, non-overflow column case.
                                dataIn.setLimit(fieldDataLength);
                                inUserCode = dataIn;
                                sColumn.readExternalFromArray(dataIn);
                                inUserCode = null;
                                int unread = dataIn.clearLimit();
                                if (unread != 0)
                                    DataInputUtil.skipFully(dataIn, unread);
                            } else {
                                // column being fetched is a long column.
                                FormatIdInputStream newIn = new FormatIdInputStream(overflowIn);
                                // long columns are fetched as a stream.
                                boolean fetchStream = true;
                                if (!(sColumn instanceof StreamStorable)) {
                                    fetchStream = false;
                                }
                                if (fetchStream) {
                                    ((StreamStorable) sColumn).setStream(newIn);
                                } else {
                                    inUserCode = newIn;
                                    sColumn.readExternal(newIn);
                                    inUserCode = null;
                                }
                            }
                        } else {
                            sColumn.restoreToNull();
                        }
                    } else {
                        if (StoredFieldHeader.isNull(fieldStatus)) {
                            throw StandardException.newException(SQLState.DATA_NULL_STORABLE_COLUMN, Integer.toString(columnId));
                        }
                        // This is a non-extensible field, which means the
                        // caller must know the correct type and thus the
                        // element in row is the correct type or null. It
                        // must be Serializable.
                        // 
                        // We do not support Externalizable here.
                        dataIn.setLimit(fieldDataLength);
                        inUserCode = dataIn;
                        // RESOLVE (no non-storables?)
                        row[columnId] = (Object) dataIn.readObject();
                        inUserCode = null;
                        int unread = dataIn.clearLimit();
                        if (unread != 0)
                            DataInputUtil.skipFully(dataIn, unread);
                    }
                } else {
                    if (column instanceof DataValueDescriptor) {
                        // RESOLVE - This is in place for 1.2. In the future
                        // we may want to return this column as non-existent
                        // even if it is a storable column, or maybe use a
                        // supplied default.
                        ((DataValueDescriptor) column).restoreToNull();
                    } else {
                        row[columnId] = null;
                    }
                }
                // move the counter to point to beginning of next field.
                offset_to_field_data = dataIn.getPosition();
            } else {
                // field is non-existent
                Object column = row[columnId];
                if (column instanceof DataValueDescriptor) {
                    // RESOLVE - This is in place for 1.2. In the future
                    // we may want to return this column as non-existent
                    // even if it is a storable column, or maybe use a
                    // supplied default.
                    ((DataValueDescriptor) column).restoreToNull();
                } else {
                    row[columnId] = null;
                }
            }
        }
        if ((numberFields + startColumn) > max_colid)
            return true;
        else
            return false;
    } catch (IOException ioe) {
        if (inUserCode != null) {
            dataIn.clearLimit();
            if (ioe instanceof EOFException) {
                if (SanityManager.DEBUG) {
                    SanityManager.DEBUG_PRINT("DEBUG_TRACE", "StoredPage - EOF while restoring record: " + recordHeader + "Page dump = " + this);
                }
                // an EOFException when it sees the -1 from a read
                throw StandardException.newException(SQLState.DATA_STORABLE_READ_MISMATCH, ioe, inUserCode.getErrorInfo());
            }
            // some SQLData error reporting
            Exception ne = inUserCode.getNestedException();
            if (ne != null) {
                if (ne instanceof InstantiationException) {
                    throw StandardException.newException(SQLState.DATA_SQLDATA_READ_INSTANTIATION_EXCEPTION, ne, inUserCode.getErrorInfo());
                }
                if (ne instanceof IllegalAccessException) {
                    throw StandardException.newException(SQLState.DATA_SQLDATA_READ_ILLEGAL_ACCESS_EXCEPTION, ne, inUserCode.getErrorInfo());
                }
                if (ne instanceof StandardException) {
                    throw (StandardException) ne;
                }
            }
            throw StandardException.newException(SQLState.DATA_STORABLE_READ_EXCEPTION, ioe, inUserCode.getErrorInfo());
        }
        // re-throw to higher levels so they can put it in correct context.
        throw ioe;
    } catch (ClassNotFoundException cnfe) {
        dataIn.clearLimit();
        // make the database corrupt, just that this field is inaccessable
        throw StandardException.newException(SQLState.DATA_STORABLE_READ_MISSING_CLASS, cnfe, inUserCode.getErrorInfo());
    } catch (LinkageError le) {
        // Some error during the link of a user class
        if (inUserCode != null) {
            dataIn.clearLimit();
            throw StandardException.newException(SQLState.DATA_STORABLE_READ_EXCEPTION, le, inUserCode.getErrorInfo());
        }
        throw le;
    }
}
Also used : ErrorObjectInput(org.apache.derby.iapi.services.io.ErrorObjectInput) FormatIdInputStream(org.apache.derby.iapi.services.io.FormatIdInputStream) ByteArrayInputStream(java.io.ByteArrayInputStream) ArrayInputStream(org.apache.derby.iapi.services.io.ArrayInputStream) InputStream(java.io.InputStream) IOException(java.io.IOException) StandardException(org.apache.derby.shared.common.error.StandardException) IOException(java.io.IOException) EOFException(java.io.EOFException) FormatIdInputStream(org.apache.derby.iapi.services.io.FormatIdInputStream) StandardException(org.apache.derby.shared.common.error.StandardException) StreamStorable(org.apache.derby.iapi.services.io.StreamStorable) EOFException(java.io.EOFException) DataValueDescriptor(org.apache.derby.iapi.types.DataValueDescriptor)

Example 5 with FormatIdInputStream

use of org.apache.derby.iapi.services.io.FormatIdInputStream in project derby by apache.

the class StoredPage method readRecordFromStream.

/**
 * restore a record from a stream.
 * <p>
 * The rawDataIn stream is expected to be positioned after the record
 * header.
 *
 * @return The identifier to be used to open the conglomerate later.
 *
 * @param row               restore row into this object array.
 * @param max_colid         The maximum numbered column id that will be
 *                          requested by caller.  It should be:
 *                            min(row.length - 1, maximum bit set in vCols)
 *                          It is used to stop the inner most loop from
 *                          looking at more columns in the row.
 * @param vCols             If not null, bit map indicates valid cols.
 * @param mCols             If not null, int array indicates columns already
 *                          read in from the stream.  A non-zero entry
 *                          means the column has already been read in.
 * @param dataIn            restore row from this stream.
 * @param recordHeader      The record header of the row, it was read in
 *                          from stream and dataIn is positioned after it.
 * @param recordToLock      The head row to use for locking, used to lock
 *                          head row of overflow columns/rows.
 *
 * @exception  StandardException  Standard exception policy.
 */
private final boolean readRecordFromStream(Object[] row, int max_colid, int[] vCols, int[] mCols, LimitObjectInput dataIn, StoredRecordHeader recordHeader, RecordHandle recordToLock) throws StandardException, IOException {
    ErrorObjectInput inUserCode = null;
    try {
        // Get the number of columns in the row.
        int numberFields = recordHeader.getNumberFields();
        int startColumn = recordHeader.getFirstField();
        if (startColumn > max_colid) {
            // done if the startColumn is higher than highest column.
            return true;
        }
        // For each column in the row, restore the column from
        // the corresponding field in the record.  If the field
        // is missing or not set, set the column to null.
        int highestColumnOnPage = numberFields + startColumn;
        int vColsSize = (vCols == null) ? 0 : vCols.length;
        for (int columnId = startColumn; columnId <= max_colid; columnId++) {
            // that have already been read.
            if (((vCols != null) && (!(vColsSize > columnId && (vCols[columnId] != 0)))) || ((mCols != null) && (mCols[columnId] != 0))) {
                if (columnId < highestColumnOnPage) {
                    // If the field exists in the row on the page, but the
                    // partial row being returned does not include it,
                    // skip the field ...
                    skipField(dataIn);
                }
                continue;
            }
            // that this record has
            if (columnId >= highestColumnOnPage) {
                // field is non-existent
                Object column = row[columnId];
                if (column instanceof DataValueDescriptor) {
                    // RESOLVE - This is in place for 1.2. In the future
                    // we may want to return this column as non-existent
                    // even if it is a storable column, or maybe use a
                    // supplied default.
                    ((DataValueDescriptor) column).restoreToNull();
                } else {
                    row[columnId] = null;
                }
                continue;
            }
            // read the field header
            int fieldStatus = StoredFieldHeader.readStatus(dataIn);
            int fieldDataLength = StoredFieldHeader.readFieldDataLength(dataIn, fieldStatus, slotFieldSize);
            if (SanityManager.DEBUG) {
                SanityManager.ASSERT(!StoredFieldHeader.isExtensible(fieldStatus), "extensible fields not supported yet");
            }
            Object column = row[columnId];
            OverflowInputStream overflowIn = null;
            // field is non-existent, return null
            if (StoredFieldHeader.isNonexistent(fieldStatus)) {
                if (column instanceof DataValueDescriptor) {
                    // RESOLVE - This is in place for 1.2. In the future
                    // we may want to return this column as non-existent
                    // even if it is a storable column, or maybe use a
                    // supplied default.
                    ((DataValueDescriptor) column).restoreToNull();
                } else {
                    row[columnId] = null;
                }
                continue;
            }
            boolean isOverflow = StoredFieldHeader.isOverflow(fieldStatus);
            if (isOverflow) {
                // A fetched long column needs to be returned as a stream
                // 
                long overflowPage = CompressedNumber.readLong((InputStream) dataIn);
                int overflowId = CompressedNumber.readInt((InputStream) dataIn);
                // Prepare the stream for results...
                // create the byteHolder the size of a page, so, that it
                // will fit the field Data that would fit on a page.
                MemByteHolder byteHolder = new MemByteHolder(pageData.length);
                overflowIn = new OverflowInputStream(byteHolder, owner, overflowPage, overflowId, recordToLock);
            }
            // Deal with Object columns
            if (column instanceof DataValueDescriptor) {
                DataValueDescriptor sColumn = (DataValueDescriptor) column;
                // is the column null ?
                if (StoredFieldHeader.isNull(fieldStatus)) {
                    sColumn.restoreToNull();
                    continue;
                }
                // set the limit for the user read
                if (!isOverflow) {
                    // normal, non-overflow column case.
                    dataIn.setLimit(fieldDataLength);
                    inUserCode = dataIn;
                    sColumn.readExternal(dataIn);
                    inUserCode = null;
                    int unread = dataIn.clearLimit();
                    if (unread != 0)
                        DataInputUtil.skipFully(dataIn, unread);
                } else {
                    // column being fetched is a Object long column.
                    FormatIdInputStream newIn = new FormatIdInputStream(overflowIn);
                    // if a column is a long column, store recommends user
                    // fetch it as a stream.
                    boolean fetchStream = true;
                    if (!(sColumn instanceof StreamStorable)) {
                        fetchStream = false;
                    }
                    if (fetchStream) {
                        ((StreamStorable) sColumn).setStream(newIn);
                    } else {
                        inUserCode = newIn;
                        sColumn.readExternal(newIn);
                        inUserCode = null;
                    }
                }
                continue;
            }
            if (StoredFieldHeader.isNull(fieldStatus)) {
                throw StandardException.newException(SQLState.DATA_NULL_STORABLE_COLUMN, Integer.toString(columnId));
            }
            // This is a non-extensible field, which means the caller must
            // know the correct type and thus the element in row is the
            // correct type or null. It must be Serializable.
            // 
            // We do not support Externalizable here.
            dataIn.setLimit(fieldDataLength);
            inUserCode = dataIn;
            row[columnId] = (Object) dataIn.readObject();
            inUserCode = null;
            int unread = dataIn.clearLimit();
            if (unread != 0)
                DataInputUtil.skipFully(dataIn, unread);
            continue;
        }
        if ((numberFields + startColumn) > max_colid)
            return true;
        else
            return false;
    } catch (IOException ioe) {
        if (inUserCode != null) {
            dataIn.clearLimit();
            if (ioe instanceof EOFException) {
                if (SanityManager.DEBUG) {
                    SanityManager.DEBUG_PRINT("DEBUG_TRACE", "StoredPage - EOF while restoring record: " + recordHeader + "Page dump = " + this);
                }
                // an EOFException when it sees the -1 from a read
                throw StandardException.newException(SQLState.DATA_STORABLE_READ_MISMATCH, ioe, inUserCode.getErrorInfo());
            }
            // some SQLData error reporting
            Exception ne = inUserCode.getNestedException();
            if (ne != null) {
                if (ne instanceof InstantiationException) {
                    throw StandardException.newException(SQLState.DATA_SQLDATA_READ_INSTANTIATION_EXCEPTION, ne, inUserCode.getErrorInfo());
                }
                if (ne instanceof IllegalAccessException) {
                    throw StandardException.newException(SQLState.DATA_SQLDATA_READ_ILLEGAL_ACCESS_EXCEPTION, ne, inUserCode.getErrorInfo());
                }
                if (ne instanceof StandardException) {
                    throw (StandardException) ne;
                }
            }
            throw StandardException.newException(SQLState.DATA_STORABLE_READ_EXCEPTION, ioe, inUserCode.getErrorInfo());
        }
        // re-throw to higher levels so they can put it in correct context.
        throw ioe;
    } catch (ClassNotFoundException cnfe) {
        dataIn.clearLimit();
        // make the database corrupt, just that this field is inaccessable
        throw StandardException.newException(SQLState.DATA_STORABLE_READ_MISSING_CLASS, cnfe, inUserCode.getErrorInfo());
    } catch (LinkageError le) {
        // Some error during the link of a user class
        if (inUserCode != null) {
            dataIn.clearLimit();
            throw StandardException.newException(SQLState.DATA_STORABLE_READ_EXCEPTION, le, inUserCode.getErrorInfo());
        }
        throw le;
    }
}
Also used : ErrorObjectInput(org.apache.derby.iapi.services.io.ErrorObjectInput) IOException(java.io.IOException) StandardException(org.apache.derby.shared.common.error.StandardException) IOException(java.io.IOException) EOFException(java.io.EOFException) FormatIdInputStream(org.apache.derby.iapi.services.io.FormatIdInputStream) StandardException(org.apache.derby.shared.common.error.StandardException) StreamStorable(org.apache.derby.iapi.services.io.StreamStorable) EOFException(java.io.EOFException) DataValueDescriptor(org.apache.derby.iapi.types.DataValueDescriptor)

Aggregations

FormatIdInputStream (org.apache.derby.iapi.services.io.FormatIdInputStream)6 IOException (java.io.IOException)5 EOFException (java.io.EOFException)3 ArrayInputStream (org.apache.derby.iapi.services.io.ArrayInputStream)3 ErrorObjectInput (org.apache.derby.iapi.services.io.ErrorObjectInput)3 StreamStorable (org.apache.derby.iapi.services.io.StreamStorable)3 DataValueDescriptor (org.apache.derby.iapi.types.DataValueDescriptor)3 StandardException (org.apache.derby.shared.common.error.StandardException)3 ByteArrayInputStream (java.io.ByteArrayInputStream)2 InputStream (java.io.InputStream)2 BufferedInputStream (java.io.BufferedInputStream)1 PushbackInputStream (java.io.PushbackInputStream)1 SQLException (java.sql.SQLException)1 LimitInputStream (org.apache.derby.iapi.services.io.LimitInputStream)1