@Override
  public SelectResults auxFilterEvaluate(ExecutionContext context,
      SelectResults intermediateResults) throws FunctionDomainException, TypeMismatchException,
      NameResolutionException, QueryInvocationTargetException {
    // evaluate the result set from the indexed values
    // using the intermediate results so far (passed in)
    // put results into new intermediate results
    List sortedConditionsList =
        getCondtionsSortedOnIncreasingEstimatedIndexResultSize(context);

    Boolean applyLimit = (Boolean) context.cacheGet(CompiledValue.CAN_APPLY_LIMIT_AT_INDEX);

    boolean modifiedApplyLimits = false;
    if (applyLimit != null && applyLimit && sortedConditionsList.size() > 1
        && _operator == LITERAL_and) {
      context.cachePut(CAN_APPLY_LIMIT_AT_INDEX, Boolean.FALSE);
      modifiedApplyLimits = true;
    }

    // Sort the operands in increasing order of resultset size
    Iterator sortedConditionsItr = sortedConditionsList.iterator();
    while (sortedConditionsItr.hasNext()) {
      // Asif:TODO The intermediate ResultSet should be passed as null when invoking
      // filterEvaluate. Just because filterEvaluate is being called, itself
      // guarantees that there will be at least on auxFilterEvalaute call.
      // The filterEvalaute will return after invoking auxIterEvaluate.
      // The auxIterEvaluate cannot get invoked for an OR junction.
      // The approach of calculation of resultset should be Bubble UP ( i.e
      // bottom to Top of the tree. This implies that for filterEvaluate, we
      // should not be passing IntermediateResultSet.
      // Each invocation of filterEvaluate will be complete in itself with the
      // recursion being ended by evaluating auxIterEvaluate if any. The passing
      // of IntermediateResult in filterEvalaute causes AND junction evaluation
      // to be corrupted , if the intermediateResultset contains some value.

      if (modifiedApplyLimits && sortedConditionsList.size() == 1) {
        context.cachePut(CAN_APPLY_LIMIT_AT_INDEX, Boolean.TRUE);
        modifiedApplyLimits = false;
      }

      SelectResults filterResults =
          ((Filter) sortedConditionsItr.next()).filterEvaluate(context, null);
      if (_operator == LITERAL_and) {
        if (filterResults != null && filterResults.isEmpty()) {
          return filterResults;
        } else if (filterResults != null) {
          intermediateResults = (intermediateResults == null) ? filterResults
              : QueryUtils.intersection(intermediateResults, filterResults, context);

          sortedConditionsItr.remove();

          if (intermediateResults.size() <= indexThresholdSize) {
            // Abort further intersection , the remaining filter operands will be
            // transferred for
            // iter evaluation
            break;
          }
        }
      } else {
        // Asif : In case of OR clause, the filterEvaluate cannot return a
        // null value ,as a null value implies Cartesian of Iterators
        // in current scope which can happen only if the operand of OR
        // clause evaluates to true (& which we are not allowing).
        // Though if the operand evaluates to false,it is permissible case
        // for filterEvaluation.
        Assert.assertTrue(filterResults != null);
        intermediateResults = intermediateResults == null ? filterResults
            : QueryUtils.union(intermediateResults, filterResults, context);
      }
    }
    if (_operator == LITERAL_and && !sortedConditionsList.isEmpty()) {
      unevaluatedFilterOperands = sortedConditionsList;
    }
    return intermediateResults;
  }
invariant: all operands are known to be evaluated as a filter no operand organization is
necessary
geode-core/src/main/java/org/apache/geode/cache/query/internal/CompiledJunction.java