use of org.apache.geode.cache.query.internal.types.ObjectTypeImpl in project geode by apache.
the class CompiledSelect method evaluate.
public SelectResults evaluate(ExecutionContext context) throws FunctionDomainException, TypeMismatchException, NameResolutionException, QueryInvocationTargetException {
context.newScope((Integer) context.cacheGet(scopeID));
context.pushExecCache((Integer) context.cacheGet(scopeID));
context.setDistinct(this.distinct);
if (this.hasUnmappedOrderByCols && context.getBucketList() != null) {
throw new QueryInvalidException(LocalizedStrings.DefaultQuery_ORDER_BY_ATTRIBS_NOT_PRESENT_IN_PROJ.toLocalizedString());
}
if (hints != null) {
context.cachePut(QUERY_INDEX_HINTS, hints);
}
try {
// set flag to keep objects serialized for "select *" queries
if ((DefaultQuery) context.getQuery() != null) {
((DefaultQuery) context.getQuery()).keepResultsSerialized(this, context);
}
Iterator iter = iterators.iterator();
while (iter.hasNext()) {
CompiledIteratorDef iterDef = (CompiledIteratorDef) iter.next();
RuntimeIterator rIter = iterDef.getRuntimeIterator(context);
context.bindIterator(rIter);
// Ideally the function below should always be called after binding has occurred
// So that the internal ID gets set during binding to the scope. If not so then chances
// are that internal_id is still null causing index_internal_id to be null.
// Though in our case it may not be an issue as the compute dependency phase must have
// already set the index id
}
Integer limitValue = evaluateLimitValue(context, this.limit);
SelectResults result = null;
boolean evalAsFilters = false;
if (this.whereClause == null) {
result = doIterationEvaluate(context, false);
} else {
if (!this.whereClause.isDependentOnCurrentScope(context)) {
// independent
// where
// @todo
// check
// for
// dependency
// on
// current
// scope
// only?
// clause
Object b = this.whereClause.evaluate(context);
if (b == null || b == QueryService.UNDEFINED) {
// treat as if all elements are undefined
result = prepareEmptyResultSet(context, false);
// ResultsSet.emptyResultsSet(resultSet, 0);
// return result;
} else if (!(b instanceof Boolean)) {
throw new TypeMismatchException(LocalizedStrings.CompiledSelect_THE_WHERE_CLAUSE_WAS_TYPE_0_INSTEAD_OF_BOOLEAN.toLocalizedString(b.getClass().getName()));
} else if ((Boolean) b) {
result = doIterationEvaluate(context, false);
} else {
result = prepareEmptyResultSet(context, false);
// ResultsSet.emptyResultsSet(resultSet, 0);
// return result;
}
} else {
// Check the numer of independent iterators
int numInd = context.getAllIndependentIteratorsOfCurrentScope().size();
// If order by clause is defined, then the first column should be the preferred index
if (this.orderByAttrs != null && numInd == 1) {
CompiledSortCriterion csc = (CompiledSortCriterion) orderByAttrs.get(0);
StringBuilder preferredIndexCondn = new StringBuilder();
this.evalCanonicalizedExpressionForCSC(csc, context, preferredIndexCondn);
context.cachePut(PREF_INDEX_COND, preferredIndexCondn.toString());
}
boolean unlock = true;
Object obj = context.cacheGet(this.whereClause);
if (obj != null && (obj instanceof IndexInfo[] || obj.equals(CLAUSE_EVALUATED))) {
// if indexinfo is cached means the read lock
// is not being taken this time, so releasing
// the lock is not required
unlock = false;
}
// see if we should evaluate as filters,
// and count how many actual index lookups will be performed
PlanInfo planInfo = this.whereClause.getPlanInfo(context);
if (context.cacheGet(this.whereClause) == null) {
context.cachePut(this.whereClause, CLAUSE_EVALUATED);
}
try {
evalAsFilters = planInfo.evalAsFilter;
// let context know if there is exactly one index lookup
context.setOneIndexLookup(planInfo.indexes.size() == 1);
if (evalAsFilters) {
((QueryExecutionContext) context).setIndexUsed(true);
// Ignore order by attribs for a while
boolean canApplyOrderByAtIndex = false;
if (limitValue >= 0 && numInd == 1 && ((Filter) this.whereClause).isLimitApplicableAtIndexLevel(context)) {
context.cachePut(CAN_APPLY_LIMIT_AT_INDEX, Boolean.TRUE);
}
StringBuilder temp = null;
if (this.orderByAttrs != null) {
temp = new StringBuilder();
CompiledSortCriterion csc = (CompiledSortCriterion) this.orderByAttrs.get(0);
this.evalCanonicalizedExpressionForCSC(csc, context, temp);
}
boolean needsTopLevelOrdering = true;
if (temp != null && numInd == 1 && ((Filter) this.whereClause).isOrderByApplicableAtIndexLevel(context, temp.toString())) {
context.cachePut(CAN_APPLY_ORDER_BY_AT_INDEX, Boolean.TRUE);
context.cachePut(ORDERBY_ATTRIB, this.orderByAttrs);
canApplyOrderByAtIndex = true;
if (this.orderByAttrs.size() == 1) {
needsTopLevelOrdering = false;
// we should use a sorted set
if (this.limit != null) {
// Currently check bucket list to determine if it's a pr query
if (context.getBucketList() != null && context.getBucketList().size() > 0) {
needsTopLevelOrdering = true;
}
}
}
} else if (temp != null) {
// If order by is present but cannot be applied at index level,
// then limit also cannot be applied
// at index level
context.cachePut(CAN_APPLY_LIMIT_AT_INDEX, Boolean.FALSE);
}
context.cachePut(RESULT_LIMIT, limitValue);
if (numInd == 1 && ((Filter) this.whereClause).isProjectionEvaluationAPossibility(context) && (this.orderByAttrs == null || (canApplyOrderByAtIndex && !needsTopLevelOrdering)) && this.projAttrs != null) {
// Possibility of evaluating the resultset as filter itself
ObjectType resultType = this.cachedElementTypeForOrderBy != null ? this.cachedElementTypeForOrderBy : this.prepareResultType(context);
context.cachePut(RESULT_TYPE, resultType);
context.cachePut(PROJ_ATTRIB, this.projAttrs);
}
result = ((Filter) this.whereClause).filterEvaluate(context, null);
if (!(context.cacheGet(RESULT_TYPE) instanceof Boolean)) {
QueryObserverHolder.getInstance().beforeApplyingProjectionOnFilterEvaluatedResults(result);
result = applyProjectionOnCollection(result, context, !needsTopLevelOrdering);
}
} else {
// otherwise iterate over the single from var to evaluate
result = doIterationEvaluate(context, true);
}
} finally {
// because we need to select index which can be read-locked.
if (unlock) {
releaseReadLockOnUsedIndex(planInfo);
}
}
}
}
// if (result == null) { return QueryService.UNDEFINED; }
assert result != null;
// drop duplicates if this is DISTINCT
if (result instanceof SelectResults) {
SelectResults sr = (SelectResults) result;
CollectionType colnType = sr.getCollectionType();
// if (this.distinct && colnType.allowsDuplicates()) {
if (this.distinct) {
Collection r;
// Set s = sr.asSet();
if (colnType.allowsDuplicates()) {
// don't just convert to a ResultsSet (or StructSet), since
// the bags can convert themselves to a Set more efficiently
r = sr.asSet();
} else {
r = sr;
}
result = new ResultsCollectionWrapper(colnType.getElementType(), r, limitValue);
if (r instanceof Bag.SetView) {
((ResultsCollectionWrapper) result).setModifiable(false);
}
} else {
// SelectResults is of type
if (limitValue > -1) {
((Bag) sr).applyLimit(limitValue);
}
}
/*
* We still have to get size of SelectResults in some cases like, if index was used OR query
* is a distinct query.
*
* If SelectResult size is zero then we need to put Integer for 0 count.
*/
if (this.count) {
SelectResults res = (SelectResults) result;
if ((this.distinct || evalAsFilters || countStartQueryResult == 0)) {
// at coordinator node for PR queries.
if (context.getBucketList() != null && this.distinct) {
return result;
}
// Take size and empty the results
int resultCount = res.size();
res.clear();
ResultsBag countResult = new ResultsBag(new ObjectTypeImpl(Integer.class), context.getCachePerfStats());
countResult.addAndGetOccurence(resultCount);
result = countResult;
} else {
((Bag) res).addAndGetOccurence(countStartQueryResult);
}
}
}
return result;
} finally {
context.popScope();
context.popExecCache();
}
}
use of org.apache.geode.cache.query.internal.types.ObjectTypeImpl in project geode by apache.
the class QueryMessage method getNextReplyObject.
/**
* Provide results to send back to requestor. terminate by returning END_OF_STREAM token object
*/
@Override
protected Object getNextReplyObject(PartitionedRegion pr) throws CacheException, ForceReattemptException, InterruptedException {
final boolean isDebugEnabled = logger.isDebugEnabled();
if (QueryMonitor.isLowMemory()) {
String reason = LocalizedStrings.QueryMonitor_LOW_MEMORY_CANCELED_QUERY.toLocalizedString(QueryMonitor.getMemoryUsedDuringLowMemory());
throw new QueryExecutionLowMemoryException(reason);
}
if (Thread.interrupted()) {
throw new InterruptedException();
}
while (this.currentResultIterator == null || !this.currentResultIterator.hasNext()) {
if (this.currentSelectResultIterator.hasNext()) {
if (this.isTraceInfoIteration && this.currentResultIterator != null) {
this.isTraceInfoIteration = false;
}
Collection results = this.currentSelectResultIterator.next();
if (isDebugEnabled) {
logger.debug("Query result size: {}", results.size());
}
this.currentResultIterator = results.iterator();
} else {
return Token.END_OF_STREAM;
}
}
Object data = this.currentResultIterator.next();
boolean isPostGFE_8_1 = this.getSender().getVersionObject().compareTo(Version.GFE_81) > 0;
// inaccurate struct type for backward compatibility.
if (this.isStructType && !this.isTraceInfoIteration && isPostGFE_8_1) {
return ((Struct) data).getFieldValues();
} else if (this.isStructType && !this.isTraceInfoIteration) {
Struct struct = (Struct) data;
ObjectType[] fieldTypes = struct.getStructType().getFieldTypes();
for (int i = 0; i < fieldTypes.length; ++i) {
fieldTypes[i] = new ObjectTypeImpl(Object.class);
}
return data;
} else {
return data;
}
}
use of org.apache.geode.cache.query.internal.types.ObjectTypeImpl in project geode by apache.
the class IndexCreationJUnitTest method testIndexObjectTypeWithRegionConstraint.
@Test
public void testIndexObjectTypeWithRegionConstraint() throws Exception {
QueryService qs;
qs = CacheUtils.getQueryService();
Index i1 = qs.createIndex("Index1", IndexType.FUNCTIONAL, "b.secId", "/portfolios pf, pf.positions.values b");
ObjectType type = ((IndexProtocol) i1).getResultSetType();
String[] fieldNames = { "index_iter1", "index_iter2" };
ObjectType[] fieldTypes = { new ObjectTypeImpl(Portfolio.class), new ObjectTypeImpl(Object.class) };
// ObjectType expectedType = new StructTypeImpl( fieldNames,fieldTypes);
ObjectType expectedType = new StructTypeImpl(fieldNames, fieldTypes);
if (!(type instanceof StructType && type.equals(expectedType))) {
fail("The ObjectType obtained from index is not of the expected type. Type obtained from index=" + type);
}
Index i2 = qs.createIndex("Index2", IndexType.FUNCTIONAL, "pf.ID", "/portfolios.values pf");
type = ((IndexProtocol) i2).getResultSetType();
expectedType = new ObjectTypeImpl(Portfolio.class);
if (!type.equals(expectedType)) {
fail("The ObjectType obtained from index is not of the expected type. Type obtained from index=" + type);
}
Index i3 = qs.createIndex("Index3", IndexType.FUNCTIONAL, "pos.secId", "/portfolios['0'].positions.values pos");
type = ((IndexProtocol) i3).getResultSetType();
expectedType = new ObjectTypeImpl(Object.class);
if (!type.equals(expectedType)) {
fail("The ObjectType obtained from index is not of the expected type. Type obtained from index=" + type);
}
Index i4 = qs.createIndex("Index4", IndexType.PRIMARY_KEY, "ID", "/portfolios");
type = ((IndexProtocol) i4).getResultSetType();
expectedType = new ObjectTypeImpl(Portfolio.class);
if (!type.equals(expectedType)) {
fail("The ObjectType obtained from index is not of the expected type. Type obtained from index=" + type);
}
}
Aggregations