Search in sources :

Example 1 with Qualifier

use of org.apache.derby.iapi.store.access.Qualifier in project derby by apache.

the class HashTableResultSet method getNextRowCore.

/**
 * Return the requested values computed
 * from the next row (if any) for which
 * the restriction evaluates to true.
 * <p>
 * restriction and projection parameters
 * are evaluated for each row.
 *
 * @exception StandardException thrown on failure.
 * @exception StandardException ResultSetNotOpen thrown if not yet open.
 *
 * @return the next row in the result
 */
public ExecRow getNextRowCore() throws StandardException {
    if (isXplainOnlyMode())
        return null;
    ExecRow result = null;
    DataValueDescriptor[] columns = null;
    beginTime = getCurrentTimeMillis();
    if (isOpen) {
        /* We use a do/while loop to ensure that we continue down
			 * the duplicate chain, if one exists, until we find a
			 * row that matches on all probe predicates (or the
			 * duplicate chain is exhausted.)
			 */
        do {
            if (firstNext) {
                firstNext = false;
                /* Hash key could be either a single column or multiple 
                     * columns.  If a single column, then it is the datavalue 
                     * wrapper, otherwise it is a KeyHasher.
					 */
                Object hashEntry;
                if (keyColumns.length == 1) {
                    hashEntry = ht.get(nextQualifiers[0][0].getOrderable());
                } else {
                    KeyHasher mh = new KeyHasher(keyColumns.length);
                    for (int index = 0; index < keyColumns.length; index++) {
                        // RESOLVE (mikem) - will need to change when we
                        // support OR's in qualifiers.
                        mh.setObject(index, nextQualifiers[0][index].getOrderable());
                    }
                    hashEntry = ht.get(mh);
                }
                if (hashEntry instanceof List) {
                    entryVector = (List) hashEntry;
                    entryVectorSize = entryVector.size();
                    columns = (DataValueDescriptor[]) entryVector.get(0);
                } else {
                    entryVector = null;
                    entryVectorSize = 0;
                    columns = (DataValueDescriptor[]) hashEntry;
                }
            } else if (numFetchedOnNext < entryVectorSize) {
                // We are walking a list and there are more rows left.
                columns = (DataValueDescriptor[]) entryVector.get(numFetchedOnNext);
            }
            if (columns != null) {
                if (SanityManager.DEBUG) {
                    // Columns is really a Storable[]
                    for (int i = 0; i < columns.length; i++) {
                        if (!(columns[i] instanceof Storable)) {
                            SanityManager.THROWASSERT("columns[" + i + "] expected to be Storable, not " + columns[i].getClass().getName());
                        }
                    }
                }
                // See if the entry satisfies all of the other qualifiers
                boolean qualifies = true;
                if (SanityManager.DEBUG) {
                    // we don't support 2 d qualifiers yet.
                    SanityManager.ASSERT(nextQualifiers.length == 1);
                }
                for (int index = 0; index < nextQualifiers[0].length; index++) {
                    Qualifier q = nextQualifiers[0][index];
                    qualifies = columns[q.getColumnId()].compare(q.getOperator(), q.getOrderable(), q.getOrderedNulls(), q.getUnknownRV());
                    if (q.negateCompareResult()) {
                        qualifies = !(qualifies);
                    }
                    // Stop if any predicate fails
                    if (!qualifies) {
                        break;
                    }
                }
                if (qualifies) {
                    for (int index = 0; index < columns.length; index++) {
                        nextCandidate.setColumn(index + 1, columns[index]);
                    }
                    result = doProjection(nextCandidate);
                } else {
                    result = null;
                }
                numFetchedOnNext++;
            } else {
                result = null;
            }
        } while (result == null && numFetchedOnNext < entryVectorSize);
    }
    setCurrentRow(result);
    nextTime += getElapsedMillis(beginTime);
    if (runTimeStatsOn) {
        if (!isTopResultSet) {
            /* This is simply for RunTimeStats */
            /* We first need to get the subquery tracking array via the StatementContext */
            StatementContext sc = activation.getLanguageConnectionContext().getStatementContext();
            subqueryTrackingArray = sc.getSubqueryTrackingArray();
        }
        nextTime += getElapsedMillis(beginTime);
    }
    return result;
}
Also used : KeyHasher(org.apache.derby.iapi.store.access.KeyHasher) ExecRow(org.apache.derby.iapi.sql.execute.ExecRow) List(java.util.List) Qualifier(org.apache.derby.iapi.store.access.Qualifier) DataValueDescriptor(org.apache.derby.iapi.types.DataValueDescriptor) Storable(org.apache.derby.iapi.services.io.Storable) StatementContext(org.apache.derby.iapi.sql.conn.StatementContext)

