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;
}
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);
}
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);
}
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);
}
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);
}
Aggregations