use of org.apache.geode.cache.query.internal.IndexInfo in project geode by apache.
the class CompactRangeIndex method addToResultsFromEntries.
/*
*
* @param lowerBoundKey the index key to match on for a lower bound on a ranged query, otherwise
* the key to match on
*
* @param upperBoundKey the index key to match on for an upper bound on a ranged query, otherwise
* null
*
* @param lowerBoundOperator the operator to use to determine a match against the lower bound
*
* @param upperBoundOperator the operator to use to determine a match against the upper bound
*/
private void addToResultsFromEntries(Object lowerBoundKey, Object upperBoundKey, int lowerBoundOperator, int upperBoundOperator, CloseableIterator<IndexStoreEntry> entriesIter, Collection result, CompiledValue iterOps, RuntimeIterator runtimeItr, ExecutionContext context, List projAttrib, SelectResults intermediateResults, boolean isIntersection, int limit) throws FunctionDomainException, TypeMismatchException, NameResolutionException, QueryInvocationTargetException {
QueryObserver observer = QueryObserverHolder.getInstance();
boolean limitApplied = false;
if (entriesIter == null || (limitApplied = verifyLimit(result, limit))) {
if (limitApplied) {
if (observer != null) {
observer.limitAppliedAtIndexLevel(this, limit, result);
}
}
return;
}
Set seenKey = null;
if (IndexManager.IS_TEST_EXPANSION) {
seenKey = new HashSet();
}
while (entriesIter.hasNext()) {
try {
// Check if query execution on this thread is canceled.
QueryMonitor.isQueryExecutionCanceled();
if (IndexManager.testHook != null) {
if (this.region.getCache().getLogger().fineEnabled()) {
this.region.getCache().getLogger().fine("IndexManager TestHook is set in addToResultsFromEntries.");
}
IndexManager.testHook.hook(11);
}
IndexStoreEntry indexEntry = null;
try {
indexEntry = entriesIter.next();
} catch (NoSuchElementException ignore) {
// Continue from while.
continue;
}
Object value = indexEntry.getDeserializedValue();
if (IndexManager.IS_TEST_EXPANSION) {
Object rk = indexEntry.getDeserializedRegionKey();
if (seenKey.contains(rk)) {
continue;
}
seenKey.add(rk);
List expandedResults = expandValue(context, lowerBoundKey, upperBoundKey, lowerBoundOperator, upperBoundOperator, value);
Iterator iterator = ((Collection) expandedResults).iterator();
while (iterator.hasNext()) {
value = iterator.next();
if (value != null) {
boolean ok = true;
if (runtimeItr != null) {
runtimeItr.setCurrent(value);
}
if (ok && runtimeItr != null && iterOps != null) {
ok = QueryUtils.applyCondition(iterOps, context);
}
if (ok) {
if (context != null && context.isCqQueryContext()) {
result.add(new CqEntry(indexEntry.getDeserializedRegionKey(), value));
} else {
applyProjection(projAttrib, context, result, value, intermediateResults, isIntersection);
}
if (verifyLimit(result, limit)) {
observer.limitAppliedAtIndexLevel(this, limit, result);
return;
}
}
}
}
} else {
if (value != null) {
boolean ok = true;
if (indexEntry.isUpdateInProgress() || TEST_ALWAYS_UPDATE_IN_PROGRESS) {
IndexInfo indexInfo = (IndexInfo) context.cacheGet(CompiledValue.INDEX_INFO);
if (runtimeItr == null) {
runtimeItr = getRuntimeIteratorForThisIndex(context, indexInfo);
if (runtimeItr == null) {
// could not match index with iterator
throw new QueryInvocationTargetException("Query alias's must be used consistently");
}
}
runtimeItr.setCurrent(value);
// Verify index key in region entry value.
ok = evaluateEntry((IndexInfo) indexInfo, context, null);
}
if (runtimeItr != null) {
runtimeItr.setCurrent(value);
}
if (ok && runtimeItr != null && iterOps != null) {
ok = QueryUtils.applyCondition(iterOps, context);
}
if (ok) {
if (context != null && context.isCqQueryContext()) {
result.add(new CqEntry(indexEntry.getDeserializedRegionKey(), value));
} else {
if (IndexManager.testHook != null) {
IndexManager.testHook.hook(200);
}
applyProjection(projAttrib, context, result, value, intermediateResults, isIntersection);
}
if (verifyLimit(result, limit)) {
observer.limitAppliedAtIndexLevel(this, limit, result);
return;
}
}
}
}
} catch (ClassCastException | EntryDestroyedException ignore) {
// ignore it
}
}
}
use of org.apache.geode.cache.query.internal.IndexInfo in project geode by apache.
the class AbstractIndex method populateListForEquiJoin.
/**
* This will populate resultSet from both type of indexes, {@link CompactRangeIndex} and
* {@link RangeIndex}.
*/
void populateListForEquiJoin(List list, Object outerEntries, Object innerEntries, ExecutionContext context, Object key) throws FunctionDomainException, TypeMismatchException, NameResolutionException, QueryInvocationTargetException {
Assert.assertTrue(outerEntries != null && innerEntries != null, "OuterEntries or InnerEntries must not be null");
Object[][] values = new Object[2][];
Iterator itr = null;
int j = 0;
while (j < 2) {
boolean isRangeIndex = false;
if (j == 0) {
if (outerEntries instanceof RegionEntryToValuesMap) {
itr = ((RegionEntryToValuesMap) outerEntries).map.entrySet().iterator();
isRangeIndex = true;
} else if (outerEntries instanceof CloseableIterator) {
itr = (Iterator) outerEntries;
}
} else {
if (innerEntries instanceof RegionEntryToValuesMap) {
itr = ((RegionEntryToValuesMap) innerEntries).map.entrySet().iterator();
isRangeIndex = true;
} else if (innerEntries instanceof CloseableIterator) {
itr = (Iterator) innerEntries;
}
}
// extract the values from the RegionEntries
List dummy = new ArrayList();
RegionEntry re = null;
IndexStoreEntry ie = null;
Object val = null;
Object entryVal = null;
IndexInfo[] indexInfo = (IndexInfo[]) context.cacheGet(CompiledValue.INDEX_INFO);
IndexInfo indInfo = indexInfo[j];
while (itr.hasNext()) {
if (isRangeIndex) {
Map.Entry entry = (Map.Entry) itr.next();
val = entry.getValue();
if (val instanceof Collection) {
entryVal = ((Iterable) val).iterator().next();
} else {
entryVal = val;
}
re = (RegionEntry) entry.getKey();
} else {
ie = (IndexStoreEntry) itr.next();
}
// Bug#41010: We need to verify if Inner and Outer Entries
// are consistent with index key values.
boolean ok = true;
if (isRangeIndex) {
if (re.isUpdateInProgress()) {
ok = ((RangeIndex) indInfo._getIndex()).verifyEntryAndIndexValue(re, entryVal, context);
}
} else if (ie.isUpdateInProgress()) {
ok = ((CompactRangeIndex) indInfo._getIndex()).verifyInnerAndOuterEntryValues(ie, context, indInfo, key);
}
if (ok) {
if (isRangeIndex) {
if (val instanceof Collection) {
dummy.addAll((Collection) val);
} else {
dummy.add(val);
}
} else {
if (IndexManager.IS_TEST_EXPANSION) {
dummy.addAll(((CompactRangeIndex) indInfo._getIndex()).expandValue(context, key, null, OQLLexerTokenTypes.TOK_EQ, -1, ie.getDeserializedValue()));
} else {
dummy.add(ie.getDeserializedValue());
}
}
}
}
Object[] newValues = new Object[dummy.size()];
dummy.toArray(newValues);
values[j++] = newValues;
}
list.add(values);
}
use of org.apache.geode.cache.query.internal.IndexInfo in project geode by apache.
the class HashIndex method addValueToResultSet.
private void addValueToResultSet(RegionEntry re, Collection result, CompiledValue iterOps, RuntimeIterator runtimeItr, ExecutionContext context, List projAttrib, SelectResults intermediateResults, boolean isIntersection, int limit, QueryObserver observer, long iteratorCreationTime) throws FunctionDomainException, TypeMismatchException, NameResolutionException, QueryInvocationTargetException {
Object value = getTargetObject(re);
if (value != null) {
boolean ok = true;
// we will reevaluate to be sure the value still matches the key
if (re.isUpdateInProgress() || IndexManager.needsRecalculation(iteratorCreationTime, re.getLastModified())) {
IndexInfo indexInfo = (IndexInfo) context.cacheGet(CompiledValue.INDEX_INFO);
if (runtimeItr == null) {
runtimeItr = getRuntimeIteratorForThisIndex(context, indexInfo);
if (runtimeItr == null) {
// could not match index with iterator
throw new QueryInvocationTargetException("Query alias's must be used consistently");
}
}
runtimeItr.setCurrent(value);
// Verify index key in region entry value.
ok = evaluateEntry(indexInfo, context, null);
}
if (runtimeItr != null) {
runtimeItr.setCurrent(value);
}
if (ok && runtimeItr != null && iterOps != null) {
ok = QueryUtils.applyCondition(iterOps, context);
}
if (ok) {
if (context != null && context.isCqQueryContext()) {
result.add(new CqEntry(re.getKey(), value));
} else {
applyProjection(projAttrib, context, result, value, intermediateResults, isIntersection);
}
if (limit != -1 && result.size() == limit) {
observer.limitAppliedAtIndexLevel(this, limit, result);
return;
}
}
}
}
use of org.apache.geode.cache.query.internal.IndexInfo in project geode by apache.
the class HashIndex method evaluateEntry.
/**
* This evaluates the left and right side of a where condition for which this Index was used.
* Like, if condition is "ID > 1", {@link IndexInfo} will contain Left as ID, Right as '1' and
* operator as TOK_GT. This method will evaluate ID from region entry value and verify the ID > 1.
*
* Note: IndexInfo is created for each query separately based on the condition being evaluated
* using the Index.
*
* @return true if RegionEntry value satisfies the where condition (contained in IndexInfo).
*/
private boolean evaluateEntry(IndexInfo indexInfo, ExecutionContext context, Object keyVal) throws FunctionDomainException, TypeMismatchException, NameResolutionException, QueryInvocationTargetException {
CompiledValue path = ((IndexInfo) indexInfo)._path();
Object left = path.evaluate(context);
CompiledValue key = ((IndexInfo) indexInfo)._key();
Object right = null;
// For CompiledUndefined indexInfo has null key.
if (keyVal == null && key == null) {
if (left == QueryService.UNDEFINED) {
return true;
} else {
return false;
}
}
if (key != null) {
right = key.evaluate(context);
} else {
right = keyVal;
}
int operator = indexInfo._operator();
if (left == null && right == null) {
return Boolean.TRUE;
} else {
return (Boolean) TypeUtils.compare(left, right, operator);
}
}
use of org.apache.geode.cache.query.internal.IndexInfo in project geode by apache.
the class CompactRangeIndex method evaluateEntry.
/**
* This evaluates the left and right side of a where condition for which this Index was used.
* Like, if condition is "ID > 1", {@link IndexInfo} will contain Left as ID, Right as '1' and
* operator as TOK_GT. This method will evaluate ID from region entry value and verify the ID > 1.
*
* Note: IndexInfo is created for each query separately based on the condition being evaluated
* using the Index.
*
* @return true if RegionEntry value satisfies the where condition (contained in IndexInfo).
*/
protected boolean evaluateEntry(IndexInfo indexInfo, ExecutionContext context, Object keyVal) throws FunctionDomainException, TypeMismatchException, NameResolutionException, QueryInvocationTargetException {
CompiledValue path = ((IndexInfo) indexInfo)._path();
Object left = path.evaluate(context);
CompiledValue key = ((IndexInfo) indexInfo)._key();
Object right = null;
// For CompiledUndefined indexInfo has null key.
if (keyVal == null && key == null) {
if (left == QueryService.UNDEFINED) {
return true;
} else {
return false;
}
}
if (key != null) {
right = key.evaluate(context);
// a tuple. In other cases it does not
if (null != right && indexInfo._getIndex() instanceof CompactMapRangeIndex && right instanceof Object[]) {
right = ((Object[]) right)[0];
}
} else {
right = keyVal;
}
int operator = indexInfo._operator();
if (left == null && right == null) {
return Boolean.TRUE;
} else {
if (left instanceof PdxString) {
if (right instanceof String) {
switch(key.getType()) {
case CompiledValue.LITERAL:
right = ((CompiledLiteral) key).getSavedPdxString();
break;
case OQLLexerTokenTypes.QUERY_PARAM:
right = ((CompiledBindArgument) key).getSavedPdxString(context);
break;
case CompiledValue.FUNCTION:
case CompiledValue.PATH:
right = new PdxString((String) right);
}
}
}
Object result = TypeUtils.compare(left, right, operator);
// either of them is null and operator is other than == or !=
if (result == QueryService.UNDEFINED) {
// Undefined is added to results for != conditions only
if (operator != OQLLexerTokenTypes.TOK_NE || operator != OQLLexerTokenTypes.TOK_NE_ALT) {
return Boolean.TRUE;
} else {
return Boolean.FALSE;
}
} else {
return (Boolean) result;
}
}
}
Aggregations