geode-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From dschnei...@apache.org
Subject [38/53] [partial] incubator-geode git commit: Initial import of geode-1.0.0.0-SNAPSHOT-2. All the new sub-project directories (like jvsd) were not imported. A diff was done to confirm that this commit is exactly the same as the open directory the snapsho
Date Mon, 06 Jul 2015 18:15:45 GMT
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/31d1b20e/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/CompiledSortCriterion.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/CompiledSortCriterion.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/CompiledSortCriterion.java
index e704e74..398805a 100644
--- a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/CompiledSortCriterion.java
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/CompiledSortCriterion.java
@@ -9,62 +9,314 @@
 package com.gemstone.gemfire.cache.query.internal;
 
 import java.util.*;
+
+import com.gemstone.gemfire.GemFireCacheException;
+import com.gemstone.gemfire.GemFireException;
+import com.gemstone.gemfire.cache.CacheException;
+import com.gemstone.gemfire.cache.query.AmbiguousNameException;
 import com.gemstone.gemfire.cache.query.FunctionDomainException;
+import com.gemstone.gemfire.cache.query.IndexInvalidException;
 import com.gemstone.gemfire.cache.query.NameResolutionException;
+import com.gemstone.gemfire.cache.query.QueryException;
+import com.gemstone.gemfire.cache.query.QueryInvalidException;
 import com.gemstone.gemfire.cache.query.QueryInvocationTargetException;
 import com.gemstone.gemfire.cache.query.TypeMismatchException;
+import com.gemstone.gemfire.cache.query.internal.parse.OQLLexerTokenTypes;
+import com.gemstone.gemfire.cache.query.internal.types.TypeUtils;
+import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
 
 /**
- * This class represents a compiled form of sort criterian present in order by clause
+ * This class represents a compiled form of sort criterian present in order by
+ * clause
+ * 
  * @author Yogesh Mahajan
+ * @author Asif
  */
-public class CompiledSortCriterion extends AbstractCompiledValue  {
-	//Asif: criterion true indicates descending order
-	boolean criterion = false;	
-	CompiledValue expr = null;
-  
+public class CompiledSortCriterion extends AbstractCompiledValue {
+  // Asif: criterion true indicates descending order
+  private boolean criterion = false;
+  private CompiledValue expr = null;
+  int columnIndex = -1;
+  // private String correctedCanonicalizedExpression = null;
+  private CompiledValue originalCorrectedExpression = null;
+
   @Override
   public List getChildren() {
-    return Collections.singletonList(this.expr);
+    return Collections.singletonList(this.originalCorrectedExpression);
+  }
+
+  /**
+   * @return int
+   */
+  public int getType() {
+    return SORT_CRITERION;
   }
-  
-	/**
-	 * @return int
-	 */
-	public int getType()
-    {
-        return SORT_CRITERION;
+
+  /**
+   * evaluates sort criteria in order by clause
+   * 
+   * @param context
+   * @return Object
+   * @throws FunctionDomainException
+   * @throws TypeMismatchException
+   * @throws NameResolutionException
+   * @throws QueryInvocationTargetException
+   *
+   *           public Object evaluate(ExecutionContext context) throws
+   *           FunctionDomainException, TypeMismatchException,
+   *           NameResolutionException, QueryInvocationTargetException {
+   *           if(this.columnIndex >= 0) { return
+   *           context.getFieldFromProjectedRow(this.columnIndex); }else {
+   *           return this.expr.evaluate(context); } }
+   */
+
+  public Object evaluate(Object data, ExecutionContext context) {
+    Object value = null;
+    if (this.columnIndex > 0) {
+      value = ((Object[]) data)[this.columnIndex];
+    } else if (this.columnIndex == 0) {
+      if (data instanceof Object[]) {
+        value = ((Object[]) data)[this.columnIndex];
+      } else {
+        value = data;
+      }
+    } else {
+      throw new IllegalStateException(" Order By Column attribute unmapped");
+    }
+    context.setCurrentProjectionField(value);
+    try {
+      return this.expr.evaluate(context);
+    } catch (Exception e) {
+      throw new CacheException(e) {
+      };
     }
-	/** evaluates sort criteria in order by clause 
-	 * @param context
-	 * @return Object
-	 * @throws FunctionDomainException
-	 * @throws TypeMismatchException
-	 * @throws NameResolutionException
-	 * @throws QueryInvocationTargetException
-	 */
-	public Object evaluate(ExecutionContext context)throws FunctionDomainException, TypeMismatchException,
-    NameResolutionException, QueryInvocationTargetException 
-	{
-		return this.expr.evaluate(context);  
-		 
-	}
-	/**
-	 * concstructor
-	 * @param criterion
-	 * @param cv
-	 */
-	CompiledSortCriterion(boolean criterion, CompiledValue cv) {
-	  this.expr = cv;
-	  this.criterion = criterion;
-	}
-	
+
+  }
+
+  /**
+   * concstructor
+   * 
+   * @param criterion
+   * @param cv
+   */
+  CompiledSortCriterion(boolean criterion, CompiledValue cv) {
+    this.expr = cv;
+    this.criterion = criterion;
+    this.originalCorrectedExpression = this.expr;
+  }
+
   public boolean getCriterion() {
     return criterion;
   }
 
   public CompiledValue getExpr() {
-    return expr;
+    return this.originalCorrectedExpression;
+  }
+
+  public int getColumnIndex() {
+    return this.columnIndex;
+  }
+
+  /*
+   * public String getCorrectedCanonicalizedExpression() { return
+   * this.correctedCanonicalizedExpression; }
+   */
+
+  @Override
+  public Object evaluate(ExecutionContext context)
+      throws FunctionDomainException, TypeMismatchException,
+      NameResolutionException, QueryInvocationTargetException {
+    
+    return this.expr.evaluate(context);
+  }
+
+  private void substituteExpression(CompiledValue newExpression, int columnIndex) {
+    this.expr = newExpression;
+    this.columnIndex = columnIndex;
+  }
+
+  private void substituteExpressionWithProjectionField(int columnIndex) {
+    this.expr = ProjectionField.getProjectionField();
+    this.columnIndex = columnIndex;
+  }
+
+  private CompiledValue getReconstructedExpression(String projAttribStr,
+      ExecutionContext context) throws AmbiguousNameException,
+      TypeMismatchException, NameResolutionException {
+    List<CompiledValue> expressions = PathUtils.collectCompiledValuesInThePath(
+        expr, context);
+    StringBuffer tempBuff = new StringBuffer();
+    ListIterator<CompiledValue> listIter = expressions.listIterator(expressions
+        .size());
+    while (listIter.hasPrevious()) {
+      listIter.previous().generateCanonicalizedExpression(tempBuff, context);
+      if (tempBuff.toString().equals(projAttribStr)) {
+        // we have found our match from where we have to replace the expression
+        break;
+      } else {
+        tempBuff.delete(0, tempBuff.length());
+      }
+    }
+
+    // Now we need to create a new CompiledValue which terminates with
+    // ProjectionField
+    CompiledValue cvToRetainTill = listIter.previous();
+
+    CompiledValue prevCV = null;
+    List<Object> reconstruct = new ArrayList<Object>();
+    CompiledValue cv = expressions.get(0);
+    int index = 0;
+    do {
+      prevCV = cv;
+      
+      switch( cv.getType()) {     
+      case CompiledOperation.METHOD_INV:
+        reconstruct.add(0, ((CompiledOperation) cv).getArguments());
+        reconstruct.add(0, ((CompiledOperation) cv).getMethodName());
+        break;       
+      case CompiledPath.PATH:
+        reconstruct.add(0, ((CompiledPath) cv).getTailID());
+        break;      
+      case CompiledIndexOperation.TOK_LBRACK:
+        reconstruct.add(0, ((CompiledIndexOperation) cv).getExpression());
+        break;     
+       default:
+         throw new IllegalStateException(
+             "Unexpected CompiledValue in order by clause");
+      }
+      reconstruct.add(0, Integer.valueOf(prevCV.getType()));
+      cv = expressions.get(++index);
+    } while (prevCV != cvToRetainTill);
+
+    // Now reconstruct back
+    Iterator<Object> iter = reconstruct.iterator();
+    CompiledValue currentValue = ProjectionField.getProjectionField();
+    while (iter.hasNext()) {
+      int type = ((Integer) iter.next()).intValue();
+      switch (type) {
+      case CompiledValue.PATH:
+        currentValue = new CompiledPath(currentValue, (String) iter.next());
+        break;
+      case OQLLexerTokenTypes.METHOD_INV:
+        currentValue = new CompiledOperation(currentValue,
+            (String) iter.next(), (List) iter.next());
+        break;
+      case OQLLexerTokenTypes.TOK_LBRACK:
+        currentValue = new CompiledIndexOperation(currentValue,
+            (CompiledValue) iter.next());
+        break;
+      }
+
+    }
+
+    return currentValue;
+  }
+
+  boolean mapExpressionToProjectionField(List projAttrs,
+      ExecutionContext context) throws AmbiguousNameException,
+      TypeMismatchException, NameResolutionException {
+    boolean mappedColumn = false;
+    this.originalCorrectedExpression = expr;
+    if (projAttrs != null) {
+      // if expr is CompiledID , check for alias
+      if (expr.getType() == OQLLexerTokenTypes.Identifier) {
+
+        for (int i = 0; i < projAttrs.size() && !mappedColumn; ++i) {
+          Object[] prj = (Object[]) TypeUtils.checkCast(projAttrs.get(i),
+              Object[].class);
+          if (prj[0] != null && prj[0].equals(((CompiledID) expr).getId())) {
+            // set the field index
+            this.substituteExpressionWithProjectionField(i);
+            this.originalCorrectedExpression = (CompiledValue) prj[1];
+            mappedColumn = true;
+
+          }
+        }
+
+      }
+      if (!mappedColumn) {
+        // the order by expr is not an alias check for path
+        StringBuffer orderByExprBuffer = new StringBuffer(), projAttribBuffer = new StringBuffer();
+        expr.generateCanonicalizedExpression(orderByExprBuffer, context);
+        final String orderByExprStr = orderByExprBuffer.toString();
+        for (int i = 0; i < projAttrs.size(); ++i) {
+          Object[] prj = (Object[]) TypeUtils.checkCast(projAttrs.get(i),
+              Object[].class);
+          CompiledValue cvProj = (CompiledValue) TypeUtils.checkCast(prj[1],
+              CompiledValue.class);
+          cvProj.generateCanonicalizedExpression(projAttribBuffer, context);
+          final String projAttribStr = projAttribBuffer.toString();
+          if (projAttribStr.equals(orderByExprStr)) {
+            // set the field index
+            this.substituteExpressionWithProjectionField(i);
+            mappedColumn = true;
+            break;
+          } else if (orderByExprStr.startsWith(projAttribStr)) {
+            CompiledValue newExpr = getReconstructedExpression(projAttribStr,
+                context);
+            this.substituteExpression(newExpr, i);
+            mappedColumn = true;
+            break;
+          }
+          projAttribBuffer.delete(0, projAttribBuffer.length());
+        }
+      }
+    } else {
+      RuntimeIterator rIter = context.findRuntimeIterator(expr);
+      List currentIters = context.getCurrentIterators();
+      for (int i = 0; i < currentIters.size(); ++i) {
+        RuntimeIterator runtimeIter = (RuntimeIterator) currentIters.get(i);
+        if (runtimeIter == rIter) {
+          /* this.substituteExpressionWithProjectionField( i); */
+          StringBuffer temp = new StringBuffer();
+          rIter.generateCanonicalizedExpression(temp, context);
+          // this.correctedCanonicalizedExpression = temp.toString();
+          /* mappedColumn = true; */
+          String projAttribStr = temp.toString();
+          temp = new StringBuffer();
+          expr.generateCanonicalizedExpression(temp, context);
+          String orderbyStr = temp.toString();
+          if (projAttribStr.equals(orderbyStr)) {
+            this.substituteExpressionWithProjectionField(i);
+            mappedColumn = true;
+            break;
+          } else {
+            CompiledValue newExpr = getReconstructedExpression(projAttribStr,
+                context);
+            this.substituteExpression(newExpr, i);
+            mappedColumn = true;
+            break;
+          }
+        }
+      }
+    }
+    return mappedColumn;
+
+  }
+
+  static class ProjectionField extends AbstractCompiledValue {
+
+    private static ProjectionField singleton = new ProjectionField();
+
+    private ProjectionField() {
+    }
+
+    public Object evaluate(ExecutionContext context)
+        throws FunctionDomainException, TypeMismatchException,
+        NameResolutionException, QueryInvocationTargetException {
+      return context.getCurrentProjectionField();
+
+    }
+
+    @Override
+    public int getType() {
+      return FIELD;
+    }
+
+    public static ProjectionField getProjectionField() {
+      return singleton;
+    }
+
   }
-	
+
 }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/31d1b20e/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/CompiledUndefined.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/CompiledUndefined.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/CompiledUndefined.java
index 5b3888a..f9c978d 100644
--- a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/CompiledUndefined.java
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/CompiledUndefined.java
@@ -86,12 +86,11 @@ public class CompiledUndefined extends AbstractCompiledValue implements
     int indexFieldsSize = -1;
     SelectResults set = null;
     if (resultType instanceof StructType) {
-      set = (SelectResults) new StructBag((StructTypeImpl)resultType,
-                                          context.getCachePerfStats());
+      set = QueryUtils.createStructCollection(context, (StructTypeImpl)resultType) ;
       indexFieldsSize = ((StructTypeImpl) resultType).getFieldNames().length;
     }
     else {
-      set = new ResultsBag(resultType, context.getCachePerfStats());
+      set = QueryUtils.createResultCollection(context, resultType);
       indexFieldsSize = 1;
     }
     int op = _is_defined ? TOK_NE : TOK_EQ;

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/31d1b20e/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/CompiledValue.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/CompiledValue.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/CompiledValue.java
index b2c62d5..d273ea2 100644
--- a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/CompiledValue.java
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/CompiledValue.java
@@ -37,6 +37,8 @@ public interface CompiledValue {
   public final static int SINGLECONDNEVALUATOR= -13;
   public final static int DOUBLECONDNRANGEJUNCTIONEVALUATOR = -14;
   public final static int LIKE = -15;
+  public final static int FIELD = -16;
+  public final static int GROUP_BY_SELECT = -17;
   public static  final int INDEX_RESULT_THRESHOLD_DEFAULT = 100;
   public static final String INDX_THRESHOLD_PROP_STR = "gemfire.Query.INDEX_THRESHOLD_SIZE";
   public static final String INDEX_INFO = "index_info";
@@ -49,7 +51,7 @@ public interface CompiledValue {
   public static final String CAN_APPLY_LIMIT_AT_INDEX = "can_apply_limit_at_index";
   public static final String CAN_APPLY_ORDER_BY_AT_INDEX = "can_apply_orderby_at_index";
   public static final String PREF_INDEX_COND = "preferred_index_condition"; 
-  public static final String QUERY_INDEX_HINTS = "query_index_hints";
+  public static final String QUERY_INDEX_HINTS = "query_index_hints";  
   public static final CompiledValue MAP_INDEX_ALL_KEYS = new AbstractCompiledValue() {
     
     @Override

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/31d1b20e/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/CompositeGroupJunction.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/CompositeGroupJunction.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/CompositeGroupJunction.java
index 7be4b2f..d95db73 100644
--- a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/CompositeGroupJunction.java
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/CompositeGroupJunction.java
@@ -227,13 +227,11 @@ public class CompositeGroupJunction extends AbstractCompiledValue implements
             .filterEvaluate(context, intermediateResults, false,
                 null/* iterOpn = null */, null/* send independent itrs null */, false,true, false);
         if (intermediateResults.isEmpty()) {
-          return new StructBag(
-            QueryUtils
-                .createStructTypeForRuntimeIterators(this.completeExpansion ? context
-                    .getCurrentIterators()
-                    : QueryUtils.getDependentItrChainForIndpndntItrs(
-                        this.indpndnts, context)),
-                               context.getCachePerfStats()); }
+          StructType structType = QueryUtils .createStructTypeForRuntimeIterators(
+              this.completeExpansion ? context.getCurrentIterators() : QueryUtils.
+                  getDependentItrChainForIndpndntItrs( this.indpndnts, context));
+          return QueryUtils.createStructCollection(context, structType) ;
+        }
       }
     }
     CompiledValue cc = (CompiledValue) itr.next();
@@ -299,17 +297,15 @@ public class CompositeGroupJunction extends AbstractCompiledValue implements
               ObjectType type = ((RuntimeIterator) finalList.iterator().next())
                   .getElementType();
               if (type instanceof StructType) {
-                empty = new StructBag((StructTypeImpl) type,
-                                      context.getCachePerfStats());
+                empty = QueryUtils.createStructCollection(context, (StructTypeImpl) type) ;
               }
               else {
-                empty = new ResultsBag(type, context.getCachePerfStats());
+                empty = QueryUtils.createResultCollection(context, type);
               }
             }
             else {
-              empty = new StructBag(QueryUtils
-                  .createStructTypeForRuntimeIterators(finalList),
-                                    context.getCachePerfStats());
+              StructType strucType =QueryUtils.createStructTypeForRuntimeIterators(finalList);
+              empty = QueryUtils.createStructCollection(context, strucType) ;
             }
             return empty;
           }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/31d1b20e/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/CumulativeNonDistinctResults.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/CumulativeNonDistinctResults.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/CumulativeNonDistinctResults.java
