CAY-2499 Support for COUNT(DISTINCT(column)) function aggregate

Project: http://git-wip-us.apache.org/repos/asf/cayenne/repo
Commit: http://git-wip-us.apache.org/repos/asf/cayenne/commit/54b3f811
Tree: http://git-wip-us.apache.org/repos/asf/cayenne/tree/54b3f811
Diff: http://git-wip-us.apache.org/repos/asf/cayenne/diff/54b3f811

Branch: refs/heads/master
Commit: 54b3f81107f16ed90d9b24277b19a69114094ae9
Parents: 55c91f9
Author: John Huss <johnth...@apache.org>
Authored: Fri Dec 7 14:18:45 2018 -0600
Committer: John Huss <johnth...@apache.org>
Committed: Wed Dec 12 14:48:55 2018 -0600

----------------------------------------------------------------------
 RELEASE-NOTES.txt                               |    3 +-
 .../cayenne/exp/FunctionExpressionFactory.java  |    8 +
 .../java/org/apache/cayenne/exp/Property.java   |    7 +
 .../apache/cayenne/exp/parser/ASTDistinct.java  |   41 +
 .../cayenne/exp/parser/ExpressionParser.java    |   81 +-
 .../exp/parser/ExpressionParserConstants.java   |   83 +-
 .../parser/ExpressionParserTokenManager.java    | 1017 +++++++++---------
 .../parser/ExpressionParserTreeConstants.java   |   31 +-
 .../exp/parser/JJTExpressionParserState.java    |   19 -
 .../cayenne/exp/parser/ExpressionParser.jjt     |    6 +
 .../org/apache/cayenne/exp/PropertyTest.java    |   10 +
 .../cayenne/query/ObjectSelect_AggregateIT.java |   16 +
 12 files changed, 711 insertions(+), 611 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cayenne/blob/54b3f811/RELEASE-NOTES.txt
----------------------------------------------------------------------
diff --git a/RELEASE-NOTES.txt b/RELEASE-NOTES.txt
index 90ec498..a885141 100644
--- a/RELEASE-NOTES.txt
+++ b/RELEASE-NOTES.txt
@@ -27,6 +27,7 @@ CAY-2489 Add validation to the case of not to PK relationships
 CAY-2491 Remaster Db Import View
 CAY-2493 Save cgen configuration with datamap XML
 CAY-2494 Rename dbImport tag from 'config' to 'dbImport'
+CAY-2499 Support for COUNT(DISTINCT(column)) function aggregate
 
 Bug Fixes:
 
@@ -568,4 +569,4 @@ CAY-1804 Serialisation of long[] type was not working 
correctly.
 CAY-1806 Error importing eomodel
 CAY-1817 NPE during Validate Project
 CAY-1827 EhCache region corresponding to a cache group loses its settings 
after 'removeGroup'
-CAY-1832 Exception when modifying objects in postLoad callback
\ No newline at end of file
+CAY-1832 Exception when modifying objects in postLoad callback

http://git-wip-us.apache.org/repos/asf/cayenne/blob/54b3f811/cayenne-server/src/main/java/org/apache/cayenne/exp/FunctionExpressionFactory.java
----------------------------------------------------------------------
diff --git 
a/cayenne-server/src/main/java/org/apache/cayenne/exp/FunctionExpressionFactory.java
 
b/cayenne-server/src/main/java/org/apache/cayenne/exp/FunctionExpressionFactory.java
index 114fb1d..7c3c980 100644
--- 
a/cayenne-server/src/main/java/org/apache/cayenne/exp/FunctionExpressionFactory.java
+++ 
b/cayenne-server/src/main/java/org/apache/cayenne/exp/FunctionExpressionFactory.java
@@ -26,6 +26,7 @@ import org.apache.cayenne.exp.parser.ASTCount;
 import org.apache.cayenne.exp.parser.ASTCurrentDate;
 import org.apache.cayenne.exp.parser.ASTCurrentTime;
 import org.apache.cayenne.exp.parser.ASTCurrentTimestamp;