Example 2 with Qualifier

use of org.apache.derby.iapi.store.access.Qualifier in project derby by apache.

the class BTreeScan method process_qualifier.

/**
 * process_qualifier - Determine if a row meets all qualifier conditions.
 * <p>
 * Check all qualifiers in the qualifier array against row.  Return true
 * if all compares specified by the qualifier array return true, else
 * return false.
 * <p>
 * It is up to caller to make sure qualifier list is non-null.
 *
 * @param row      The row with the same partial column list as the
 *                 row returned by the current scan.
 *
 * @exception  StandardException  Standard exception policy.
 */
protected boolean process_qualifier(DataValueDescriptor[] row) throws StandardException {
    boolean row_qualifies = true;
    Qualifier q;
    if (SanityManager.DEBUG) {
        // routine should not be called if there is no qualifier
        SanityManager.ASSERT(this.init_qualifier != null);
        SanityManager.ASSERT(this.init_qualifier.length > 0);
    }
    for (int i = 0; i < this.init_qualifier[0].length; i++) {
        // process each AND clause
        row_qualifies = false;
        // process each OR clause.
        q = this.init_qualifier[0][i];
        // Get the column from the possibly partial row, of the
        // q.getColumnId()'th column in the full row.
        DataValueDescriptor columnValue = row[q.getColumnId()];
        row_qualifies = columnValue.compare(q.getOperator(), q.getOrderable(), q.getOrderedNulls(), q.getUnknownRV());
        if (q.negateCompareResult())
            row_qualifies = !row_qualifies;
        // Once an AND fails the whole Qualification fails - do a return!
        if (!row_qualifies)
            return (false);
    }
    for (int and_idx = 1; and_idx < this.init_qualifier.length; and_idx++) {
        // process each AND clause
        row_qualifies = false;
        if (SanityManager.DEBUG) {
            // Each OR clause must be non-empty.
            SanityManager.ASSERT(this.init_qualifier[and_idx].length > 0);
        }
        for (int or_idx = 0; or_idx < this.init_qualifier[and_idx].length; or_idx++) {
            // process each OR clause.
            q = this.init_qualifier[and_idx][or_idx];
            // Get the column from the possibly partial row, of the
            // q.getColumnId()'th column in the full row.
            DataValueDescriptor columnValue = row[q.getColumnId()];
            row_qualifies = columnValue.compare(q.getOperator(), q.getOrderable(), q.getOrderedNulls(), q.getUnknownRV());
            if (q.negateCompareResult())
                row_qualifies = !row_qualifies;
            // once one OR qualifies the entire clause is TRUE
            if (row_qualifies)
                break;
        }
        if (!row_qualifies)
            break;
    }
    return (row_qualifies);
}
Also used : Qualifier(org.apache.derby.iapi.store.access.Qualifier) DataValueDescriptor(org.apache.derby.iapi.types.DataValueDescriptor)

Example 3 with Qualifier

use of org.apache.derby.iapi.store.access.Qualifier in project derby by apache.

the class GenericConglomerateController method fetch.

/**
 * @see ConglomerateController#fetch
 */
