Search in sources :

Example 1 with ByteArray

use of org.apache.derby.iapi.util.ByteArray in project derby by apache.

the class ExpressionClassBuilder method getGeneratedClass.

// /////////////////////////////////////////////////////////////////////
// 
// GENERATE BYTE CODE
// 
// /////////////////////////////////////////////////////////////////////
/**
 * Take the generated class, and turn it into an
 * actual class.
 * <p> This method assumes, does not check, that
 * the class and its parts are all complete.
 *
 * @param savedBytes place to save generated bytes.
 *	if null, it is ignored
 * @exception StandardException thrown when exception occurs
 */
GeneratedClass getGeneratedClass(ByteArray savedBytes) throws StandardException {
    if (gc != null)
        return gc;
    if (savedBytes != null) {
        ByteArray classBytecode = cb.getClassBytecode();
        // note: be sure to set the length since
        // the class builder allocates the byte array
        // in big chunks
        savedBytes.setBytes(classBytecode.getArray());
        savedBytes.setLength(classBytecode.getLength());
    }
    gc = cb.getGeneratedClass();
    // !! yippee !! here it is...
    return gc;
}
Also used : ByteArray(org.apache.derby.iapi.util.ByteArray)

Example 2 with ByteArray

use of org.apache.derby.iapi.util.ByteArray in project derby by apache.

the class StoredPage method logColumn.

/**
 * Log column from input row to the given output stream.
 * <p>
 * Read data from row[arrayPosition], and write the column data in
 * raw store page format to the given column.  Along the way determine
 * if the column will fit on the current page.
 * <p>
 * Action taken in this routine is determined by the kind of column as
 * specified in the columnFlag:
 *     COLUMN_NONE   - the column is insignificant
 *     COLUMN_FIRST  - this is the first column in a logRow() call
 *     COLUMN_LONG   - this is a known long column, therefore we will
 *                     store part of the column on the current page and
 *                     overflow the rest if necessary.
 * <p>
 * Upon entry to this routine logicalDataOut is tied to the
 * DynamicByteArrayOutputStream out.
 * <BR>
 * If a column is a long column and it does not totally fit on the current
 * page, then a LongColumnException is thrown.  We package up info about
 * the current long column in the partially filled in exception so that
 * callers can take correct action.  The column will now be set a as a
 * stream.
 *
 * @return The spaceAvailable after accounting for space for this column.
 *
 * @param row           array of column from which to read the column from.
 * @param arrayPosition The array position of column to be reading from row.
 * @param out           The stream to write the raw store page format of the
 *                      the column to.
 * @param spaceAvailable    The number of bytes available on the page for
 *                          this column, this may differ from current page
 *                          as it may include bytes used by previous
 *                          columns.
 * @param columnFlag    one of: COLUMN_NONE, COLUMN_FIRST, or COLUMN_LONG.
 *
 * @exception  StandardException    Standard exception policy.
 * @exception  LongColumnException  Thrown if column will not fit on a
 *                                  single page. See notes above
 */