+import org.apache.cayenne.exp.parser.ASTDistinct;
 import org.apache.cayenne.exp.parser.ASTExtract;
 import org.apache.cayenne.exp.parser.ASTLength;
 import org.apache.cayenne.exp.parser.ASTLocate;
@@ -322,6 +323,13 @@ public class FunctionExpressionFactory {
     public static Expression countExp(Expression exp) {
         return new ASTCount(exp);
     }
+    
+    /**
+     * @return Expression COUNT(DISTINCT(exp))
+     */
+    public static Expression countDistinctExp(Expression exp) {
+        return new ASTCount(new ASTDistinct(exp));
+    }
 
     /**
      * @return Expression MIN(exp)

http://git-wip-us.apache.org/repos/asf/cayenne/blob/54b3f811/cayenne-server/src/main/java/org/apache/cayenne/exp/Property.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/exp/Property.java 
b/cayenne-server/src/main/java/org/apache/cayenne/exp/Property.java
index 6872615..4df67b1 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/exp/Property.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/exp/Property.java
@@ -643,6 +643,13 @@ public class Property<E> {
     public Property<Long> count() {
         return create(FunctionExpressionFactory.countExp(getExpression()), 
Long.class);
     }
+    
+    /**
+     * @see FunctionExpressionFactory#countDistinctExp(Expression)
+     */
+    public Property<Long> countDistinct() {
+        return 
create(FunctionExpressionFactory.countDistinctExp(getExpression()), Long.class);
+    }
 
     /**
      * @see FunctionExpressionFactory#maxExp(Expression)

http://git-wip-us.apache.org/repos/asf/cayenne/blob/54b3f811/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTDistinct.java
----------------------------------------------------------------------
diff --git 
a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTDistinct.java 
b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTDistinct.java
new file mode 100644
index 0000000..39088c3
--- /dev/null
+++ 
b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTDistinct.java
@@ -0,0 +1,41 @@
+/*****************************************************************
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ ****************************************************************/
+
+package org.apache.cayenne.exp.parser;
+
+import org.apache.cayenne.exp.Expression;
+
+/**
+ * @since 4.0
+ */
+public class ASTDistinct extends ASTAggregateFunctionCall {
+
+       ASTDistinct(int id) {
+        super(id, "DISTINCT");
+    }
+
+    public ASTDistinct(Expression expression) {
+        super(ExpressionParserTreeConstants.JJTDISTINCT, "DISTINCT", 
expression);
+    }
+
+    @Override
+    public Expression shallowCopy() {
+        return new ASTDistinct(id);
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/54b3f811/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ExpressionParser.java
----------------------------------------------------------------------
diff --git 
a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ExpressionParser.java
 
b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ExpressionParser.java
index 06d4c0d..cbab144 100644
--- 
a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ExpressionParser.java
+++ 
b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ExpressionParser.java
@@ -21,6 +21,8 @@
 
 package org.apache.cayenne.exp.parser;
 
+import java.math.BigDecimal;
+import java.math.BigInteger;
 import org.apache.cayenne.exp.Expression;
 
 /**
@@ -194,10 +196,10 @@ public class ExpressionParser/*@bgen(jjtree)*/implements 
ExpressionParserTreeCon
     case HOUR:
     case MINUTE:
     case SECOND:
-    case 64:
     case 65:
     case 66:
     case 67:
+    case 68:
     case PROPERTY_PATH:
     case SINGLE_QUOTED_STRING:
     case DOUBLE_QUOTED_STRING:
@@ -271,10 +273,10 @@ public class ExpressionParser/*@bgen(jjtree)*/implements 
ExpressionParserTreeCon
     case HOUR:
     case MINUTE:
     case SECOND:
-    case 64:
     case 65:
     case 66:
     case 67:
+    case 68:
     case PROPERTY_PATH:
     case SINGLE_QUOTED_STRING:
     case DOUBLE_QUOTED_STRING:
@@ -544,7 +546,7 @@ public class ExpressionParser/*@bgen(jjtree)*/implements 
ExpressionParserTreeCon
                  jjtree.openNodeScope(jjtn011);
           try {
             switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-            case 64:
+            case 65:
               namedParameter();
               break;
             case 16:
@@ -703,7 +705,7 @@ public class ExpressionParser/*@bgen(jjtree)*/implements 
ExpressionParserTreeCon
                        jjtree.openNodeScope(jjtn003);
       try {
         switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-        case 64:
+        case 65:
           namedParameter();
           break;
         case 16:
@@ -833,10 +835,10 @@ public class ExpressionParser/*@bgen(jjtree)*/implements 
ExpressionParserTreeCon
     case HOUR:
     case MINUTE:
     case SECOND:
-    case 64:
     case 65:
     case 66:
     case 67:
+    case 68:
     case PROPERTY_PATH:
     case INT_LITERAL:
     case FLOAT_LITERAL:
@@ -884,9 +886,9 @@ public class ExpressionParser/*@bgen(jjtree)*/implements 
ExpressionParserTreeCon
 
   final public void stringParameter() throws ParseException {
     switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-    case 65:
     case 66:
     case 67:
+    case 68:
     case PROPERTY_PATH:
       pathExpression();
       break;
@@ -987,10 +989,10 @@ public class ExpressionParser/*@bgen(jjtree)*/implements 
ExpressionParserTreeCon
     case HOUR:
     case MINUTE:
     case SECOND:
-    case 64:
     case 65:
     case 66:
     case 67:
+    case 68:
     case PROPERTY_PATH:
     case SINGLE_QUOTED_STRING:
     case DOUBLE_QUOTED_STRING:
@@ -1067,7 +1069,7 @@ public class ExpressionParser/*@bgen(jjtree)*/implements 
ExpressionParserTreeCon
                                    }
       }
       break;
-    case 64:
+    case 65:
       namedParameter();
       break;
     case INT_LITERAL:
@@ -1509,10 +1511,10 @@ public class 
ExpressionParser/*@bgen(jjtree)*/implements ExpressionParserTreeCon
     case HOUR:
     case MINUTE:
     case SECOND:
-    case 64:
     case 65:
     case 66:
     case 67:
+    case 68:
     case PROPERTY_PATH:
     case INT_LITERAL:
     case FLOAT_LITERAL:
@@ -1571,10 +1573,10 @@ public class 
ExpressionParser/*@bgen(jjtree)*/implements ExpressionParserTreeCon
     case HOUR:
     case MINUTE:
     case SECOND:
-    case 64:
     case 65:
     case 66:
     case 67:
+    case 68:
     case PROPERTY_PATH:
     case INT_LITERAL:
     case FLOAT_LITERAL:
@@ -1659,7 +1661,7 @@ public class ExpressionParser/*@bgen(jjtree)*/implements 
ExpressionParserTreeCon
                             }
       }
       break;
-    case 64:
+    case 65:
       namedParameter();
       break;
     case LENGTH:
@@ -1679,9 +1681,9 @@ public class ExpressionParser/*@bgen(jjtree)*/implements 
ExpressionParserTreeCon
     case SECOND:
       functionsReturningNumerics();
       break;
-    case 65:
     case 66:
     case 67:
+    case 68:
     case PROPERTY_PATH:
       pathExpression();
       break;
@@ -2149,9 +2151,9 @@ public class ExpressionParser/*@bgen(jjtree)*/implements 
ExpressionParserTreeCon
       case ASTERISK:
         asterisk();
         break;
-      case 65:
       case 66:
       case 67:
+      case 68:
       case PROPERTY_PATH:
         pathExpression();
         break;
@@ -2440,9 +2442,40 @@ public class ExpressionParser/*@bgen(jjtree)*/implements 
ExpressionParserTreeCon
     }
   }
 
+  final public void distinct() throws ParseException {
+                             /*@bgen(jjtree) Distinct */
+  ASTDistinct jjtn000 = new ASTDistinct(JJTDISTINCT);
+  boolean jjtc000 = true;
+  jjtree.openNodeScope(jjtn000);
+    try {
+      jj_consume_token(DISTINCT);
+      jj_consume_token(16);
+      pathExpression();
+      jj_consume_token(17);
+    } catch (Throwable jjte000) {
+          if (jjtc000) {
+            jjtree.clearNodeScope(jjtn000);
+            jjtc000 = false;
+          } else {
+            jjtree.popNode();
+          }
+          if (jjte000 instanceof RuntimeException) {
+            {if (true) throw (RuntimeException)jjte000;}
+          }
+          if (jjte000 instanceof ParseException) {
+            {if (true) throw (ParseException)jjte000;}
+          }
+          {if (true) throw (Error)jjte000;}
+    } finally {
+          if (jjtc000) {
+            jjtree.closeNodeScope(jjtn000, true);
+          }
+    }
+  }
+
   final public void namedParameter() throws ParseException {
         Token t;
-    jj_consume_token(64);
+    jj_consume_token(65);
     t = jj_consume_token(PROPERTY_PATH);
                                   ASTNamedParameter jjtn001 = new 
ASTNamedParameter(JJTNAMEDPARAMETER);
                                   boolean jjtc001 = true;
@@ -2476,8 +2509,8 @@ public class ExpressionParser/*@bgen(jjtree)*/implements 
ExpressionParserTreeCon
                                    }
       }
       break;
-    case 65:
-      jj_consume_token(65);
+    case 66:
+      jj_consume_token(66);
       t = jj_consume_token(PROPERTY_PATH);
                                    ASTObjPath jjtn002 = new 
ASTObjPath(JJTOBJPATH);
                                    boolean jjtc002 = true;
@@ -2492,8 +2525,8 @@ public class ExpressionParser/*@bgen(jjtree)*/implements 
ExpressionParserTreeCon
                                    }
       }
       break;
-    case 66:
-      jj_consume_token(66);
+    case 67:
+      jj_consume_token(67);
       t = jj_consume_token(PROPERTY_PATH);
                                    ASTDbPath jjtn003 = new 
ASTDbPath(JJTDBPATH);
                                    boolean jjtc003 = true;
@@ -2508,8 +2541,8 @@ public class ExpressionParser/*@bgen(jjtree)*/implements 
ExpressionParserTreeCon
                                    }
       }
       break;
-    case 67:
-      jj_consume_token(67);
+    case 68:
+      jj_consume_token(68);
       t = jj_consume_token(PROPERTY_PATH);
                                    ASTEnum jjtn004 = new ASTEnum(JJTENUM);
                                    boolean jjtc004 = true;
@@ -2553,10 +2586,10 @@ public class 
ExpressionParser/*@bgen(jjtree)*/implements ExpressionParserTreeCon
       jj_la1_0 = new int[] 
{0x2,0x4,0x18,0x16010018,0x60,0x180,0x10000,0x4fff8,0x4fff8,0x16010000,0x18,0x10000,0x4e000,0x80000,0x16010000,0x0,0x0,0x16010000,0x0,0x100000,0x200000,0x400000,0x1800000,0x1800000,0x6000000,0x6000000,0x8000000,0x8000000,0x16010000,0x2000000,0x6010000,0x10000,0x0,0x80000,0x80000,0x0,0x80000,0x0,0x0,0x0,0x0,0x0,};
    }
    private static void jj_la1_init_1() {
-      jj_la1_1 = new int[] 
{0x0,0x0,0x0,0xfffffffe,0x0,0x0,0x0,0x0,0x0,0xfffffffe,0x0,0x0,0x0,0x0,0xfffffff2,0x3e00,0x3e00,0xfffffffe,0xc,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xffc7c000,0x0,0xffc7c000,0xffc7c000,0x3e00,0x0,0x0,0xffc7c000,0x0,0x1f0,0x0,0x380000,0xffc00000,0x0,};
+      jj_la1_1 = new int[] 
{0x0,0x0,0x0,0xfffffdfe,0x0,0x0,0x0,0x0,0x0,0xfffffdfe,0x0,0x0,0x0,0x0,0xfffffdf2,0x7c00,0x7c00,0xfffffdfe,0xc,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xff8f8000,0x0,0xff8f8000,0xff8f8000,0x7c00,0x0,0x0,0xff8f8000,0x0,0x1f0,0x0,0x700000,0xff800000,0x0,};
    }
    private static void jj_la1_init_2() {
-      jj_la1_2 = new int[] 
{0x0,0x0,0x0,0x7202f,0x0,0x0,0x1,0x0,0x0,0x7202f,0x0,0x1,0x0,0x0,0x7202f,0x1202e,0x12000,0x7202f,0x72001,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x10,0x10,0x6002f,0x0,0x6002f,0x6002f,0x0,0x0,0x0,0x0,0x0,0x0,0x3e,0x0,0x0,0x2e,};
+      jj_la1_2 = new int[] 
{0x0,0x0,0x0,0xe405f,0x0,0x0,0x2,0x0,0x0,0xe405f,0x0,0x2,0x0,0x0,0xe405f,0x2405c,0x24000,0xe405f,0xe4002,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20,0x20,0xc005f,0x0,0xc005f,0xc005f,0x0,0x0,0x0,0x1,0x0,0x0,0x7c,0x0,0x1,0x5c,};
    }
 
   /** Constructor with InputStream. */
