@Override
  protected PlanInfo protGetPlanInfo(ExecutionContext context)
      throws TypeMismatchException, NameResolutionException {
    PlanInfo result = new PlanInfo();
    IndexInfo[] indexInfo = getIndexInfo(context);
    if (indexInfo == null) {
      return result;
    }
    for (final IndexInfo info : indexInfo) {
      result.indexes.add(info._index);
    }
    result.evalAsFilter = true;
    String preferredCondn = (String) context.cacheGet(PREF_INDEX_COND);
    if (preferredCondn != null) {
      // This means that the system is having only one independent iterator so equi join is ruled
      // out.
      // thus the first index is guaranteed to be on the condition which may match our preferred
      // index
      if (indexInfo[0]._index.getCanonicalizedIndexedExpression().equals(preferredCondn)
          && (indexInfo[0]._index.getType() == IndexType.FUNCTIONAL
              || indexInfo[0]._index.getType() == IndexType.HASH)) {
        result.isPreferred = true;
      }
    }
    return result;
  }
Invariant: the receiver is dependent on the current iterator.
geode-core/src/main/java/org/apache/geode/cache/query/internal/CompiledIn.java