📄 hashtableresultset.java
字号:
if (SanityManager.DEBUG) { // Columns is really a Storable[] for (int i = 0; i < columns.length; i++) { if (! (columns[0] 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; /* We've already "evaluated" the 1st keyColumns qualifiers * when we probed into the hash table, but we need to * evaluate them again here because of the behavior of * NULLs. NULLs are treated as equal when building and * probing the hash table so that we only get a single * entry. However, NULL does not equal NULL, so the * compare() method below will eliminate any row that * has a key column containing a NULL. */ // RESOLVE (mikem) will have to change when qualifiers // support OR's. 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); } currentRow = result; 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; } /** * Return the total amount of time spent in this ResultSet * * @param type CURRENT_RESULTSET_ONLY - time spent only in this ResultSet * ENTIRE_RESULTSET_TREE - time spent in this ResultSet and below. * * @return long The total amount of time spent (in milliseconds). */ public long getTimeSpent(int type) { long totTime = constructorTime + openTime + nextTime + closeTime; if (type == CURRENT_RESULTSET_ONLY) { return totTime - source.getTimeSpent(ENTIRE_RESULTSET_TREE); } else { return totTime; } } // ResultSet interface /** * If the result set has been opened, * close the open scan. * * @exception StandardException thrown on error */ public void close() throws StandardException { beginTime = getCurrentTimeMillis(); if ( isOpen ) { // we don't want to keep around a pointer to the // row ... so it can be thrown away. // REVISIT: does this need to be in a finally // block, to ensure that it is executed? clearCurrentRow(); if (closeCleanup != null) { closeCleanup.invoke(activation); // let activation tidy up } currentRow = null; source.close(); super.close(); if (hashTableBuilt) { // close the hash table, eating any exception ht.close(); ht = null; hashTableBuilt = false; } } else if (SanityManager.DEBUG) SanityManager.DEBUG("CloseRepeatInfo","Close of ProjectRestrictResultSet repeated"); closeTime += getElapsedMillis(beginTime); } // // CursorResultSet interface // /** * Gets information from its source. We might want * to have this take a CursorResultSet in its constructor some day, * instead of doing a cast here? * * @see CursorResultSet * * @return the row location of the current cursor row. * @exception StandardException thrown on failure. */ public RowLocation getRowLocation() throws StandardException { if (SanityManager.DEBUG) SanityManager.ASSERT(source instanceof CursorResultSet, "source not instance of CursorResultSet"); return ( (CursorResultSet)source ).getRowLocation(); } /** * Gets last row returned. * * @see CursorResultSet * * @return the last row returned. * @exception StandardException thrown on failure. */ /* RESOLVE - this should return activation.getCurrentRow(resultSetNumber), * once there is such a method. (currentRow is redundant) */ public ExecRow getCurrentRow() throws StandardException { ExecRow candidateRow = null; ExecRow result = null; boolean restrict = false; DataValueDescriptor restrictBoolean; if (SanityManager.DEBUG) SanityManager.ASSERT(isOpen, "PRRS is expected to be open"); /* Nothing to do if we're not currently on a row */ if (currentRow == null) { return null; } /* Call the child result set to get it's current row. * If no row exists, then return null, else requalify it * before returning. */ candidateRow = ((CursorResultSet) source).getCurrentRow(); if (candidateRow != null) { setCurrentRow(candidateRow); /* If restriction is null, then all rows qualify */ restrictBoolean = (DataValueDescriptor) ((singleTableRestriction == null) ? null : singleTableRestriction.invoke(activation)); // if the result is null, we make it false -- // so the row won't be returned. restrict = (restrictBoolean == null) || ((! restrictBoolean.isNull()) && restrictBoolean.getBoolean()); } if (candidateRow != null && restrict) { result = doProjection(candidateRow); } currentRow = result; /* Clear the current row, if null */ if (result == null) { clearCurrentRow(); } return currentRow; } /** * Do the projection against the source row. Use reflection * where necessary, otherwise get the source column into our * result row. * * @param sourceRow The source row. * * @return The result of the projection * * @exception StandardException thrown on failure. */ private ExecRow doProjection(ExecRow sourceRow) throws StandardException { // No need to use reflection if reusing the result if (reuseResult && projRow != null) { return projRow; } ExecRow result; // Use reflection to do as much of projection as required if (projection != null) { result = (ExecRow) projection.invoke(activation); } else { result = mappedResultRow; } // Copy any mapped columns from the source for (int index = 0; index < projectMapping.length; index++) { if (projectMapping[index] != -1) { result.setColumn(index + 1, sourceRow.getColumn(projectMapping[index])); } } /* We need to reSet the current row after doing the projection */ setCurrentRow(result); /* Remember the result if reusing it */ if (reuseResult) { projRow = result; } return result; } // RowSource interface /** * @see RowSource#getNextRowFromRowSource * @exception StandardException on error */ public DataValueDescriptor[] getNextRowFromRowSource() throws StandardException { ExecRow execRow = source.getNextRowCore(); /* Use the single table predicates, if any, * to filter out rows while populating the * hash table. */ while (execRow != null) { boolean restrict = false; DataValueDescriptor restrictBoolean; rowsSeen++; /* If restriction is null, then all rows qualify */ restrictBoolean = (DataValueDescriptor) ((singleTableRestriction == null) ? null : singleTableRestriction.invoke(activation)); // if the result is null, we make it false -- // so the row won't be returned. restrict = (restrictBoolean == null) || ((! restrictBoolean.isNull()) && restrictBoolean.getBoolean()); if (!restrict) { execRow = source.getNextRowCore(); continue; } if (targetResultSet != null) { /* Let the target preprocess the row. For now, this * means doing an in place clone on any indexed columns * to optimize cloning and so that we don't try to drain * a stream multiple times. This is where we also * enforce any check constraints. */ clonedExecRow = targetResultSet.preprocessSourceRow(execRow); } /* Get a single ExecRow of the same size * on the way in so that we have a row * to use on the way out. */ if (firstIntoHashtable) { nextCandidate = activation.getExecutionFactory().getValueRow(execRow.nColumns()); firstIntoHashtable = false; } return execRow.getRowArray(); } return null; } /** * Is this ResultSet or it's source result set for update * * @return Whether or not the result set is for update. */ public boolean isForUpdate() { if (source == null) { return false; } return source.isForUpdate(); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -