You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@geode.apache.org by up...@apache.org on 2016/04/21 00:29:25 UTC

[3/6] incubator-geode git commit: Implementing the UDA functionality in the OQL engine

Implementing the UDA functionality in the OQL engine


Project: http://git-wip-us.apache.org/repos/asf/incubator-geode/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-geode/commit/4f85cac9
Tree: http://git-wip-us.apache.org/repos/asf/incubator-geode/tree/4f85cac9
Diff: http://git-wip-us.apache.org/repos/asf/incubator-geode/diff/4f85cac9

Branch: refs/heads/feature/GEODE-1269
Commit: 4f85cac959a20e81ec842307b7dd27faeb5041d8
Parents: f702bcf
Author: Asif Shahid <as...@snappydata.io>
Authored: Thu Apr 14 22:01:41 2016 -0700
Committer: Asif Shahid <as...@snappydata.io>
Committed: Thu Apr 14 22:01:41 2016 -0700

----------------------------------------------------------------------
 .../gemfire/cache/query/Aggregator.java         |  20 +-
 .../gemfire/cache/query/QueryService.java       |  22 ++
 .../internal/CompiledAggregateFunction.java     |  60 +--
 .../query/internal/CompiledGroupBySelect.java   |  39 +-
 .../query/internal/DefaultQueryService.java     |  14 +
 .../cache/query/internal/ProxyQueryService.java |  12 +
 .../gemfire/cache/query/internal/QCompiler.java |   4 +
 .../internal/aggregate/AbstractAggregator.java  |  23 +-
 .../cache/query/internal/aggregate/Avg.java     |  34 +-
 .../query/internal/aggregate/AvgDistinct.java   |   4 +-
 .../cache/query/internal/aggregate/Count.java   |  41 +-
 .../query/internal/aggregate/CountDistinct.java |   4 +-
 .../internal/aggregate/DistinctAggregator.java  |  42 +-
 .../cache/query/internal/aggregate/MaxMin.java  |  39 +-
 .../cache/query/internal/aggregate/Sum.java     |  40 +-
 .../query/internal/aggregate/SumDistinct.java   |   6 +-
 .../query/internal/parse/ASTAggregateFunc.java  |  12 +-
 .../cache/query/internal/parse/OQLLexer.java    | 164 ++++----
 .../internal/parse/OQLLexerTokenTypes.java      | 169 ++++----
 .../query/internal/parse/OQLLexerTokenTypes.txt | 169 ++++----
 .../cache/query/internal/parse/OQLParser.java   | 387 ++++++++++---------
 .../gemfire/cache/query/internal/parse/oql.g    |  13 +-
 .../internal/DistributionAdvisor.java           |  13 +
 .../gemstone/gemfire/internal/DSFIDFactory.java |  83 ++--
 .../internal/DataSerializableFixedID.java       |  10 +-
 .../internal/cache/GemFireCacheImpl.java        |  12 +-
 .../gemfire/internal/cache/InternalCache.java   |   3 +
 .../cache/PartitionedRegionQueryEvaluator.java  |   8 +-
 .../cache/UpdateAttributesProcessor.java        | 146 +++++++
 .../internal/cache/xmlcache/CacheCreation.java  |  41 +-
 .../internal/cache/xmlcache/CacheXml.java       |   5 +
 .../cache/xmlcache/CacheXmlGenerator.java       |  26 +-
 .../internal/cache/xmlcache/CacheXmlParser.java |  29 ++
 .../internal/i18n/ParentLocalizedStrings.java   |  10 +-
 .../geode.apache.org/schema/cache/cache-1.0.xsd |  12 +
 .../dunit/GroupByPartitionedQueryDUnitTest.java |   6 -
 .../CompiledAggregateFunctionJUnitTest.java     |  46 +--
 .../internal/aggregate/AggregatorJUnitTest.java | 193 +++++----
 .../cache30/CacheXmlGeode10DUnitTest.java       |  74 ++++
 .../gemfire/cache30/CacheXmlTestCase.java       |   2 +-
 .../website/content/schema/cache/cache-1.0.xsd  |  13 +
 41 files changed, 1361 insertions(+), 689 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/4f85cac9/geode-core/src/main/java/com/gemstone/gemfire/cache/query/Aggregator.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/com/gemstone/gemfire/cache/query/Aggregator.java b/geode-core/src/main/java/com/gemstone/gemfire/cache/query/Aggregator.java
index 6991e53..b43f9ff 100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/cache/query/Aggregator.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/cache/query/Aggregator.java
@@ -21,7 +21,17 @@ package com.gemstone.gemfire.cache.query;
  * result. In addition to the methods in the interface, implementing classes
  * must have a 0-arg public constructor.
  * 