public boolean fetch(RowLocation loc, DataValueDescriptor[] row, FormatableBitSet validColumns, boolean waitForLock) throws StandardException {
    if (open_conglom.isClosed()) {
        if (open_conglom.getHold()) {
            if (open_conglom.isClosed())
                open_conglom.reopen();
        } else {
            throw (StandardException.newException(SQLState.HEAP_IS_CLOSED, open_conglom.getConglomerate().getId()));
        }
    }
    if (SanityManager.DEBUG) {
        // Make sure valid columns are in the list.  The RowUtil
        // call is too expensive to make in a released system for
        // every fetch.
        int invalidColumn = RowUtil.columnOutOfRange(row, validColumns, open_conglom.getFormatIds().length);
        if (invalidColumn >= 0) {
            throw (StandardException.newException(SQLState.HEAP_TEMPLATE_MISMATCH, invalidColumn, open_conglom.getFormatIds().length));
        }
    }
    // Get the record handle out of its wrapper.
    RowPosition pos = open_conglom.getRuntimeMem().get_scratch_row_position();
    getRowPositionFromRowLocation(loc, pos);
    if (!open_conglom.latchPage(pos)) {
        return false;
    }
    if (open_conglom.isForUpdate()) {
        open_conglom.lockPositionForWrite(pos, waitForLock);
    } else {
        open_conglom.lockPositionForRead(pos, (RowPosition) null, false, waitForLock);
    }
    if (pos.current_page == null) {
        // false to indicate that the row is no longer valid. (DERBY-4676)
        return false;
    }
    // Fetch the row.
    // RESOLVE (STO061) - don't know whether the fetch is for update or not.
    // 
    // 
    // RESOLVE (mikem) - get rid of new here.
    boolean ret_val = (pos.current_page.fetchFromSlot(pos.current_rh, pos.current_slot, row, new FetchDescriptor(row.length, validColumns, (Qualifier[][]) null), false) != null);
    // and just always make the unlock call.
    if (!open_conglom.isForUpdate())
        open_conglom.unlockPositionAfterRead(pos);
    pos.current_page.unlatch();
    return (ret_val);
}
Also used : FetchDescriptor(org.apache.derby.iapi.store.raw.FetchDescriptor) Qualifier(org.apache.derby.iapi.store.access.Qualifier)

Example 4 with Qualifier

use of org.apache.derby.iapi.store.access.Qualifier in project derby by apache.

the class GenericConglomerateController method fetch.

/**
 * @see ConglomerateController#fetch
 */
public boolean fetch(RowLocation loc, DataValueDescriptor[] row, FormatableBitSet validColumns) throws StandardException {
    if (open_conglom.isClosed()) {
        if (open_conglom.getHold()) {
            if (open_conglom.isClosed())
                open_conglom.reopen();
        } else {
            throw (StandardException.newException(SQLState.HEAP_IS_CLOSED, open_conglom.getConglomerate().getId()));
        }
    }
    if (SanityManager.DEBUG) {
        // Make sure valid columns are in the list.  The RowUtil
        // call is too expensive to make in a released system for
        // every fetch.
        int invalidColumn = RowUtil.columnOutOfRange(row, validColumns, open_conglom.getFormatIds().length);
        if (invalidColumn >= 0) {
            throw (StandardException.newException(SQLState.HEAP_TEMPLATE_MISMATCH, invalidColumn, open_conglom.getFormatIds().length));
        }
    }
    // Get the record handle out of its wrapper.
    RowPosition pos = open_conglom.getRuntimeMem().get_scratch_row_position();
    getRowPositionFromRowLocation(loc, pos);
    if (!open_conglom.latchPage(pos)) {
        return (false);
    }
    if (open_conglom.isForUpdate()) {
        open_conglom.lockPositionForWrite(pos, true);
    } else {
        open_conglom.lockPositionForRead(pos, (RowPosition) null, false, true);
    }
    if (pos.current_page == null) {
        // false to indicate that the row is no longer valid. (DERBY-4676)
        return false;
    }
    // Fetch the row.
    // RESOLVE (STO061) - don't know whether the fetch is for update or not.
    // 
    // RESOLVE (mikem) - get rid of new here.
    boolean ret_val = (pos.current_page.fetchFromSlot(pos.current_rh, pos.current_slot, row, new FetchDescriptor(row.length, validColumns, (Qualifier[][]) null), false) != null);
    if (!open_conglom.isForUpdate())
        open_conglom.unlockPositionAfterRead(pos);
    pos.current_page.unlatch();
    return (ret_val);
}
Also used : FetchDescriptor(org.apache.derby.iapi.store.raw.FetchDescriptor) Qualifier(org.apache.derby.iapi.store.access.Qualifier)

