Search in sources :

Example 51 with ObjectTypeImpl

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();
    }
}
Also used : TypeMismatchException(org.apache.geode.cache.query.TypeMismatchException) ObjectType(org.apache.geode.cache.query.types.ObjectType) SelectResults(org.apache.geode.cache.query.SelectResults) CollectionType(org.apache.geode.cache.query.types.CollectionType) Iterator(java.util.Iterator) QueryInvalidException(org.apache.geode.cache.query.QueryInvalidException) ObjectTypeImpl(org.apache.geode.cache.query.internal.types.ObjectTypeImpl) Collection(java.util.Collection)

Example 52 with ObjectTypeImpl

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;
    }
}
Also used : QueryExecutionLowMemoryException(org.apache.geode.cache.query.QueryExecutionLowMemoryException) ObjectTypeImpl(org.apache.geode.cache.query.internal.types.ObjectTypeImpl) Collection(java.util.Collection) Struct(org.apache.geode.cache.query.Struct)

Example 53 with ObjectTypeImpl

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);
    }
}
Also used : IndexProtocol(org.apache.geode.cache.query.internal.index.IndexProtocol) ObjectType(org.apache.geode.cache.query.types.ObjectType) StructType(org.apache.geode.cache.query.types.StructType) DefaultQueryService(org.apache.geode.cache.query.internal.DefaultQueryService) QueryService(org.apache.geode.cache.query.QueryService) Portfolio(org.apache.geode.cache.query.data.Portfolio) ObjectTypeImpl(org.apache.geode.cache.query.internal.types.ObjectTypeImpl) StructTypeImpl(org.apache.geode.cache.query.internal.types.StructTypeImpl) RangeIndex(org.apache.geode.cache.query.internal.index.RangeIndex) CompactMapRangeIndex(org.apache.geode.cache.query.internal.index.CompactMapRangeIndex) Index(org.apache.geode.cache.query.Index) CompactRangeIndex(org.apache.geode.cache.query.internal.index.CompactRangeIndex) Test(org.junit.Test) IntegrationTest(org.apache.geode.test.junit.categories.IntegrationTest)

Aggregations

ObjectTypeImpl (org.apache.geode.cache.query.internal.types.ObjectTypeImpl)53 Test (org.junit.Test)37 SelectResults (org.apache.geode.cache.query.SelectResults)31 ArrayList (java.util.ArrayList)27 Portfolio (org.apache.geode.cache.query.data.Portfolio)27 QueryService (org.apache.geode.cache.query.QueryService)25 ObjectType (org.apache.geode.cache.query.types.ObjectType)25 List (java.util.List)24 Query (org.apache.geode.cache.query.Query)24 Region (org.apache.geode.cache.Region)23 QueryObserverAdapter (org.apache.geode.cache.query.internal.QueryObserverAdapter)23 IntegrationTest (org.apache.geode.test.junit.categories.IntegrationTest)20 UnitTest (org.apache.geode.test.junit.categories.UnitTest)17 Index (org.apache.geode.cache.query.Index)16 StructTypeImpl (org.apache.geode.cache.query.internal.types.StructTypeImpl)14 Collection (java.util.Collection)11 Iterator (java.util.Iterator)10 ResultsBag (org.apache.geode.cache.query.internal.ResultsBag)8 ResultsCollectionWrapper (org.apache.geode.cache.query.internal.ResultsCollectionWrapper)8 AttributesFactory (org.apache.geode.cache.AttributesFactory)7