private int logColumn(Object[] row, int arrayPosition, DynamicByteArrayOutputStream out, int spaceAvailable, int columnFlag, int overflowThreshold) throws StandardException, IOException {
    // RESOLVE (mikem) - why will row be null?
    Object column = (row != null ? row[arrayPosition] : null);
    // header is already formatted.
    if (column instanceof RawField) {
        // field data is raw, no need to set up a field header etc.
        byte[] data = ((RawField) column).getData();
        if (data.length <= spaceAvailable) {
            out.write(data);
            spaceAvailable -= data.length;
        }
        return spaceAvailable;
    }
    // If this is a long column, it may fit in this page or it may not.
    boolean longColumnDone = true;
    // default field status.
    int fieldStatus = StoredFieldHeader.setFixed(StoredFieldHeader.setInitial(), true);
    int beginPosition = out.getPosition();
    int columnBeginPosition = 0;
    int headerLength;
    int fieldDataLength = 0;
    if (column instanceof StreamStorable) {
        StreamStorable stream_storable_column = (StreamStorable) column;
        if (stream_storable_column.returnStream() != null) {
            column = (Object) stream_storable_column.returnStream();
        }
    }
    if ((column == null) && (columnFlag != COLUMN_CREATE_NULL)) {
        fieldStatus = StoredFieldHeader.setNonexistent(fieldStatus);
        headerLength = StoredFieldHeader.write(logicalDataOut, fieldStatus, fieldDataLength, slotFieldSize);
    } else if (column instanceof InputStream) {
        RememberBytesInputStream bufferedIn = null;
        int bufferLen = 0;
        int estimatedMaxDataSize = getMaxDataLength(spaceAvailable, overflowThreshold);
        // buffer.
        if (column instanceof RememberBytesInputStream) {
            // data is already RememberBytesInputStream
            bufferedIn = (RememberBytesInputStream) column;
            bufferLen = bufferedIn.numBytesSaved();
        } else {
            // data comes in as an inputstream
            bufferedIn = new RememberBytesInputStream((InputStream) column, new MemByteHolder(maxFieldSize + 1));
            // into the RememberBytesInputStream.
            if (row[arrayPosition] instanceof StreamStorable)
                ((StreamStorable) row[arrayPosition]).setStream(bufferedIn);
            // set column to the RememberBytesInputStream so that
            // all future access to this column will be able to get
            // at bytes that have been already read. This assignment
            // is needed to ensure that if long column exception is
            // thrown, the column is set correctly
            column = bufferedIn;
        }
        // read the buffer by reading the max we can read.
        if (bufferLen < (estimatedMaxDataSize + 1)) {
            bufferLen += bufferedIn.fillBuf(estimatedMaxDataSize + 1 - bufferLen);
        }
        if ((bufferLen <= estimatedMaxDataSize)) {
            // we will be able to fit this into the page
            fieldDataLength = bufferLen;
            fieldStatus = StoredFieldHeader.setFixed(fieldStatus, true);
            headerLength = StoredFieldHeader.write(logicalDataOut, fieldStatus, fieldDataLength, slotFieldSize);
            // if the field is extensible, then we write the serializable
            // formatId.  if the field is non-extensible, we don't need to
            // write the formatId.  but at this point, how do we know
            // whether the field is extensible or not???  For Plato release,
            // we do not support InputStream on extensible types,
            // therefore, we ignore the formatId for now.
            bufferedIn.putBuf(logicalDataOut, fieldDataLength);
        } else {
            if (columnFlag == COLUMN_LONG) {
                // column is a long column and the remaining portion does
                // not fit on the current page.
                longColumnDone = false;
                // it's a portion of a long column, and there is more to
                // write reserve enough room for overflow pointer, then
                // write as much data as we can leaving an extra 2 bytes
                // for overflow field header.
                fieldDataLength = estimatedMaxDataSize - OVERFLOW_POINTER_SIZE - 2;
                fieldStatus = StoredFieldHeader.setFixed(fieldStatus, true);
                headerLength = StoredFieldHeader.write(logicalDataOut, fieldStatus, fieldDataLength, slotFieldSize);
                bufferedIn.putBuf(logicalDataOut, fieldDataLength);
                // now, we need to adjust the buffer, move the unread
                // bytes to the beginning position the cursor correctly,
                // so, next time around, we can read more into the buffer.
                int remainingBytes = bufferedIn.available();
                // move the unread bytes to the beginning of the byteHolder.
                int bytesShifted = bufferedIn.shiftToFront();
            } else {
                // column not a long column and does not fit on page.
                int delta = maxFieldSize - bufferLen + 1;
                if (delta > 0)
                    bufferLen += bufferedIn.fillBuf(delta);
                fieldDataLength = bufferLen;
                // the data will not fit on this page make sure the new
                // input stream is passed back to the upper layer...
                column = (Object) bufferedIn;
            }
        }
    } else if (columnFlag == COLUMN_CREATE_NULL) {
        // 
        // This block handles the case when a couple columns have been added
        // recently and now one of the later columns is being updated. Newly added columns
        // which appear in the row before the updated column don't actually have
        // any values yet. We stuff NULLs into those newly added columns here.
        // This fixes DERBY-5679.
        // 
        fieldStatus = StoredFieldHeader.setNull(fieldStatus, true);
        // header is written with 0 length here.
        headerLength = StoredFieldHeader.write(logicalDataOut, fieldStatus, fieldDataLength, slotFieldSize);
    } else if (column instanceof DataValueDescriptor) {
        DataValueDescriptor sColumn = (DataValueDescriptor) column;
        boolean isNull = (columnFlag == COLUMN_CREATE_NULL) || sColumn.isNull();
        if (isNull) {
            fieldStatus = StoredFieldHeader.setNull(fieldStatus, true);
        }
        // header is written with 0 length here.
        headerLength = StoredFieldHeader.write(logicalDataOut, fieldStatus, fieldDataLength, slotFieldSize);
        if (!isNull) {
            // write the field data to the log
            try {
                columnBeginPosition = out.getPosition();
                sColumn.writeExternal(logicalDataOut);
            } catch (IOException ioe) {
                // SQLData error reporting
                if (logicalDataOut != null) {
                    Exception ne = logicalDataOut.getNestedException();
                    if (ne != null) {
                        if (ne instanceof StandardException) {
                            throw (StandardException) ne;
                        }
                    }
                }
                throw StandardException.newException(SQLState.DATA_STORABLE_WRITE_EXCEPTION, ioe);
            }
            fieldDataLength = (out.getPosition() - beginPosition) - headerLength;
        }
    } else if (column instanceof RecordHandle) {
        // we are inserting an overflow pointer for a long column
        // casted reference to column to avoid repeated casting.
        RecordHandle overflowHandle = (RecordHandle) column;
        fieldStatus = StoredFieldHeader.setOverflow(fieldStatus, true);
        headerLength = StoredFieldHeader.write(logicalDataOut, fieldStatus, fieldDataLength, slotFieldSize);
        fieldDataLength += CompressedNumber.writeLong(out, overflowHandle.getPageNumber());
        fieldDataLength += CompressedNumber.writeInt(out, overflowHandle.getId());
    } else {
        // Serializable/Externalizable/Formattable
        // all look the same at this point.
        // header is written with 0 length here.
        headerLength = StoredFieldHeader.write(logicalDataOut, fieldStatus, fieldDataLength, slotFieldSize);
        logicalDataOut.writeObject(column);
        fieldDataLength = (out.getPosition() - beginPosition) - headerLength;
    }
    // calculate the size of the field on page with compresed field header
    fieldStatus = StoredFieldHeader.setFixed(fieldStatus, false);
    int fieldSizeOnPage = StoredFieldHeader.size(fieldStatus, fieldDataLength, slotFieldSize) + fieldDataLength;
    userRowSize += fieldDataLength;
    boolean fieldIsLong = isLong(fieldSizeOnPage, overflowThreshold);
    // Do we have enough space on the page for this field?
    if (((spaceAvailable < fieldSizeOnPage) || (fieldIsLong)) && (columnFlag != COLUMN_LONG)) {
        if (fieldIsLong) {
            if (!(column instanceof InputStream)) {
                // Convert already written object to an InputStream.
                ByteArray fieldData = new ByteArray(((DynamicByteArrayOutputStream) out).getByteArray(), (columnBeginPosition), fieldDataLength);
                ByteArrayInputStream columnIn = new ByteArrayInputStream(fieldData.getArray(), columnBeginPosition, fieldDataLength);
                MemByteHolder byteHolder = new MemByteHolder(fieldDataLength + 1);
                RememberBytesInputStream bufferedIn = new RememberBytesInputStream(columnIn, byteHolder);
                // the data will not fit on this page make sure the new
                // input stream is passed back to the upper layer...
                column = bufferedIn;
            }
            out.setPosition(beginPosition);
            // This exception carries the information for the client
            // routine to continue inserting the long row on multiple
            // pages.
            LongColumnException lce = new LongColumnException();
            lce.setColumn(column);
            throw lce;
        } else {
            // Column does not fit on this page, but it isn't a long column.
            out.setPosition(beginPosition);
            return (spaceAvailable);
        }
    }
    // Now we go back to update the fieldDataLength in the field header
    out.setPosition(beginPosition);
    // slotFieldSize is set based on the pageSize.
    // We are borrowing this to set the size of our fieldDataLength.
    fieldStatus = StoredFieldHeader.setFixed(fieldStatus, true);
    headerLength = StoredFieldHeader.write(out, fieldStatus, fieldDataLength, slotFieldSize);
    // set position to the end of the field
    out.setPosition(beginPosition + fieldDataLength + headerLength);
    spaceAvailable -= fieldSizeOnPage;
    // YYZ: revisit
    if (columnFlag == COLUMN_LONG) {
        // BasePage.insertLongColumn to signal end of loop.
        if (longColumnDone)
            return -1;
        else
            return 1;
    } else {
        return (spaceAvailable);
    }
}
Also used : FormatIdInputStream(org.apache.derby.iapi.services.io.FormatIdInputStream) ByteArrayInputStream(java.io.ByteArrayInputStream) ArrayInputStream(org.apache.derby.iapi.services.io.ArrayInputStream) InputStream(java.io.InputStream) RecordHandle(org.apache.derby.iapi.store.raw.RecordHandle) IOException(java.io.IOException) StandardException(org.apache.derby.shared.common.error.StandardException) IOException(java.io.IOException) EOFException(java.io.EOFException) StandardException(org.apache.derby.shared.common.error.StandardException) ByteArrayInputStream(java.io.ByteArrayInputStream) StreamStorable(org.apache.derby.iapi.services.io.StreamStorable) ByteArray(org.apache.derby.iapi.util.ByteArray) DataValueDescriptor(org.apache.derby.iapi.types.DataValueDescriptor)