new file mode 100644
index 0000000..b8273e5
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/CumulativeNonDistinctResults.java
@@ -0,0 +1,375 @@
+package com.gemstone.gemfire.cache.query.internal;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+import java.util.AbstractCollection;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import org.eclipse.jetty.webapp.MetaData;
+
+import com.gemstone.gemfire.DataSerializer;
+import com.gemstone.gemfire.cache.CacheException;
+import com.gemstone.gemfire.cache.query.QueryException;
+import com.gemstone.gemfire.cache.query.SelectResults;
+import com.gemstone.gemfire.cache.query.Struct;
+import com.gemstone.gemfire.cache.query.internal.types.CollectionTypeImpl;
+import com.gemstone.gemfire.cache.query.internal.types.StructTypeImpl;
+import com.gemstone.gemfire.cache.query.internal.utils.LimitIterator;
+import com.gemstone.gemfire.cache.query.internal.utils.PDXUtils;
+import com.gemstone.gemfire.cache.query.types.CollectionType;
+import com.gemstone.gemfire.cache.query.types.ObjectType;
+import com.gemstone.gemfire.internal.DataSerializableFixedID;
+import com.gemstone.gemfire.internal.HeapDataOutputStream;
+import com.gemstone.gemfire.internal.HeapDataOutputStream.LongUpdater;
+import com.gemstone.gemfire.internal.Version;
+
+/**
+ * This is used as a wrapper over all the results of PR which are of non
+ * distinct type
+ * 
+ * @author asif
+ *
+ */
+public class CumulativeNonDistinctResults<E> implements SelectResults<E>,
+    DataSerializableFixedID {
+
+  private CollectionType collectionType;
+  private Collection<E> data;
+
+  public CumulativeNonDistinctResults() {
+  }
+
+  public CumulativeNonDistinctResults(
+      Collection<? extends Collection<E>> results, int limit,
+      ObjectType elementType, List<Metadata> collectionsMetadata) {
+
+    this.collectionType = new CollectionTypeImpl(
+        CumulativeNonDistinctResults.class, elementType);
+    this.data = new CumulativeNonDistinctResultsCollection(results, limit,
+        collectionsMetadata);
+
+  }
+
+  @Override
+  public int size() {
+    return this.data.size();
+  }
+
+  @Override
+  public boolean isEmpty() {
+    return this.data.isEmpty();
+  }
+
+  @Override
+  public boolean contains(Object o) {
+    return this.data.contains(o);
+  }
+
+  @Override
+  public Iterator<E> iterator() {
+    return this.data.iterator();
+  }
+
+  @Override
+  public Object[] toArray() {
+    return this.data.toArray();
+  }
+
+  @Override
+  public <T> T[] toArray(T[] a) {
+    return this.data.toArray(a);
+  }
+
+  @Override
+  public boolean add(E e) {
+    throw new UnsupportedOperationException(
+        "Addition to collection not supported");
+  }
+
+  @Override
+  public boolean remove(Object o) {
+    throw new UnsupportedOperationException(
+        "Removal from collection not supported");
+  }
+
+  @Override
+  public boolean containsAll(Collection<?> c) {
+    return this.data.containsAll(c);
+  }
+
+  @Override
+  public boolean addAll(Collection<? extends E> c) {
+    throw new UnsupportedOperationException(
+        "Addition to collection not supported");
+  }
+
+  @Override
+  public boolean removeAll(Collection<?> c) {
+    throw new UnsupportedOperationException(
+        "Removal from collection not supported");
+  }
+
+  @Override
+  public boolean retainAll(Collection<?> c) {
+    throw new UnsupportedOperationException(
+        "Removal from collection not supported");
+  }
+
+  @Override
+  public void clear() {
+    throw new UnsupportedOperationException(
+        "Removal from collection not supported");
+
+  }
+
+  @Override
+  public boolean isModifiable() {
+    return false;
+  }
+
+  @Override
+  public int occurrences(E element) {
+
+    // expensive!!
+    int count = 0;
+    for (Iterator<E> itr = this.iterator()/* this.base.iterator() */; itr
+        .hasNext();) {
+      E v = itr.next();
+      if (element == null ? v == null : element.equals(v)) {
+        count++;
+      }
+    }
+    return count;
+  }
+
+  @Override
+  public Set<E> asSet() {
+    return new HashSet<E>(this);
+  }
+
+  @Override
+  public List<E> asList() {
+    return new ArrayList<E>(this);
+  }
+
+  @Override
+  public CollectionType getCollectionType() {
+    return this.collectionType;
+  }
+
+  @Override
+  public void setElementType(ObjectType elementType) {
+    throw new UnsupportedOperationException(" not supported");
+  }
+
+  private class CumulativeNonDistinctResultsCollection extends
+      AbstractCollection<E> {
+
+    private final Collection<? extends Collection<E>> results;
+    private final List<Metadata> collectionsMetdata;
+    private final int limit;
+
+    public CumulativeNonDistinctResultsCollection(
+        Collection<? extends Collection<E>> results, int limit,
+        List<Metadata> collectionsMetadata) {
+      this.results = results;
+      this.limit = limit;
+      this.collectionsMetdata = collectionsMetadata;
+
+    }
+
+    @Override
+    public int size() {
+
+      int totalSize = 0;
+      for (Collection<E> result : this.results) {
+        totalSize += result.size();
+      }
+      if (this.limit >= 0) {
+        return totalSize > this.limit ? this.limit : totalSize;
+      } else {
+        return totalSize;
+      }
+    }
+
+    /*
+     * @Override public boolean isEmpty() { boolean isEmpty = true; for
+     * (SelectResults<E> result : this.sortedResults) { isEmpty =
+     * result.isEmpty(); if (!isEmpty) { break; } } return isEmpty; }
+     */
+
+    @Override
+    public Iterator<E> iterator() {
+      Iterator<E> iter = new CumulativeCollectionIterator();
+
+      if (this.limit > -1) {
+        iter = new LimitIterator<E>(iter, this.limit);
+      }
+      return iter;
+    }
+
+    private class CumulativeCollectionIterator implements Iterator<E> {
+
+      protected final Iterator<E>[] iterators;
+      protected int currentIterator = 0;
+      private Boolean cachedHasNext = null;
+      final private boolean isStruct;
+      private final boolean[] objectChangedMarker = new boolean[1];
+      protected CumulativeCollectionIterator() {
+        this.iterators = new Iterator[results.size()];
+        Iterator<? extends Collection<E>> listIter = results.iterator();
+        int index = 0;
+        while (listIter.hasNext()) {
+          Iterator<E> temp = (Iterator<E>) listIter.next().iterator();
+          this.iterators[index++] = temp;
+        }
+        this.isStruct = collectionType.getElementType().isStructType();
+      }
+
+      @Override
+      public boolean hasNext() {
+        if (this.cachedHasNext != null) {
+          return this.cachedHasNext.booleanValue();
+        }
+        boolean hasNext = false;
+
+        for (int i = currentIterator; i < this.iterators.length; ++i) {
+          if (this.iterators[i].hasNext()) {
+            hasNext = true;
+            this.currentIterator = i;
+            break;
+          }
+        }
+        this.cachedHasNext = Boolean.valueOf(hasNext);
+        return hasNext;
+      }
+
+      @SuppressWarnings("unchecked")
+      @Override
+      public E next() {
+        if (this.cachedHasNext == null) {
+          this.hasNext();
+        }
+        this.cachedHasNext = null;
+        Metadata metadata = collectionsMetdata.get(this.currentIterator);
+        E original = this.iterators[this.currentIterator].next();
+        Object e =  PDXUtils.convertPDX(original, isStruct,
+            metadata.getDomainObjectForPdx, metadata.getDeserializedObject,
+            metadata.localResults, objectChangedMarker, false);
+        if(isStruct) {
+          if(objectChangedMarker[0]) {
+            return (E)new StructImpl((StructTypeImpl)collectionType.getElementType(), (Object[])e);
+          }else {
+            return original;
+          }
+        }else {
+          return (E)e;
+        }
+
+      }
+
+      @Override
+      public void remove() {
+        throw new UnsupportedOperationException("remove not supported");
+
+      }
+    }
+  }
+
+  @Override
+  public Version[] getSerializationVersions() {
+    return null;
+  }
+
+  @Override
+  public void fromData(DataInput in) throws IOException, ClassNotFoundException {
+    ObjectType elementType = (ObjectType) DataSerializer.readObject(in);
+    this.collectionType = new CollectionTypeImpl(
+        CumulativeNonDistinctResults.class, elementType);
+    boolean isStruct = elementType.isStructType();
+
+    long size = in.readLong();
+    this.data = new ArrayList<E>((int) size);
+    long numLeft = size;
+    while (numLeft > 0) {
+      if (isStruct) {
+        Object[] fields = DataSerializer.readObjectArray(in);
+        this.data.add((E) new StructImpl((StructTypeImpl) elementType, fields));
+      } else {
+        E element = DataSerializer.readObject(in);
+        this.data.add(element);
+      }
+      --numLeft;
+    }
+  }
+
+  public int getDSFID() {
+    return CUMULATIVE_RESULTS;
+  }
+
+  // TODO : optimize for struct elements , by directly writing the fields
+  // instead
+  // of struct
+  @Override
+  public void toData(DataOutput out) throws IOException {
+    boolean isStruct = this.collectionType.getElementType().isStructType();
+    DataSerializer.writeObject(this.collectionType.getElementType(), out);
+
+    HeapDataOutputStream hdos = new HeapDataOutputStream(1024, null);
+    LongUpdater lu = hdos.reserveLong();
+    Iterator<E> iter = this.iterator();
+    int numElements = 0;
+    while (iter.hasNext()) {
+      E data = iter.next();
+      if (isStruct) {
+        Object[] fields = ((Struct) data).getFieldValues();
+        DataSerializer.writeObjectArray(fields, out);
+      } else {
+        DataSerializer.writeObject(data, hdos);
+      }
+      ++numElements;
+    }
+    lu.update(numElements);
+    hdos.sendTo(out);
+
+  }
+
+  @Override
+  public String toString() {
+    StringBuilder builder = new StringBuilder("CumulativeNonDistinctResults::");
+    builder.append('[');
+    Iterator<E> iter = this.iterator();
+    while (iter.hasNext()) {
+      builder.append(iter.next()).append(',');
+    }
+    builder.deleteCharAt(builder.length() - 1);
+    builder.append(']');
+    return builder.toString();
+  }
+
+  public static class Metadata {
+    final boolean getDomainObjectForPdx;
+    final boolean getDeserializedObject;
+    final boolean localResults;
+
+    private Metadata(boolean getDomainObjectForPdx,
+        boolean getDeserializedObject, boolean localResults) {
+      this.getDomainObjectForPdx = getDomainObjectForPdx;
+      this.getDeserializedObject = getDeserializedObject;
+      this.localResults = localResults;
+
+    }
+  }
+
+  public static Metadata getCollectionMetadata(boolean getDomainObjectForPdx,
+      boolean getDeserializedObject, boolean localResults) {
+    return new Metadata(getDomainObjectForPdx, getDeserializedObject,
+        localResults);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/31d1b20e/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/DefaultQuery.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/DefaultQuery.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/DefaultQuery.java
index 677e5e0..3c87d7e 100644
--- a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/DefaultQuery.java
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/DefaultQuery.java
@@ -33,6 +33,8 @@ import com.gemstone.gemfire.cache.partition.PartitionRegionHelper;
 import com.gemstone.gemfire.cache.query.FunctionDomainException;
 import com.gemstone.gemfire.cache.query.NameResolutionException;
 import com.gemstone.gemfire.cache.query.Query;
+import com.gemstone.gemfire.cache.query.QueryException;
+import com.gemstone.gemfire.cache.query.QueryInvalidException;
 import com.gemstone.gemfire.cache.query.QueryInvocationTargetException;
 import com.gemstone.gemfire.cache.query.QueryService;
 import com.gemstone.gemfire.cache.query.QueryStatistics;
@@ -259,10 +261,19 @@ public class DefaultQuery implements Query {
   /** Should be constructed from DefaultQueryService
    * @see QueryService#newQuery
    */
-  public DefaultQuery(String queryString, Cache cache) {
+  public DefaultQuery(String queryString, Cache cache, boolean isForRemote) {
     this.queryString = queryString;
     QCompiler compiler = new QCompiler();
     this.compiledQuery = compiler.compileQuery(queryString);
+    CompiledSelect cs = this.getSimpleSelect();
+    if(cs != null && !isForRemote && (cs.isGroupBy() || cs.isOrderBy())) {
+      QueryExecutionContext ctx = new QueryExecutionContext(null, cache);
+      try {
+        cs.computeDependencies(ctx);       
+      }catch(QueryException qe) {
+        throw new QueryInvalidException("",qe);
+      }
+    }
     this.traceOn = (compiler.isTraceRequested() || QUERY_VERBOSE);
     this.cache = cache;
     this.stats = new DefaultQueryStatistics();
@@ -344,7 +355,8 @@ public class DefaultQuery implements Query {
         result = qe.executeQuery(this, parameters, null);
         // For local queries returning pdx objects wrap the resultset with ResultsCollectionPdxDeserializerWrapper
         // which deserializes these pdx objects.
-        if(!isRemoteQuery() && !this.cache.getPdxReadSerialized() && result instanceof SelectResults) {
+        if(needsPDXDeserializationWrapper(true /* is query on PR*/) 
+            && result instanceof SelectResults ) {
           //we use copy on read false here because the copying has already taken effect earlier in the PartitionedRegionQueryEvaluator
           result = new ResultsCollectionPdxDeserializerWrapper((SelectResults) result, false);
         } 
@@ -377,7 +389,7 @@ public class DefaultQuery implements Query {
       boolean needsCopyOnReadWrapper = this.cache.getCopyOnRead() && !DefaultQueryService.COPY_ON_READ_AT_ENTRY_LEVEL || (((QueryExecutionContext)context).isIndexUsed() && DefaultQueryService.COPY_ON_READ_AT_ENTRY_LEVEL);
       // For local queries returning pdx objects wrap the resultset with ResultsCollectionPdxDeserializerWrapper
       // which deserializes these pdx objects.
-      if(!isRemoteQuery() && !this.cache.getPdxReadSerialized() && result instanceof SelectResults) {
+      if(needsPDXDeserializationWrapper(false /* is query on PR*/) && result instanceof SelectResults) {
         result = new ResultsCollectionPdxDeserializerWrapper((SelectResults) result, needsCopyOnReadWrapper);
       } 
       else if (!isRemoteQuery() && this.cache.getCopyOnRead() && result instanceof SelectResults) {
@@ -408,6 +420,28 @@ public class DefaultQuery implements Query {
 
   }
 
+  //For Order by queries ,since they are already ordered by the comparator 
+  //&& it takes care of conversion, we do not have to wrap it in a wrapper
+  public boolean needsPDXDeserializationWrapper(boolean isQueryOnPR) {
+      if( !isRemoteQuery() && !this.cache.getPdxReadSerialized() ) {
+        return true;
+        /*if(isQueryOnPR) {
+          // if the query is on PR we need a top level pdx deserialization wrapper only in case of 
+          //order by query or non distinct query
+          CompiledSelect cs = this.getSimpleSelect();
+          if(cs != null) {
+            return cs.getOrderByAttrs() != null ;
+          }else {
+           return true; 
+          }
+        }else {
+          return true;
+        }*/
+      }else {
+        return false;
+      }
+  }
+ 
   private Object executeOnServer(Object[] parameters) {
     long startTime = CachePerfStats.getStatTime();
     Object result = null;
@@ -1072,7 +1106,9 @@ public class DefaultQuery implements Query {
       //for dependent iterators, deserialization is required
       if (cs.getIterators().size() == context.getAllIndependentIteratorsOfCurrentScope().size()
           && cs.getWhereClause() == null
-          && cs.getProjectionAttributes() == null && !cs.isDistinct()) {
+          && cs.getProjectionAttributes() == null && !cs.isDistinct()
+          && cs.getOrderByAttrs() == null
+          ) {
         setKeepSerialized(true);
       }
     }
@@ -1082,7 +1118,7 @@ public class DefaultQuery implements Query {
     return keepSerialized;
   }
 
-  public void setKeepSerialized(boolean keepSerialized) {
+  private void setKeepSerialized(boolean keepSerialized) {
     this.keepSerialized = keepSerialized;
   }
   

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/31d1b20e/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/DefaultQueryService.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/DefaultQueryService.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/DefaultQueryService.java
index e917a04..71d2e86 100644
--- a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/DefaultQueryService.java
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/DefaultQueryService.java
@@ -62,7 +62,7 @@ import com.gemstone.gemfire.internal.cache.ForceReattemptException;
 import com.gemstone.gemfire.internal.cache.InternalCache;
 import com.gemstone.gemfire.internal.cache.LocalRegion;
 import com.gemstone.gemfire.internal.cache.PartitionedRegion;
-import com.gemstone.gemfire.internal.cache.control.InternalResourceManager;
+import com.gemstone.gemfire.internal.cache.control.MemoryThresholds;
 import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
 import com.gemstone.gemfire.internal.logging.LogService;
 import com.gemstone.gemfire.internal.logging.log4j.LocalizedMessage;
@@ -118,8 +118,8 @@ public class DefaultQueryService implements QueryService {
         throw new QueryInvalidException(LocalizedStrings.DefaultQueryService_THE_QUERY_STRING_MUST_NOT_BE_NULL.toLocalizedString());
     if (queryString.length() == 0)
         throw new QueryInvalidException(LocalizedStrings.DefaultQueryService_THE_QUERY_STRING_MUST_NOT_BE_EMPTY.toLocalizedString());
-    DefaultQuery query = new DefaultQuery(queryString, this.cache);
     ServerProxy serverProxy = pool == null ? null : new ServerProxy(pool);
+    DefaultQuery query = new DefaultQuery(queryString, this.cache, serverProxy != null);
     query.setServerProxy(serverProxy);
     return query;
   }
@@ -208,11 +208,11 @@ public class DefaultQueryService implements QueryService {
     //  throw new UnsupportedOperationException(LocalizedStrings.DefaultQueryService_INDEX_CREATION_IS_NOT_SUPPORTED_FOR_REGIONS_WHICH_OVERFLOW_TO_DISK_THE_REGION_INVOLVED_IS_0.toLocalizedString(regionPath));
     //}
     // if its a pr the create index on all of the local buckets.
-    if (((LocalRegion)region).heapThresholdReached.get() &&
-        !InternalResourceManager.isLowMemoryExceptionDisabled()) {
+    if (((LocalRegion)region).memoryThresholdReached.get() &&
+        !MemoryThresholds.isLowMemoryExceptionDisabled()) {
       LocalRegion lr = (LocalRegion)region;
       throw new LowMemoryException(LocalizedStrings.ResourceManager_LOW_MEMORY_FOR_INDEX
-          .toLocalizedString(region.getName()), lr.getHeapThresholdReachedMembers());
+          .toLocalizedString(region.getName()), lr.getMemoryThresholdReachedMembers());
     }
     if (region instanceof PartitionedRegion) {
       try {

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/31d1b20e/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/ExecutionContext.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/ExecutionContext.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/ExecutionContext.java
index a9d5aa4..dd110e1 100644
--- a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/ExecutionContext.java
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/ExecutionContext.java
@@ -81,7 +81,8 @@ public class ExecutionContext {
   private BucketRegion bukRgn = null;
   private PartitionedRegion pr = null;
   private boolean distinct = false;
-  
+  private Object currentProjectionField = null;
+  private boolean isPRQueryNode = false;
   /**
    * Param specialIteratorVar name of special variable to use to denote the
    * current iteration element. Used to implement the "this" var in the query
@@ -254,11 +255,7 @@ public class ExecutionContext {
   public QScope currentScope() {
     return (QScope) scopes.peek();
   }
-
-  //  public RuntimeIterator getCurrentIterator() {
-  //    //return currentScope().getIterator();
-  //    throw new RuntimeException("Shud not be called");
-  //  }
+ 
   public List getCurrentIterators() {
     return currentScope().getIterators();
   }
@@ -316,11 +313,7 @@ public class ExecutionContext {
     scope._oneIndexLookup = b;
   }
 
-  // set the current iteration element
-  //  void setCurrent(Object obj) {
-  //    //currentScope().setCurrent(obj);
-  //    throw new RuntimeException("Shud not be called");
-  //  }
+  
   void setCurrent(RuntimeIterator iter, Object obj) {
     currentScope().setCurrent(iter, obj);
   }
@@ -680,10 +673,6 @@ public class ExecutionContext {
     throw new UnsupportedOperationException("Method should not have been called");
   }
 
-  public SelectResults getResults() {
-    throw new UnsupportedOperationException("Method should not have been called");
-  }
-
   public Query getQuery() {
     throw new UnsupportedOperationException("Method should not have been called");
   }
@@ -711,4 +700,25 @@ public class ExecutionContext {
   public void setDistinct(boolean distinct) {
     this.distinct = distinct;
   }
+  
+  public boolean isBindArgsSet() {
+    return this.bindArguments != null;
+  }
+  
+  public void setCurrentProjectionField(Object field) {
+    this.currentProjectionField = field;
+  }
+  
+  public Object getCurrentProjectionField() {
+    return this.currentProjectionField ;
+  }
+  
+  public void setIsPRQueryNode(boolean isPRQueryNode) {
+    this.isPRQueryNode = isPRQueryNode;
+  }
+  
+  public boolean getIsPRQueryNode() {
+    return this.isPRQueryNode;
+  }
+  
 }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/31d1b20e/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/LinkedResultSet.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/LinkedResultSet.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/LinkedResultSet.java
index 02f9a8f..2f53bc5 100644
--- a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/LinkedResultSet.java
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/LinkedResultSet.java
@@ -31,7 +31,7 @@ import com.gemstone.gemfire.internal.DataSerializableFixedID;
 import com.gemstone.gemfire.internal.Version;
 import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
 
-public class LinkedResultSet extends java.util.LinkedHashSet implements
+public class LinkedResultSet extends java.util.LinkedHashSet implements Ordered,
     SelectResults, DataSerializableFixedID {
 
   private static final long serialVersionUID = 5184711453750319225L;
@@ -83,7 +83,7 @@ public class LinkedResultSet extends java.util.LinkedHashSet implements
   }
 
   public CollectionType getCollectionType() {
-    return new CollectionTypeImpl(LinkedHashSet.class, this.elementType);
+    return new CollectionTypeImpl(Ordered.class, this.elementType);
   }
 
   public boolean isModifiable() {
@@ -123,4 +123,14 @@ public class LinkedResultSet extends java.util.LinkedHashSet implements
     return null;
   }
 
+  @Override
+  public Comparator comparator() {    
+    return null;
+  }
+
+  @Override
+  public boolean dataPreordered() {
+    return true;
+  }
+
 }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/31d1b20e/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/LinkedStructSet.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/LinkedStructSet.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/LinkedStructSet.java
index f787e17..c75cfb2 100644
--- a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/LinkedStructSet.java
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/LinkedStructSet.java
@@ -32,7 +32,7 @@ import com.gemstone.gemfire.internal.Version;
 import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
 
 public class LinkedStructSet extends LinkedHashSet<Struct> implements
-    SelectResults<Struct>, DataSerializableFixedID {
+    SelectResults<Struct>, Ordered, DataSerializableFixedID {
 
   private static final long serialVersionUID = -1687142950781718156L;
 
@@ -226,7 +226,7 @@ public class LinkedStructSet extends LinkedHashSet<Struct> implements
   }
 
   public CollectionType getCollectionType() {
-    return new CollectionTypeImpl(SortedSet.class, this.structType);
+    return new CollectionTypeImpl(Ordered.class, this.structType);
   }
 
   // note: this method is dangerous in that it could result in undefined
@@ -345,4 +345,14 @@ public class LinkedStructSet extends LinkedHashSet<Struct> implements
     return null;
   }
 
+  @Override
+  public Comparator comparator() {
+    return null;
+  }
+
+  @Override
+  public boolean dataPreordered() {    
+    return true;
+  }
+
 }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/31d1b20e/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/NWayMergeResults.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/NWayMergeResults.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/NWayMergeResults.java
new file mode 100644
index 0000000..eb54a1c
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/NWayMergeResults.java
@@ -0,0 +1,530 @@
+package com.gemstone.gemfire.cache.query.internal;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+import java.util.AbstractCollection;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.NoSuchElementException;
+import java.util.Set;
+
+import com.gemstone.gemfire.DataSerializer;
+import com.gemstone.gemfire.cache.query.SelectResults;
+import com.gemstone.gemfire.cache.query.Struct;
+import com.gemstone.gemfire.cache.query.internal.types.CollectionTypeImpl;
+import com.gemstone.gemfire.cache.query.internal.types.StructTypeImpl;
+import com.gemstone.gemfire.cache.query.internal.utils.LimitIterator;
+import com.gemstone.gemfire.cache.query.types.CollectionType;
+import com.gemstone.gemfire.cache.query.types.ObjectType;
+import com.gemstone.gemfire.internal.DataSerializableFixedID;
+import com.gemstone.gemfire.internal.HeapDataOutputStream;
+import com.gemstone.gemfire.internal.HeapDataOutputStream.LongUpdater;
+import com.gemstone.gemfire.internal.Version;
+
+/**
+ * The n - way merge results returns a sorted results on the cumulative sorted
+ * results for partitioned region based query
+ * 
+ * @author asif
+ *
+ */
+public class NWayMergeResults<E> implements SelectResults<E>, Ordered,
+    DataSerializableFixedID {
+  private CollectionType collectionType;
+  private Collection<E> data;
+  private boolean isDistinct;
+
+  public NWayMergeResults() {
+  }
+
+  public NWayMergeResults(Collection<? extends Collection<E>> sortedResults,
+      boolean isDistinct, int limit,
+      List<CompiledSortCriterion> orderByAttribs, ExecutionContext context,
+      ObjectType elementType) {
+
+    this.isDistinct = isDistinct;
+    this.collectionType = new CollectionTypeImpl(Ordered.class,
+        elementType);
+    this.data = new NWayMergeResultsCollection(sortedResults, limit,
+        orderByAttribs, context);
+
+  }
+
+  @Override
+  public int size() {
+    return this.data.size();
+  }
+
+  @Override
+  public boolean isEmpty() {
+    return this.data.isEmpty();
+  }
+
+  @Override
+  public boolean contains(Object o) {
+    return this.data.contains(o);
+  }
+
+  @Override
+  public Iterator<E> iterator() {
+    return this.data.iterator();
+  }
+
+  @Override
+  public Object[] toArray() {
+    return this.data.toArray();
+  }
+
+  @Override
+  public <T> T[] toArray(T[] a) {
+    return this.data.toArray(a);
+  }
+
+  @Override
+  public boolean add(E e) {
+    throw new UnsupportedOperationException(
+        "Addition to collection not supported");
+  }
+
+  @Override
+  public boolean remove(Object o) {
+    throw new UnsupportedOperationException(
+        "Removal from collection not supported");
+  }
+
+  @Override
+  public boolean containsAll(Collection<?> c) {
+    return this.data.containsAll(c);
+  }
+
+  @Override
+  public boolean addAll(Collection<? extends E> c) {
+    throw new UnsupportedOperationException(
+        "Addition to collection not supported");
+  }
+
+  @Override
+  public boolean removeAll(Collection<?> c) {
+    throw new UnsupportedOperationException(
+        "Removal from collection not supported");
+  }
+
+  @Override
+  public boolean retainAll(Collection<?> c) {
+    throw new UnsupportedOperationException(
+        "Removal from collection not supported");
+  }
+
+  @Override
+  public void clear() {
+    throw new UnsupportedOperationException(
+        "Removal from collection not supported");
+
+  }
+
+  @Override
+  public boolean isModifiable() {
+    return false;
+  }
+
+  @Override
+  public int occurrences(E element) {
+    if (this.isDistinct) {
+      return this.data.contains(element) ? 1 : 0;
+    }
+    // expensive!!
+    int count = 0;
+    for (Iterator<E> itr = this.iterator()/* this.base.iterator() */; itr
+        .hasNext();) {
+      E v = itr.next();
+      if (element == null ? v == null : element.equals(v)) {
+        count++;
+      }
+    }
+    return count;
+  }
+
+  @Override
+  public Set<E> asSet() {
+    return new HashSet<E>(this);
+  }
+
+  @Override
+  public List<E> asList() {
+    return new ArrayList<E>(this);
+  }
+
+  @Override
+  public CollectionType getCollectionType() {
+    return this.collectionType;
+  }
+
+  @Override
+  public void setElementType(ObjectType elementType) {
+    throw new UnsupportedOperationException(" not supported");
+  }
+
+  private class NWayMergeResultsCollection extends AbstractCollection<E> {
+
+    private final Collection<? extends Collection<E>> sortedResults;
+    private final OrderByComparator comparator;
+    private final int limit;
+
+    public NWayMergeResultsCollection(
+        Collection<? extends Collection<E>> sortedResults, int limit,
+        List<CompiledSortCriterion> orderByAttribs, ExecutionContext context) {
+      this.sortedResults = sortedResults;
+      this.limit = limit;
+      this.comparator = new OrderByComparator(orderByAttribs,
+          collectionType.getElementType(), context);
+
+    }
+
+    @Override
+    public int size() {
+      if (isDistinct) {
+        Iterator<E> iter = this.iterator();
+        int count = 0;
+        while (iter.hasNext()) {
+          ++count;
+          iter.next();
+        }
+        return count;
+
+      } else {
+        int totalSize = 0;
+        for (Collection<E> result : this.sortedResults) {
+          totalSize += result.size();
+        }
+        if (this.limit >= 0) {
+          return totalSize > this.limit ? this.limit : totalSize;
+        } else {
+          return totalSize;
+        }
+      }
+
+    }
+
+    /*
+     * @Override public boolean isEmpty() { boolean isEmpty = true; for
+     * (SelectResults<E> result : this.sortedResults) { isEmpty =
+     * result.isEmpty(); if (!isEmpty) { break; } } return isEmpty; }
+     */
+
+    @Override
+    public Iterator<E> iterator() {
+      Iterator<E> iter;
+      if (isDistinct) {
+        iter = new NWayMergeDistinctIterator();
+      } else {
+        iter = new NWayMergeIterator();
+      }
+      if (this.limit > -1) {
+        iter = new LimitIterator<E>(iter, this.limit);
+      }
+      return iter;
+    }
+
+    private class NWayMergeIterator implements Iterator<E> {
+
+      protected final IteratorWrapper<E>[] iterators;
+      protected int lastReturnedIteratorIndex = -1;
+
+      protected NWayMergeIterator() {
+        this.iterators = new IteratorWrapper[sortedResults.size()];
+        Iterator<? extends Collection<E>> listIter = sortedResults.iterator();
+        int index = 0;
+        while (listIter.hasNext()) {
+          IteratorWrapper<E> temp = new IteratorWrapper<E>(listIter.next()
+              .iterator());
+          this.iterators[index++] = temp;
+          // initialize
+          temp.move();
+        }
+      }
+
+      @Override
+      public boolean hasNext() {
+        boolean hasNext = false;
+        for (int i = 0; i < this.iterators.length; ++i) {
+          if (i == this.lastReturnedIteratorIndex) {
+            hasNext = this.iterators[i].hasNext();
+          } else {
+            hasNext = !this.iterators[i].EOF;
+          }
+          if (hasNext) {
+            break;
+          }
+        }
+        return hasNext;
+      }
+
+      protected E basicNext() {
+        if (this.iterators.length == 1) {
+          this.lastReturnedIteratorIndex = 0;
+          if (iterators[0].EOF) {
+            throw new NoSuchElementException();
+          }
+          return iterators[0].get();
+        }
+
+        int iteratorIndex = -1;
+        E refObject = null;
+        for (int j = 0; j < this.iterators.length; ++j) {
+          if (!this.iterators[j].EOF) {
+            E temp = this.iterators[j].get();
+            iteratorIndex = j;
+            refObject = temp;
+            break;
+
+          }
+        }
+        if (iteratorIndex == -1) {
+          throw new NoSuchElementException();
+        }
+
+        E currentOptima = null;
+        int indexOfIteratorForOptima = -1;
+
+        currentOptima = refObject;
+        indexOfIteratorForOptima = iteratorIndex;
+        for (int j = iteratorIndex + 1; j < this.iterators.length; ++j) {
+          if (this.iterators[j].EOF) {
+            continue;
+          }
+          E temp = this.iterators[j].get();
+
+          int compareResult = compare(currentOptima, temp); 
+              
+          if (compareResult > 0) {
+            currentOptima = temp;
+            indexOfIteratorForOptima = j;
+          }
+        }
+        this.lastReturnedIteratorIndex = indexOfIteratorForOptima;
+        return currentOptima;
+      }
+      
+      protected int compare(E obj1, E obj2) {
+        return collectionType.getElementType().isStructType() ? comparator
+            .compare(((StructImpl) obj1).getFieldValues(),
+                ((StructImpl) obj2).getFieldValues()) : comparator.compare(
+            obj1, obj2);
+            
+      }
+
+      @Override
+      public E next() {
+        if (this.lastReturnedIteratorIndex != -1) {
+          iterators[this.lastReturnedIteratorIndex].move();
+        }
+        return this.basicNext();
+      }
+
+      @Override
+      public void remove() {
+        throw new UnsupportedOperationException("remove not supported");
+
+      }
+
+      private class IteratorWrapper<T> {
+        private final Iterator<T> iter;
+        private T current = null;
+        private boolean EOF = false;
+
+        private IteratorWrapper(Iterator<T> iter) {
+          this.iter = iter;
+        }
+
+        T get() {
+          return this.current;
+        }
+
+        boolean hasNext() {
+          return this.iter.hasNext();
+        }
+
+        void move() {
+          if (this.iter.hasNext()) {
+            this.current = this.iter.next();
+          } else {
+            this.current = null;
+            this.EOF = true;
+          }
+        }
+
+      }
+    }
+
+    private class NWayMergeDistinctIterator extends NWayMergeIterator {
+
+      private E lastReturned = null;
+      private Boolean cachedHasNext = null;
+      private boolean uninitialized = true;
+
+      NWayMergeDistinctIterator() {
+      }
+
+      @Override
+      public boolean hasNext() {
+        if (this.cachedHasNext != null) {
+          return this.cachedHasNext.booleanValue();
+        }
+        boolean hasNext = false;
+        for (int i = 0; i < this.iterators.length; ++i) {
+          if (this.uninitialized) {            
+            hasNext = !this.iterators[i].EOF;
+            if (hasNext) {
+              break;
+            }
+          } else {
+            if (this.lastReturnedIteratorIndex == i) {
+              do {
+                this.iterators[i].move();
+                if (this.iterators[i].EOF) {
+                  break;
+                }// else if (!this.lastReturned.equals(this.iterators[i].get()))
+                 // {
+                else if (compare(lastReturned, this.iterators[i].get()) != 0) {
+                  hasNext = true;
+                  break;
+                }
+              } while (true);
+            } else {
+              do {
+                if (this.iterators[i].EOF) {
+                  break;
+                } // else if
+                  // (!this.iterators[i].get().equals(this.lastReturned)) {
+                else if (compare(this.iterators[i].get(),
+                    this.lastReturned) != 0) {
+                  hasNext = true;
+                  break;
+                } else {
+                  this.iterators[i].move();
+                }
+              } while (true);
+            }
+          }
+        }
+        this.uninitialized = false;
+        this.cachedHasNext = Boolean.valueOf(hasNext);
+        return hasNext;
+      }
+
+      
+
+      @Override
+      public E next() {
+        if (this.cachedHasNext == null) {
+          this.hasNext();
+        }
+        this.cachedHasNext = null;
+        this.lastReturned = this.basicNext();
+        return this.lastReturned;
+      }
+
+      @Override
+      public void remove() {
+        super.remove();
+      }
+
+    }
+
+    
+  }
+
+  @Override
+  public Version[] getSerializationVersions() {
+    return null;
+  }
+
+  @Override
+  public void fromData(DataInput in) throws IOException, ClassNotFoundException {
+    ObjectType elementType = (ObjectType) DataSerializer.readObject(in);
+    this.collectionType = new CollectionTypeImpl(NWayMergeResults.class, elementType );
+    boolean isStruct = elementType.isStructType();
+    this.isDistinct = DataSerializer.readPrimitiveBoolean(in);
+    long size = in.readLong();
+    this.data = new ArrayList<E>((int) size);
+    long numLeft = size;
+    while (numLeft > 0) {
+      if(isStruct) {
+        Object[] fields = DataSerializer.readObjectArray(in);
+        this.data.add((E)new StructImpl((StructTypeImpl) elementType, fields));
+      }else {
+        E element = DataSerializer.readObject(in);
+        this.data.add(element);
+      }
+      --numLeft;
+    }
+  }
+
+  public int getDSFID() {
+    return NWAY_MERGE_RESULTS;
+  }
+
+  // TODO : optimize for struct elements , by directly writing the fields
+  // instead
+  // of struct
+  @Override
+  public void toData(DataOutput out) throws IOException {
+    boolean isStruct = this.collectionType.getElementType().isStructType();
+    DataSerializer.writeObject(this.collectionType.getElementType(), out);
+    DataSerializer.writePrimitiveBoolean(this.isDistinct, out);
+    HeapDataOutputStream hdos = new HeapDataOutputStream(1024, null);
+    LongUpdater lu = hdos.reserveLong();
+    Iterator<E> iter = this.iterator();
+    int numElements = 0;
+    while (iter.hasNext()) {
+      E data = iter.next();      
+      if(isStruct) {
+        Object[] fields = ((Struct)data).getFieldValues();
+        DataSerializer.writeObjectArray(fields, out);
+      }else {
+        DataSerializer.writeObject(data, hdos);
+      }
+      ++numElements;
+    }
+    lu.update(numElements);
+    hdos.sendTo(out);
+
+  }
+
+  @Override
+  public String toString() {
+    StringBuilder builder = new StringBuilder("NWayMergeResults:: isDistinct="
+        + this.isDistinct).append(":");
+    builder.append('[');
+    Iterator<E> iter = this.iterator();
+    while (iter.hasNext()) {
+      builder.append(iter.next()).append(',');
+    }
+    builder.deleteCharAt(builder.length() - 1);
+    builder.append(']');
+    return builder.toString();
+  }
+
+  @Override
+  public Comparator comparator() {
+    if(this.data instanceof NWayMergeResults.NWayMergeResultsCollection) {
+      return ((NWayMergeResultsCollection)this.data).comparator;
+    }else {
+      return null;
+    }
+  }
+
+  @Override
+  public boolean dataPreordered() {
+    if(this.data instanceof NWayMergeResults.NWayMergeResultsCollection) {
+      return false;
+    }else {
+      return true;
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/31d1b20e/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/OrderByComparator.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/OrderByComparator.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/OrderByComparator.java
new file mode 100644
index 0000000..3b6a6f0
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/OrderByComparator.java
@@ -0,0 +1,221 @@
+package com.gemstone.gemfire.cache.query.internal;
+
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.List;
+
+import com.gemstone.gemfire.cache.query.FunctionDomainException;
+import com.gemstone.gemfire.cache.query.NameResolutionException;
+import com.gemstone.gemfire.cache.query.QueryInvocationTargetException;
+import com.gemstone.gemfire.cache.query.QueryService;
+import com.gemstone.gemfire.cache.query.TypeMismatchException;
+import com.gemstone.gemfire.cache.query.types.ObjectType;
+import com.gemstone.gemfire.internal.cache.VMCachedDeserializable;
+import com.gemstone.gemfire.pdx.internal.PdxString;
+
+/**
+ * A generic comparator class which compares two Object/StructImpl according to
+ * their sort criterion specified in order by clause
+ * 
+ * @author yogesh
+ * @author asif
+ */
+public class OrderByComparator implements Comparator {
+  private final ObjectType objType;
+  private final ExecutionContext context;
+  protected final List<CompiledSortCriterion> orderByAttrs;
+
+  public OrderByComparator(List<CompiledSortCriterion> orderByAttrs,
+      ObjectType objType, ExecutionContext context) {
+    this.objType = objType;
+    this.context = context;
+    this.orderByAttrs = orderByAttrs;
+  }
+
+  /**
+   * Yogesh : This methods evaluates sort criteria and returns a ArrayList of
+   * Object[] arrays of evaluated criteria
+   * 
+   * @param value
+   * @return Object[]
+   */
+  protected Object[] evaluateSortCriteria(Object value) {
+
+    CompiledSortCriterion csc;
+    Object[] array = null;
+    if (orderByAttrs != null) {
+      array = new Object[orderByAttrs.size()];
+      Iterator orderiter = orderByAttrs.iterator();
+      int i = 0;
+      while (orderiter.hasNext()) {
+        csc = (CompiledSortCriterion) orderiter.next();
+        Object[] arr = new Object[2];
+        arr[0] = csc.evaluate(value, context);
+        arr[1] = Boolean.valueOf(csc.getCriterion());
+        array[i++] = arr;
+      }
+
+    }
+    return array;
+  }
+
+  /**
+   * Compares its two arguments for order. Returns a negative integer, zero, or
+   * a positive integer as the first argument is less than, equal to, or greater
+   * than the second.
+   * 
+   * @param obj1
+   *          the first object to be compared.
+   * @param obj2
+   *          the second object to be compared.
+   * @return a negative integer, zero, or a positive integer as the first
+   *         argument is less than, equal to, or greater than the second.
+   * @throws ClassCastException
+   *           if the arguments' types prevent them from being compared by this
+   *           Comparator.
+   */
+  public int compare(Object obj1, Object obj2) {
+    int result = -1;
+    if (obj1 == null && obj2 == null) {
+      return 0;
+    }
+    assert !(obj1 instanceof VMCachedDeserializable || obj2 instanceof VMCachedDeserializable);
+
+    if ((this.objType.isStructType() && obj1 instanceof Object[] && obj2 instanceof Object[])
+        || !this.objType.isStructType()) { // obj1 instanceof Object && obj2
+                                           // instanceof Object){
+      Object[] list1 = this.evaluateSortCriteria(obj1);
+      Object[] list2 = this.evaluateSortCriteria(obj2);
+
+      if (list1.length != list2.length) {
+        Support
+            .assertionFailed("Error Occured due to improper sort criteria evaluation ");
+      } else {
+        for (int i = 0; i < list1.length; i++) {
+          Object arr1[] = (Object[]) list1[i];
+          Object arr2[] = (Object[]) list2[i];
+          // check for null.
+          if (arr1[0] == null || arr2[0] == null) {
+            if (arr1[0] == null) {
+              result = (arr2[0] == null ? 0 : -1);
+            } else {
+              result = 1;
+            }
+          } else if (arr1[0] == QueryService.UNDEFINED
+              || arr2[0] == QueryService.UNDEFINED) {
+            if (arr1[0] == QueryService.UNDEFINED) {
+              result = (arr2[0] == QueryService.UNDEFINED ? 0 : -1);
+            } else {
+              result = 1;
+            }
+          } else {
+            if (arr1[0] instanceof Number && arr2[0] instanceof Number) {
+              double diff = ((Number) arr1[0]).doubleValue()
+                  - ((Number) arr2[0]).doubleValue();
+              result = diff > 0 ? 1 : diff < 0 ? -1 : 0;
+            } else {
+              if (arr1[0] instanceof PdxString && arr2[0] instanceof String) {
+                arr2[0] = new PdxString((String) arr2[0]);
+              } else if (arr2[0] instanceof PdxString
+                  && arr1[0] instanceof String) {
+                arr1[0] = new PdxString((String) arr1[0]);
+              }
+              result = ((Comparable) arr1[0]).compareTo(arr2[0]);
+            }
+
+          }
+
+          // equals.
+          if (result == 0) {
+            continue;
+          } else {
+            // not equal, change the sign based on the order by type (asc,
+            // desc).
+            if (((Boolean) arr1[1]).booleanValue()) {
+              result = (result * -1);
+            }
+            return result;
+          }
+        }
+        QueryObserver observer = QueryObserverHolder.getInstance();
+        if (observer != null) {
+          observer.orderByColumnsEqual();
+        }
+        // The comparable fields are equal, so we check if the overall keys are
+        // equal or not
+        if (this.objType.isStructType()) {
+          int i = 0;
+          for (Object o1 : (Object[]) obj1) {
+            Object o2 = ((Object[]) obj2)[i++];
+
+            // Check for null value.
+            if (o1 == null || o2 == null) {
+              if (o1 == null) {
+                if (o2 == null) {
+                  continue;
+                }
+                return -1;
+              } else {
+                return 1;
+              }
+            } else if (o1 == QueryService.UNDEFINED
+                || o2 == QueryService.UNDEFINED) {
+              if (o1 == QueryService.UNDEFINED) {
+                if (o2 == QueryService.UNDEFINED) {
+                  continue;
+                }
+                return -1;
+              } else {
+                return 1;
+              }
+            }
+
+            if (o1 instanceof Comparable) {
+              final int rslt;
+              if (o1 instanceof Number && o2 instanceof Number) {
+                double diff = ((Number) o1).doubleValue()
+                    - ((Number) o2).doubleValue();
+                rslt = diff > 0 ? 1 : diff < 0 ? -1 : 0;
+              } else {
+                if (o1 instanceof PdxString && o2 instanceof String) {
+                  o2 = new PdxString((String) o2);
+                } else if (o2 instanceof PdxString && o1 instanceof String) {
+                  o1 = new PdxString((String) o1);
+                }
+                rslt = ((Comparable) o1).compareTo(o2);
+              }
+              if (rslt == 0) {
+                continue;
+              } else {
+                return rslt;
+              }
+            } else if (!o1.equals(o2)) {
+              return -1;
+            }
+          }
+          return 0;
+        } else {
+          if (obj1 instanceof PdxString && obj2 instanceof String) {
+            obj2 = new PdxString((String) obj2);
+          } else if (obj2 instanceof PdxString && obj1 instanceof String) {
+            obj1 = new PdxString((String) obj1);
+          }
+
+          if (obj1 instanceof Comparable) {
+            return ((Comparable) obj1).compareTo(obj2);
+          } else {
+            return obj1.equals(obj2) ? 0 : -1;
+          }
+        }
+      }
+    }
+    return -1;
+  }
+
+  void addEvaluatedSortCriteria(Object row, ExecutionContext context)
+      throws FunctionDomainException, TypeMismatchException,
+      NameResolutionException, QueryInvocationTargetException {
+    // No op
+  }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/31d1b20e/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/OrderByComparatorUnmapped.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/OrderByComparatorUnmapped.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/OrderByComparatorUnmapped.java
new file mode 100644
index 0000000..7b9af53
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/OrderByComparatorUnmapped.java
@@ -0,0 +1,74 @@
+package com.gemstone.gemfire.cache.query.internal;
+
+import it.unimi.dsi.fastutil.objects.Object2ObjectOpenCustomHashMap;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import com.gemstone.gemfire.cache.query.FunctionDomainException;
+import com.gemstone.gemfire.cache.query.NameResolutionException;
+import com.gemstone.gemfire.cache.query.QueryInvocationTargetException;
+import com.gemstone.gemfire.cache.query.TypeMismatchException;
+import com.gemstone.gemfire.cache.query.types.ObjectType;
+
+@Deprecated
+public class OrderByComparatorUnmapped extends OrderByComparator {
+
+  private final Map<Object, Object[]> orderByMap;
+
+  public OrderByComparatorUnmapped(List<CompiledSortCriterion> orderByAttrs,
+      ObjectType objType, ExecutionContext context) {
+    super(orderByAttrs, objType, context);
+    if (objType.isStructType()) {
+      orderByMap = new Object2ObjectOpenCustomHashMap<Object, Object[]>(
+          new StructBag.ObjectArrayFUHashingStrategy());
+    } else {
+      this.orderByMap = new HashMap<Object, Object[]>();
+    }
+
+  }
+
+  @Override
+  void addEvaluatedSortCriteria(Object row, ExecutionContext context)
+      throws FunctionDomainException, TypeMismatchException,
+      NameResolutionException, QueryInvocationTargetException {
+
+    this.orderByMap.put(row, this.calculateSortCriteria(context, row));
+  }
+
+  @Override
+  protected Object[] evaluateSortCriteria(Object row) {
+    return (Object[]) orderByMap.get(row);
+  }
+
+
+  private Object[] calculateSortCriteria(ExecutionContext context, Object row)
+
+  throws FunctionDomainException, TypeMismatchException,
+      NameResolutionException, QueryInvocationTargetException {
+
+    CompiledSortCriterion csc;
+    if (orderByAttrs != null) {
+      Object[] evaluatedResult = new Object[this.orderByAttrs.size()];
+
+      Iterator<CompiledSortCriterion> orderiter = orderByAttrs.iterator();
+      int index = 0;
+      while (orderiter.hasNext()) {
+        csc = orderiter.next();
+        Object[] arr = new Object[2];
+        if (csc.getColumnIndex() == -1) {
+          arr[0] = csc.evaluate(context);
+        } else {
+          arr[0] = csc.evaluate(row, context);
+        }
+        arr[1] = Boolean.valueOf(csc.getCriterion());
+        evaluatedResult[index++] = arr;
+      }
+      return evaluatedResult;
+    }
+    return null;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/31d1b20e/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/Ordered.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/Ordered.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/Ordered.java
new file mode 100644
index 0000000..3c60a82
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/Ordered.java
@@ -0,0 +1,28 @@
+package com.gemstone.gemfire.cache.query.internal;
+
+import java.util.Comparator;
+
+/**
+ *
+ * This interface is to be implemented by all the query SelectResults implementation which have ordered
+ * data. This encompasses those classes which have data stored in a List, LinkedMap, LinkedSet, TreeMap
+ * , TreeSet etc.
+ * @see NWayMergeResults
+ * @see SortedResultsBag
+ * @see SortedStructBag
+ * @see SortedStructSet
+ * @see SortedResultSet
+ * @see LinkedResultSet
+ * @see LinkedStructSet
+ * @author ashahid
+ *
+ */
+public interface Ordered {
+  Comparator comparator(); 
+  
+  //Implies that underlying structure is a LinkedHashMap or LinkedHashSet & the structs are stored
+  // directly , ie not in terms of Object[]
+  // SortedResultsBag, LinkedResultSet are two such types.
+  
+  boolean dataPreordered();
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/31d1b20e/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/PathUtils.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/PathUtils.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/PathUtils.java
index 0e02c7d..b4e7a51 100644
--- a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/PathUtils.java
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/PathUtils.java
@@ -19,6 +19,7 @@ import com.gemstone.gemfire.cache.query.QueryService;
 import com.gemstone.gemfire.cache.query.Struct;
 import com.gemstone.gemfire.cache.query.TypeMismatchException;
 import com.gemstone.gemfire.cache.query.types.*;
+import com.gemstone.gemfire.cache.query.internal.parse.OQLLexerTokenTypes;
 import com.gemstone.gemfire.cache.query.internal.types.*;
 
 
@@ -194,5 +195,67 @@ public class PathUtils {
     }
     return TypeUtils.OBJECT_TYPE;
   }
+  
+  /**
+   * Collects all the compiled values in the path , starting from the self at
+   * position 0 in the returned List
+   * 
+   * @param expr
+   * @return List of CompiledValues ( includes the RuntimeIterator)
+   * @throws TypeMismatchException
+   * @throws AmbiguousNameException
+   */
+  public static List<CompiledValue> collectCompiledValuesInThePath(
+      CompiledValue expr, ExecutionContext context)
+      throws AmbiguousNameException, TypeMismatchException {
+    boolean toContinue = true;
+    List<CompiledValue> retList = new ArrayList<CompiledValue>();
+
+    int exprType = expr.getType();
+    while (toContinue) {
+      switch (exprType) {
+      case OQLLexerTokenTypes.RegionPath:
+        retList.add(expr);
+        toContinue = false;
+        break;
+      case OQLLexerTokenTypes.METHOD_INV:
+        retList.add(expr);
+        CompiledOperation operation = (CompiledOperation) expr;
+        expr = operation.getReceiver(null/*
+                                          * pass the ExecutionContext as null,
+                                          * thus never implicitly resolving to
+                                          * RuntimeIterator
+                                          */);
+        if (expr == null) {
+          expr = operation;
+          toContinue = false;
+        }
+        break;
+      case CompiledValue.PATH:
+        retList.add(expr);
+        expr = ((CompiledPath) expr).getReceiver();
+        break;
+      case OQLLexerTokenTypes.ITERATOR_DEF:
+        retList.add(expr);
+        toContinue = false;
+        break;
+      case OQLLexerTokenTypes.TOK_LBRACK:
+        retList.add(expr);
+        expr = ((CompiledIndexOperation) expr).getReceiver();
+        break;
+      case OQLLexerTokenTypes.Identifier:
+        CompiledID cid = (CompiledID) expr;
+        expr = context.resolve(cid.getId());
+        break;
+      default:
+        toContinue = false;
+        break;
+      }
+
+      if (toContinue)
+        exprType = expr.getType();
+    }
+    return retList;
+  }
 
 }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/31d1b20e/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/QCompiler.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/QCompiler.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/QCompiler.java
index d9502bc..4777dc1 100644
--- a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/QCompiler.java
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/QCompiler.java
@@ -12,14 +12,19 @@ package com.gemstone.gemfire.cache.query.internal;
 import java.io.StringReader;
 import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Stack;
 
 import org.apache.logging.log4j.Logger;
 
+import antlr.collections.AST;
+import antlr.debug.misc.ASTFrame;
+
 import com.gemstone.gemfire.cache.query.FunctionDomainException;
 import com.gemstone.gemfire.cache.query.NameResolutionException;
+import com.gemstone.gemfire.cache.query.QueryException;
 import com.gemstone.gemfire.cache.query.QueryInvalidException;
 import com.gemstone.gemfire.cache.query.QueryInvocationTargetException;
 import com.gemstone.gemfire.cache.query.TypeMismatchException;
@@ -73,7 +78,7 @@ public class QCompiler implements OQLLexerTokenTypes {
       // operators in the grammer proper
       parser.setASTNodeClass ("com.gemstone.gemfire.cache.query.internal.parse.ASTUnsupported");
       parser.queryProgram ();
-      GemFireAST n = (GemFireAST)parser.getAST ();    
+      GemFireAST n = (GemFireAST)parser.getAST ();
       n.compile(this);
     } catch (Exception ex){ // This is to make sure that we are wrapping any antlr exception with GemFire Exception. 
       throw new QueryInvalidException(LocalizedStrings.QCompiler_SYNTAX_ERROR_IN_QUERY_0.toLocalizedString(ex.getMessage()), ex);
@@ -137,6 +142,15 @@ public class QCompiler implements OQLLexerTokenTypes {
   	}
   	push(list) ;
   }
+  
+  public void compileGroupByClause(int numOfChildren) {
+    List list = new ArrayList();
+    for (int i = 0; i < numOfChildren; i++) {
+      Object csc = this.stack.pop();
+      list.add(0, csc);
+    }
+    push(list);
+  }
   /**
    * Yogesh: compiles sort criteria present in order by clause and push into the stack
    * @param sortCriterion
@@ -177,39 +191,113 @@ public class QCompiler implements OQLLexerTokenTypes {
         ";stack=" + this.stack);
   }
   
-  public void select() {    
-    // List of orderBy sortCriteria
-    Object limitObject = pop();
-    CompiledValue limit;
+  public void select(Map<Integer, Object> queryComponents) {
+    
+    CompiledValue limit = null;
+    Object limitObject = queryComponents.remove(OQLLexerTokenTypes.LIMIT);
     if (limitObject instanceof Integer) {
       limit = new CompiledLiteral(limitObject);
-    }
-    else {
+    } else {
       limit = (CompiledBindArgument) limitObject;
     }
-    List orderByAttrs = (List)pop();
-    // whereClause
-    CompiledValue where = (CompiledValue)pop();
-    // fromClause: list of CompiledIteratorDefs
-    List iterators = (List)pop();
-    // pop the projection attributes
-    List projAttrs = (List)pop();
+    List<CompiledSortCriterion> orderByAttrs = (List<CompiledSortCriterion>) queryComponents
+        .remove(OQLLexerTokenTypes.LITERAL_order);
+
+    List iterators = (List) queryComponents
+        .remove(OQLLexerTokenTypes.LITERAL_from);
+    List projAttrs = (List) queryComponents
+        .remove(OQLLexerTokenTypes.PROJECTION_ATTRS);
+    if (projAttrs == null) {
+      // remove any * or all attribute
+      queryComponents.remove(OQLLexerTokenTypes.TOK_STAR);
+      queryComponents.remove(OQLLexerTokenTypes.LITERAL_all);
+    }
     // "COUNT" or null
-    String aggrExpr = (String)pop();
-    // "DISTINCT" or null
-    String distinct = (String)pop();
+    /*String aggrExpr = (String) queryComponents
+        .remove(OQLLexerTokenTypes.LITERAL_count);*/
     
-    ArrayList<String> hints = null;
-    Object hintObject = pop();
+    // "DISTINCT" or null
+    String distinct = (String) queryComponents
+        .remove(OQLLexerTokenTypes.LITERAL_distinct);
+   List<String> hints = null;
+    Object hintObject = queryComponents.remove(OQLLexerTokenTypes.LITERAL_hint);
     if (hintObject != null) {
-      hints = (ArrayList<String>) hintObject;
+      hints = (List<String>) hintObject;
     }
-    
-    CompiledSelect select = new CompiledSelect(distinct != null, aggrExpr != null, where,
-        iterators, projAttrs, orderByAttrs, limit, hints);
+
+    List<CompiledValue> groupByClause = (List<CompiledValue>) queryComponents
+        .remove(OQLLexerTokenTypes.LITERAL_group);
+
+    // whatever remains , treat it as where
+    // whereClause
+    CompiledValue where = null;
+
+    if (queryComponents.size() == 1) {
+      where = (CompiledValue) queryComponents.values().iterator().next();
+    } else if (queryComponents.size() > 1) {
+      throw new QueryInvalidException(
+          "Unexpected/unsupported query clauses found");
+    }
+    LinkedHashMap<Integer, CompiledAggregateFunction> aggMap = identifyAggregateExpressions(projAttrs);
+    boolean isCountOnly = checkForCountOnly(aggMap, projAttrs, groupByClause);
+    if(isCountOnly) {
+      projAttrs = null;
+    }
+    CompiledSelect select = createSelect(distinct != null,
+        isCountOnly, where, iterators, projAttrs, orderByAttrs, limit,
+        hints, groupByClause, aggMap);
     push(select);
   }
   
+  private boolean checkForCountOnly(
+      Map<Integer, CompiledAggregateFunction> aggregateMap, List projAttribs, List<CompiledValue> groupBy) {
+    if (aggregateMap != null && aggregateMap.size() == 1
+        && projAttribs.size() == 1 && groupBy == null) {
+      for (Map.Entry<Integer, CompiledAggregateFunction> entry : aggregateMap
+          .entrySet()) {
+        CompiledAggregateFunction caf = entry.getValue();
+        if (caf.getFunctionType() == OQLLexerTokenTypes.COUNT
+            && caf.getParameter() == null) {
+          return true;
+        }
+      }
+    }
+    return false;
+  }
+  
+  private CompiledSelect createSelect(boolean isDistinct, boolean isCountOnly, CompiledValue where,
+      List iterators, List projAttrs, List<CompiledSortCriterion> orderByAttrs, CompiledValue limit,
+      List<String> hints,List<CompiledValue> groupByClause, LinkedHashMap<Integer, 
+      CompiledAggregateFunction> aggMap    ) {
+    if(isCountOnly || (groupByClause == null  && aggMap == null) 
+        || (aggMap == null  && orderByAttrs == null)) {
+      return  new CompiledSelect(isDistinct,
+          isCountOnly, where, iterators, projAttrs, orderByAttrs, limit,
+          hints, groupByClause);
+    }else {
+      return new CompiledGroupBySelect(isDistinct,
+          isCountOnly, where, iterators, projAttrs, orderByAttrs, limit,
+          hints, groupByClause, aggMap);
+    }
+  }
+  
+  private LinkedHashMap<Integer, CompiledAggregateFunction> identifyAggregateExpressions(List projAttribs) {
+    if(projAttribs != null) {
+      LinkedHashMap<Integer, CompiledAggregateFunction> mapping = new LinkedHashMap<Integer,CompiledAggregateFunction>();
+      int index = 0;
+      for(Object o : projAttribs) {
+        CompiledValue proj =(CompiledValue) ((Object[])o)[1];
+        if( proj.getType() == OQLLexerTokenTypes.AGG_FUNC) {
+          mapping.put(index, (CompiledAggregateFunction)proj);
+        }
+        ++index;
+      }
+      return mapping.size() == 0 ? null : mapping;
+    }else {
+      return null;
+    }
+    
+  }
   public void projection () {
     // find an id or null on the stack, then an expr CompiledValue
     // push an Object[2] on the stack. First element is id, second is CompiledValue
@@ -218,6 +306,10 @@ public class QCompiler implements OQLLexerTokenTypes {
     push (new Object[] {id == null ? null : id.getId (), expr});
   }
   
+  public void aggregateFunction (CompiledValue expr, int aggFuncType, boolean distinctOnly) {
+    push (new CompiledAggregateFunction(expr, aggFuncType, distinctOnly));
+  }
+  
   public void iteratorDef () {
     // find type id  and colln on the stack
     

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/31d1b20e/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/QScope.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/QScope.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/QScope.java
index 93f4871..2a1c47d 100644
--- a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/QScope.java
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/QScope.java
@@ -71,6 +71,7 @@ class QScope  {
     iterator.setCurrent(obj);
   }
   
+  
   /**
    * 
    * @return unique int identifying the scope. It also indicates the relative visibility
@@ -79,4 +80,5 @@ class QScope  {
   int getScopeID() {
     return this.scopeID;
   }
+  
 }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/31d1b20e/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/QueryExecutionContext.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/QueryExecutionContext.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/QueryExecutionContext.java
index fe8c70e..b9a4c14 100644
--- a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/QueryExecutionContext.java
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/QueryExecutionContext.java
@@ -38,7 +38,6 @@ public class QueryExecutionContext extends ExecutionContext {
 
   private boolean cqQueryContext = false;
   
-  private SelectResults results;
   
   private List bucketList;
   
@@ -74,17 +73,7 @@ public class QueryExecutionContext extends ExecutionContext {
     super(bindArguments, cache);
   }
 
-  /**
-   * @param bindArguments
-   * @param cache
-   * @param results
-   */
-  public QueryExecutionContext(Object[] bindArguments, Cache cache,
-      SelectResults results, Query query) {
-    super(bindArguments, cache);
-    this.results = results;
-    this.query = query;
-  }
+  
 
   /**
    * @param bindArguments
@@ -157,9 +146,6 @@ public class QueryExecutionContext extends ExecutionContext {
     return this.cqQueryContext;
   }
 
-  public SelectResults getResults() {
-    return this.results;
-  }
 
   public Query getQuery() {
     return query;

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/31d1b20e/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/QueryObserver.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/QueryObserver.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/QueryObserver.java
index 37b6910..9ec3c8b 100644
--- a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/QueryObserver.java
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/QueryObserver.java
@@ -319,5 +319,12 @@ public interface QueryObserver {
   void invokedQueryUtilsIntersection(SelectResults sr1, SelectResults sr2);
   
   void limitAppliedAtIndexLevel(Index index, int limit , Collection indexResult);
+  
+  /**
+   * Callback issued if the order by columns of two objects match. 
+   * Note that it is still possible to receive compare value other than 0 , 
+   * if the overall objects are unequal.
+   */
+  void orderByColumnsEqual();
 
 }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/31d1b20e/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/QueryObserverAdapter.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/QueryObserverAdapter.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/QueryObserverAdapter.java
index 4fc06c1..e58e8ad 100644
--- a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/QueryObserverAdapter.java
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/QueryObserverAdapter.java
@@ -325,4 +325,9 @@ public class QueryObserverAdapter implements QueryObserver {
   public void limitAppliedAtIndexLevel(Index index, int limit , Collection indexResult){
     
   }
+
+  @Override
+  public void orderByColumnsEqual() {
+    
+  }
 }


Mime
View raw message