- *
+ * For replicated Regions, it is necessary to implement required functionality in {@link #accumulate(Object)} and {@link #terminate()}
+ * 
+ * For PartitionedRegions, the aggregator Objects are themselves serialized from the
+ * bucket nodes to the query node. On the query node, the aggregators are merged
+ * in {@link #merge(Aggregator)}
+ * 
+ * For PartitionedRegions, the aggregator class needs to be serializable
+ * 
+ * 
+ * @author ashahid
+ * @since 9.0
  */
 public interface Aggregator {
 
@@ -42,4 +52,12 @@ public interface Aggregator {
    * @return Return the result scalar value
    */
   public Object terminate();
+
+  /**
+   * Merges the incoming aggregator from bucket nodes with the resultant aggregator
+   * on the query node
+   * 
+   * @param otherAggregator
+   */
+  public void merge(Aggregator otherAggregator);
 }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/4f85cac9/geode-core/src/main/java/com/gemstone/gemfire/cache/query/QueryService.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/com/gemstone/gemfire/cache/query/QueryService.java b/geode-core/src/main/java/com/gemstone/gemfire/cache/query/QueryService.java
index 3a98a43..3be7e80 100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/cache/query/QueryService.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/cache/query/QueryService.java
@@ -847,5 +847,27 @@ public interface QueryService {
    * 
    */
   public CqServiceStatistics getCqStatistics();
+  
+  /**
+   * Creates a UserDefinedAggregate ( UDA ) which can be referenced in querying.
+   * The UDA class must implement {@link Aggregator} interface.
+   * This call defines the UDA through out the system , getting executed on all peers     
+   * @param udaName String alias with which the UDA class is refered to
+   * @param udaClass Fully qualified UDA class name
+   * @throws UDAExistsException If the system has already a UDA defined with the udaName
+   * @throws NameResolutionException If system is unable to load the UDA class using the class name
+   * 
+   * @since 9.0
+   */
+  public void createUDA(String udaName, String udaClass) throws UDAExistsException, NameResolutionException;
+  
+  /**
+   * Removes the UDA defined in system with name
+   * This call removes the UDA mapping from the system ,  getting executed on all peers
+   * @param udaName String alias with which the UDA is known
+   * 
+   * @since 9.0
+   */
+  public void removeUDA(String udaName) ;
     
 }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/4f85cac9/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/CompiledAggregateFunction.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/CompiledAggregateFunction.java b/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/CompiledAggregateFunction.java
index 87f29fa..cc63c8a 100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/CompiledAggregateFunction.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/CompiledAggregateFunction.java
@@ -16,23 +16,17 @@
  */
 package com.gemstone.gemfire.cache.query.internal;
 
+import com.gemstone.gemfire.cache.query.Aggregator;
 import com.gemstone.gemfire.cache.query.AmbiguousNameException;
 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.internal.aggregate.AvgBucketNode;
+import com.gemstone.gemfire.cache.query.internal.aggregate.Avg;
 import com.gemstone.gemfire.cache.query.internal.aggregate.AvgDistinct;
-import com.gemstone.gemfire.cache.query.internal.aggregate.AvgDistinctPRQueryNode;
-import com.gemstone.gemfire.cache.query.internal.aggregate.AvgPRQueryNode;
 import com.gemstone.gemfire.cache.query.internal.aggregate.Count;
 import com.gemstone.gemfire.cache.query.internal.aggregate.CountDistinct;
-import com.gemstone.gemfire.cache.query.internal.aggregate.CountDistinctPRQueryNode;
-import com.gemstone.gemfire.cache.query.internal.aggregate.SumDistinctPRQueryNode;
-import com.gemstone.gemfire.cache.query.internal.aggregate.CountPRQueryNode;
-import com.gemstone.gemfire.cache.query.internal.aggregate.DistinctAggregator;
 import com.gemstone.gemfire.cache.query.internal.aggregate.MaxMin;
-import com.gemstone.gemfire.cache.query.internal.aggregate.Avg;
 import com.gemstone.gemfire.cache.query.internal.aggregate.Sum;
 import com.gemstone.gemfire.cache.query.internal.aggregate.SumDistinct;
 import com.gemstone.gemfire.cache.query.internal.parse.OQLLexerTokenTypes;
@@ -40,6 +34,7 @@ import com.gemstone.gemfire.cache.query.internal.types.ObjectTypeImpl;
 import com.gemstone.gemfire.cache.query.types.ObjectType;
 
 /**
+ * Represents the  built-in aggregate function node
  * 
  *
  */
@@ -67,20 +62,12 @@ public class CompiledAggregateFunction extends AbstractCompiledValue {
   }
 
   @Override
-  public Object evaluate(ExecutionContext context)
-      throws FunctionDomainException, TypeMismatchException,
-      NameResolutionException, QueryInvocationTargetException {
-    boolean isPRQueryNode = context.getIsPRQueryNode();
-    boolean isBucketNode = context.getBucketList() != null;
+  public Aggregator evaluate(ExecutionContext context) throws FunctionDomainException, TypeMismatchException, NameResolutionException,
+                                                      QueryInvocationTargetException {
     switch (this.aggFuncType) {
 
     case OQLLexerTokenTypes.SUM:
-      if (isPRQueryNode) {
-        return this.distinctOnly ? new SumDistinctPRQueryNode() : new Sum();
-      } else {
-        return this.distinctOnly ? (isBucketNode ? new DistinctAggregator()
-            : new SumDistinct()) : new Sum();
-      }
+      return this.distinctOnly ? new SumDistinct() : new Sum();
 
     case OQLLexerTokenTypes.MAX:
       return new MaxMin(true);
@@ -89,33 +76,21 @@ public class CompiledAggregateFunction extends AbstractCompiledValue {
       return new MaxMin(false);
 
     case OQLLexerTokenTypes.AVG:
-      if (isPRQueryNode) {
-        return this.distinctOnly ? new AvgDistinctPRQueryNode()
-            : new AvgPRQueryNode();
-      } else {
-        return this.distinctOnly ? (isBucketNode ? new DistinctAggregator()
-            : new AvgDistinct()) : (isBucketNode ? new AvgBucketNode()
-            : new Avg());
-      }
+
+      return this.distinctOnly ? new AvgDistinct() : new Avg();
 
     case OQLLexerTokenTypes.COUNT:
-      if (isPRQueryNode) {
-        return this.distinctOnly ? new CountDistinctPRQueryNode()
-            : new CountPRQueryNode();
-      } else {
-        return this.distinctOnly ? (isBucketNode ? new DistinctAggregator()
-            : new CountDistinct()) : new Count();
-      }
+
+      return this.distinctOnly ? new CountDistinct() : new Count();
 
     default:
-      throw new UnsupportedOperationException(
-          "Aggregate function not implemented");
+      throw new UnsupportedOperationException("Aggregate function not implemented");
 
     }
 
   }
 
-  private String getStringRep() {
+  protected String getStringRep() {
     switch (this.aggFuncType) {
 
     case OQLLexerTokenTypes.SUM:
@@ -132,8 +107,7 @@ public class CompiledAggregateFunction extends AbstractCompiledValue {
     case OQLLexerTokenTypes.COUNT:
       return "count";
     default:
-      throw new UnsupportedOperationException(
-          "Aggregate function not implemented");
+      throw new UnsupportedOperationException("Aggregate function not implemented");
 
     }
   }
@@ -159,16 +133,14 @@ public class CompiledAggregateFunction extends AbstractCompiledValue {
       return new ObjectTypeImpl(Integer.class);
 
     default:
-      throw new UnsupportedOperationException(
-          "Aggregate function not implemented");
+      throw new UnsupportedOperationException("Aggregate function not implemented");
 
     }
   }
 
   @Override
-  public void generateCanonicalizedExpression(StringBuffer clauseBuffer,
-      ExecutionContext context) throws AmbiguousNameException,
-      TypeMismatchException, NameResolutionException {
+  public void generateCanonicalizedExpression(StringBuffer clauseBuffer, ExecutionContext context) throws AmbiguousNameException, TypeMismatchException,
+                                                                                                  NameResolutionException {
     clauseBuffer.insert(0, ')');
     if (this.expr != null) {
       this.expr.generateCanonicalizedExpression(clauseBuffer, context);

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/4f85cac9/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/CompiledGroupBySelect.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/CompiledGroupBySelect.java b/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/CompiledGroupBySelect.java
index 59e228f..daa75bf 100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/CompiledGroupBySelect.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/CompiledGroupBySelect.java
@@ -181,6 +181,7 @@ public class CompiledGroupBySelect extends CompiledSelect {
     ObjectType elementType = baseResults.getCollectionType().getElementType();
     boolean isStruct = elementType != null && elementType.isStructType();
     boolean isBucketNodes = context.getBucketList() != null;
+    boolean isPRQueryNode = context.getIsPRQueryNode();
     boolean createOrderedResultSet = isBucketNodes && this.orderByAttrs != null;
     boolean[] objectChangedMarker = new boolean[]{false};
     int limitValue = evaluateLimitValue(context, limit);
@@ -197,7 +198,7 @@ public class CompiledGroupBySelect extends CompiledSelect {
       boolean unterminated = iter.hasNext();
       while (iter.hasNext()) {
         current = iter.next();
-        accumulate(isStruct, aggregators, current, objectChangedMarker);
+        accumulate(isStruct, aggregators, current, objectChangedMarker, isPRQueryNode);
       }
       if (unterminated) {
         this.terminateAndAddToResults(isStruct, newResults, aggregators,
@@ -286,8 +287,8 @@ public class CompiledGroupBySelect extends CompiledSelect {
     Object[] orderByTupleHolderCurrent = null;
     Object[] orderByTupleHolderPrev = null;
     Object orderByCurrent = null;
-    Object orderByPrev = null;
-   
+    Object orderByPrev = null;  
+    boolean isPRQueryNode = context.getIsPRQueryNode();
     boolean isSingleOrderBy = this.orderByAttrs.size() <= 1;
     if (!isSingleOrderBy) {
       orderByTupleHolderPrev = new Object[orderByAttrs.size()];
@@ -311,13 +312,13 @@ public class CompiledGroupBySelect extends CompiledSelect {
       if (isFirst
           || areOrderByTupleEqual(isSingleOrderBy, orderByPrev, orderByCurrent,
               orderByTupleHolderPrev, orderByTupleHolderCurrent)) {
-        accumulate(isStruct, aggregators, current, objectChangedMarker);
+        accumulate(isStruct, aggregators, current, objectChangedMarker, isPRQueryNode);
         unterminated = true;
         isFirst = false;
       } else {
         keepAdding = terminateAndAddToResults(isStruct, newResults, aggregators, prev,
             context, isStructFields, limitValue);
-        this.accumulate(isStruct, aggregators, current, objectChangedMarker);
+        this.accumulate(isStruct, aggregators, current, objectChangedMarker, isPRQueryNode);
         unterminated = true;
       }
       // swap the holder arrays
@@ -350,15 +351,16 @@ public class CompiledGroupBySelect extends CompiledSelect {
     if(limitValue == 0) {
       return false;
     }
-    
+    boolean isBucketNodes = context.getBucketList() != null;
+   
     for (Aggregator aggregator : aggregators) {
       if (isStruct) {
         int pos = this.aggregateColsPos.nextSetBit(bitstart);
         bitstart = pos + 1;
-        Object scalarResult = aggregator.terminate();
+        Object scalarResult = isBucketNodes? aggregator : aggregator.terminate();
         newRowArray[pos] = scalarResult;
       } else {
-        newObject = aggregator.terminate();
+        newObject = isBucketNodes? aggregator: aggregator.terminate();
       }
     }
     
@@ -402,19 +404,28 @@ public class CompiledGroupBySelect extends CompiledSelect {
   }
 
   private void accumulate(boolean isStruct, Aggregator[] aggregators,
-      Object current, boolean[] objectChangedMarker) {
+      Object current, boolean[] objectChangedMarker,
+      boolean isPRQueryNode) {
     int bitstart = 0;
     for (Aggregator aggregator : aggregators) {
       if (isStruct) {
         int pos = this.aggregateColsPos.nextSetBit(bitstart);
         bitstart = pos + 1;
         Struct struct = (Struct) current;
-        Object scalar = PDXUtils.convertPDX(struct.getFieldValues()[pos], false, true, true, true, objectChangedMarker, isStruct);
-        
-        aggregator.accumulate(scalar);
+        Object scalar = PDXUtils.convertPDX(struct.getFieldValues()[pos], false, true, true, 
+            true, objectChangedMarker, isStruct);
+        if(isPRQueryNode) {
+          aggregator.merge((Aggregator)scalar);
+        }else {
+          aggregator.accumulate(scalar);
+        }
       } else {
         current =   PDXUtils.convertPDX(current, false, true, true, true, objectChangedMarker, isStruct);
-        aggregator.accumulate(current);
+        if(isPRQueryNode) {
+          aggregator.merge((Aggregator)current);
+        }else {
+          aggregator.accumulate(current);
+        }
       }
     }
   }
@@ -503,7 +514,7 @@ public class CompiledGroupBySelect extends CompiledSelect {
           }
         }
 
-        // the grpup by expr is not an alias check for path
+        // the group by expr is not an alias check for path
         StringBuffer groupByExprBuffer = new StringBuffer();
         grpBy.generateCanonicalizedExpression(groupByExprBuffer, context);
         final String grpByExprStr = groupByExprBuffer.toString();

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/4f85cac9/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/DefaultQueryService.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/DefaultQueryService.java b/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/DefaultQueryService.java
index 392cb9d..b1fde78 100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/DefaultQueryService.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/DefaultQueryService.java
@@ -56,6 +56,8 @@ import com.gemstone.gemfire.cache.query.QueryInvalidException;
 import com.gemstone.gemfire.cache.query.QueryService;
 import com.gemstone.gemfire.cache.query.RegionNotFoundException;
 import com.gemstone.gemfire.cache.query.TypeMismatchException;
+import com.gemstone.gemfire.cache.query.UDAExistsException;
+import com.gemstone.gemfire.cache.query.internal.aggregate.uda.UDAManager;
 import com.gemstone.gemfire.cache.query.internal.cq.ClientCQ;
 import com.gemstone.gemfire.cache.query.internal.cq.CqService;
 import com.gemstone.gemfire.cache.query.internal.cq.InternalCqQuery;
@@ -67,6 +69,7 @@ import com.gemstone.gemfire.cache.query.internal.index.IndexUtils;
 import com.gemstone.gemfire.cache.query.internal.index.PartitionedIndex;
 import com.gemstone.gemfire.cache.query.internal.parse.OQLLexerTokenTypes;
 import com.gemstone.gemfire.internal.cache.ForceReattemptException;
+import com.gemstone.gemfire.internal.cache.GemFireCacheImpl;
 import com.gemstone.gemfire.internal.cache.InternalCache;
 import com.gemstone.gemfire.internal.cache.LocalRegion;
 import com.gemstone.gemfire.internal.cache.PartitionedRegion;
@@ -997,5 +1000,16 @@ public class DefaultQueryService implements QueryService {
   public InternalPool getPool() {
     return pool;
   }
+
+  @Override
+  public void createUDA(String udaName, String udaClass) throws UDAExistsException, NameResolutionException {
+    ((GemFireCacheImpl)this.cache).getUDAManager().createUDA(udaName, udaClass);
+    
+  }
+
+  @Override
+  public void removeUDA(String udaName) {
+    ((GemFireCacheImpl)this.cache).getUDAManager().removeUDA(udaName);
+  }
   
 }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/4f85cac9/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/ProxyQueryService.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/ProxyQueryService.java b/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/ProxyQueryService.java
index 60ab9b4..9ffea02 100755
--- a/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/ProxyQueryService.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/ProxyQueryService.java
@@ -43,6 +43,7 @@ import com.gemstone.gemfire.cache.query.Query;
 import com.gemstone.gemfire.cache.query.QueryInvalidException;
 import com.gemstone.gemfire.cache.query.QueryService;
 import com.gemstone.gemfire.cache.query.RegionNotFoundException;
+import com.gemstone.gemfire.cache.query.UDAExistsException;
 import com.gemstone.gemfire.cache.query.internal.cq.ClientCQ;
 import com.gemstone.gemfire.cache.query.internal.cq.InternalCqQuery;
 import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
@@ -448,4 +449,15 @@ public class ProxyQueryService implements QueryService {
     UserAttributes.userAttributes.set(null);
   }
 
+  @Override
+  public void createUDA(String udaName, String udaClass) throws UDAExistsException {
+    throw new UnsupportedOperationException("UDA creation on server is not supported from the client");
+  }
+
+  @Override
+  public void removeUDA(String udaName) {
+    throw new UnsupportedOperationException("UDA removal on server is not supported from the client");
+    
+  }
+
 }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/4f85cac9/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/QCompiler.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/QCompiler.java b/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/QCompiler.java
index b43d082..a6872a1 100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/QCompiler.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/QCompiler.java
@@ -316,6 +316,10 @@ public class QCompiler implements OQLLexerTokenTypes {
     push (new CompiledAggregateFunction(expr, aggFuncType, distinctOnly));
   }
   
+  public void uda (CompiledValue expr,int aggFuncType, String name) {
+    push (new CompiledUDAFunction(expr, aggFuncType, name ));
+  }
+  
   public void iteratorDef () {
     // find type id  and colln on the stack
     

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/4f85cac9/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/aggregate/AbstractAggregator.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/aggregate/AbstractAggregator.java b/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/aggregate/AbstractAggregator.java
index 0d56a3a..efd224f 100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/aggregate/AbstractAggregator.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/aggregate/AbstractAggregator.java
@@ -16,6 +16,8 @@
  */
 package com.gemstone.gemfire.cache.query.internal.aggregate;
 
+import java.math.BigDecimal;
+
 import com.gemstone.gemfire.cache.query.Aggregator;
 
 /**
@@ -24,23 +26,20 @@ import com.gemstone.gemfire.cache.query.Aggregator;
  *
  */
 public abstract class AbstractAggregator implements Aggregator {
-
   public static Number downCast(double value) {
     Number retVal;
-    if (value % 1 == 0) {
-      long longValue = (long) value;
-      if (longValue <= Integer.MAX_VALUE && longValue >= Integer.MIN_VALUE) {
-        retVal = Integer.valueOf((int) longValue);
+    BigDecimal db = new BigDecimal(value);
+    try {
+      long val = db.longValueExact();
+      if (val <= Integer.MAX_VALUE && val >= Integer.MIN_VALUE) {
+        retVal = Integer.valueOf((int) val);
       } else {
-        retVal = Long.valueOf(longValue);
-      }
-    } else {
-      if (value <= Float.MAX_VALUE && value >= Float.MIN_VALUE) {
-        retVal = Float.valueOf((float) value);
-      } else {
-        retVal = Double.valueOf(value);
+        retVal = Long.valueOf(val);
       }
+    } catch (ArithmeticException se) {
+      retVal = Double.valueOf(value);
     }
+
     return retVal;
   }
 }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/4f85cac9/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/aggregate/Avg.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/aggregate/Avg.java b/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/aggregate/Avg.java
index 7a0f00a..4a76288 100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/aggregate/Avg.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/aggregate/Avg.java
@@ -16,6 +16,12 @@
  */
 package com.gemstone.gemfire.cache.query.internal.aggregate;
 
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+
+import com.gemstone.gemfire.DataSerializer;
+import com.gemstone.gemfire.cache.query.Aggregator;
 import com.gemstone.gemfire.cache.query.QueryService;
 
 /**
@@ -26,6 +32,9 @@ import com.gemstone.gemfire.cache.query.QueryService;
 public class Avg extends Sum {
   private int num = 0;
 
+  public Avg() {
+  }
+
   @Override
   public void accumulate(Object value) {
     if (value != null && value != QueryService.UNDEFINED) {
@@ -36,7 +45,6 @@ public class Avg extends Sum {
 
   @Override
   public void init() {
-
   }
 
   @Override
@@ -46,4 +54,28 @@ public class Avg extends Sum {
     return downCast(result);
   }
 
+  @Override
+  public void merge(Aggregator aggregator) {
+    Avg avg = (Avg) aggregator;
+    this.num += avg.num;
+    super.merge(aggregator);
+  }
+
+  @Override
+  public int getDSFID() {
+    return AGG_FUNC_AVG;
+  }
+
+  @Override
+  public void toData(DataOutput out) throws IOException {
+    super.toData(out);
+    DataSerializer.writePrimitiveInt(this.num, out);
+  }
+
+  @Override
+  public void fromData(DataInput in) throws IOException, ClassNotFoundException {
+    super.fromData(in);
+    this.num = DataSerializer.readPrimitiveInt(in);
+  }
+
 }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/4f85cac9/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/aggregate/AvgDistinct.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/aggregate/AvgDistinct.java b/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/aggregate/AvgDistinct.java
index 4548731..0613a9a 100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/aggregate/AvgDistinct.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/aggregate/AvgDistinct.java
@@ -25,6 +25,9 @@ import com.gemstone.gemfire.cache.query.QueryService;
  */
 public class AvgDistinct extends SumDistinct {
 
+  public AvgDistinct() {
+  }
+
   @Override
   public void accumulate(Object value) {
     if (value != null && value != QueryService.UNDEFINED) {
@@ -38,5 +41,4 @@ public class AvgDistinct extends SumDistinct {
     double result = sum / this.distinct.size();
     return downCast(result);
   }
-
 }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/4f85cac9/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/aggregate/Count.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/aggregate/Count.java b/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/aggregate/Count.java
index 8992150..279b3cd 100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/aggregate/Count.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/aggregate/Count.java
@@ -16,8 +16,15 @@
  */
 package com.gemstone.gemfire.cache.query.internal.aggregate;
 
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+
+import com.gemstone.gemfire.DataSerializer;
 import com.gemstone.gemfire.cache.query.Aggregator;
 import com.gemstone.gemfire.cache.query.QueryService;
+import com.gemstone.gemfire.internal.DataSerializableFixedID;
+import com.gemstone.gemfire.internal.Version;
 
 /**
  * Computes the count of the non distinct rows for replicated & PR based
@@ -25,9 +32,12 @@ import com.gemstone.gemfire.cache.query.QueryService;
  * 
  *
  */
-public class Count implements Aggregator {
-  private int count = 0;
+public class Count extends AbstractAggregator implements DataSerializableFixedID {
+  private long count = 0;
 
+  public Count(){    
+  }
+  
   @Override
   public void accumulate(Object value) {
     if (value != null && value != QueryService.UNDEFINED) {
@@ -37,12 +47,35 @@ public class Count implements Aggregator {
 
   @Override
   public void init() {
-
   }
 
   @Override
   public Object terminate() {
-    return Integer.valueOf(count);
+    return downCast(count);
+  }
+  
+  @Override 
+  public void merge(Aggregator countAgg) {
+    this.count += ((Count)countAgg).count;
   }
 
+  @Override
+  public Version[] getSerializationVersions() {   
+    return null;
+  }
+
+  @Override
+  public int getDSFID() {    
+    return AGG_FUNC_COUNT;
+  }
+
+  @Override
+  public void toData(DataOutput out) throws IOException {
+    DataSerializer.writePrimitiveLong(this.count, out);
+  }
+
+  @Override
+  public void fromData(DataInput in) throws IOException, ClassNotFoundException {    
+    this.count = DataSerializer.readPrimitiveLong(in);
+  }
 }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/4f85cac9/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/aggregate/CountDistinct.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/aggregate/CountDistinct.java b/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/aggregate/CountDistinct.java
index c878a24..2ac4f91 100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/aggregate/CountDistinct.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/aggregate/CountDistinct.java
@@ -24,9 +24,11 @@ package com.gemstone.gemfire.cache.query.internal.aggregate;
 
 public class CountDistinct extends DistinctAggregator {
 
+  public CountDistinct() {
+  }
+
   @Override
   public Object terminate() {
     return Integer.valueOf(this.distinct.size());
   }
-
 }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/4f85cac9/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/aggregate/DistinctAggregator.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/aggregate/DistinctAggregator.java b/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/aggregate/DistinctAggregator.java
index 2720897..fdccbb5 100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/aggregate/DistinctAggregator.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/aggregate/DistinctAggregator.java
@@ -16,19 +16,26 @@
  */
 package com.gemstone.gemfire.cache.query.internal.aggregate;
 
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
 import java.util.HashSet;
-import java.util.Set;
 
+import com.gemstone.gemfire.DataSerializer;
+import com.gemstone.gemfire.cache.query.Aggregator;
 import com.gemstone.gemfire.cache.query.QueryService;
+import com.gemstone.gemfire.internal.DataSerializableFixedID;
+import com.gemstone.gemfire.internal.Version;
 
 /**
  * The class used to hold the distinct values. This will get instantiated on the
  * bucket node as part of distinct queries for sum, count, average.
  * 
+ * 
  *
  */
-public class DistinctAggregator extends AbstractAggregator {
-  protected final Set<Object> distinct;
+public class DistinctAggregator extends AbstractAggregator implements DataSerializableFixedID {
+  protected HashSet<Object> distinct;
 
   public DistinctAggregator() {
     this.distinct = new HashSet<Object>();
@@ -42,14 +49,35 @@ public class DistinctAggregator extends AbstractAggregator {
   }
 
   @Override
-  public void init() {
-    // TODO Auto-generated method stub
-
-  }
+  public void init() {}
 
   @Override
   public Object terminate() {
     return this.distinct;
   }
 
+  @Override
+  public void merge(Aggregator otherAgg) {
+    this.distinct.addAll(((DistinctAggregator) otherAgg).distinct);
+  }
+
+  @Override
+  public Version[] getSerializationVersions() {
+    return null;
+  }
+
+  @Override
+  public int getDSFID() {
+    return AGG_FUNC_DISTINCT_AGG;
+  }
+
+  @Override
+  public void toData(DataOutput out) throws IOException {
+    DataSerializer.writeHashSet(this.distinct, out);
+  }
+
+  @Override
+  public void fromData(DataInput in) throws IOException, ClassNotFoundException {
+    this.distinct = DataSerializer.readHashSet(in);
+  }
 }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/4f85cac9/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/aggregate/MaxMin.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/aggregate/MaxMin.java b/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/aggregate/MaxMin.java
index b643c9c..c74ba78 100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/aggregate/MaxMin.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/aggregate/MaxMin.java
@@ -16,8 +16,15 @@
  */
 package com.gemstone.gemfire.cache.query.internal.aggregate;
 
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+
+import com.gemstone.gemfire.DataSerializer;
 import com.gemstone.gemfire.cache.query.Aggregator;
 import com.gemstone.gemfire.cache.query.QueryService;
+import com.gemstone.gemfire.internal.DataSerializableFixedID;
+import com.gemstone.gemfire.internal.Version;
 
 /**
  * Computes the Max or Min
@@ -25,13 +32,17 @@ import com.gemstone.gemfire.cache.query.QueryService;
  *
  */
 
-public class MaxMin implements Aggregator {
-  private final boolean findMax;
+public class MaxMin implements Aggregator, DataSerializableFixedID  {
+  private final boolean findMax; 
   private Comparable currentOptima;
 
   public MaxMin(boolean findMax) {
     this.findMax = findMax;
   }
+  
+  public MaxMin() {
+    this.findMax = false;
+  }
 
   @Override
   public void accumulate(Object value) {
@@ -63,5 +74,29 @@ public class MaxMin implements Aggregator {
   public Object terminate() {
     return currentOptima;
   }
+  
+  @Override
+  public void merge(Aggregator maxMin) {
+    this.accumulate( ((MaxMin)maxMin).currentOptima);
+  }
 
+  @Override
+  public Version[] getSerializationVersions() {   
+    return null;
+  }
+
+  @Override
+  public int getDSFID() {
+    return AGG_FUNC_MAX_MIN;
+  }
+
+  @Override
+  public void toData(DataOutput out) throws IOException {    
+    DataSerializer.writeObject(this.currentOptima, out);
+  }
+
+  @Override
+  public void fromData(DataInput in) throws IOException, ClassNotFoundException {
+    this.currentOptima = DataSerializer.readObject(in);    
+  }
 }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/4f85cac9/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/aggregate/Sum.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/aggregate/Sum.java b/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/aggregate/Sum.java
index 96f80b8..bd813ed 100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/aggregate/Sum.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/aggregate/Sum.java
@@ -16,17 +16,29 @@
  */
 package com.gemstone.gemfire.cache.query.internal.aggregate;
 
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+
+import com.gemstone.gemfire.DataSerializer;
+import com.gemstone.gemfire.cache.query.Aggregator;
 import com.gemstone.gemfire.cache.query.QueryService;
+import com.gemstone.gemfire.internal.DataSerializableFixedID;
+import com.gemstone.gemfire.internal.Version;
 
 /**
  * Computes the sum for replicated & PR based queries.
  * 
  *
  */
-public class Sum extends AbstractAggregator {
+public class Sum extends AbstractAggregator implements DataSerializableFixedID{
 
   private double result = 0;
 
+  
+  public Sum() {   
+  }
+  
   @Override
   public void accumulate(Object value) {
     if (value != null && value != QueryService.UNDEFINED) {
@@ -44,4 +56,30 @@ public class Sum extends AbstractAggregator {
   public Object terminate() {
     return downCast(result);
   }
+  
+  @Override
+  public void merge(Aggregator aggregator) {
+    Sum sumAgg = (Sum)aggregator;
+    this.result += sumAgg.result; 
+  }
+
+  @Override
+  public Version[] getSerializationVersions() {   
+    return null;
+  }
+
+  @Override
+  public int getDSFID() {    
+    return AGG_FUNC_SUM;
+  }
+
+  @Override
+  public void toData(DataOutput out) throws IOException {
+    DataSerializer.writePrimitiveDouble(this.result, out);
+  }
+
+  @Override
+  public void fromData(DataInput in) throws IOException, ClassNotFoundException {    
+    this.result = DataSerializer.readPrimitiveDouble(in);
+  }
 }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/4f85cac9/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/aggregate/SumDistinct.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/aggregate/SumDistinct.java b/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/aggregate/SumDistinct.java
index 57c2a9a..3f765f7 100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/aggregate/SumDistinct.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/aggregate/SumDistinct.java
@@ -22,6 +22,9 @@ package com.gemstone.gemfire.cache.query.internal.aggregate;
  */
 public class SumDistinct extends DistinctAggregator {
 
+  public SumDistinct() {   
+  }
+  
   @Override
   public Object terminate() {
     double sum = 0;
@@ -29,6 +32,5 @@ public class SumDistinct extends DistinctAggregator {
       sum += ((Number) o).doubleValue();
     }
     return downCast(sum);
-  }
-
+  }   
 }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/4f85cac9/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/parse/ASTAggregateFunc.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/parse/ASTAggregateFunc.java b/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/parse/ASTAggregateFunc.java
index 8c989f9..91202ee 100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/parse/ASTAggregateFunc.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/parse/ASTAggregateFunc.java
@@ -30,7 +30,7 @@ public class ASTAggregateFunc extends GemFireAST {
   private static final long serialVersionUID = 8713004765228379685L;
   private int  aggFunctionType;
   private boolean  distinctOnly = false;
-  
+  private String udaName;
   
   public ASTAggregateFunc() { 
     
@@ -45,6 +45,10 @@ public class ASTAggregateFunc extends GemFireAST {
     this.aggFunctionType = type;
   }
   
+  public void setUDAName(String name) {
+    this.udaName = name;
+  }
+  
   public void setDistinctOnly(boolean distinctOnly) {
     this.distinctOnly = distinctOnly;
   }
@@ -60,6 +64,10 @@ public class ASTAggregateFunc extends GemFireAST {
         throw new QueryInvalidException("invalid parameter to aggregate function");
       }
     }
-    compiler.aggregateFunction((CompiledValue)expr, this.aggFunctionType, this.distinctOnly);
+    if(this.aggFunctionType == OQLLexerTokenTypes.UDA) {
+      compiler.uda((CompiledValue)expr,this.aggFunctionType,this.getText() );
+    }else {
+      compiler.aggregateFunction((CompiledValue)expr, this.aggFunctionType, this.distinctOnly);
+    }
   }
 }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/4f85cac9/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/parse/OQLLexer.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/parse/OQLLexer.java b/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/parse/OQLLexer.java
index 2ada98d..afb1fb2 100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/parse/OQLLexer.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/parse/OQLLexer.java
@@ -1,4 +1,4 @@
-// $ANTLR 2.7.4: "oql.g" -> "OQLLexer.java"$
+// $ANTLR 2.7.7 (20060906): "oql.g" -> "OQLLexer.java"$
 
 package com.gemstone.gemfire.cache.query.internal.parse;
 import java.util.*;
@@ -58,86 +58,86 @@ public OQLLexer(LexerSharedInputState state) {
 	caseSensitiveLiterals = false;
 	setCaseSensitive(false);
 	literals = new Hashtable();
-	literals.put(new ANTLRHashString("type", this), new Integer(78));
-	literals.put(new ANTLRHashString("byte", this), new Integer(131));
-	literals.put(new ANTLRHashString("list", this), new Integer(122));
-	literals.put(new ANTLRHashString("undefine", this), new Integer(72));
-	literals.put(new ANTLRHashString("time", this), new Integer(135));
-	literals.put(new ANTLRHashString("short", this), new Integer(123));
-	literals.put(new ANTLRHashString("dictionary", this), new Integer(139));
-	literals.put(new ANTLRHashString("listtoset", this), new Integer(103));
-	literals.put(new ANTLRHashString("abs", this), new Integer(101));
-	literals.put(new ANTLRHashString("timestamp", this), new Integer(137));
-	literals.put(new ANTLRHashString("limit", this), new Integer(80));
-	literals.put(new ANTLRHashString("distinct", this), new Integer(74));
-	literals.put(new ANTLRHashString("octet", this), new Integer(132));
-	literals.put(new ANTLRHashString("where", this), new Integer(79));
-	literals.put(new ANTLRHashString("orelse", this), new Integer(89));
-	literals.put(new ANTLRHashString("select", this), new Integer(73));
-	literals.put(new ANTLRHashString("and", this), new Integer(90));
-	literals.put(new ANTLRHashString("float", this), new Integer(126));
-	literals.put(new ANTLRHashString("not", this), new Integer(102));
-	literals.put(new ANTLRHashString("interval", this), new Integer(136));
-	literals.put(new ANTLRHashString("date", this), new Integer(134));
-	literals.put(new ANTLRHashString("from", this), new Integer(76));
-	literals.put(new ANTLRHashString("null", this), new Integer(142));
-	literals.put(new ANTLRHashString("flatten", this), new Integer(105));
-	literals.put(new ANTLRHashString("count", this), new Integer(115));
-	literals.put(new ANTLRHashString("last", this), new Integer(109));
-	literals.put(new ANTLRHashString("query", this), new Integer(71));
-	literals.put(new ANTLRHashString("mod", this), new Integer(99));
-	literals.put(new ANTLRHashString("trace", this), new Integer(66));
-	literals.put(new ANTLRHashString("nvl", this), new Integer(106));
-	literals.put(new ANTLRHashString("like", this), new Integer(96));
-	literals.put(new ANTLRHashString("except", this), new Integer(98));
-	literals.put(new ANTLRHashString("set", this), new Integer(120));
-	literals.put(new ANTLRHashString("to_date", this), new Integer(107));
-	literals.put(new ANTLRHashString("intersect", this), new Integer(100));
-	literals.put(new ANTLRHashString("map", this), new Integer(140));
-	literals.put(new ANTLRHashString("array", this), new Integer(119));
-	literals.put(new ANTLRHashString("or", this), new Integer(88));
-	literals.put(new ANTLRHashString("any", this), new Integer(94));
-	literals.put(new ANTLRHashString("double", this), new Integer(127));
-	literals.put(new ANTLRHashString("min", this), new Integer(113));
-	literals.put(new ANTLRHashString("as", this), new Integer(68));
-	literals.put(new ANTLRHashString("first", this), new Integer(108));
-	literals.put(new ANTLRHashString("by", this), new Integer(82));
-	literals.put(new ANTLRHashString("all", this), new Integer(75));
-	literals.put(new ANTLRHashString("union", this), new Integer(97));
-	literals.put(new ANTLRHashString("order", this), new Integer(85));
-	literals.put(new ANTLRHashString("is_defined", this), new Integer(117));
-	literals.put(new ANTLRHashString("collection", this), new Integer(138));
-	literals.put(new ANTLRHashString("some", this), new Integer(95));
-	literals.put(new ANTLRHashString("enum", this), new Integer(133));
-	literals.put(new ANTLRHashString("declare", this), new Integer(69));
-	literals.put(new ANTLRHashString("int", this), new Integer(125));
-	literals.put(new ANTLRHashString("for", this), new Integer(91));
-	literals.put(new ANTLRHashString("is_undefined", this), new Integer(116));
-	literals.put(new ANTLRHashString("boolean", this), new Integer(130));
-	literals.put(new ANTLRHashString("char", this), new Integer(128));
-	literals.put(new ANTLRHashString("define", this), new Integer(70));
-	literals.put(new ANTLRHashString("element", this), new Integer(104));
-	literals.put(new ANTLRHashString("string", this), new Integer(129));
-	literals.put(new ANTLRHashString("hint", this), new Integer(84));
-	literals.put(new ANTLRHashString("false", this), new Integer(145));
-	literals.put(new ANTLRHashString("exists", this), new Integer(92));
-	literals.put(new ANTLRHashString("asc", this), new Integer(86));
-	literals.put(new ANTLRHashString("undefined", this), new Integer(143));
-	literals.put(new ANTLRHashString("desc", this), new Integer(87));
-	literals.put(new ANTLRHashString("bag", this), new Integer(121));
-	literals.put(new ANTLRHashString("max", this), new Integer(114));
-	literals.put(new ANTLRHashString("sum", this), new Integer(111));
-	literals.put(new ANTLRHashString("struct", this), new Integer(118));
-	literals.put(new ANTLRHashString("import", this), new Integer(67));
-	literals.put(new ANTLRHashString("in", this), new Integer(77));
-	literals.put(new ANTLRHashString("avg", this), new Integer(112));
-	literals.put(new ANTLRHashString("true", this), new Integer(144));
-	literals.put(new ANTLRHashString("long", this), new Integer(124));
-	literals.put(new ANTLRHashString("nil", this), new Integer(141));
-	literals.put(new ANTLRHashString("group", this), new Integer(81));
-	literals.put(new ANTLRHashString("having", this), new Integer(83));
-	literals.put(new ANTLRHashString("unique", this), new Integer(110));
-	literals.put(new ANTLRHashString("andthen", this), new Integer(93));
+	literals.put(new ANTLRHashString("type", this), new Integer(79));
+	literals.put(new ANTLRHashString("byte", this), new Integer(132));
+	literals.put(new ANTLRHashString("list", this), new Integer(123));
+	literals.put(new ANTLRHashString("undefine", this), new Integer(73));
+	literals.put(new ANTLRHashString("time", this), new Integer(136));
+	literals.put(new ANTLRHashString("short", this), new Integer(124));
+	literals.put(new ANTLRHashString("dictionary", this), new Integer(140));
+	literals.put(new ANTLRHashString("listtoset", this), new Integer(104));
+	literals.put(new ANTLRHashString("abs", this), new Integer(102));
+	literals.put(new ANTLRHashString("timestamp", this), new Integer(138));
+	literals.put(new ANTLRHashString("limit", this), new Integer(81));
+	literals.put(new ANTLRHashString("distinct", this), new Integer(75));
+	literals.put(new ANTLRHashString("octet", this), new Integer(133));
+	literals.put(new ANTLRHashString("where", this), new Integer(80));
+	literals.put(new ANTLRHashString("orelse", this), new Integer(90));
+	literals.put(new ANTLRHashString("select", this), new Integer(74));
+	literals.put(new ANTLRHashString("and", this), new Integer(91));
+	literals.put(new ANTLRHashString("float", this), new Integer(127));
+	literals.put(new ANTLRHashString("not", this), new Integer(103));
+	literals.put(new ANTLRHashString("interval", this), new Integer(137));
+	literals.put(new ANTLRHashString("date", this), new Integer(135));
+	literals.put(new ANTLRHashString("from", this), new Integer(77));
+	literals.put(new ANTLRHashString("null", this), new Integer(143));
+	literals.put(new ANTLRHashString("flatten", this), new Integer(106));
+	literals.put(new ANTLRHashString("count", this), new Integer(116));
+	literals.put(new ANTLRHashString("last", this), new Integer(110));
+	literals.put(new ANTLRHashString("query", this), new Integer(72));
+	literals.put(new ANTLRHashString("mod", this), new Integer(100));
+	literals.put(new ANTLRHashString("trace", this), new Integer(67));
+	literals.put(new ANTLRHashString("nvl", this), new Integer(107));
+	literals.put(new ANTLRHashString("like", this), new Integer(97));
+	literals.put(new ANTLRHashString("except", this), new Integer(99));
+	literals.put(new ANTLRHashString("set", this), new Integer(121));
+	literals.put(new ANTLRHashString("to_date", this), new Integer(108));
+	literals.put(new ANTLRHashString("intersect", this), new Integer(101));
+	literals.put(new ANTLRHashString("map", this), new Integer(141));
+	literals.put(new ANTLRHashString("array", this), new Integer(120));
+	literals.put(new ANTLRHashString("or", this), new Integer(89));
+	literals.put(new ANTLRHashString("any", this), new Integer(95));
+	literals.put(new ANTLRHashString("double", this), new Integer(128));
+	literals.put(new ANTLRHashString("min", this), new Integer(114));
+	literals.put(new ANTLRHashString("as", this), new Integer(69));
+	literals.put(new ANTLRHashString("first", this), new Integer(109));
+	literals.put(new ANTLRHashString("by", this), new Integer(83));
+	literals.put(new ANTLRHashString("all", this), new Integer(76));
+	literals.put(new ANTLRHashString("union", this), new Integer(98));
+	literals.put(new ANTLRHashString("order", this), new Integer(86));
+	literals.put(new ANTLRHashString("is_defined", this), new Integer(118));
+	literals.put(new ANTLRHashString("collection", this), new Integer(139));
+	literals.put(new ANTLRHashString("some", this), new Integer(96));
+	literals.put(new ANTLRHashString("enum", this), new Integer(134));
+	literals.put(new ANTLRHashString("declare", this), new Integer(70));
+	literals.put(new ANTLRHashString("int", this), new Integer(126));
+	literals.put(new ANTLRHashString("for", this), new Integer(92));
+	literals.put(new ANTLRHashString("is_undefined", this), new Integer(117));
+	literals.put(new ANTLRHashString("boolean", this), new Integer(131));
+	literals.put(new ANTLRHashString("char", this), new Integer(129));
+	literals.put(new ANTLRHashString("define", this), new Integer(71));
+	literals.put(new ANTLRHashString("element", this), new Integer(105));
+	literals.put(new ANTLRHashString("string", this), new Integer(130));
+	literals.put(new ANTLRHashString("hint", this), new Integer(85));
+	literals.put(new ANTLRHashString("false", this), new Integer(146));
+	literals.put(new ANTLRHashString("exists", this), new Integer(93));
+	literals.put(new ANTLRHashString("asc", this), new Integer(87));
+	literals.put(new ANTLRHashString("undefined", this), new Integer(144));
+	literals.put(new ANTLRHashString("desc", this), new Integer(88));
+	literals.put(new ANTLRHashString("bag", this), new Integer(122));
+	literals.put(new ANTLRHashString("max", this), new Integer(115));
+	literals.put(new ANTLRHashString("sum", this), new Integer(112));
+	literals.put(new ANTLRHashString("struct", this), new Integer(119));
+	literals.put(new ANTLRHashString("import", this), new Integer(68));
+	literals.put(new ANTLRHashString("in", this), new Integer(78));
+	literals.put(new ANTLRHashString("avg", this), new Integer(113));
+	literals.put(new ANTLRHashString("true", this), new Integer(145));
+	literals.put(new ANTLRHashString("long", this), new Integer(125));
+	literals.put(new ANTLRHashString("nil", this), new Integer(142));
+	literals.put(new ANTLRHashString("group", this), new Integer(82));
+	literals.put(new ANTLRHashString("having", this), new Integer(84));
+	literals.put(new ANTLRHashString("unique", this), new Integer(111));
+	literals.put(new ANTLRHashString("andthen", this), new Integer(94));
 }
 
 public Token nextToken() throws TokenStreamException {
@@ -1607,7 +1607,7 @@ tryAgain:
 						synPredMatched61 = false;
 					}
 					rewind(_m61);
-					inputState.guessing--;
+inputState.guessing--;
 				}
 				if ( synPredMatched61 ) {
 					{

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/4f85cac9/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/parse/OQLLexerTokenTypes.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/parse/OQLLexerTokenTypes.java b/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/parse/OQLLexerTokenTypes.java
index f30f3c0..7e632b2 100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/parse/OQLLexerTokenTypes.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/parse/OQLLexerTokenTypes.java
@@ -1,4 +1,4 @@
-// $ANTLR 2.7.4: "oql.g" -> "OQLParser.java"$
+// $ANTLR 2.7.7 (20060906): "oql.g" -> "OQLParser.java"$
 
 package com.gemstone.gemfire.cache.query.internal.parse;
 import java.util.*;
@@ -69,87 +69,88 @@ public interface OQLLexerTokenTypes {
 	int COUNT = 63;
 	int MAX = 64;
 	int MIN = 65;
-	int LITERAL_trace = 66;
-	int LITERAL_import = 67;
-	int LITERAL_as = 68;
-	int LITERAL_declare = 69;
-	int LITERAL_define = 70;
-	int LITERAL_query = 71;
-	int LITERAL_undefine = 72;
-	int LITERAL_select = 73;
-	int LITERAL_distinct = 74;
-	int LITERAL_all = 75;
-	int LITERAL_from = 76;
-	int LITERAL_in = 77;
-	int LITERAL_type = 78;
-	int LITERAL_where = 79;
-	int LITERAL_limit = 80;
-	int LITERAL_group = 81;
-	int LITERAL_by = 82;
-	int LITERAL_having = 83;
-	int LITERAL_hint = 84;
-	int LITERAL_order = 85;
-	int LITERAL_asc = 86;
-	int LITERAL_desc = 87;
-	int LITERAL_or = 88;
-	int LITERAL_orelse = 89;
-	int LITERAL_and = 90;
-	int LITERAL_for = 91;
-	int LITERAL_exists = 92;
-	int LITERAL_andthen = 93;
-	int LITERAL_any = 94;
-	int LITERAL_some = 95;
-	int LITERAL_like = 96;
-	int LITERAL_union = 97;
-	int LITERAL_except = 98;
-	int LITERAL_mod = 99;
-	int LITERAL_intersect = 100;
-	int LITERAL_abs = 101;
-	int LITERAL_not = 102;
-	int LITERAL_listtoset = 103;
-	int LITERAL_element = 104;
-	int LITERAL_flatten = 105;
-	int LITERAL_nvl = 106;
-	int LITERAL_to_date = 107;
-	int LITERAL_first = 108;
-	int LITERAL_last = 109;
-	int LITERAL_unique = 110;
-	int LITERAL_sum = 111;
-	int LITERAL_avg = 112;
-	int LITERAL_min = 113;
-	int LITERAL_max = 114;
-	int LITERAL_count = 115;
-	int LITERAL_is_undefined = 116;
-	int LITERAL_is_defined = 117;
-	int LITERAL_struct = 118;
-	int LITERAL_array = 119;
-	int LITERAL_set = 120;
-	int LITERAL_bag = 121;
-	int LITERAL_list = 122;
-	int LITERAL_short = 123;
-	int LITERAL_long = 124;
-	int LITERAL_int = 125;
-	int LITERAL_float = 126;
-	int LITERAL_double = 127;
-	int LITERAL_char = 128;
-	int LITERAL_string = 129;
-	int LITERAL_boolean = 130;
-	int LITERAL_byte = 131;
-	int LITERAL_octet = 132;
-	int LITERAL_enum = 133;
-	int LITERAL_date = 134;
-	int LITERAL_time = 135;
-	int LITERAL_interval = 136;
-	int LITERAL_timestamp = 137;
-	int LITERAL_collection = 138;
-	int LITERAL_dictionary = 139;
-	int LITERAL_map = 140;
-	int LITERAL_nil = 141;
-	int LITERAL_null = 142;
-	int LITERAL_undefined = 143;
-	int LITERAL_true = 144;
-	int LITERAL_false = 145;
-	int NUM_LONG = 146;
-	int NUM_FLOAT = 147;
-	int NUM_DOUBLE = 148;
+	int UDA = 66;
+	int LITERAL_trace = 67;
+	int LITERAL_import = 68;
+	int LITERAL_as = 69;
+	int LITERAL_declare = 70;
+	int LITERAL_define = 71;
+	int LITERAL_query = 72;
+	int LITERAL_undefine = 73;
+	int LITERAL_select = 74;
+	int LITERAL_distinct = 75;
+	int LITERAL_all = 76;
+	int LITERAL_from = 77;
+	int LITERAL_in = 78;
+	int LITERAL_type = 79;
+	int LITERAL_where = 80;
+	int LITERAL_limit = 81;
+	int LITERAL_group = 82;
+	int LITERAL_by = 83;
+	int LITERAL_having = 84;
+	int LITERAL_hint = 85;
+	int LITERAL_order = 86;
+	int LITERAL_asc = 87;
+	int LITERAL_desc = 88;
+	int LITERAL_or = 89;
+	int LITERAL_orelse = 90;
+	int LITERAL_and = 91;
+	int LITERAL_for = 92;
+	int LITERAL_exists = 93;
+	int LITERAL_andthen = 94;
+	int LITERAL_any = 95;
+	int LITERAL_some = 96;
+	int LITERAL_like = 97;
+	int LITERAL_union = 98;
+	int LITERAL_except = 99;
+	int LITERAL_mod = 100;
+	int LITERAL_intersect = 101;
+	int LITERAL_abs = 102;
+	int LITERAL_not = 103;
+	int LITERAL_listtoset = 104;
+	int LITERAL_element = 105;
+	int LITERAL_flatten = 106;
+	int LITERAL_nvl = 107;
+	int LITERAL_to_date = 108;
+	int LITERAL_first = 109;
+	int LITERAL_last = 110;
+	int LITERAL_unique = 111;
+	int LITERAL_sum = 112;
+	int LITERAL_avg = 113;
+	int LITERAL_min = 114;
+	int LITERAL_max = 115;
+	int LITERAL_count = 116;
+	int LITERAL_is_undefined = 117;
+	int LITERAL_is_defined = 118;
+	int LITERAL_struct = 119;
+	int LITERAL_array = 120;
+	int LITERAL_set = 121;
+	int LITERAL_bag = 122;
+	int LITERAL_list = 123;
+	int LITERAL_short = 124;
+	int LITERAL_long = 125;
+	int LITERAL_int = 126;
+	int LITERAL_float = 127;
+	int LITERAL_double = 128;
+	int LITERAL_char = 129;
+	int LITERAL_string = 130;
+	int LITERAL_boolean = 131;
+	int LITERAL_byte = 132;
+	int LITERAL_octet = 133;
+	int LITERAL_enum = 134;
+	int LITERAL_date = 135;
+	int LITERAL_time = 136;
+	int LITERAL_interval = 137;
+	int LITERAL_timestamp = 138;
+	int LITERAL_collection = 139;
+	int LITERAL_dictionary = 140;
+	int LITERAL_map = 141;
+	int LITERAL_nil = 142;
+	int LITERAL_null = 143;
+	int LITERAL_undefined = 144;
+	int LITERAL_true = 145;
+	int LITERAL_false = 146;
+	int NUM_LONG = 147;
+	int NUM_FLOAT = 148;
+	int NUM_DOUBLE = 149;
 }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/4f85cac9/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/parse/OQLLexerTokenTypes.txt
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/parse/OQLLexerTokenTypes.txt b/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/parse/OQLLexerTokenTypes.txt
index 8c8fda5..44c262b 100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/parse/OQLLexerTokenTypes.txt
+++ b/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/parse/OQLLexerTokenTypes.txt
@@ -1,4 +1,4 @@
-// $ANTLR 2.7.4: oql.g -> OQLLexerTokenTypes.txt$
+// $ANTLR 2.7.7 (20060906): oql.g -> OQLLexerTokenTypes.txt$
 OQLLexer    // output token vocab name
 TOK_RPAREN=4
 TOK_LPAREN=5
@@ -62,86 +62,87 @@ AVG=62
 COUNT=63
 MAX=64
 MIN=65
-LITERAL_trace="trace"=66
-LITERAL_import="import"=67
-LITERAL_as="as"=68
-LITERAL_declare="declare"=69
-LITERAL_define="define"=70
-LITERAL_query="query"=71
-LITERAL_undefine="undefine"=72
-LITERAL_select="select"=73
-LITERAL_distinct="distinct"=74
-LITERAL_all="all"=75
-LITERAL_from="from"=76
-LITERAL_in="in"=77
-LITERAL_type="type"=78
-LITERAL_where="where"=79
-LITERAL_limit="limit"=80
-LITERAL_group="group"=81
-LITERAL_by="by"=82
-LITERAL_having="having"=83
-LITERAL_hint="hint"=84
-LITERAL_order="order"=85
-LITERAL_asc="asc"=86
-LITERAL_desc="desc"=87
-LITERAL_or="or"=88
-LITERAL_orelse="orelse"=89
-LITERAL_and="and"=90
-LITERAL_for="for"=91
-LITERAL_exists="exists"=92
-LITERAL_andthen="andthen"=93
-LITERAL_any="any"=94
-LITERAL_some="some"=95
-LITERAL_like="like"=96
-LITERAL_union="union"=97
-LITERAL_except="except"=98
-LITERAL_mod="mod"=99
-LITERAL_intersect="intersect"=100
-LITERAL_abs="abs"=101
-LITERAL_not="not"=102
-LITERAL_listtoset="listtoset"=103
-LITERAL_element="element"=104
-LITERAL_flatten="flatten"=105
-LITERAL_nvl="nvl"=106
-LITERAL_to_date="to_date"=107
-LITERAL_first="first"=108
-LITERAL_last="last"=109
-LITERAL_unique="unique"=110
-LITERAL_sum="sum"=111
-LITERAL_avg="avg"=112
-LITERAL_min="min"=113
-LITERAL_max="max"=114
-LITERAL_count="count"=115
-LITERAL_is_undefined="is_undefined"=116
-LITERAL_is_defined="is_defined"=117
-LITERAL_struct="struct"=118
-LITERAL_array="array"=119
-LITERAL_set="set"=120
-LITERAL_bag="bag"=121
-LITERAL_list="list"=122
-LITERAL_short="short"=123
-LITERAL_long="long"=124
-LITERAL_int="int"=125
-LITERAL_float="float"=126
-LITERAL_double="double"=127
-LITERAL_char="char"=128
-LITERAL_string="string"=129
-LITERAL_boolean="boolean"=130
-LITERAL_byte="byte"=131
-LITERAL_octet="octet"=132
-LITERAL_enum="enum"=133
-LITERAL_date="date"=134
-LITERAL_time="time"=135
-LITERAL_interval="interval"=136
-LITERAL_timestamp="timestamp"=137
-LITERAL_collection="collection"=138
-LITERAL_dictionary="dictionary"=139
-LITERAL_map="map"=140
-LITERAL_nil="nil"=141
-LITERAL_null="null"=142
-LITERAL_undefined="undefined"=143
-LITERAL_true="true"=144
-LITERAL_false="false"=145
-NUM_LONG=146
-NUM_FLOAT=147
-NUM_DOUBLE=148
+UDA=66
+LITERAL_trace="trace"=67
+LITERAL_import="import"=68
+LITERAL_as="as"=69
+LITERAL_declare="declare"=70
+LITERAL_define="define"=71
+LITERAL_query="query"=72
+LITERAL_undefine="undefine"=73
+LITERAL_select="select"=74
+LITERAL_distinct="distinct"=75
+LITERAL_all="all"=76
+LITERAL_from="from"=77
+LITERAL_in="in"=78
+LITERAL_type="type"=79
+LITERAL_where="where"=80
+LITERAL_limit="limit"=81
+LITERAL_group="group"=82
+LITERAL_by="by"=83
+LITERAL_having="having"=84
+LITERAL_hint="hint"=85
+LITERAL_order="order"=86
+LITERAL_asc="asc"=87
+LITERAL_desc="desc"=88
+LITERAL_or="or"=89
+LITERAL_orelse="orelse"=90
+LITERAL_and="and"=91
+LITERAL_for="for"=92
+LITERAL_exists="exists"=93
+LITERAL_andthen="andthen"=94
+LITERAL_any="any"=95
+LITERAL_some="some"=96
+LITERAL_like="like"=97
+LITERAL_union="union"=98
+LITERAL_except="except"=99
+LITERAL_mod="mod"=100
+LITERAL_intersect="intersect"=101
+LITERAL_abs="abs"=102
+LITERAL_not="not"=103
+LITERAL_listtoset="listtoset"=104
+LITERAL_element="element"=105
+LITERAL_flatten="flatten"=106
+LITERAL_nvl="nvl"=107
+LITERAL_to_date="to_date"=108
+LITERAL_first="first"=109
+LITERAL_last="last"=110
+LITERAL_unique="unique"=111
+LITERAL_sum="sum"=112
+LITERAL_avg="avg"=113
+LITERAL_min="min"=114
+LITERAL_max="max"=115
+LITERAL_count="count"=116
+LITERAL_is_undefined="is_undefined"=117
+LITERAL_is_defined="is_defined"=118
+LITERAL_struct="struct"=119
+LITERAL_array="array"=120
+LITERAL_set="set"=121
+LITERAL_bag="bag"=122
+LITERAL_list="list"=123
+LITERAL_short="short"=124
+LITERAL_long="long"=125
+LITERAL_int="int"=126
+LITERAL_float="float"=127
+LITERAL_double="double"=128
+LITERAL_char="char"=129
+LITERAL_string="string"=130
+LITERAL_boolean="boolean"=131
+LITERAL_byte="byte"=132
+LITERAL_octet="octet"=133
+LITERAL_enum="enum"=134
+LITERAL_date="date"=135
+LITERAL_time="time"=136
+LITERAL_interval="interval"=137
+LITERAL_timestamp="timestamp"=138
+LITERAL_collection="collection"=139
+LITERAL_dictionary="dictionary"=140
+LITERAL_map="map"=141
+LITERAL_nil="nil"=142
+LITERAL_null="null"=143
+LITERAL_undefined="undefined"=144
+LITERAL_true="true"=145
+LITERAL_false="false"=146
+NUM_LONG=147
+NUM_FLOAT=148
+NUM_DOUBLE=149