Example 3 with ByteArray

use of org.apache.derby.iapi.util.ByteArray in project derby by apache.

the class DeleteOperation method writeOptionalDataToBuffer.

/**
 *	    if logical undo, writes out the row that was deleted
 *
 *		@exception IOException Can be thrown by any of the methods of ObjectOutput
 *		@exception StandardException Standard Derby policy.
 */
private void writeOptionalDataToBuffer(RawTransaction t) throws StandardException, IOException {
    if (SanityManager.DEBUG) {
        SanityManager.ASSERT(this.page != null);
    }
    DynamicByteArrayOutputStream logBuffer = t.getLogBuffer();
    int optionalDataStart = logBuffer.getPosition();
    if (SanityManager.DEBUG) {
        SanityManager.ASSERT(optionalDataStart == 0, "Buffer for writing the optional data should start at position 0");
    }
    if (undo != null)
        this.page.logRecord(doMeSlot, BasePage.LOG_RECORD_DEFAULT, recordId, (FormatableBitSet) null, logBuffer, (RecordHandle) null);
    int optionalDataLength = logBuffer.getPosition() - optionalDataStart;
    if (SanityManager.DEBUG) {
        if (optionalDataLength != logBuffer.getUsed())
            SanityManager.THROWASSERT("wrong optional data length, optionalDataLength = " + optionalDataLength + ", logBuffer.getUsed() = " + logBuffer.getUsed());
    }
    // set the position to the beginning of the buffer
    logBuffer.setPosition(optionalDataStart);
    this.preparedLog = new ByteArray(logBuffer.getByteArray(), optionalDataStart, optionalDataLength);
}
Also used : DynamicByteArrayOutputStream(org.apache.derby.iapi.services.io.DynamicByteArrayOutputStream) RecordHandle(org.apache.derby.iapi.store.raw.RecordHandle) ByteArray(org.apache.derby.iapi.util.ByteArray) FormatableBitSet(org.apache.derby.iapi.services.io.FormatableBitSet)