@@ -2676,7 +2709,7 @@ public class ExpressionParser/*@bgen(jjtree)*/implements 
ExpressionParserTreeCon
   /** Generate ParseException. */
   public ParseException generateParseException() {
     jj_expentries.clear();
-    boolean[] la1tokens = new boolean[87];
+    boolean[] la1tokens = new boolean[88];
     if (jj_kind >= 0) {
       la1tokens[jj_kind] = true;
       jj_kind = -1;
@@ -2696,7 +2729,7 @@ public class ExpressionParser/*@bgen(jjtree)*/implements 
ExpressionParserTreeCon
         }
       }
     }
-    for (int i = 0; i < 87; i++) {
+    for (int i = 0; i < 88; i++) {
       if (la1tokens[i]) {
         jj_expentry = new int[1];
         jj_expentry[0] = i;

http://git-wip-us.apache.org/repos/asf/cayenne/blob/54b3f811/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ExpressionParserConstants.java
----------------------------------------------------------------------
diff --git 
a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ExpressionParserConstants.java
 
b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ExpressionParserConstants.java
index 18c00e2..c934325 100644
--- 
a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ExpressionParserConstants.java
+++ 
b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ExpressionParserConstants.java
@@ -47,81 +47,83 @@ public interface ExpressionParserConstants {
   /** RegularExpression Id. */
   int COUNT = 40;
   /** RegularExpression Id. */
-  int CONCAT = 41;
+  int DISTINCT = 41;
   /** RegularExpression Id. */
-  int SUBSTRING = 42;
+  int CONCAT = 42;
   /** RegularExpression Id. */
-  int TRIM = 43;
+  int SUBSTRING = 43;
   /** RegularExpression Id. */
-  int LOWER = 44;
+  int TRIM = 44;
   /** RegularExpression Id. */
-  int UPPER = 45;
+  int LOWER = 45;
   /** RegularExpression Id. */
-  int LENGTH = 46;
+  int UPPER = 46;
   /** RegularExpression Id. */
-  int LOCATE = 47;
+  int LENGTH = 47;
   /** RegularExpression Id. */
-  int ABS = 48;
+  int LOCATE = 48;
   /** RegularExpression Id. */
-  int SQRT = 49;
+  int ABS = 49;
   /** RegularExpression Id. */
-  int MOD = 50;
+  int SQRT = 50;
   /** RegularExpression Id. */
-  int CURRENT_DATE = 51;
+  int MOD = 51;
   /** RegularExpression Id. */
-  int CURRENT_TIME = 52;
+  int CURRENT_DATE = 52;
   /** RegularExpression Id. */
-  int CURRENT_TIMESTAMP = 53;
+  int CURRENT_TIME = 53;
   /** RegularExpression Id. */
-  int YEAR = 54;
+  int CURRENT_TIMESTAMP = 54;
   /** RegularExpression Id. */
-  int MONTH = 55;
+  int YEAR = 55;
   /** RegularExpression Id. */
-  int WEEK = 56;
+  int MONTH = 56;
   /** RegularExpression Id. */
-  int DAY_OF_YEAR = 57;
+  int WEEK = 57;
   /** RegularExpression Id. */
-  int DAY = 58;
+  int DAY_OF_YEAR = 58;
   /** RegularExpression Id. */
-  int DAY_OF_MONTH = 59;
+  int DAY = 59;
   /** RegularExpression Id. */
-  int DAY_OF_WEEK = 60;
+  int DAY_OF_MONTH = 60;
   /** RegularExpression Id. */
-  int HOUR = 61;
+  int DAY_OF_WEEK = 61;
   /** RegularExpression Id. */
-  int MINUTE = 62;
+  int HOUR = 62;
   /** RegularExpression Id. */
-  int SECOND = 63;
+  int MINUTE = 63;
   /** RegularExpression Id. */
-  int ASTERISK = 68;
+  int SECOND = 64;
   /** RegularExpression Id. */
-  int PROPERTY_PATH = 69;
+  int ASTERISK = 69;
   /** RegularExpression Id. */
-  int IDENTIFIER = 70;
+  int PROPERTY_PATH = 70;
   /** RegularExpression Id. */
-  int LETTER = 71;
+  int IDENTIFIER = 71;
   /** RegularExpression Id. */
-  int DIGIT = 72;
+  int LETTER = 72;
   /** RegularExpression Id. */
-  int ESC = 75;
+  int DIGIT = 73;
   /** RegularExpression Id. */
-  int SINGLE_QUOTED_STRING = 77;
+  int ESC = 76;
   /** RegularExpression Id. */
-  int STRING_ESC = 78;
+  int SINGLE_QUOTED_STRING = 78;
   /** RegularExpression Id. */
-  int DOUBLE_QUOTED_STRING = 80;
+  int STRING_ESC = 79;
   /** RegularExpression Id. */
-  int INT_LITERAL = 81;
+  int DOUBLE_QUOTED_STRING = 81;
   /** RegularExpression Id. */
-  int FLOAT_LITERAL = 82;
+  int INT_LITERAL = 82;
   /** RegularExpression Id. */
-  int DEC_FLT = 83;
+  int FLOAT_LITERAL = 83;
   /** RegularExpression Id. */
-  int DEC_DIGITS = 84;
+  int DEC_FLT = 84;
   /** RegularExpression Id. */
-  int EXPONENT = 85;
+  int DEC_DIGITS = 85;
   /** RegularExpression Id. */
-  int FLT_SUFF = 86;
+  int EXPONENT = 86;
+  /** RegularExpression Id. */
+  int FLT_SUFF = 87;
 
   /** Lexical state. */
   int DEFAULT = 0;
@@ -173,6 +175,7 @@ public interface ExpressionParserConstants {
     "\"max\"",
     "\"sum\"",
     "\"count\"",
+    "\"distinct\"",
     "\"concat\"",
     "\"substring\"",
     "\"trim\"",
@@ -208,10 +211,10 @@ public interface ExpressionParserConstants {
     "\"\\\'\"",
     "\"\\\"\"",
     "<ESC>",
-    "<token of kind 76>",
+    "<token of kind 77>",
     "\"\\\'\"",
     "<STRING_ESC>",
-    "<token of kind 79>",
+    "<token of kind 80>",
     "\"\\\"\"",
     "<INT_LITERAL>",
     "<FLOAT_LITERAL>",

Reply via email to