Example 5 with Qualifier

use of org.apache.derby.iapi.store.access.Qualifier in project derby by apache.

the class StoredPage method qualifyRecordFromSlot.

/**
 * Process the list of qualifiers on the row in the stream.
 * <p>
 * The rawDataIn stream is expected to be positioned after the record
 * header.
 * <p>
 * Check all qualifiers in the qualifier array against row.  Return true
 * if all compares specified by the qualifier array return true, else
 * return false.
 * <p>
 * This routine assumes client caller has already checked if the row
 * is deleted or not.  The row that it get's is expected to match
 * the partial column list of the scan.
 * <p>
 * On entering this routine the stream should be positioned to the
 * beginning of the row data, just after the row header.  On exit
 * the stream will also be positioned there.
 *
 * A two dimensional array is to be used to pass around a AND's and OR's in
 * conjunctive normal form.  The top slot of the 2 dimensional array is
 * optimized for the more frequent where no OR's are present.  The first
 * array slot is always a list of AND's to be treated as described above
 * for single dimensional AND qualifier arrays.  The subsequent slots are
 * to be treated as AND'd arrays or OR's.  Thus the 2 dimensional array
 * qual[][] argument is to be treated as the following, note if
 * qual.length = 1 then only the first array is valid and it is and an
 * array of and clauses:
 *
 * (qual[0][0] and qual[0][0] ... and qual[0][qual[0].length - 1])
 * and
 * (qual[1][0] or  qual[1][1] ... or  qual[1][qual[1].length - 1])
 * and
 * (qual[2][0] or  qual[2][1] ... or  qual[2][qual[2].length - 1])
 * ...
 * and
 * (qual[qual.length - 1][0] or  qual[1][1] ... or  qual[1][2])
 *
 * @return Whether or not the row input qualifies.
 *
 * @param row                   restore row into this object array.
 * @param offset_to_row_data    offset in bytes from top of page to row
 * @param fetchDesc             Description of fetch including which cols
 *                              and qualifiers.
 * @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 qualifyRecordFromSlot(Object[] row, int offset_to_row_data, FetchDescriptor fetchDesc, StoredRecordHeader recordHeader, RecordHandle recordToLock) throws StandardException, IOException {
    boolean row_qualifies = true;
    Qualifier[][] qual_list = fetchDesc.getQualifierList();
    int[] materializedCols = fetchDesc.getMaterializedColumns();
    if (SanityManager.DEBUG) {
        SanityManager.ASSERT(qual_list != null, "Not coded yet!");
    }
    if (SanityManager.DEBUG) {
        SanityManager.ASSERT(row != null);
    }
    for (int i = 0; i < qual_list[0].length; i++) {
        // process each AND clause
        row_qualifies = false;
        // Apply one qualifier to the row.
        Qualifier q = qual_list[0][i];
        int col_id = q.getColumnId();
        if (SanityManager.DEBUG) {
            SanityManager.ASSERT((col_id < row.length), "Qualifier is referencing a column not in the row.");
        }
        // materialize the column object if we haven't done it yet.
        if (materializedCols[col_id] == 0) {
            // materialize just this column from the row, no qualifiers
            readOneColumnFromPage(row, col_id, offset_to_row_data, recordHeader, recordToLock);
            // mark offset, indicating the row has been read in.
            // 
            // RESOLVE (mikem) - right now value of entry is useless, it
            // is an int so that in the future we could cache the offset
            // to fields to improve performance of getting to a column
            // after qualifying.
            materializedCols[col_id] = offset_to_row_data;
        }
        if (SanityManager.DEBUG) {
            if (row[col_id] == null)
                SanityManager.THROWASSERT("1:row = " + RowUtil.toString(row) + "row.length = " + row.length + ";q.getColumnId() = " + q.getColumnId());
        }
        // do the compare between the column value and value in the
        // qualifier.
        row_qualifies = ((DataValueDescriptor) row[col_id]).compare(q.getOperator(), q.getOrderable(), q.getOrderedNulls(), q.getUnknownRV());
        if (q.negateCompareResult())
            row_qualifies = !row_qualifies;
        // Once an AND fails the whole Qualification fails - do a return!
        if (!row_qualifies)
            return (false);
    }
    for (int and_idx = 1; and_idx < qual_list.length; and_idx++) {
        // loop through each of the "and" clause.
        row_qualifies = false;
        for (int or_idx = 0; or_idx < qual_list[and_idx].length; or_idx++) {
            // Apply one qualifier to the row.
            Qualifier q = qual_list[and_idx][or_idx];
            int col_id = q.getColumnId();
            if (SanityManager.DEBUG) {
                SanityManager.ASSERT((col_id < row.length), "Qualifier is referencing a column not in the row.");
            }
            // materialize the column object if we haven't done it yet.
            if (materializedCols[col_id] == 0) {
                // materialize just this column from the row, no qualifiers
                readOneColumnFromPage(row, col_id, offset_to_row_data, recordHeader, recordToLock);
                // mark offset, indicating the row has been read in.
                // 
                // RESOLVE (mikem) - right now value of entry is useless, it
                // is an int so that in the future we could cache the offset
                // to fields to improve performance of getting to a column
                // after qualifying.
                materializedCols[col_id] = offset_to_row_data;
            }
            if (SanityManager.DEBUG) {
                if (row[col_id] == null)
                    SanityManager.THROWASSERT("1:row = " + RowUtil.toString(row) + "row.length = " + row.length + ";q.getColumnId() = " + q.getColumnId());
            }
            // do the compare between the column value and value in the
            // qualifier.
            row_qualifies = ((DataValueDescriptor) row[col_id]).compare(q.getOperator(), q.getOrderable(), q.getOrderedNulls(), q.getUnknownRV());
            if (q.negateCompareResult())
                row_qualifies = !row_qualifies;
            // to go and process next AND clause.
            if (row_qualifies)
                break;
        }
        // qualifications so as soon as one is false processing is done.
        if (!row_qualifies)
            break;
    }
    return (row_qualifies);
}
Also used : Qualifier(org.apache.derby.iapi.store.access.Qualifier)

Aggregations

Qualifier (org.apache.derby.iapi.store.access.Qualifier)12 DataValueDescriptor (org.apache.derby.iapi.types.DataValueDescriptor)6 FetchDescriptor (org.apache.derby.iapi.store.raw.FetchDescriptor)4 List (java.util.List)1 FormatableBitSet (org.apache.derby.iapi.services.io.FormatableBitSet)1 Storable (org.apache.derby.iapi.services.io.Storable)1 StatementContext (org.apache.derby.iapi.sql.conn.StatementContext)1 ExecRow (org.apache.derby.iapi.sql.execute.ExecRow)1 ConglomerateController (org.apache.derby.iapi.store.access.ConglomerateController)1 KeyHasher (org.apache.derby.iapi.store.access.KeyHasher)1 AuxObject (org.apache.derby.iapi.store.raw.AuxObject)1 RowLocation (org.apache.derby.iapi.types.RowLocation)1 SQLLongint (org.apache.derby.iapi.types.SQLLongint)1 StorableFormatId (org.apache.derby.impl.store.access.StorableFormatId)1