Example 4 with ByteArray

use of org.apache.derby.iapi.util.ByteArray in project derby by apache.

the class UpdateFieldOperation method writeOptionalDataToBuffer.

/**
 *	  Write the old column value and and new column value as optional data.
 *	  If logical undo, writes out the entire row's before image.
 *
 *		@exception IOException Can be thrown by any of the methods of ObjectOutput.
 *		@exception StandardException Standard Derby policy.
 */
private void writeOptionalDataToBuffer(RawTransaction t, Object column) throws StandardException, IOException {
    if (SanityManager.DEBUG) {
        SanityManager.ASSERT(this.page != null);
    }
    DynamicByteArrayOutputStream logBuffer = t.getLogBuffer();
    int optionalDataStart = logBuffer.getPosition();
    if (SanityManager.DEBUG) {
        SanityManager.ASSERT(optionalDataStart == 0, "Buffer for writing optional data should start at position 0");
    }
    // the after image of the column
    this.page.logColumn(doMeSlot, fieldId, column, logBuffer, 100);
    // the BI of the column
    this.page.logField(doMeSlot, fieldId, logBuffer);
    if (undo != null) {
        // RESOLVE: we want the AFTER image of the row, not the BEFORE
        // image.   This works for now because only btree needs a logical
        // undoable updateField and it always update only the pointer field
        // to point to something else.
        // 
        // But in the future, it needs to be changed.
        this.page.logRecord(doMeSlot, BasePage.LOG_RECORD_DEFAULT, recordId, (FormatableBitSet) null, logBuffer, (RecordHandle) null);
    // log the BI of the entire row
    }
    int optionalDataLength = logBuffer.getPosition() - optionalDataStart;
    if (SanityManager.DEBUG) {
        if (optionalDataLength != logBuffer.getUsed())
            SanityManager.THROWASSERT("wrong optional data length, optionalDataLength = " + optionalDataLength + ", logBuffer.getUsed() = " + logBuffer.getUsed());
    }
    // set the position to the beginning of the buffer
    logBuffer.setPosition(optionalDataStart);
    this.preparedLog = new ByteArray(logBuffer.getByteArray(), optionalDataStart, optionalDataLength);
}
Also used : DynamicByteArrayOutputStream(org.apache.derby.iapi.services.io.DynamicByteArrayOutputStream) ByteArray(org.apache.derby.iapi.util.ByteArray)

Example 5 with ByteArray

use of org.apache.derby.iapi.util.ByteArray in project derby by apache.

the class ContainerOperation method readExternal.

/**
 *		@exception IOException cannot read log record from log stream
 *		@exception ClassNotFoundException cannot read ByteArray object
 */
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
    super.readExternal(in);
    operation = in.readByte();
    if (operation == CREATE && hasCreateByteArray) {
        createByteArray = new ByteArray();
        createByteArray.readExternal(in);
    }
}
Also used : ByteArray(org.apache.derby.iapi.util.ByteArray)

Aggregations

ByteArray (org.apache.derby.iapi.util.ByteArray)13 DynamicByteArrayOutputStream (org.apache.derby.iapi.services.io.DynamicByteArrayOutputStream)6 IOException (java.io.IOException)2 FormatableBitSet (org.apache.derby.iapi.services.io.FormatableBitSet)2 RecordHandle (org.apache.derby.iapi.store.raw.RecordHandle)2 StandardException (org.apache.derby.shared.common.error.StandardException)2 ByteArrayInputStream (java.io.ByteArrayInputStream)1 EOFException (java.io.EOFException)1 InputStream (java.io.InputStream)1 Connection (java.sql.Connection)1 ArrayInputStream (org.apache.derby.iapi.services.io.ArrayInputStream)1 FormatIdInputStream (org.apache.derby.iapi.services.io.FormatIdInputStream)1 StreamStorable (org.apache.derby.iapi.services.io.StreamStorable)1 ClassFactory (org.apache.derby.iapi.services.loader.ClassFactory)1 LanguageConnectionContext (org.apache.derby.iapi.sql.conn.LanguageConnectionContext)1 LogInstant (org.apache.derby.iapi.store.raw.log.LogInstant)1 TransactionId (org.apache.derby.iapi.store.raw.xact.TransactionId)1 DataValueDescriptor (org.apache.derby.iapi.types.DataValueDescriptor)1 EmbedConnection (org.apache.derby.impl.jdbc.EmbedConnection)1 LogCounter (org.apache.derby.impl.store.raw.log.LogCounter)1