diff --git a/src/main/java/com/avaje/ebean/OrderBy.java b/src/main/java/com/avaje/ebean/OrderBy.java index 97b5f7177..dcdb638c6 100644 --- a/src/main/java/com/avaje/ebean/OrderBy.java +++ b/src/main/java/com/avaje/ebean/OrderBy.java @@ -148,6 +148,13 @@ public final class OrderBy implements Serializable { return copy; } + /** + * Add to the order by by parsing a raw expression. + */ + public void add(String rawExpression) { + parse(rawExpression); + } + /** * Add a property to the order by. */ diff --git a/src/main/java/com/avaje/ebeaninternal/server/grammer/EqlAdapter.java b/src/main/java/com/avaje/ebeaninternal/server/grammer/EqlAdapter.java index 2a200d9cb..3dfc85493 100644 --- a/src/main/java/com/avaje/ebeaninternal/server/grammer/EqlAdapter.java +++ b/src/main/java/com/avaje/ebeaninternal/server/grammer/EqlAdapter.java @@ -4,6 +4,7 @@ import com.avaje.ebean.Expression; import com.avaje.ebean.ExpressionList; import com.avaje.ebean.FetchConfig; import com.avaje.ebean.LikeType; +import com.avaje.ebean.OrderBy; import com.avaje.ebeaninternal.api.SpiQuery; import com.avaje.ebeaninternal.server.grammer.antlr.EQLBaseListener; import com.avaje.ebeaninternal.server.grammer.antlr.EQLLexer; @@ -22,6 +23,10 @@ class EqlAdapter extends EQLBaseListener { private static final String DISTINCT = "distinct"; + private static final String NULLS = "nulls"; + + private static final String ASC = "asc"; + private final SpiQuery query; private final EqlAdapterHelper helper; @@ -126,6 +131,34 @@ class EqlAdapter extends EQLBaseListener { } } + @Override + public void enterOrderby_property(EQLParser.Orderby_propertyContext ctx) { + + int childCount = ctx.getChildCount(); + + String path = child(ctx, 0); + boolean asc = true; + String nulls = null; + String nullsFirstLast = null; + + if (childCount == 3) { + asc = child(ctx, 1).startsWith(ASC); + nullsFirstLast = ctx.getChild(2).getChild(1).getText(); + nulls = NULLS; + + } else if (childCount == 2) { + String firstChild = child(ctx, 1); + if (firstChild.startsWith(NULLS)) { + nullsFirstLast = ctx.getChild(1).getChild(1).getText(); + nulls = NULLS; + } else { + asc = firstChild.startsWith(ASC); + } + } + + query.orderBy().add(new OrderBy.Property(path, asc, nulls, nullsFirstLast)); + } + @Override public void enterLimit_clause(EQLParser.Limit_clauseContext ctx) { diff --git a/src/main/java/com/avaje/ebeaninternal/server/grammer/antlr/EQL.tokens b/src/main/java/com/avaje/ebeaninternal/server/grammer/antlr/EQL.tokens index 6a00e9224..c6d1f969f 100644 --- a/src/main/java/com/avaje/ebeaninternal/server/grammer/antlr/EQL.tokens +++ b/src/main/java/com/avaje/ebeaninternal/server/grammer/antlr/EQL.tokens @@ -48,63 +48,77 @@ T__46=47 T__47=48 T__48=49 T__49=50 -INPUT_VARIABLE=51 -PATH_VARIABLE=52 -BOOLEAN_LITERAL=53 -NUMBER_LITERAL=54 -DOUBLE=55 -INT=56 -ZERO=57 -STRING_LITERAL=58 -WS=59 +T__50=51 +T__51=52 +T__52=53 +T__53=54 +T__54=55 +T__55=56 +T__56=57 +INPUT_VARIABLE=58 +PATH_VARIABLE=59 +BOOLEAN_LITERAL=60 +NUMBER_LITERAL=61 +DOUBLE=62 +INT=63 +ZERO=64 +STRING_LITERAL=65 +WS=66 'select'=1 '('=2 ')'=3 'distinct'=4 'where'=5 -'limit'=6 -'offset'=7 -'fetch'=8 -','=9 -'+'=10 -'query'=11 -'lazy'=12 -'or'=13 -'and'=14 -'not'=15 -'in'=16 -'between'=17 -'is'=18 -'null'=19 -'isNull'=20 -'isNotNull'=21 -'notNull'=22 -'empty'=23 -'isEmpty'=24 -'isNotEmpty'=25 -'notEmpty'=26 -'like'=27 -'ilike'=28 -'contains'=29 -'icontains'=30 -'startsWith'=31 -'istartsWith'=32 -'endsWith'=33 -'iendsWith'=34 -'='=35 -'eq'=36 -'>'=37 -'gt'=38 -'>='=39 -'ge'=40 -'gte'=41 -'<'=42 -'lt'=43 -'<='=44 -'le'=45 -'lte'=46 -'<>'=47 -'!='=48 -'ne'=49 -'ieq'=50 -'0'=57 +'order'=6 +'by'=7 +','=8 +'nulls'=9 +'first'=10 +'last'=11 +'asc'=12 +'desc'=13 +'limit'=14 +'offset'=15 +'fetch'=16 +'+'=17 +'query'=18 +'lazy'=19 +'or'=20 +'and'=21 +'not'=22 +'in'=23 +'between'=24 +'is'=25 +'null'=26 +'isNull'=27 +'isNotNull'=28 +'notNull'=29 +'empty'=30 +'isEmpty'=31 +'isNotEmpty'=32 +'notEmpty'=33 +'like'=34 +'ilike'=35 +'contains'=36 +'icontains'=37 +'startsWith'=38 +'istartsWith'=39 +'endsWith'=40 +'iendsWith'=41 +'='=42 +'eq'=43 +'>'=44 +'gt'=45 +'>='=46 +'ge'=47 +'gte'=48 +'<'=49 +'lt'=50 +'<='=51 +'le'=52 +'lte'=53 +'<>'=54 +'!='=55 +'ne'=56 +'ieq'=57 +'0'=64 diff --git a/src/main/java/com/avaje/ebeaninternal/server/grammer/antlr/EQLBaseListener.java b/src/main/java/com/avaje/ebeaninternal/server/grammer/antlr/EQLBaseListener.java index 6c8137e57..9bea015fd 100644 --- a/src/main/java/com/avaje/ebeaninternal/server/grammer/antlr/EQLBaseListener.java +++ b/src/main/java/com/avaje/ebeaninternal/server/grammer/antlr/EQLBaseListener.java @@ -71,6 +71,54 @@ public class EQLBaseListener implements EQLListener { *

The default implementation does nothing.

*/ @Override public void exitWhere_clause(EQLParser.Where_clauseContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterOrderby_clause(EQLParser.Orderby_clauseContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitOrderby_clause(EQLParser.Orderby_clauseContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterOrderby_property(EQLParser.Orderby_propertyContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitOrderby_property(EQLParser.Orderby_propertyContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterNulls_firstlast(EQLParser.Nulls_firstlastContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitNulls_firstlast(EQLParser.Nulls_firstlastContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterAsc_desc(EQLParser.Asc_descContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitAsc_desc(EQLParser.Asc_descContext ctx) { } /** * {@inheritDoc} * diff --git a/src/main/java/com/avaje/ebeaninternal/server/grammer/antlr/EQLLexer.java b/src/main/java/com/avaje/ebeaninternal/server/grammer/antlr/EQLLexer.java index 9f4c85e39..3e15448b1 100644 --- a/src/main/java/com/avaje/ebeaninternal/server/grammer/antlr/EQLLexer.java +++ b/src/main/java/com/avaje/ebeaninternal/server/grammer/antlr/EQLLexer.java @@ -23,9 +23,10 @@ public class EQLLexer extends Lexer { T__24=25, T__25=26, T__26=27, T__27=28, T__28=29, T__29=30, T__30=31, T__31=32, T__32=33, T__33=34, T__34=35, T__35=36, T__36=37, T__37=38, T__38=39, T__39=40, T__40=41, T__41=42, T__42=43, T__43=44, T__44=45, - T__45=46, T__46=47, T__47=48, T__48=49, T__49=50, INPUT_VARIABLE=51, PATH_VARIABLE=52, - BOOLEAN_LITERAL=53, NUMBER_LITERAL=54, DOUBLE=55, INT=56, ZERO=57, STRING_LITERAL=58, - WS=59; + T__45=46, T__46=47, T__47=48, T__48=49, T__49=50, T__50=51, T__51=52, + T__52=53, T__53=54, T__54=55, T__55=56, T__56=57, INPUT_VARIABLE=58, PATH_VARIABLE=59, + BOOLEAN_LITERAL=60, NUMBER_LITERAL=61, DOUBLE=62, INT=63, ZERO=64, STRING_LITERAL=65, + WS=66; public static String[] modeNames = { "DEFAULT_MODE" }; @@ -37,14 +38,16 @@ public class EQLLexer extends Lexer { "T__25", "T__26", "T__27", "T__28", "T__29", "T__30", "T__31", "T__32", "T__33", "T__34", "T__35", "T__36", "T__37", "T__38", "T__39", "T__40", "T__41", "T__42", "T__43", "T__44", "T__45", "T__46", "T__47", "T__48", - "T__49", "INPUT_VARIABLE", "PATH_VARIABLE", "BOOLEAN_LITERAL", "NUMBER_LITERAL", + "T__49", "T__50", "T__51", "T__52", "T__53", "T__54", "T__55", "T__56", + "INPUT_VARIABLE", "PATH_VARIABLE", "BOOLEAN_LITERAL", "NUMBER_LITERAL", "DOUBLE", "INT", "ZERO", "STRING_LITERAL", "WS" }; private static final String[] _LITERAL_NAMES = { - null, "'select'", "'('", "')'", "'distinct'", "'where'", "'limit'", "'offset'", - "'fetch'", "','", "'+'", "'query'", "'lazy'", "'or'", "'and'", "'not'", - "'in'", "'between'", "'is'", "'null'", "'isNull'", "'isNotNull'", "'notNull'", + null, "'select'", "'('", "')'", "'distinct'", "'where'", "'order'", "'by'", + "','", "'nulls'", "'first'", "'last'", "'asc'", "'desc'", "'limit'", "'offset'", + "'fetch'", "'+'", "'query'", "'lazy'", "'or'", "'and'", "'not'", "'in'", + "'between'", "'is'", "'null'", "'isNull'", "'isNotNull'", "'notNull'", "'empty'", "'isEmpty'", "'isNotEmpty'", "'notEmpty'", "'like'", "'ilike'", "'contains'", "'icontains'", "'startsWith'", "'istartsWith'", "'endsWith'", "'iendsWith'", "'='", "'eq'", "'>'", "'gt'", "'>='", "'ge'", "'gte'", @@ -56,8 +59,9 @@ public class EQLLexer extends Lexer { null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, - null, null, null, "INPUT_VARIABLE", "PATH_VARIABLE", "BOOLEAN_LITERAL", - "NUMBER_LITERAL", "DOUBLE", "INT", "ZERO", "STRING_LITERAL", "WS" + null, null, null, null, null, null, null, null, null, null, "INPUT_VARIABLE", + "PATH_VARIABLE", "BOOLEAN_LITERAL", "NUMBER_LITERAL", "DOUBLE", "INT", + "ZERO", "STRING_LITERAL", "WS" }; public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES); @@ -114,157 +118,172 @@ public class EQLLexer extends Lexer { public ATN getATN() { return _ATN; } public static final String _serializedATN = - "\3\u0430\ud6d1\u8206\uad2d\u4417\uaef1\u8d80\uaadd\2=\u01cf\b\1\4\2\t"+ + "\3\u0430\ud6d1\u8206\uad2d\u4417\uaef1\u8d80\uaadd\2D\u0200\b\1\4\2\t"+ "\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7\4\b\t\b\4\t\t\t\4\n\t\n\4\13"+ "\t\13\4\f\t\f\4\r\t\r\4\16\t\16\4\17\t\17\4\20\t\20\4\21\t\21\4\22\t\22"+ "\4\23\t\23\4\24\t\24\4\25\t\25\4\26\t\26\4\27\t\27\4\30\t\30\4\31\t\31"+ "\4\32\t\32\4\33\t\33\4\34\t\34\4\35\t\35\4\36\t\36\4\37\t\37\4 \t \4!"+ "\t!\4\"\t\"\4#\t#\4$\t$\4%\t%\4&\t&\4\'\t\'\4(\t(\4)\t)\4*\t*\4+\t+\4"+ ",\t,\4-\t-\4.\t.\4/\t/\4\60\t\60\4\61\t\61\4\62\t\62\4\63\t\63\4\64\t"+ - "\64\4\65\t\65\4\66\t\66\4\67\t\67\48\t8\49\t9\4:\t:\4;\t;\4<\t<\3\2\3"+ - "\2\3\2\3\2\3\2\3\2\3\2\3\3\3\3\3\4\3\4\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5"+ - "\3\5\3\6\3\6\3\6\3\6\3\6\3\6\3\7\3\7\3\7\3\7\3\7\3\7\3\b\3\b\3\b\3\b\3"+ - "\b\3\b\3\b\3\t\3\t\3\t\3\t\3\t\3\t\3\n\3\n\3\13\3\13\3\f\3\f\3\f\3\f\3"+ - "\f\3\f\3\r\3\r\3\r\3\r\3\r\3\16\3\16\3\16\3\17\3\17\3\17\3\17\3\20\3\20"+ - "\3\20\3\20\3\21\3\21\3\21\3\22\3\22\3\22\3\22\3\22\3\22\3\22\3\22\3\23"+ - "\3\23\3\23\3\24\3\24\3\24\3\24\3\24\3\25\3\25\3\25\3\25\3\25\3\25\3\25"+ - "\3\26\3\26\3\26\3\26\3\26\3\26\3\26\3\26\3\26\3\26\3\27\3\27\3\27\3\27"+ - "\3\27\3\27\3\27\3\27\3\30\3\30\3\30\3\30\3\30\3\30\3\31\3\31\3\31\3\31"+ - "\3\31\3\31\3\31\3\31\3\32\3\32\3\32\3\32\3\32\3\32\3\32\3\32\3\32\3\32"+ - "\3\32\3\33\3\33\3\33\3\33\3\33\3\33\3\33\3\33\3\33\3\34\3\34\3\34\3\34"+ - "\3\34\3\35\3\35\3\35\3\35\3\35\3\35\3\36\3\36\3\36\3\36\3\36\3\36\3\36"+ - "\3\36\3\36\3\37\3\37\3\37\3\37\3\37\3\37\3\37\3\37\3\37\3\37\3 \3 \3 "+ - "\3 \3 \3 \3 \3 \3 \3 \3 \3!\3!\3!\3!\3!\3!\3!\3!\3!\3!\3!\3!\3\"\3\"\3"+ - "\"\3\"\3\"\3\"\3\"\3\"\3\"\3#\3#\3#\3#\3#\3#\3#\3#\3#\3#\3$\3$\3%\3%\3"+ - "%\3&\3&\3\'\3\'\3\'\3(\3(\3(\3)\3)\3)\3*\3*\3*\3*\3+\3+\3,\3,\3,\3-\3"+ - "-\3-\3.\3.\3.\3/\3/\3/\3/\3\60\3\60\3\60\3\61\3\61\3\61\3\62\3\62\3\62"+ - "\3\63\3\63\3\63\3\63\3\64\3\64\3\64\7\64\u018a\n\64\f\64\16\64\u018d\13"+ - "\64\3\65\3\65\7\65\u0191\n\65\f\65\16\65\u0194\13\65\3\66\3\66\3\66\3"+ - "\66\3\66\3\66\3\66\3\66\3\66\5\66\u019f\n\66\3\67\5\67\u01a2\n\67\3\67"+ - "\3\67\5\67\u01a6\n\67\3\67\3\67\5\67\u01aa\n\67\38\68\u01ad\n8\r8\168"+ - "\u01ae\38\38\78\u01b3\n8\f8\168\u01b6\138\39\39\79\u01ba\n9\f9\169\u01bd"+ - "\139\3:\3:\3;\3;\3;\3;\7;\u01c5\n;\f;\16;\u01c8\13;\3;\3;\3<\3<\3<\3<"+ - "\2\2=\3\3\5\4\7\5\t\6\13\7\r\b\17\t\21\n\23\13\25\f\27\r\31\16\33\17\35"+ + "\64\4\65\t\65\4\66\t\66\4\67\t\67\48\t8\49\t9\4:\t:\4;\t;\4<\t<\4=\t="+ + "\4>\t>\4?\t?\4@\t@\4A\tA\4B\tB\4C\tC\3\2\3\2\3\2\3\2\3\2\3\2\3\2\3\3\3"+ + "\3\3\4\3\4\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\6\3\6\3\6\3\6\3\6\3\6"+ + "\3\7\3\7\3\7\3\7\3\7\3\7\3\b\3\b\3\b\3\t\3\t\3\n\3\n\3\n\3\n\3\n\3\n\3"+ + "\13\3\13\3\13\3\13\3\13\3\13\3\f\3\f\3\f\3\f\3\f\3\r\3\r\3\r\3\r\3\16"+ + "\3\16\3\16\3\16\3\16\3\17\3\17\3\17\3\17\3\17\3\17\3\20\3\20\3\20\3\20"+ + "\3\20\3\20\3\20\3\21\3\21\3\21\3\21\3\21\3\21\3\22\3\22\3\23\3\23\3\23"+ + "\3\23\3\23\3\23\3\24\3\24\3\24\3\24\3\24\3\25\3\25\3\25\3\26\3\26\3\26"+ + "\3\26\3\27\3\27\3\27\3\27\3\30\3\30\3\30\3\31\3\31\3\31\3\31\3\31\3\31"+ + "\3\31\3\31\3\32\3\32\3\32\3\33\3\33\3\33\3\33\3\33\3\34\3\34\3\34\3\34"+ + "\3\34\3\34\3\34\3\35\3\35\3\35\3\35\3\35\3\35\3\35\3\35\3\35\3\35\3\36"+ + "\3\36\3\36\3\36\3\36\3\36\3\36\3\36\3\37\3\37\3\37\3\37\3\37\3\37\3 \3"+ + " \3 \3 \3 \3 \3 \3 \3!\3!\3!\3!\3!\3!\3!\3!\3!\3!\3!\3\"\3\"\3\"\3\"\3"+ + "\"\3\"\3\"\3\"\3\"\3#\3#\3#\3#\3#\3$\3$\3$\3$\3$\3$\3%\3%\3%\3%\3%\3%"+ + "\3%\3%\3%\3&\3&\3&\3&\3&\3&\3&\3&\3&\3&\3\'\3\'\3\'\3\'\3\'\3\'\3\'\3"+ + "\'\3\'\3\'\3\'\3(\3(\3(\3(\3(\3(\3(\3(\3(\3(\3(\3(\3)\3)\3)\3)\3)\3)\3"+ + ")\3)\3)\3*\3*\3*\3*\3*\3*\3*\3*\3*\3*\3+\3+\3,\3,\3,\3-\3-\3.\3.\3.\3"+ + "/\3/\3/\3\60\3\60\3\60\3\61\3\61\3\61\3\61\3\62\3\62\3\63\3\63\3\63\3"+ + "\64\3\64\3\64\3\65\3\65\3\65\3\66\3\66\3\66\3\66\3\67\3\67\3\67\38\38"+ + "\38\39\39\39\3:\3:\3:\3:\3;\3;\3;\7;\u01bb\n;\f;\16;\u01be\13;\3<\3<\7"+ + "<\u01c2\n<\f<\16<\u01c5\13<\3=\3=\3=\3=\3=\3=\3=\3=\3=\5=\u01d0\n=\3>"+ + "\5>\u01d3\n>\3>\3>\5>\u01d7\n>\3>\3>\5>\u01db\n>\3?\6?\u01de\n?\r?\16"+ + "?\u01df\3?\3?\7?\u01e4\n?\f?\16?\u01e7\13?\3@\3@\7@\u01eb\n@\f@\16@\u01ee"+ + "\13@\3A\3A\3B\3B\3B\3B\7B\u01f6\nB\fB\16B\u01f9\13B\3B\3B\3C\3C\3C\3C"+ + "\2\2D\3\3\5\4\7\5\t\6\13\7\r\b\17\t\21\n\23\13\25\f\27\r\31\16\33\17\35"+ "\20\37\21!\22#\23%\24\'\25)\26+\27-\30/\31\61\32\63\33\65\34\67\359\36"+ ";\37= ?!A\"C#E$G%I&K\'M(O)Q*S+U,W-Y.[/]\60_\61a\62c\63e\64g\65i\66k\67"+ - "m8o9q:s;u\3\2\2\2\u012c\u012d\7u\2\2\u012d\u012e\7v\2\2\u012e\u012f\7c\2\2\u012f"+ - "\u0130\7t\2\2\u0130\u0131\7v\2\2\u0131\u0132\7u\2\2\u0132\u0133\7Y\2\2"+ - "\u0133\u0134\7k\2\2\u0134\u0135\7v\2\2\u0135\u0136\7j\2\2\u0136@\3\2\2"+ - "\2\u0137\u0138\7k\2\2\u0138\u0139\7u\2\2\u0139\u013a\7v\2\2\u013a\u013b"+ - "\7c\2\2\u013b\u013c\7t\2\2\u013c\u013d\7v\2\2\u013d\u013e\7u\2\2\u013e"+ - "\u013f\7Y\2\2\u013f\u0140\7k\2\2\u0140\u0141\7v\2\2\u0141\u0142\7j\2\2"+ - "\u0142B\3\2\2\2\u0143\u0144\7g\2\2\u0144\u0145\7p\2\2\u0145\u0146\7f\2"+ - "\2\u0146\u0147\7u\2\2\u0147\u0148\7Y\2\2\u0148\u0149\7k\2\2\u0149\u014a"+ - "\7v\2\2\u014a\u014b\7j\2\2\u014bD\3\2\2\2\u014c\u014d\7k\2\2\u014d\u014e"+ - "\7g\2\2\u014e\u014f\7p\2\2\u014f\u0150\7f\2\2\u0150\u0151\7u\2\2\u0151"+ - "\u0152\7Y\2\2\u0152\u0153\7k\2\2\u0153\u0154\7v\2\2\u0154\u0155\7j\2\2"+ - "\u0155F\3\2\2\2\u0156\u0157\7?\2\2\u0157H\3\2\2\2\u0158\u0159\7g\2\2\u0159"+ - "\u015a\7s\2\2\u015aJ\3\2\2\2\u015b\u015c\7@\2\2\u015cL\3\2\2\2\u015d\u015e"+ - "\7i\2\2\u015e\u015f\7v\2\2\u015fN\3\2\2\2\u0160\u0161\7@\2\2\u0161\u0162"+ - "\7?\2\2\u0162P\3\2\2\2\u0163\u0164\7i\2\2\u0164\u0165\7g\2\2\u0165R\3"+ - "\2\2\2\u0166\u0167\7i\2\2\u0167\u0168\7v\2\2\u0168\u0169\7g\2\2\u0169"+ - "T\3\2\2\2\u016a\u016b\7>\2\2\u016bV\3\2\2\2\u016c\u016d\7n\2\2\u016d\u016e"+ - "\7v\2\2\u016eX\3\2\2\2\u016f\u0170\7>\2\2\u0170\u0171\7?\2\2\u0171Z\3"+ - "\2\2\2\u0172\u0173\7n\2\2\u0173\u0174\7g\2\2\u0174\\\3\2\2\2\u0175\u0176"+ - "\7n\2\2\u0176\u0177\7v\2\2\u0177\u0178\7g\2\2\u0178^\3\2\2\2\u0179\u017a"+ - "\7>\2\2\u017a\u017b\7@\2\2\u017b`\3\2\2\2\u017c\u017d\7#\2\2\u017d\u017e"+ - "\7?\2\2\u017eb\3\2\2\2\u017f\u0180\7p\2\2\u0180\u0181\7g\2\2\u0181d\3"+ - "\2\2\2\u0182\u0183\7k\2\2\u0183\u0184\7g\2\2\u0184\u0185\7s\2\2\u0185"+ - "f\3\2\2\2\u0186\u0187\7<\2\2\u0187\u018b\t\2\2\2\u0188\u018a\t\3\2\2\u0189"+ - "\u0188\3\2\2\2\u018a\u018d\3\2\2\2\u018b\u0189\3\2\2\2\u018b\u018c\3\2"+ - "\2\2\u018ch\3\2\2\2\u018d\u018b\3\2\2\2\u018e\u0192\t\2\2\2\u018f\u0191"+ - "\t\4\2\2\u0190\u018f\3\2\2\2\u0191\u0194\3\2\2\2\u0192\u0190\3\2\2\2\u0192"+ - "\u0193\3\2\2\2\u0193j\3\2\2\2\u0194\u0192\3\2\2\2\u0195\u0196\7v\2\2\u0196"+ - "\u0197\7t\2\2\u0197\u0198\7w\2\2\u0198\u019f\7g\2\2\u0199\u019a\7h\2\2"+ - "\u019a\u019b\7c\2\2\u019b\u019c\7n\2\2\u019c\u019d\7u\2\2\u019d\u019f"+ - "\7g\2\2\u019e\u0195\3\2\2\2\u019e\u0199\3\2\2\2\u019fl\3\2\2\2\u01a0\u01a2"+ - "\7/\2\2\u01a1\u01a0\3\2\2\2\u01a1\u01a2\3\2\2\2\u01a2\u01a3\3\2\2\2\u01a3"+ - "\u01aa\5o8\2\u01a4\u01a6\7/\2\2\u01a5\u01a4\3\2\2\2\u01a5\u01a6\3\2\2"+ - "\2\u01a6\u01a7\3\2\2\2\u01a7\u01aa\5q9\2\u01a8\u01aa\5s:\2\u01a9\u01a1"+ - "\3\2\2\2\u01a9\u01a5\3\2\2\2\u01a9\u01a8\3\2\2\2\u01aan\3\2\2\2\u01ab"+ - "\u01ad\t\5\2\2\u01ac\u01ab\3\2\2\2\u01ad\u01ae\3\2\2\2\u01ae\u01ac\3\2"+ - "\2\2\u01ae\u01af\3\2\2\2\u01af\u01b0\3\2\2\2\u01b0\u01b4\7\60\2\2\u01b1"+ - "\u01b3\t\5\2\2\u01b2\u01b1\3\2\2\2\u01b3\u01b6\3\2\2\2\u01b4\u01b2\3\2"+ - "\2\2\u01b4\u01b5\3\2\2\2\u01b5p\3\2\2\2\u01b6\u01b4\3\2\2\2\u01b7\u01bb"+ - "\t\6\2\2\u01b8\u01ba\t\5\2\2\u01b9\u01b8\3\2\2\2\u01ba\u01bd\3\2\2\2\u01bb"+ - "\u01b9\3\2\2\2\u01bb\u01bc\3\2\2\2\u01bcr\3\2\2\2\u01bd\u01bb\3\2\2\2"+ - "\u01be\u01bf\7\62\2\2\u01bft\3\2\2\2\u01c0\u01c6\7)\2\2\u01c1\u01c5\n"+ - "\7\2\2\u01c2\u01c3\7)\2\2\u01c3\u01c5\7)\2\2\u01c4\u01c1\3\2\2\2\u01c4"+ - "\u01c2\3\2\2\2\u01c5\u01c8\3\2\2\2\u01c6\u01c4\3\2\2\2\u01c6\u01c7\3\2"+ - "\2\2\u01c7\u01c9\3\2\2\2\u01c8\u01c6\3\2\2\2\u01c9\u01ca\7)\2\2\u01ca"+ - "v\3\2\2\2\u01cb\u01cc\t\b\2\2\u01cc\u01cd\3\2\2\2\u01cd\u01ce\b<\2\2\u01ce"+ - "x\3\2\2\2\16\2\u018b\u0192\u019e\u01a1\u01a5\u01a9\u01ae\u01b4\u01bb\u01c4"+ - "\u01c6\3\b\2\2"; + "m8o9q:s;u{?}@\177A\u0081B\u0083C\u0085D\3\2\t\5\2C\\aac|\6\2\62;"+ + "C\\aac|\7\2\60\60\62;C\\aac|\3\2\62;\3\2\63;\3\2))\5\2\13\f\17\17\"\""+ + "\u020b\2\3\3\2\2\2\2\5\3\2\2\2\2\7\3\2\2\2\2\t\3\2\2\2\2\13\3\2\2\2\2"+ + "\r\3\2\2\2\2\17\3\2\2\2\2\21\3\2\2\2\2\23\3\2\2\2\2\25\3\2\2\2\2\27\3"+ + "\2\2\2\2\31\3\2\2\2\2\33\3\2\2\2\2\35\3\2\2\2\2\37\3\2\2\2\2!\3\2\2\2"+ + "\2#\3\2\2\2\2%\3\2\2\2\2\'\3\2\2\2\2)\3\2\2\2\2+\3\2\2\2\2-\3\2\2\2\2"+ + "/\3\2\2\2\2\61\3\2\2\2\2\63\3\2\2\2\2\65\3\2\2\2\2\67\3\2\2\2\29\3\2\2"+ + "\2\2;\3\2\2\2\2=\3\2\2\2\2?\3\2\2\2\2A\3\2\2\2\2C\3\2\2\2\2E\3\2\2\2\2"+ + "G\3\2\2\2\2I\3\2\2\2\2K\3\2\2\2\2M\3\2\2\2\2O\3\2\2\2\2Q\3\2\2\2\2S\3"+ + "\2\2\2\2U\3\2\2\2\2W\3\2\2\2\2Y\3\2\2\2\2[\3\2\2\2\2]\3\2\2\2\2_\3\2\2"+ + "\2\2a\3\2\2\2\2c\3\2\2\2\2e\3\2\2\2\2g\3\2\2\2\2i\3\2\2\2\2k\3\2\2\2\2"+ + "m\3\2\2\2\2o\3\2\2\2\2q\3\2\2\2\2s\3\2\2\2\2u\3\2\2\2\2w\3\2\2\2\2y\3"+ + "\2\2\2\2{\3\2\2\2\2}\3\2\2\2\2\177\3\2\2\2\2\u0081\3\2\2\2\2\u0083\3\2"+ + "\2\2\2\u0085\3\2\2\2\3\u0087\3\2\2\2\5\u008e\3\2\2\2\7\u0090\3\2\2\2\t"+ + "\u0092\3\2\2\2\13\u009b\3\2\2\2\r\u00a1\3\2\2\2\17\u00a7\3\2\2\2\21\u00aa"+ + "\3\2\2\2\23\u00ac\3\2\2\2\25\u00b2\3\2\2\2\27\u00b8\3\2\2\2\31\u00bd\3"+ + "\2\2\2\33\u00c1\3\2\2\2\35\u00c6\3\2\2\2\37\u00cc\3\2\2\2!\u00d3\3\2\2"+ + "\2#\u00d9\3\2\2\2%\u00db\3\2\2\2\'\u00e1\3\2\2\2)\u00e6\3\2\2\2+\u00e9"+ + "\3\2\2\2-\u00ed\3\2\2\2/\u00f1\3\2\2\2\61\u00f4\3\2\2\2\63\u00fc\3\2\2"+ + "\2\65\u00ff\3\2\2\2\67\u0104\3\2\2\29\u010b\3\2\2\2;\u0115\3\2\2\2=\u011d"+ + "\3\2\2\2?\u0123\3\2\2\2A\u012b\3\2\2\2C\u0136\3\2\2\2E\u013f\3\2\2\2G"+ + "\u0144\3\2\2\2I\u014a\3\2\2\2K\u0153\3\2\2\2M\u015d\3\2\2\2O\u0168\3\2"+ + "\2\2Q\u0174\3\2\2\2S\u017d\3\2\2\2U\u0187\3\2\2\2W\u0189\3\2\2\2Y\u018c"+ + "\3\2\2\2[\u018e\3\2\2\2]\u0191\3\2\2\2_\u0194\3\2\2\2a\u0197\3\2\2\2c"+ + "\u019b\3\2\2\2e\u019d\3\2\2\2g\u01a0\3\2\2\2i\u01a3\3\2\2\2k\u01a6\3\2"+ + "\2\2m\u01aa\3\2\2\2o\u01ad\3\2\2\2q\u01b0\3\2\2\2s\u01b3\3\2\2\2u\u01b7"+ + "\3\2\2\2w\u01bf\3\2\2\2y\u01cf\3\2\2\2{\u01da\3\2\2\2}\u01dd\3\2\2\2\177"+ + "\u01e8\3\2\2\2\u0081\u01ef\3\2\2\2\u0083\u01f1\3\2\2\2\u0085\u01fc\3\2"+ + "\2\2\u0087\u0088\7u\2\2\u0088\u0089\7g\2\2\u0089\u008a\7n\2\2\u008a\u008b"+ + "\7g\2\2\u008b\u008c\7e\2\2\u008c\u008d\7v\2\2\u008d\4\3\2\2\2\u008e\u008f"+ + "\7*\2\2\u008f\6\3\2\2\2\u0090\u0091\7+\2\2\u0091\b\3\2\2\2\u0092\u0093"+ + "\7f\2\2\u0093\u0094\7k\2\2\u0094\u0095\7u\2\2\u0095\u0096\7v\2\2\u0096"+ + "\u0097\7k\2\2\u0097\u0098\7p\2\2\u0098\u0099\7e\2\2\u0099\u009a\7v\2\2"+ + "\u009a\n\3\2\2\2\u009b\u009c\7y\2\2\u009c\u009d\7j\2\2\u009d\u009e\7g"+ + "\2\2\u009e\u009f\7t\2\2\u009f\u00a0\7g\2\2\u00a0\f\3\2\2\2\u00a1\u00a2"+ + "\7q\2\2\u00a2\u00a3\7t\2\2\u00a3\u00a4\7f\2\2\u00a4\u00a5\7g\2\2\u00a5"+ + "\u00a6\7t\2\2\u00a6\16\3\2\2\2\u00a7\u00a8\7d\2\2\u00a8\u00a9\7{\2\2\u00a9"+ + "\20\3\2\2\2\u00aa\u00ab\7.\2\2\u00ab\22\3\2\2\2\u00ac\u00ad\7p\2\2\u00ad"+ + "\u00ae\7w\2\2\u00ae\u00af\7n\2\2\u00af\u00b0\7n\2\2\u00b0\u00b1\7u\2\2"+ + "\u00b1\24\3\2\2\2\u00b2\u00b3\7h\2\2\u00b3\u00b4\7k\2\2\u00b4\u00b5\7"+ + "t\2\2\u00b5\u00b6\7u\2\2\u00b6\u00b7\7v\2\2\u00b7\26\3\2\2\2\u00b8\u00b9"+ + "\7n\2\2\u00b9\u00ba\7c\2\2\u00ba\u00bb\7u\2\2\u00bb\u00bc\7v\2\2\u00bc"+ + "\30\3\2\2\2\u00bd\u00be\7c\2\2\u00be\u00bf\7u\2\2\u00bf\u00c0\7e\2\2\u00c0"+ + "\32\3\2\2\2\u00c1\u00c2\7f\2\2\u00c2\u00c3\7g\2\2\u00c3\u00c4\7u\2\2\u00c4"+ + "\u00c5\7e\2\2\u00c5\34\3\2\2\2\u00c6\u00c7\7n\2\2\u00c7\u00c8\7k\2\2\u00c8"+ + "\u00c9\7o\2\2\u00c9\u00ca\7k\2\2\u00ca\u00cb\7v\2\2\u00cb\36\3\2\2\2\u00cc"+ + "\u00cd\7q\2\2\u00cd\u00ce\7h\2\2\u00ce\u00cf\7h\2\2\u00cf\u00d0\7u\2\2"+ + "\u00d0\u00d1\7g\2\2\u00d1\u00d2\7v\2\2\u00d2 \3\2\2\2\u00d3\u00d4\7h\2"+ + "\2\u00d4\u00d5\7g\2\2\u00d5\u00d6\7v\2\2\u00d6\u00d7\7e\2\2\u00d7\u00d8"+ + "\7j\2\2\u00d8\"\3\2\2\2\u00d9\u00da\7-\2\2\u00da$\3\2\2\2\u00db\u00dc"+ + "\7s\2\2\u00dc\u00dd\7w\2\2\u00dd\u00de\7g\2\2\u00de\u00df\7t\2\2\u00df"+ + "\u00e0\7{\2\2\u00e0&\3\2\2\2\u00e1\u00e2\7n\2\2\u00e2\u00e3\7c\2\2\u00e3"+ + "\u00e4\7|\2\2\u00e4\u00e5\7{\2\2\u00e5(\3\2\2\2\u00e6\u00e7\7q\2\2\u00e7"+ + "\u00e8\7t\2\2\u00e8*\3\2\2\2\u00e9\u00ea\7c\2\2\u00ea\u00eb\7p\2\2\u00eb"+ + "\u00ec\7f\2\2\u00ec,\3\2\2\2\u00ed\u00ee\7p\2\2\u00ee\u00ef\7q\2\2\u00ef"+ + "\u00f0\7v\2\2\u00f0.\3\2\2\2\u00f1\u00f2\7k\2\2\u00f2\u00f3\7p\2\2\u00f3"+ + "\60\3\2\2\2\u00f4\u00f5\7d\2\2\u00f5\u00f6\7g\2\2\u00f6\u00f7\7v\2\2\u00f7"+ + "\u00f8\7y\2\2\u00f8\u00f9\7g\2\2\u00f9\u00fa\7g\2\2\u00fa\u00fb\7p\2\2"+ + "\u00fb\62\3\2\2\2\u00fc\u00fd\7k\2\2\u00fd\u00fe\7u\2\2\u00fe\64\3\2\2"+ + "\2\u00ff\u0100\7p\2\2\u0100\u0101\7w\2\2\u0101\u0102\7n\2\2\u0102\u0103"+ + "\7n\2\2\u0103\66\3\2\2\2\u0104\u0105\7k\2\2\u0105\u0106\7u\2\2\u0106\u0107"+ + "\7P\2\2\u0107\u0108\7w\2\2\u0108\u0109\7n\2\2\u0109\u010a\7n\2\2\u010a"+ + "8\3\2\2\2\u010b\u010c\7k\2\2\u010c\u010d\7u\2\2\u010d\u010e\7P\2\2\u010e"+ + "\u010f\7q\2\2\u010f\u0110\7v\2\2\u0110\u0111\7P\2\2\u0111\u0112\7w\2\2"+ + "\u0112\u0113\7n\2\2\u0113\u0114\7n\2\2\u0114:\3\2\2\2\u0115\u0116\7p\2"+ + "\2\u0116\u0117\7q\2\2\u0117\u0118\7v\2\2\u0118\u0119\7P\2\2\u0119\u011a"+ + "\7w\2\2\u011a\u011b\7n\2\2\u011b\u011c\7n\2\2\u011c<\3\2\2\2\u011d\u011e"+ + "\7g\2\2\u011e\u011f\7o\2\2\u011f\u0120\7r\2\2\u0120\u0121\7v\2\2\u0121"+ + "\u0122\7{\2\2\u0122>\3\2\2\2\u0123\u0124\7k\2\2\u0124\u0125\7u\2\2\u0125"+ + "\u0126\7G\2\2\u0126\u0127\7o\2\2\u0127\u0128\7r\2\2\u0128\u0129\7v\2\2"+ + "\u0129\u012a\7{\2\2\u012a@\3\2\2\2\u012b\u012c\7k\2\2\u012c\u012d\7u\2"+ + "\2\u012d\u012e\7P\2\2\u012e\u012f\7q\2\2\u012f\u0130\7v\2\2\u0130\u0131"+ + "\7G\2\2\u0131\u0132\7o\2\2\u0132\u0133\7r\2\2\u0133\u0134\7v\2\2\u0134"+ + "\u0135\7{\2\2\u0135B\3\2\2\2\u0136\u0137\7p\2\2\u0137\u0138\7q\2\2\u0138"+ + "\u0139\7v\2\2\u0139\u013a\7G\2\2\u013a\u013b\7o\2\2\u013b\u013c\7r\2\2"+ + "\u013c\u013d\7v\2\2\u013d\u013e\7{\2\2\u013eD\3\2\2\2\u013f\u0140\7n\2"+ + "\2\u0140\u0141\7k\2\2\u0141\u0142\7m\2\2\u0142\u0143\7g\2\2\u0143F\3\2"+ + "\2\2\u0144\u0145\7k\2\2\u0145\u0146\7n\2\2\u0146\u0147\7k\2\2\u0147\u0148"+ + "\7m\2\2\u0148\u0149\7g\2\2\u0149H\3\2\2\2\u014a\u014b\7e\2\2\u014b\u014c"+ + "\7q\2\2\u014c\u014d\7p\2\2\u014d\u014e\7v\2\2\u014e\u014f\7c\2\2\u014f"+ + "\u0150\7k\2\2\u0150\u0151\7p\2\2\u0151\u0152\7u\2\2\u0152J\3\2\2\2\u0153"+ + "\u0154\7k\2\2\u0154\u0155\7e\2\2\u0155\u0156\7q\2\2\u0156\u0157\7p\2\2"+ + "\u0157\u0158\7v\2\2\u0158\u0159\7c\2\2\u0159\u015a\7k\2\2\u015a\u015b"+ + "\7p\2\2\u015b\u015c\7u\2\2\u015cL\3\2\2\2\u015d\u015e\7u\2\2\u015e\u015f"+ + "\7v\2\2\u015f\u0160\7c\2\2\u0160\u0161\7t\2\2\u0161\u0162\7v\2\2\u0162"+ + "\u0163\7u\2\2\u0163\u0164\7Y\2\2\u0164\u0165\7k\2\2\u0165\u0166\7v\2\2"+ + "\u0166\u0167\7j\2\2\u0167N\3\2\2\2\u0168\u0169\7k\2\2\u0169\u016a\7u\2"+ + "\2\u016a\u016b\7v\2\2\u016b\u016c\7c\2\2\u016c\u016d\7t\2\2\u016d\u016e"+ + "\7v\2\2\u016e\u016f\7u\2\2\u016f\u0170\7Y\2\2\u0170\u0171\7k\2\2\u0171"+ + "\u0172\7v\2\2\u0172\u0173\7j\2\2\u0173P\3\2\2\2\u0174\u0175\7g\2\2\u0175"+ + "\u0176\7p\2\2\u0176\u0177\7f\2\2\u0177\u0178\7u\2\2\u0178\u0179\7Y\2\2"+ + "\u0179\u017a\7k\2\2\u017a\u017b\7v\2\2\u017b\u017c\7j\2\2\u017cR\3\2\2"+ + "\2\u017d\u017e\7k\2\2\u017e\u017f\7g\2\2\u017f\u0180\7p\2\2\u0180\u0181"+ + "\7f\2\2\u0181\u0182\7u\2\2\u0182\u0183\7Y\2\2\u0183\u0184\7k\2\2\u0184"+ + "\u0185\7v\2\2\u0185\u0186\7j\2\2\u0186T\3\2\2\2\u0187\u0188\7?\2\2\u0188"+ + "V\3\2\2\2\u0189\u018a\7g\2\2\u018a\u018b\7s\2\2\u018bX\3\2\2\2\u018c\u018d"+ + "\7@\2\2\u018dZ\3\2\2\2\u018e\u018f\7i\2\2\u018f\u0190\7v\2\2\u0190\\\3"+ + "\2\2\2\u0191\u0192\7@\2\2\u0192\u0193\7?\2\2\u0193^\3\2\2\2\u0194\u0195"+ + "\7i\2\2\u0195\u0196\7g\2\2\u0196`\3\2\2\2\u0197\u0198\7i\2\2\u0198\u0199"+ + "\7v\2\2\u0199\u019a\7g\2\2\u019ab\3\2\2\2\u019b\u019c\7>\2\2\u019cd\3"+ + "\2\2\2\u019d\u019e\7n\2\2\u019e\u019f\7v\2\2\u019ff\3\2\2\2\u01a0\u01a1"+ + "\7>\2\2\u01a1\u01a2\7?\2\2\u01a2h\3\2\2\2\u01a3\u01a4\7n\2\2\u01a4\u01a5"+ + "\7g\2\2\u01a5j\3\2\2\2\u01a6\u01a7\7n\2\2\u01a7\u01a8\7v\2\2\u01a8\u01a9"+ + "\7g\2\2\u01a9l\3\2\2\2\u01aa\u01ab\7>\2\2\u01ab\u01ac\7@\2\2\u01acn\3"+ + "\2\2\2\u01ad\u01ae\7#\2\2\u01ae\u01af\7?\2\2\u01afp\3\2\2\2\u01b0\u01b1"+ + "\7p\2\2\u01b1\u01b2\7g\2\2\u01b2r\3\2\2\2\u01b3\u01b4\7k\2\2\u01b4\u01b5"+ + "\7g\2\2\u01b5\u01b6\7s\2\2\u01b6t\3\2\2\2\u01b7\u01b8\7<\2\2\u01b8\u01bc"+ + "\t\2\2\2\u01b9\u01bb\t\3\2\2\u01ba\u01b9\3\2\2\2\u01bb\u01be\3\2\2\2\u01bc"+ + "\u01ba\3\2\2\2\u01bc\u01bd\3\2\2\2\u01bdv\3\2\2\2\u01be\u01bc\3\2\2\2"+ + "\u01bf\u01c3\t\2\2\2\u01c0\u01c2\t\4\2\2\u01c1\u01c0\3\2\2\2\u01c2\u01c5"+ + "\3\2\2\2\u01c3\u01c1\3\2\2\2\u01c3\u01c4\3\2\2\2\u01c4x\3\2\2\2\u01c5"+ + "\u01c3\3\2\2\2\u01c6\u01c7\7v\2\2\u01c7\u01c8\7t\2\2\u01c8\u01c9\7w\2"+ + "\2\u01c9\u01d0\7g\2\2\u01ca\u01cb\7h\2\2\u01cb\u01cc\7c\2\2\u01cc\u01cd"+ + "\7n\2\2\u01cd\u01ce\7u\2\2\u01ce\u01d0\7g\2\2\u01cf\u01c6\3\2\2\2\u01cf"+ + "\u01ca\3\2\2\2\u01d0z\3\2\2\2\u01d1\u01d3\7/\2\2\u01d2\u01d1\3\2\2\2\u01d2"+ + "\u01d3\3\2\2\2\u01d3\u01d4\3\2\2\2\u01d4\u01db\5}?\2\u01d5\u01d7\7/\2"+ + "\2\u01d6\u01d5\3\2\2\2\u01d6\u01d7\3\2\2\2\u01d7\u01d8\3\2\2\2\u01d8\u01db"+ + "\5\177@\2\u01d9\u01db\5\u0081A\2\u01da\u01d2\3\2\2\2\u01da\u01d6\3\2\2"+ + "\2\u01da\u01d9\3\2\2\2\u01db|\3\2\2\2\u01dc\u01de\t\5\2\2\u01dd\u01dc"+ + "\3\2\2\2\u01de\u01df\3\2\2\2\u01df\u01dd\3\2\2\2\u01df\u01e0\3\2\2\2\u01e0"+ + "\u01e1\3\2\2\2\u01e1\u01e5\7\60\2\2\u01e2\u01e4\t\5\2\2\u01e3\u01e2\3"+ + "\2\2\2\u01e4\u01e7\3\2\2\2\u01e5\u01e3\3\2\2\2\u01e5\u01e6\3\2\2\2\u01e6"+ + "~\3\2\2\2\u01e7\u01e5\3\2\2\2\u01e8\u01ec\t\6\2\2\u01e9\u01eb\t\5\2\2"+ + "\u01ea\u01e9\3\2\2\2\u01eb\u01ee\3\2\2\2\u01ec\u01ea\3\2\2\2\u01ec\u01ed"+ + "\3\2\2\2\u01ed\u0080\3\2\2\2\u01ee\u01ec\3\2\2\2\u01ef\u01f0\7\62\2\2"+ + "\u01f0\u0082\3\2\2\2\u01f1\u01f7\7)\2\2\u01f2\u01f6\n\7\2\2\u01f3\u01f4"+ + "\7)\2\2\u01f4\u01f6\7)\2\2\u01f5\u01f2\3\2\2\2\u01f5\u01f3\3\2\2\2\u01f6"+ + "\u01f9\3\2\2\2\u01f7\u01f5\3\2\2\2\u01f7\u01f8\3\2\2\2\u01f8\u01fa\3\2"+ + "\2\2\u01f9\u01f7\3\2\2\2\u01fa\u01fb\7)\2\2\u01fb\u0084\3\2\2\2\u01fc"+ + "\u01fd\t\b\2\2\u01fd\u01fe\3\2\2\2\u01fe\u01ff\bC\2\2\u01ff\u0086\3\2"+ + "\2\2\16\2\u01bc\u01c3\u01cf\u01d2\u01d6\u01da\u01df\u01e5\u01ec\u01f5"+ + "\u01f7\3\b\2\2"; public static final ATN _ATN = new ATNDeserializer().deserialize(_serializedATN.toCharArray()); static { diff --git a/src/main/java/com/avaje/ebeaninternal/server/grammer/antlr/EQLLexer.tokens b/src/main/java/com/avaje/ebeaninternal/server/grammer/antlr/EQLLexer.tokens index 6a00e9224..c6d1f969f 100644 --- a/src/main/java/com/avaje/ebeaninternal/server/grammer/antlr/EQLLexer.tokens +++ b/src/main/java/com/avaje/ebeaninternal/server/grammer/antlr/EQLLexer.tokens @@ -48,63 +48,77 @@ T__46=47 T__47=48 T__48=49 T__49=50 -INPUT_VARIABLE=51 -PATH_VARIABLE=52 -BOOLEAN_LITERAL=53 -NUMBER_LITERAL=54 -DOUBLE=55 -INT=56 -ZERO=57 -STRING_LITERAL=58 -WS=59 +T__50=51 +T__51=52 +T__52=53 +T__53=54 +T__54=55 +T__55=56 +T__56=57 +INPUT_VARIABLE=58 +PATH_VARIABLE=59 +BOOLEAN_LITERAL=60 +NUMBER_LITERAL=61 +DOUBLE=62 +INT=63 +ZERO=64 +STRING_LITERAL=65 +WS=66 'select'=1 '('=2 ')'=3 'distinct'=4 'where'=5 -'limit'=6 -'offset'=7 -'fetch'=8 -','=9 -'+'=10 -'query'=11 -'lazy'=12 -'or'=13 -'and'=14 -'not'=15 -'in'=16 -'between'=17 -'is'=18 -'null'=19 -'isNull'=20 -'isNotNull'=21 -'notNull'=22 -'empty'=23 -'isEmpty'=24 -'isNotEmpty'=25 -'notEmpty'=26 -'like'=27 -'ilike'=28 -'contains'=29 -'icontains'=30 -'startsWith'=31 -'istartsWith'=32 -'endsWith'=33 -'iendsWith'=34 -'='=35 -'eq'=36 -'>'=37 -'gt'=38 -'>='=39 -'ge'=40 -'gte'=41 -'<'=42 -'lt'=43 -'<='=44 -'le'=45 -'lte'=46 -'<>'=47 -'!='=48 -'ne'=49 -'ieq'=50 -'0'=57 +'order'=6 +'by'=7 +','=8 +'nulls'=9 +'first'=10 +'last'=11 +'asc'=12 +'desc'=13 +'limit'=14 +'offset'=15 +'fetch'=16 +'+'=17 +'query'=18 +'lazy'=19 +'or'=20 +'and'=21 +'not'=22 +'in'=23 +'between'=24 +'is'=25 +'null'=26 +'isNull'=27 +'isNotNull'=28 +'notNull'=29 +'empty'=30 +'isEmpty'=31 +'isNotEmpty'=32 +'notEmpty'=33 +'like'=34 +'ilike'=35 +'contains'=36 +'icontains'=37 +'startsWith'=38 +'istartsWith'=39 +'endsWith'=40 +'iendsWith'=41 +'='=42 +'eq'=43 +'>'=44 +'gt'=45 +'>='=46 +'ge'=47 +'gte'=48 +'<'=49 +'lt'=50 +'<='=51 +'le'=52 +'lte'=53 +'<>'=54 +'!='=55 +'ne'=56 +'ieq'=57 +'0'=64 diff --git a/src/main/java/com/avaje/ebeaninternal/server/grammer/antlr/EQLListener.java b/src/main/java/com/avaje/ebeaninternal/server/grammer/antlr/EQLListener.java index 5c91254dd..758e36fed 100644 --- a/src/main/java/com/avaje/ebeaninternal/server/grammer/antlr/EQLListener.java +++ b/src/main/java/com/avaje/ebeaninternal/server/grammer/antlr/EQLListener.java @@ -57,6 +57,46 @@ public interface EQLListener extends ParseTreeListener { * @param ctx the parse tree */ void exitWhere_clause(EQLParser.Where_clauseContext ctx); + /** + * Enter a parse tree produced by {@link EQLParser#orderby_clause}. + * @param ctx the parse tree + */ + void enterOrderby_clause(EQLParser.Orderby_clauseContext ctx); + /** + * Exit a parse tree produced by {@link EQLParser#orderby_clause}. + * @param ctx the parse tree + */ + void exitOrderby_clause(EQLParser.Orderby_clauseContext ctx); + /** + * Enter a parse tree produced by {@link EQLParser#orderby_property}. + * @param ctx the parse tree + */ + void enterOrderby_property(EQLParser.Orderby_propertyContext ctx); + /** + * Exit a parse tree produced by {@link EQLParser#orderby_property}. + * @param ctx the parse tree + */ + void exitOrderby_property(EQLParser.Orderby_propertyContext ctx); + /** + * Enter a parse tree produced by {@link EQLParser#nulls_firstlast}. + * @param ctx the parse tree + */ + void enterNulls_firstlast(EQLParser.Nulls_firstlastContext ctx); + /** + * Exit a parse tree produced by {@link EQLParser#nulls_firstlast}. + * @param ctx the parse tree + */ + void exitNulls_firstlast(EQLParser.Nulls_firstlastContext ctx); + /** + * Enter a parse tree produced by {@link EQLParser#asc_desc}. + * @param ctx the parse tree + */ + void enterAsc_desc(EQLParser.Asc_descContext ctx); + /** + * Exit a parse tree produced by {@link EQLParser#asc_desc}. + * @param ctx the parse tree + */ + void exitAsc_desc(EQLParser.Asc_descContext ctx); /** * Enter a parse tree produced by {@link EQLParser#limit_clause}. * @param ctx the parse tree diff --git a/src/main/java/com/avaje/ebeaninternal/server/grammer/antlr/EQLParser.java b/src/main/java/com/avaje/ebeaninternal/server/grammer/antlr/EQLParser.java index b5ab0787c..f4ede0ebc 100644 --- a/src/main/java/com/avaje/ebeaninternal/server/grammer/antlr/EQLParser.java +++ b/src/main/java/com/avaje/ebeaninternal/server/grammer/antlr/EQLParser.java @@ -23,25 +23,29 @@ public class EQLParser extends Parser { T__24=25, T__25=26, T__26=27, T__27=28, T__28=29, T__29=30, T__30=31, T__31=32, T__32=33, T__33=34, T__34=35, T__35=36, T__36=37, T__37=38, T__38=39, T__39=40, T__40=41, T__41=42, T__42=43, T__43=44, T__44=45, - T__45=46, T__46=47, T__47=48, T__48=49, T__49=50, INPUT_VARIABLE=51, PATH_VARIABLE=52, - BOOLEAN_LITERAL=53, NUMBER_LITERAL=54, DOUBLE=55, INT=56, ZERO=57, STRING_LITERAL=58, - WS=59; + T__45=46, T__46=47, T__47=48, T__48=49, T__49=50, T__50=51, T__51=52, + T__52=53, T__53=54, T__54=55, T__55=56, T__56=57, INPUT_VARIABLE=58, PATH_VARIABLE=59, + BOOLEAN_LITERAL=60, NUMBER_LITERAL=61, DOUBLE=62, INT=63, ZERO=64, STRING_LITERAL=65, + WS=66; public static final int RULE_select_statement = 0, RULE_select_clause = 1, RULE_distinct = 2, - RULE_fetch_clause = 3, RULE_where_clause = 4, RULE_limit_clause = 5, RULE_offset_clause = 6, - RULE_fetch_path = 7, RULE_fetch_property_set = 8, RULE_fetch_property_group = 9, - RULE_fetch_property = 10, RULE_fetch_query_hint = 11, RULE_fetch_lazy_hint = 12, - RULE_fetch_option = 13, RULE_fetch_query_option = 14, RULE_fetch_lazy_option = 15, - RULE_fetch_batch_size = 16, RULE_conditional_expression = 17, RULE_conditional_term = 18, - RULE_conditional_factor = 19, RULE_conditional_primary = 20, RULE_any_expression = 21, - RULE_in_expression = 22, RULE_in_value = 23, RULE_between_expression = 24, - RULE_propertyBetween_expression = 25, RULE_isNull_expression = 26, RULE_isNotNull_expression = 27, - RULE_isEmpty_expression = 28, RULE_isNotEmpty_expression = 29, RULE_like_expression = 30, - RULE_like_op = 31, RULE_comparison_expression = 32, RULE_comparison_operator = 33, - RULE_value_expression = 34, RULE_literal = 35; + RULE_fetch_clause = 3, RULE_where_clause = 4, RULE_orderby_clause = 5, + RULE_orderby_property = 6, RULE_nulls_firstlast = 7, RULE_asc_desc = 8, + RULE_limit_clause = 9, RULE_offset_clause = 10, RULE_fetch_path = 11, + RULE_fetch_property_set = 12, RULE_fetch_property_group = 13, RULE_fetch_property = 14, + RULE_fetch_query_hint = 15, RULE_fetch_lazy_hint = 16, RULE_fetch_option = 17, + RULE_fetch_query_option = 18, RULE_fetch_lazy_option = 19, RULE_fetch_batch_size = 20, + RULE_conditional_expression = 21, RULE_conditional_term = 22, RULE_conditional_factor = 23, + RULE_conditional_primary = 24, RULE_any_expression = 25, RULE_in_expression = 26, + RULE_in_value = 27, RULE_between_expression = 28, RULE_propertyBetween_expression = 29, + RULE_isNull_expression = 30, RULE_isNotNull_expression = 31, RULE_isEmpty_expression = 32, + RULE_isNotEmpty_expression = 33, RULE_like_expression = 34, RULE_like_op = 35, + RULE_comparison_expression = 36, RULE_comparison_operator = 37, RULE_value_expression = 38, + RULE_literal = 39; public static final String[] ruleNames = { "select_statement", "select_clause", "distinct", "fetch_clause", "where_clause", - "limit_clause", "offset_clause", "fetch_path", "fetch_property_set", "fetch_property_group", + "orderby_clause", "orderby_property", "nulls_firstlast", "asc_desc", "limit_clause", + "offset_clause", "fetch_path", "fetch_property_set", "fetch_property_group", "fetch_property", "fetch_query_hint", "fetch_lazy_hint", "fetch_option", "fetch_query_option", "fetch_lazy_option", "fetch_batch_size", "conditional_expression", "conditional_term", "conditional_factor", "conditional_primary", "any_expression", @@ -52,9 +56,10 @@ public class EQLParser extends Parser { }; private static final String[] _LITERAL_NAMES = { - null, "'select'", "'('", "')'", "'distinct'", "'where'", "'limit'", "'offset'", - "'fetch'", "','", "'+'", "'query'", "'lazy'", "'or'", "'and'", "'not'", - "'in'", "'between'", "'is'", "'null'", "'isNull'", "'isNotNull'", "'notNull'", + null, "'select'", "'('", "')'", "'distinct'", "'where'", "'order'", "'by'", + "','", "'nulls'", "'first'", "'last'", "'asc'", "'desc'", "'limit'", "'offset'", + "'fetch'", "'+'", "'query'", "'lazy'", "'or'", "'and'", "'not'", "'in'", + "'between'", "'is'", "'null'", "'isNull'", "'isNotNull'", "'notNull'", "'empty'", "'isEmpty'", "'isNotEmpty'", "'notEmpty'", "'like'", "'ilike'", "'contains'", "'icontains'", "'startsWith'", "'istartsWith'", "'endsWith'", "'iendsWith'", "'='", "'eq'", "'>'", "'gt'", "'>='", "'ge'", "'gte'", @@ -66,8 +71,9 @@ public class EQLParser extends Parser { null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, - null, null, null, "INPUT_VARIABLE", "PATH_VARIABLE", "BOOLEAN_LITERAL", - "NUMBER_LITERAL", "DOUBLE", "INT", "ZERO", "STRING_LITERAL", "WS" + null, null, null, null, null, null, null, null, null, null, "INPUT_VARIABLE", + "PATH_VARIABLE", "BOOLEAN_LITERAL", "NUMBER_LITERAL", "DOUBLE", "INT", + "ZERO", "STRING_LITERAL", "WS" }; public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES); @@ -131,6 +137,9 @@ public class EQLParser extends Parser { public Where_clauseContext where_clause() { return getRuleContext(Where_clauseContext.class,0); } + public Orderby_clauseContext orderby_clause() { + return getRuleContext(Orderby_clauseContext.class,0); + } public Limit_clauseContext limit_clause() { return getRuleContext(Limit_clauseContext.class,0); } @@ -155,43 +164,52 @@ public class EQLParser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(73); + setState(81); _la = _input.LA(1); if (_la==T__0) { { - setState(72); + setState(80); select_clause(); } } - setState(78); + setState(86); _errHandler.sync(this); _la = _input.LA(1); - while (_la==T__7) { + while (_la==T__15) { { { - setState(75); + setState(83); fetch_clause(); } } - setState(80); + setState(88); _errHandler.sync(this); _la = _input.LA(1); } - setState(82); + setState(90); _la = _input.LA(1); if (_la==T__4) { { - setState(81); + setState(89); where_clause(); } } - setState(85); + setState(93); _la = _input.LA(1); if (_la==T__5) { { - setState(84); + setState(92); + orderby_clause(); + } + } + + setState(96); + _la = _input.LA(1); + if (_la==T__13) { + { + setState(95); limit_clause(); } } @@ -237,22 +255,22 @@ public class EQLParser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(87); + setState(98); match(T__0); - setState(89); + setState(100); _la = _input.LA(1); if (_la==T__3) { { - setState(88); + setState(99); distinct(); } } - setState(91); + setState(102); match(T__1); - setState(92); + setState(103); fetch_property_group(); - setState(93); + setState(104); match(T__2); } } @@ -288,7 +306,7 @@ public class EQLParser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(95); + setState(106); match(T__3); } } @@ -327,7 +345,7 @@ public class EQLParser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(97); + setState(108); fetch_path(); } } @@ -366,9 +384,9 @@ public class EQLParser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(99); + setState(110); match(T__4); - setState(100); + setState(111); conditional_expression(); } } @@ -383,6 +401,226 @@ public class EQLParser extends Parser { return _localctx; } + public static class Orderby_clauseContext extends ParserRuleContext { + public List orderby_property() { + return getRuleContexts(Orderby_propertyContext.class); + } + public Orderby_propertyContext orderby_property(int i) { + return getRuleContext(Orderby_propertyContext.class,i); + } + public Orderby_clauseContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_orderby_clause; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof EQLListener ) ((EQLListener)listener).enterOrderby_clause(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof EQLListener ) ((EQLListener)listener).exitOrderby_clause(this); + } + } + + public final Orderby_clauseContext orderby_clause() throws RecognitionException { + Orderby_clauseContext _localctx = new Orderby_clauseContext(_ctx, getState()); + enterRule(_localctx, 10, RULE_orderby_clause); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(113); + match(T__5); + setState(114); + match(T__6); + setState(115); + orderby_property(); + setState(120); + _errHandler.sync(this); + _la = _input.LA(1); + while (_la==T__7) { + { + { + setState(116); + match(T__7); + setState(117); + orderby_property(); + } + } + setState(122); + _errHandler.sync(this); + _la = _input.LA(1); + } + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class Orderby_propertyContext extends ParserRuleContext { + public TerminalNode PATH_VARIABLE() { return getToken(EQLParser.PATH_VARIABLE, 0); } + public Asc_descContext asc_desc() { + return getRuleContext(Asc_descContext.class,0); + } + public Nulls_firstlastContext nulls_firstlast() { + return getRuleContext(Nulls_firstlastContext.class,0); + } + public Orderby_propertyContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_orderby_property; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof EQLListener ) ((EQLListener)listener).enterOrderby_property(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof EQLListener ) ((EQLListener)listener).exitOrderby_property(this); + } + } + + public final Orderby_propertyContext orderby_property() throws RecognitionException { + Orderby_propertyContext _localctx = new Orderby_propertyContext(_ctx, getState()); + enterRule(_localctx, 12, RULE_orderby_property); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(123); + match(PATH_VARIABLE); + setState(125); + _la = _input.LA(1); + if (_la==T__11 || _la==T__12) { + { + setState(124); + asc_desc(); + } + } + + setState(128); + _la = _input.LA(1); + if (_la==T__8) { + { + setState(127); + nulls_firstlast(); + } + } + + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class Nulls_firstlastContext extends ParserRuleContext { + public Nulls_firstlastContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_nulls_firstlast; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof EQLListener ) ((EQLListener)listener).enterNulls_firstlast(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof EQLListener ) ((EQLListener)listener).exitNulls_firstlast(this); + } + } + + public final Nulls_firstlastContext nulls_firstlast() throws RecognitionException { + Nulls_firstlastContext _localctx = new Nulls_firstlastContext(_ctx, getState()); + enterRule(_localctx, 14, RULE_nulls_firstlast); + try { + setState(134); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,9,_ctx) ) { + case 1: + enterOuterAlt(_localctx, 1); + { + setState(130); + match(T__8); + setState(131); + match(T__9); + } + break; + case 2: + enterOuterAlt(_localctx, 2); + { + setState(132); + match(T__8); + setState(133); + match(T__10); + } + break; + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class Asc_descContext extends ParserRuleContext { + public Asc_descContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_asc_desc; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof EQLListener ) ((EQLListener)listener).enterAsc_desc(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof EQLListener ) ((EQLListener)listener).exitAsc_desc(this); + } + } + + public final Asc_descContext asc_desc() throws RecognitionException { + Asc_descContext _localctx = new Asc_descContext(_ctx, getState()); + enterRule(_localctx, 16, RULE_asc_desc); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(136); + _la = _input.LA(1); + if ( !(_la==T__11 || _la==T__12) ) { + _errHandler.recoverInline(this); + } else { + consume(); + } + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + public static class Limit_clauseContext extends ParserRuleContext { public TerminalNode NUMBER_LITERAL() { return getToken(EQLParser.NUMBER_LITERAL, 0); } public Offset_clauseContext offset_clause() { @@ -404,20 +642,20 @@ public class EQLParser extends Parser { public final Limit_clauseContext limit_clause() throws RecognitionException { Limit_clauseContext _localctx = new Limit_clauseContext(_ctx, getState()); - enterRule(_localctx, 10, RULE_limit_clause); + enterRule(_localctx, 18, RULE_limit_clause); int _la; try { enterOuterAlt(_localctx, 1); { - setState(102); - match(T__5); - setState(103); + setState(138); + match(T__13); + setState(139); match(NUMBER_LITERAL); - setState(105); + setState(141); _la = _input.LA(1); - if (_la==T__6) { + if (_la==T__14) { { - setState(104); + setState(140); offset_clause(); } } @@ -453,13 +691,13 @@ public class EQLParser extends Parser { public final Offset_clauseContext offset_clause() throws RecognitionException { Offset_clauseContext _localctx = new Offset_clauseContext(_ctx, getState()); - enterRule(_localctx, 12, RULE_offset_clause); + enterRule(_localctx, 20, RULE_offset_clause); try { enterOuterAlt(_localctx, 1); { - setState(107); - match(T__6); - setState(108); + setState(143); + match(T__14); + setState(144); match(NUMBER_LITERAL); } } @@ -498,29 +736,29 @@ public class EQLParser extends Parser { public final Fetch_pathContext fetch_path() throws RecognitionException { Fetch_pathContext _localctx = new Fetch_pathContext(_ctx, getState()); - enterRule(_localctx, 14, RULE_fetch_path); + enterRule(_localctx, 22, RULE_fetch_path); int _la; try { enterOuterAlt(_localctx, 1); { - setState(110); - match(T__7); - setState(112); + setState(146); + match(T__15); + setState(148); _la = _input.LA(1); - if (_la==T__10 || _la==T__11) { + if (_la==T__17 || _la==T__18) { { - setState(111); + setState(147); fetch_option(); } } - setState(114); + setState(150); match(PATH_VARIABLE); - setState(116); + setState(152); _la = _input.LA(1); if (_la==T__1) { { - setState(115); + setState(151); fetch_property_set(); } } @@ -558,15 +796,15 @@ public class EQLParser extends Parser { public final Fetch_property_setContext fetch_property_set() throws RecognitionException { Fetch_property_setContext _localctx = new Fetch_property_setContext(_ctx, getState()); - enterRule(_localctx, 16, RULE_fetch_property_set); + enterRule(_localctx, 24, RULE_fetch_property_set); try { enterOuterAlt(_localctx, 1); { - setState(118); + setState(154); match(T__1); - setState(119); + setState(155); fetch_property_group(); - setState(120); + setState(156); match(T__2); } } @@ -604,26 +842,26 @@ public class EQLParser extends Parser { public final Fetch_property_groupContext fetch_property_group() throws RecognitionException { Fetch_property_groupContext _localctx = new Fetch_property_groupContext(_ctx, getState()); - enterRule(_localctx, 18, RULE_fetch_property_group); + enterRule(_localctx, 26, RULE_fetch_property_group); int _la; try { enterOuterAlt(_localctx, 1); { - setState(122); + setState(158); fetch_property(); - setState(127); + setState(163); _errHandler.sync(this); _la = _input.LA(1); - while (_la==T__8) { + while (_la==T__7) { { { - setState(123); - match(T__8); - setState(124); + setState(159); + match(T__7); + setState(160); fetch_property(); } } - setState(129); + setState(165); _errHandler.sync(this); _la = _input.LA(1); } @@ -664,29 +902,29 @@ public class EQLParser extends Parser { public final Fetch_propertyContext fetch_property() throws RecognitionException { Fetch_propertyContext _localctx = new Fetch_propertyContext(_ctx, getState()); - enterRule(_localctx, 20, RULE_fetch_property); + enterRule(_localctx, 28, RULE_fetch_property); try { - setState(133); + setState(169); _errHandler.sync(this); - switch ( getInterpreter().adaptivePredict(_input,9,_ctx) ) { + switch ( getInterpreter().adaptivePredict(_input,14,_ctx) ) { case 1: enterOuterAlt(_localctx, 1); { - setState(130); + setState(166); match(PATH_VARIABLE); } break; case 2: enterOuterAlt(_localctx, 2); { - setState(131); + setState(167); fetch_query_hint(); } break; case 3: enterOuterAlt(_localctx, 3); { - setState(132); + setState(168); fetch_lazy_hint(); } break; @@ -723,13 +961,13 @@ public class EQLParser extends Parser { public final Fetch_query_hintContext fetch_query_hint() throws RecognitionException { Fetch_query_hintContext _localctx = new Fetch_query_hintContext(_ctx, getState()); - enterRule(_localctx, 22, RULE_fetch_query_hint); + enterRule(_localctx, 30, RULE_fetch_query_hint); try { enterOuterAlt(_localctx, 1); { - setState(135); - match(T__9); - setState(136); + setState(171); + match(T__16); + setState(172); fetch_query_option(); } } @@ -764,13 +1002,13 @@ public class EQLParser extends Parser { public final Fetch_lazy_hintContext fetch_lazy_hint() throws RecognitionException { Fetch_lazy_hintContext _localctx = new Fetch_lazy_hintContext(_ctx, getState()); - enterRule(_localctx, 24, RULE_fetch_lazy_hint); + enterRule(_localctx, 32, RULE_fetch_lazy_hint); try { enterOuterAlt(_localctx, 1); { - setState(138); - match(T__9); - setState(139); + setState(174); + match(T__16); + setState(175); fetch_lazy_option(); } } @@ -808,21 +1046,21 @@ public class EQLParser extends Parser { public final Fetch_optionContext fetch_option() throws RecognitionException { Fetch_optionContext _localctx = new Fetch_optionContext(_ctx, getState()); - enterRule(_localctx, 26, RULE_fetch_option); + enterRule(_localctx, 34, RULE_fetch_option); try { - setState(143); + setState(179); switch (_input.LA(1)) { - case T__10: + case T__17: enterOuterAlt(_localctx, 1); { - setState(141); + setState(177); fetch_query_option(); } break; - case T__11: + case T__18: enterOuterAlt(_localctx, 2); { - setState(142); + setState(178); fetch_lazy_option(); } break; @@ -861,18 +1099,18 @@ public class EQLParser extends Parser { public final Fetch_query_optionContext fetch_query_option() throws RecognitionException { Fetch_query_optionContext _localctx = new Fetch_query_optionContext(_ctx, getState()); - enterRule(_localctx, 28, RULE_fetch_query_option); + enterRule(_localctx, 36, RULE_fetch_query_option); int _la; try { enterOuterAlt(_localctx, 1); { - setState(145); - match(T__10); - setState(147); + setState(181); + match(T__17); + setState(183); _la = _input.LA(1); if (_la==T__1) { { - setState(146); + setState(182); fetch_batch_size(); } } @@ -910,18 +1148,18 @@ public class EQLParser extends Parser { public final Fetch_lazy_optionContext fetch_lazy_option() throws RecognitionException { Fetch_lazy_optionContext _localctx = new Fetch_lazy_optionContext(_ctx, getState()); - enterRule(_localctx, 30, RULE_fetch_lazy_option); + enterRule(_localctx, 38, RULE_fetch_lazy_option); int _la; try { enterOuterAlt(_localctx, 1); { - setState(149); - match(T__11); - setState(151); + setState(185); + match(T__18); + setState(187); _la = _input.LA(1); if (_la==T__1) { { - setState(150); + setState(186); fetch_batch_size(); } } @@ -957,15 +1195,15 @@ public class EQLParser extends Parser { public final Fetch_batch_sizeContext fetch_batch_size() throws RecognitionException { Fetch_batch_sizeContext _localctx = new Fetch_batch_sizeContext(_ctx, getState()); - enterRule(_localctx, 32, RULE_fetch_batch_size); + enterRule(_localctx, 40, RULE_fetch_batch_size); try { enterOuterAlt(_localctx, 1); { - setState(153); + setState(189); match(T__1); - setState(154); + setState(190); match(NUMBER_LITERAL); - setState(155); + setState(191); match(T__2); } } @@ -1003,26 +1241,26 @@ public class EQLParser extends Parser { public final Conditional_expressionContext conditional_expression() throws RecognitionException { Conditional_expressionContext _localctx = new Conditional_expressionContext(_ctx, getState()); - enterRule(_localctx, 34, RULE_conditional_expression); + enterRule(_localctx, 42, RULE_conditional_expression); int _la; try { enterOuterAlt(_localctx, 1); { - setState(157); + setState(193); conditional_term(); - setState(162); + setState(198); _errHandler.sync(this); _la = _input.LA(1); - while (_la==T__12) { + while (_la==T__19) { { { - setState(158); - match(T__12); - setState(159); + setState(194); + match(T__19); + setState(195); conditional_term(); } } - setState(164); + setState(200); _errHandler.sync(this); _la = _input.LA(1); } @@ -1062,26 +1300,26 @@ public class EQLParser extends Parser { public final Conditional_termContext conditional_term() throws RecognitionException { Conditional_termContext _localctx = new Conditional_termContext(_ctx, getState()); - enterRule(_localctx, 36, RULE_conditional_term); + enterRule(_localctx, 44, RULE_conditional_term); int _la; try { enterOuterAlt(_localctx, 1); { - setState(165); + setState(201); conditional_factor(); - setState(170); + setState(206); _errHandler.sync(this); _la = _input.LA(1); - while (_la==T__13) { + while (_la==T__20) { { { - setState(166); - match(T__13); - setState(167); + setState(202); + match(T__20); + setState(203); conditional_factor(); } } - setState(172); + setState(208); _errHandler.sync(this); _la = _input.LA(1); } @@ -1118,21 +1356,21 @@ public class EQLParser extends Parser { public final Conditional_factorContext conditional_factor() throws RecognitionException { Conditional_factorContext _localctx = new Conditional_factorContext(_ctx, getState()); - enterRule(_localctx, 38, RULE_conditional_factor); + enterRule(_localctx, 46, RULE_conditional_factor); int _la; try { enterOuterAlt(_localctx, 1); { - setState(174); + setState(210); _la = _input.LA(1); - if (_la==T__14) { + if (_la==T__21) { { - setState(173); - match(T__14); + setState(209); + match(T__21); } } - setState(176); + setState(212); conditional_primary(); } } @@ -1170,26 +1408,26 @@ public class EQLParser extends Parser { public final Conditional_primaryContext conditional_primary() throws RecognitionException { Conditional_primaryContext _localctx = new Conditional_primaryContext(_ctx, getState()); - enterRule(_localctx, 40, RULE_conditional_primary); + enterRule(_localctx, 48, RULE_conditional_primary); try { - setState(183); + setState(219); _errHandler.sync(this); - switch ( getInterpreter().adaptivePredict(_input,16,_ctx) ) { + switch ( getInterpreter().adaptivePredict(_input,21,_ctx) ) { case 1: enterOuterAlt(_localctx, 1); { - setState(178); + setState(214); any_expression(); } break; case 2: enterOuterAlt(_localctx, 2); { - setState(179); + setState(215); match(T__1); - setState(180); + setState(216); conditional_expression(); - setState(181); + setState(217); match(T__2); } break; @@ -1253,82 +1491,82 @@ public class EQLParser extends Parser { public final Any_expressionContext any_expression() throws RecognitionException { Any_expressionContext _localctx = new Any_expressionContext(_ctx, getState()); - enterRule(_localctx, 42, RULE_any_expression); + enterRule(_localctx, 50, RULE_any_expression); try { - setState(198); + setState(234); _errHandler.sync(this); - switch ( getInterpreter().adaptivePredict(_input,17,_ctx) ) { + switch ( getInterpreter().adaptivePredict(_input,22,_ctx) ) { case 1: enterOuterAlt(_localctx, 1); { - setState(185); + setState(221); comparison_expression(); } break; case 2: enterOuterAlt(_localctx, 2); { - setState(186); + setState(222); like_expression(); } break; case 3: enterOuterAlt(_localctx, 3); { - setState(187); + setState(223); between_expression(); } break; case 4: enterOuterAlt(_localctx, 4); { - setState(188); + setState(224); propertyBetween_expression(); } break; case 5: enterOuterAlt(_localctx, 5); { - setState(189); + setState(225); in_expression(); } break; case 6: enterOuterAlt(_localctx, 6); { - setState(190); + setState(226); isNull_expression(); } break; case 7: enterOuterAlt(_localctx, 7); { - setState(191); + setState(227); isNotNull_expression(); } break; case 8: enterOuterAlt(_localctx, 8); { - setState(192); + setState(228); isEmpty_expression(); } break; case 9: enterOuterAlt(_localctx, 9); { - setState(193); + setState(229); isNotEmpty_expression(); } break; case 10: enterOuterAlt(_localctx, 10); { - setState(194); + setState(230); match(T__1); - setState(195); + setState(231); any_expression(); - setState(196); + setState(232); match(T__2); } break; @@ -1366,15 +1604,15 @@ public class EQLParser extends Parser { public final In_expressionContext in_expression() throws RecognitionException { In_expressionContext _localctx = new In_expressionContext(_ctx, getState()); - enterRule(_localctx, 44, RULE_in_expression); + enterRule(_localctx, 52, RULE_in_expression); try { enterOuterAlt(_localctx, 1); { - setState(200); + setState(236); match(PATH_VARIABLE); - setState(201); - match(T__15); - setState(202); + setState(237); + match(T__22); + setState(238); in_value(); } } @@ -1413,42 +1651,42 @@ public class EQLParser extends Parser { public final In_valueContext in_value() throws RecognitionException { In_valueContext _localctx = new In_valueContext(_ctx, getState()); - enterRule(_localctx, 46, RULE_in_value); + enterRule(_localctx, 54, RULE_in_value); int _la; try { - setState(216); + setState(252); switch (_input.LA(1)) { case INPUT_VARIABLE: enterOuterAlt(_localctx, 1); { - setState(204); + setState(240); match(INPUT_VARIABLE); } break; case T__1: enterOuterAlt(_localctx, 2); { - setState(205); + setState(241); match(T__1); - setState(206); + setState(242); value_expression(); - setState(211); + setState(247); _errHandler.sync(this); _la = _input.LA(1); - while (_la==T__8) { + while (_la==T__7) { { { - setState(207); - match(T__8); - setState(208); + setState(243); + match(T__7); + setState(244); value_expression(); } } - setState(213); + setState(249); _errHandler.sync(this); _la = _input.LA(1); } - setState(214); + setState(250); match(T__2); } break; @@ -1491,19 +1729,19 @@ public class EQLParser extends Parser { public final Between_expressionContext between_expression() throws RecognitionException { Between_expressionContext _localctx = new Between_expressionContext(_ctx, getState()); - enterRule(_localctx, 48, RULE_between_expression); + enterRule(_localctx, 56, RULE_between_expression); try { enterOuterAlt(_localctx, 1); { - setState(218); + setState(254); match(PATH_VARIABLE); - setState(219); - match(T__16); - setState(220); + setState(255); + match(T__23); + setState(256); value_expression(); - setState(221); - match(T__13); - setState(222); + setState(257); + match(T__20); + setState(258); value_expression(); } } @@ -1542,19 +1780,19 @@ public class EQLParser extends Parser { public final PropertyBetween_expressionContext propertyBetween_expression() throws RecognitionException { PropertyBetween_expressionContext _localctx = new PropertyBetween_expressionContext(_ctx, getState()); - enterRule(_localctx, 50, RULE_propertyBetween_expression); + enterRule(_localctx, 58, RULE_propertyBetween_expression); try { enterOuterAlt(_localctx, 1); { - setState(224); + setState(260); value_expression(); - setState(225); - match(T__16); - setState(226); + setState(261); + match(T__23); + setState(262); match(PATH_VARIABLE); - setState(227); - match(T__13); - setState(228); + setState(263); + match(T__20); + setState(264); match(PATH_VARIABLE); } } @@ -1587,29 +1825,29 @@ public class EQLParser extends Parser { public final IsNull_expressionContext isNull_expression() throws RecognitionException { IsNull_expressionContext _localctx = new IsNull_expressionContext(_ctx, getState()); - enterRule(_localctx, 52, RULE_isNull_expression); + enterRule(_localctx, 60, RULE_isNull_expression); try { - setState(235); + setState(271); _errHandler.sync(this); - switch ( getInterpreter().adaptivePredict(_input,20,_ctx) ) { + switch ( getInterpreter().adaptivePredict(_input,25,_ctx) ) { case 1: enterOuterAlt(_localctx, 1); { - setState(230); + setState(266); match(PATH_VARIABLE); - setState(231); - match(T__17); - setState(232); - match(T__18); + setState(267); + match(T__24); + setState(268); + match(T__25); } break; case 2: enterOuterAlt(_localctx, 2); { - setState(233); + setState(269); match(PATH_VARIABLE); - setState(234); - match(T__19); + setState(270); + match(T__26); } break; } @@ -1643,40 +1881,40 @@ public class EQLParser extends Parser { public final IsNotNull_expressionContext isNotNull_expression() throws RecognitionException { IsNotNull_expressionContext _localctx = new IsNotNull_expressionContext(_ctx, getState()); - enterRule(_localctx, 54, RULE_isNotNull_expression); + enterRule(_localctx, 62, RULE_isNotNull_expression); try { - setState(245); + setState(281); _errHandler.sync(this); - switch ( getInterpreter().adaptivePredict(_input,21,_ctx) ) { + switch ( getInterpreter().adaptivePredict(_input,26,_ctx) ) { case 1: enterOuterAlt(_localctx, 1); { - setState(237); + setState(273); match(PATH_VARIABLE); - setState(238); - match(T__17); - setState(239); - match(T__14); - setState(240); - match(T__18); + setState(274); + match(T__24); + setState(275); + match(T__21); + setState(276); + match(T__25); } break; case 2: enterOuterAlt(_localctx, 2); { - setState(241); + setState(277); match(PATH_VARIABLE); - setState(242); - match(T__20); + setState(278); + match(T__27); } break; case 3: enterOuterAlt(_localctx, 3); { - setState(243); + setState(279); match(PATH_VARIABLE); - setState(244); - match(T__21); + setState(280); + match(T__28); } break; } @@ -1710,29 +1948,29 @@ public class EQLParser extends Parser { public final IsEmpty_expressionContext isEmpty_expression() throws RecognitionException { IsEmpty_expressionContext _localctx = new IsEmpty_expressionContext(_ctx, getState()); - enterRule(_localctx, 56, RULE_isEmpty_expression); + enterRule(_localctx, 64, RULE_isEmpty_expression); try { - setState(252); + setState(288); _errHandler.sync(this); - switch ( getInterpreter().adaptivePredict(_input,22,_ctx) ) { + switch ( getInterpreter().adaptivePredict(_input,27,_ctx) ) { case 1: enterOuterAlt(_localctx, 1); { - setState(247); + setState(283); match(PATH_VARIABLE); - setState(248); - match(T__17); - setState(249); - match(T__22); + setState(284); + match(T__24); + setState(285); + match(T__29); } break; case 2: enterOuterAlt(_localctx, 2); { - setState(250); + setState(286); match(PATH_VARIABLE); - setState(251); - match(T__23); + setState(287); + match(T__30); } break; } @@ -1766,40 +2004,40 @@ public class EQLParser extends Parser { public final IsNotEmpty_expressionContext isNotEmpty_expression() throws RecognitionException { IsNotEmpty_expressionContext _localctx = new IsNotEmpty_expressionContext(_ctx, getState()); - enterRule(_localctx, 58, RULE_isNotEmpty_expression); + enterRule(_localctx, 66, RULE_isNotEmpty_expression); try { - setState(262); + setState(298); _errHandler.sync(this); - switch ( getInterpreter().adaptivePredict(_input,23,_ctx) ) { + switch ( getInterpreter().adaptivePredict(_input,28,_ctx) ) { case 1: enterOuterAlt(_localctx, 1); { - setState(254); + setState(290); match(PATH_VARIABLE); - setState(255); - match(T__17); - setState(256); - match(T__14); - setState(257); - match(T__22); + setState(291); + match(T__24); + setState(292); + match(T__21); + setState(293); + match(T__29); } break; case 2: enterOuterAlt(_localctx, 2); { - setState(258); + setState(294); match(PATH_VARIABLE); - setState(259); - match(T__24); + setState(295); + match(T__31); } break; case 3: enterOuterAlt(_localctx, 3); { - setState(260); + setState(296); match(PATH_VARIABLE); - setState(261); - match(T__25); + setState(297); + match(T__32); } break; } @@ -1839,15 +2077,15 @@ public class EQLParser extends Parser { public final Like_expressionContext like_expression() throws RecognitionException { Like_expressionContext _localctx = new Like_expressionContext(_ctx, getState()); - enterRule(_localctx, 60, RULE_like_expression); + enterRule(_localctx, 68, RULE_like_expression); try { enterOuterAlt(_localctx, 1); { - setState(264); + setState(300); match(PATH_VARIABLE); - setState(265); + setState(301); like_op(); - setState(266); + setState(302); value_expression(); } } @@ -1879,14 +2117,14 @@ public class EQLParser extends Parser { public final Like_opContext like_op() throws RecognitionException { Like_opContext _localctx = new Like_opContext(_ctx, getState()); - enterRule(_localctx, 62, RULE_like_op); + enterRule(_localctx, 70, RULE_like_op); int _la; try { enterOuterAlt(_localctx, 1); { - setState(268); + setState(304); _la = _input.LA(1); - if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__26) | (1L << T__27) | (1L << T__28) | (1L << T__29) | (1L << T__30) | (1L << T__31) | (1L << T__32) | (1L << T__33))) != 0)) ) { + if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__33) | (1L << T__34) | (1L << T__35) | (1L << T__36) | (1L << T__37) | (1L << T__38) | (1L << T__39) | (1L << T__40))) != 0)) ) { _errHandler.recoverInline(this); } else { consume(); @@ -1928,15 +2166,15 @@ public class EQLParser extends Parser { public final Comparison_expressionContext comparison_expression() throws RecognitionException { Comparison_expressionContext _localctx = new Comparison_expressionContext(_ctx, getState()); - enterRule(_localctx, 64, RULE_comparison_expression); + enterRule(_localctx, 72, RULE_comparison_expression); try { enterOuterAlt(_localctx, 1); { - setState(270); + setState(306); match(PATH_VARIABLE); - setState(271); + setState(307); comparison_operator(); - setState(272); + setState(308); value_expression(); } } @@ -1968,14 +2206,14 @@ public class EQLParser extends Parser { public final Comparison_operatorContext comparison_operator() throws RecognitionException { Comparison_operatorContext _localctx = new Comparison_operatorContext(_ctx, getState()); - enterRule(_localctx, 66, RULE_comparison_operator); + enterRule(_localctx, 74, RULE_comparison_operator); int _la; try { enterOuterAlt(_localctx, 1); { - setState(274); + setState(310); _la = _input.LA(1); - if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__34) | (1L << T__35) | (1L << T__36) | (1L << T__37) | (1L << T__38) | (1L << T__39) | (1L << T__40) | (1L << T__41) | (1L << T__42) | (1L << T__43) | (1L << T__44) | (1L << T__45) | (1L << T__46) | (1L << T__47) | (1L << T__48) | (1L << T__49))) != 0)) ) { + if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__41) | (1L << T__42) | (1L << T__43) | (1L << T__44) | (1L << T__45) | (1L << T__46) | (1L << T__47) | (1L << T__48) | (1L << T__49) | (1L << T__50) | (1L << T__51) | (1L << T__52) | (1L << T__53) | (1L << T__54) | (1L << T__55) | (1L << T__56))) != 0)) ) { _errHandler.recoverInline(this); } else { consume(); @@ -2014,23 +2252,23 @@ public class EQLParser extends Parser { public final Value_expressionContext value_expression() throws RecognitionException { Value_expressionContext _localctx = new Value_expressionContext(_ctx, getState()); - enterRule(_localctx, 68, RULE_value_expression); + enterRule(_localctx, 76, RULE_value_expression); try { - setState(278); + setState(314); switch (_input.LA(1)) { case BOOLEAN_LITERAL: case NUMBER_LITERAL: case STRING_LITERAL: enterOuterAlt(_localctx, 1); { - setState(276); + setState(312); literal(); } break; case INPUT_VARIABLE: enterOuterAlt(_localctx, 2); { - setState(277); + setState(313); match(INPUT_VARIABLE); } break; @@ -2069,14 +2307,14 @@ public class EQLParser extends Parser { public final LiteralContext literal() throws RecognitionException { LiteralContext _localctx = new LiteralContext(_ctx, getState()); - enterRule(_localctx, 70, RULE_literal); + enterRule(_localctx, 78, RULE_literal); int _la; try { enterOuterAlt(_localctx, 1); { - setState(280); + setState(316); _la = _input.LA(1); - if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << BOOLEAN_LITERAL) | (1L << NUMBER_LITERAL) | (1L << STRING_LITERAL))) != 0)) ) { + if ( !(((((_la - 60)) & ~0x3f) == 0 && ((1L << (_la - 60)) & ((1L << (BOOLEAN_LITERAL - 60)) | (1L << (NUMBER_LITERAL - 60)) | (1L << (STRING_LITERAL - 60)))) != 0)) ) { _errHandler.recoverInline(this); } else { consume(); @@ -2095,99 +2333,112 @@ public class EQLParser extends Parser { } public static final String _serializedATN = - "\3\u0430\ud6d1\u8206\uad2d\u4417\uaef1\u8d80\uaadd\3=\u011d\4\2\t\2\4"+ + "\3\u0430\ud6d1\u8206\uad2d\u4417\uaef1\u8d80\uaadd\3D\u0141\4\2\t\2\4"+ "\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7\4\b\t\b\4\t\t\t\4\n\t\n\4\13\t"+ "\13\4\f\t\f\4\r\t\r\4\16\t\16\4\17\t\17\4\20\t\20\4\21\t\21\4\22\t\22"+ "\4\23\t\23\4\24\t\24\4\25\t\25\4\26\t\26\4\27\t\27\4\30\t\30\4\31\t\31"+ "\4\32\t\32\4\33\t\33\4\34\t\34\4\35\t\35\4\36\t\36\4\37\t\37\4 \t \4!"+ - "\t!\4\"\t\"\4#\t#\4$\t$\4%\t%\3\2\5\2L\n\2\3\2\7\2O\n\2\f\2\16\2R\13\2"+ - "\3\2\5\2U\n\2\3\2\5\2X\n\2\3\3\3\3\5\3\\\n\3\3\3\3\3\3\3\3\3\3\4\3\4\3"+ - "\5\3\5\3\6\3\6\3\6\3\7\3\7\3\7\5\7l\n\7\3\b\3\b\3\b\3\t\3\t\5\ts\n\t\3"+ - "\t\3\t\5\tw\n\t\3\n\3\n\3\n\3\n\3\13\3\13\3\13\7\13\u0080\n\13\f\13\16"+ - "\13\u0083\13\13\3\f\3\f\3\f\5\f\u0088\n\f\3\r\3\r\3\r\3\16\3\16\3\16\3"+ - "\17\3\17\5\17\u0092\n\17\3\20\3\20\5\20\u0096\n\20\3\21\3\21\5\21\u009a"+ - "\n\21\3\22\3\22\3\22\3\22\3\23\3\23\3\23\7\23\u00a3\n\23\f\23\16\23\u00a6"+ - "\13\23\3\24\3\24\3\24\7\24\u00ab\n\24\f\24\16\24\u00ae\13\24\3\25\5\25"+ - "\u00b1\n\25\3\25\3\25\3\26\3\26\3\26\3\26\3\26\5\26\u00ba\n\26\3\27\3"+ - "\27\3\27\3\27\3\27\3\27\3\27\3\27\3\27\3\27\3\27\3\27\3\27\5\27\u00c9"+ - "\n\27\3\30\3\30\3\30\3\30\3\31\3\31\3\31\3\31\3\31\7\31\u00d4\n\31\f\31"+ - "\16\31\u00d7\13\31\3\31\3\31\5\31\u00db\n\31\3\32\3\32\3\32\3\32\3\32"+ - "\3\32\3\33\3\33\3\33\3\33\3\33\3\33\3\34\3\34\3\34\3\34\3\34\5\34\u00ee"+ - "\n\34\3\35\3\35\3\35\3\35\3\35\3\35\3\35\3\35\5\35\u00f8\n\35\3\36\3\36"+ - "\3\36\3\36\3\36\5\36\u00ff\n\36\3\37\3\37\3\37\3\37\3\37\3\37\3\37\3\37"+ - "\5\37\u0109\n\37\3 \3 \3 \3 \3!\3!\3\"\3\"\3\"\3\"\3#\3#\3$\3$\5$\u0119"+ - "\n$\3%\3%\3%\2\2&\2\4\6\b\n\f\16\20\22\24\26\30\32\34\36 \"$&(*,.\60\62"+ - "\64\668:<>@BDFH\2\5\3\2\35$\3\2%\64\4\2\678<<\u011c\2K\3\2\2\2\4Y\3\2"+ - "\2\2\6a\3\2\2\2\bc\3\2\2\2\ne\3\2\2\2\fh\3\2\2\2\16m\3\2\2\2\20p\3\2\2"+ - "\2\22x\3\2\2\2\24|\3\2\2\2\26\u0087\3\2\2\2\30\u0089\3\2\2\2\32\u008c"+ - "\3\2\2\2\34\u0091\3\2\2\2\36\u0093\3\2\2\2 \u0097\3\2\2\2\"\u009b\3\2"+ - "\2\2$\u009f\3\2\2\2&\u00a7\3\2\2\2(\u00b0\3\2\2\2*\u00b9\3\2\2\2,\u00c8"+ - "\3\2\2\2.\u00ca\3\2\2\2\60\u00da\3\2\2\2\62\u00dc\3\2\2\2\64\u00e2\3\2"+ - "\2\2\66\u00ed\3\2\2\28\u00f7\3\2\2\2:\u00fe\3\2\2\2<\u0108\3\2\2\2>\u010a"+ - "\3\2\2\2@\u010e\3\2\2\2B\u0110\3\2\2\2D\u0114\3\2\2\2F\u0118\3\2\2\2H"+ - "\u011a\3\2\2\2JL\5\4\3\2KJ\3\2\2\2KL\3\2\2\2LP\3\2\2\2MO\5\b\5\2NM\3\2"+ - "\2\2OR\3\2\2\2PN\3\2\2\2PQ\3\2\2\2QT\3\2\2\2RP\3\2\2\2SU\5\n\6\2TS\3\2"+ - "\2\2TU\3\2\2\2UW\3\2\2\2VX\5\f\7\2WV\3\2\2\2WX\3\2\2\2X\3\3\2\2\2Y[\7"+ - "\3\2\2Z\\\5\6\4\2[Z\3\2\2\2[\\\3\2\2\2\\]\3\2\2\2]^\7\4\2\2^_\5\24\13"+ - "\2_`\7\5\2\2`\5\3\2\2\2ab\7\6\2\2b\7\3\2\2\2cd\5\20\t\2d\t\3\2\2\2ef\7"+ - "\7\2\2fg\5$\23\2g\13\3\2\2\2hi\7\b\2\2ik\78\2\2jl\5\16\b\2kj\3\2\2\2k"+ - "l\3\2\2\2l\r\3\2\2\2mn\7\t\2\2no\78\2\2o\17\3\2\2\2pr\7\n\2\2qs\5\34\17"+ - "\2rq\3\2\2\2rs\3\2\2\2st\3\2\2\2tv\7\66\2\2uw\5\22\n\2vu\3\2\2\2vw\3\2"+ - "\2\2w\21\3\2\2\2xy\7\4\2\2yz\5\24\13\2z{\7\5\2\2{\23\3\2\2\2|\u0081\5"+ - "\26\f\2}~\7\13\2\2~\u0080\5\26\f\2\177}\3\2\2\2\u0080\u0083\3\2\2\2\u0081"+ - "\177\3\2\2\2\u0081\u0082\3\2\2\2\u0082\25\3\2\2\2\u0083\u0081\3\2\2\2"+ - "\u0084\u0088\7\66\2\2\u0085\u0088\5\30\r\2\u0086\u0088\5\32\16\2\u0087"+ - "\u0084\3\2\2\2\u0087\u0085\3\2\2\2\u0087\u0086\3\2\2\2\u0088\27\3\2\2"+ - "\2\u0089\u008a\7\f\2\2\u008a\u008b\5\36\20\2\u008b\31\3\2\2\2\u008c\u008d"+ - "\7\f\2\2\u008d\u008e\5 \21\2\u008e\33\3\2\2\2\u008f\u0092\5\36\20\2\u0090"+ - "\u0092\5 \21\2\u0091\u008f\3\2\2\2\u0091\u0090\3\2\2\2\u0092\35\3\2\2"+ - "\2\u0093\u0095\7\r\2\2\u0094\u0096\5\"\22\2\u0095\u0094\3\2\2\2\u0095"+ - "\u0096\3\2\2\2\u0096\37\3\2\2\2\u0097\u0099\7\16\2\2\u0098\u009a\5\"\22"+ - "\2\u0099\u0098\3\2\2\2\u0099\u009a\3\2\2\2\u009a!\3\2\2\2\u009b\u009c"+ - "\7\4\2\2\u009c\u009d\78\2\2\u009d\u009e\7\5\2\2\u009e#\3\2\2\2\u009f\u00a4"+ - "\5&\24\2\u00a0\u00a1\7\17\2\2\u00a1\u00a3\5&\24\2\u00a2\u00a0\3\2\2\2"+ - "\u00a3\u00a6\3\2\2\2\u00a4\u00a2\3\2\2\2\u00a4\u00a5\3\2\2\2\u00a5%\3"+ - "\2\2\2\u00a6\u00a4\3\2\2\2\u00a7\u00ac\5(\25\2\u00a8\u00a9\7\20\2\2\u00a9"+ - "\u00ab\5(\25\2\u00aa\u00a8\3\2\2\2\u00ab\u00ae\3\2\2\2\u00ac\u00aa\3\2"+ - "\2\2\u00ac\u00ad\3\2\2\2\u00ad\'\3\2\2\2\u00ae\u00ac\3\2\2\2\u00af\u00b1"+ - "\7\21\2\2\u00b0\u00af\3\2\2\2\u00b0\u00b1\3\2\2\2\u00b1\u00b2\3\2\2\2"+ - "\u00b2\u00b3\5*\26\2\u00b3)\3\2\2\2\u00b4\u00ba\5,\27\2\u00b5\u00b6\7"+ - "\4\2\2\u00b6\u00b7\5$\23\2\u00b7\u00b8\7\5\2\2\u00b8\u00ba\3\2\2\2\u00b9"+ - "\u00b4\3\2\2\2\u00b9\u00b5\3\2\2\2\u00ba+\3\2\2\2\u00bb\u00c9\5B\"\2\u00bc"+ - "\u00c9\5> \2\u00bd\u00c9\5\62\32\2\u00be\u00c9\5\64\33\2\u00bf\u00c9\5"+ - ".\30\2\u00c0\u00c9\5\66\34\2\u00c1\u00c9\58\35\2\u00c2\u00c9\5:\36\2\u00c3"+ - "\u00c9\5<\37\2\u00c4\u00c5\7\4\2\2\u00c5\u00c6\5,\27\2\u00c6\u00c7\7\5"+ - "\2\2\u00c7\u00c9\3\2\2\2\u00c8\u00bb\3\2\2\2\u00c8\u00bc\3\2\2\2\u00c8"+ - "\u00bd\3\2\2\2\u00c8\u00be\3\2\2\2\u00c8\u00bf\3\2\2\2\u00c8\u00c0\3\2"+ - "\2\2\u00c8\u00c1\3\2\2\2\u00c8\u00c2\3\2\2\2\u00c8\u00c3\3\2\2\2\u00c8"+ - "\u00c4\3\2\2\2\u00c9-\3\2\2\2\u00ca\u00cb\7\66\2\2\u00cb\u00cc\7\22\2"+ - "\2\u00cc\u00cd\5\60\31\2\u00cd/\3\2\2\2\u00ce\u00db\7\65\2\2\u00cf\u00d0"+ - "\7\4\2\2\u00d0\u00d5\5F$\2\u00d1\u00d2\7\13\2\2\u00d2\u00d4\5F$\2\u00d3"+ - "\u00d1\3\2\2\2\u00d4\u00d7\3\2\2\2\u00d5\u00d3\3\2\2\2\u00d5\u00d6\3\2"+ - "\2\2\u00d6\u00d8\3\2\2\2\u00d7\u00d5\3\2\2\2\u00d8\u00d9\7\5\2\2\u00d9"+ - "\u00db\3\2\2\2\u00da\u00ce\3\2\2\2\u00da\u00cf\3\2\2\2\u00db\61\3\2\2"+ - "\2\u00dc\u00dd\7\66\2\2\u00dd\u00de\7\23\2\2\u00de\u00df\5F$\2\u00df\u00e0"+ - "\7\20\2\2\u00e0\u00e1\5F$\2\u00e1\63\3\2\2\2\u00e2\u00e3\5F$\2\u00e3\u00e4"+ - "\7\23\2\2\u00e4\u00e5\7\66\2\2\u00e5\u00e6\7\20\2\2\u00e6\u00e7\7\66\2"+ - "\2\u00e7\65\3\2\2\2\u00e8\u00e9\7\66\2\2\u00e9\u00ea\7\24\2\2\u00ea\u00ee"+ - "\7\25\2\2\u00eb\u00ec\7\66\2\2\u00ec\u00ee\7\26\2\2\u00ed\u00e8\3\2\2"+ - "\2\u00ed\u00eb\3\2\2\2\u00ee\67\3\2\2\2\u00ef\u00f0\7\66\2\2\u00f0\u00f1"+ - "\7\24\2\2\u00f1\u00f2\7\21\2\2\u00f2\u00f8\7\25\2\2\u00f3\u00f4\7\66\2"+ - "\2\u00f4\u00f8\7\27\2\2\u00f5\u00f6\7\66\2\2\u00f6\u00f8\7\30\2\2\u00f7"+ - "\u00ef\3\2\2\2\u00f7\u00f3\3\2\2\2\u00f7\u00f5\3\2\2\2\u00f89\3\2\2\2"+ - "\u00f9\u00fa\7\66\2\2\u00fa\u00fb\7\24\2\2\u00fb\u00ff\7\31\2\2\u00fc"+ - "\u00fd\7\66\2\2\u00fd\u00ff\7\32\2\2\u00fe\u00f9\3\2\2\2\u00fe\u00fc\3"+ - "\2\2\2\u00ff;\3\2\2\2\u0100\u0101\7\66\2\2\u0101\u0102\7\24\2\2\u0102"+ - "\u0103\7\21\2\2\u0103\u0109\7\31\2\2\u0104\u0105\7\66\2\2\u0105\u0109"+ - "\7\33\2\2\u0106\u0107\7\66\2\2\u0107\u0109\7\34\2\2\u0108\u0100\3\2\2"+ - "\2\u0108\u0104\3\2\2\2\u0108\u0106\3\2\2\2\u0109=\3\2\2\2\u010a\u010b"+ - "\7\66\2\2\u010b\u010c\5@!\2\u010c\u010d\5F$\2\u010d?\3\2\2\2\u010e\u010f"+ - "\t\2\2\2\u010fA\3\2\2\2\u0110\u0111\7\66\2\2\u0111\u0112\5D#\2\u0112\u0113"+ - "\5F$\2\u0113C\3\2\2\2\u0114\u0115\t\3\2\2\u0115E\3\2\2\2\u0116\u0119\5"+ - "H%\2\u0117\u0119\7\65\2\2\u0118\u0116\3\2\2\2\u0118\u0117\3\2\2\2\u0119"+ - "G\3\2\2\2\u011a\u011b\t\4\2\2\u011bI\3\2\2\2\33KPTW[krv\u0081\u0087\u0091"+ - "\u0095\u0099\u00a4\u00ac\u00b0\u00b9\u00c8\u00d5\u00da\u00ed\u00f7\u00fe"+ - "\u0108\u0118"; + "\t!\4\"\t\"\4#\t#\4$\t$\4%\t%\4&\t&\4\'\t\'\4(\t(\4)\t)\3\2\5\2T\n\2\3"+ + "\2\7\2W\n\2\f\2\16\2Z\13\2\3\2\5\2]\n\2\3\2\5\2`\n\2\3\2\5\2c\n\2\3\3"+ + "\3\3\5\3g\n\3\3\3\3\3\3\3\3\3\3\4\3\4\3\5\3\5\3\6\3\6\3\6\3\7\3\7\3\7"+ + "\3\7\3\7\7\7y\n\7\f\7\16\7|\13\7\3\b\3\b\5\b\u0080\n\b\3\b\5\b\u0083\n"+ + "\b\3\t\3\t\3\t\3\t\5\t\u0089\n\t\3\n\3\n\3\13\3\13\3\13\5\13\u0090\n\13"+ + "\3\f\3\f\3\f\3\r\3\r\5\r\u0097\n\r\3\r\3\r\5\r\u009b\n\r\3\16\3\16\3\16"+ + "\3\16\3\17\3\17\3\17\7\17\u00a4\n\17\f\17\16\17\u00a7\13\17\3\20\3\20"+ + "\3\20\5\20\u00ac\n\20\3\21\3\21\3\21\3\22\3\22\3\22\3\23\3\23\5\23\u00b6"+ + "\n\23\3\24\3\24\5\24\u00ba\n\24\3\25\3\25\5\25\u00be\n\25\3\26\3\26\3"+ + "\26\3\26\3\27\3\27\3\27\7\27\u00c7\n\27\f\27\16\27\u00ca\13\27\3\30\3"+ + "\30\3\30\7\30\u00cf\n\30\f\30\16\30\u00d2\13\30\3\31\5\31\u00d5\n\31\3"+ + "\31\3\31\3\32\3\32\3\32\3\32\3\32\5\32\u00de\n\32\3\33\3\33\3\33\3\33"+ + "\3\33\3\33\3\33\3\33\3\33\3\33\3\33\3\33\3\33\5\33\u00ed\n\33\3\34\3\34"+ + "\3\34\3\34\3\35\3\35\3\35\3\35\3\35\7\35\u00f8\n\35\f\35\16\35\u00fb\13"+ + "\35\3\35\3\35\5\35\u00ff\n\35\3\36\3\36\3\36\3\36\3\36\3\36\3\37\3\37"+ + "\3\37\3\37\3\37\3\37\3 \3 \3 \3 \3 \5 \u0112\n \3!\3!\3!\3!\3!\3!\3!\3"+ + "!\5!\u011c\n!\3\"\3\"\3\"\3\"\3\"\5\"\u0123\n\"\3#\3#\3#\3#\3#\3#\3#\3"+ + "#\5#\u012d\n#\3$\3$\3$\3$\3%\3%\3&\3&\3&\3&\3\'\3\'\3(\3(\5(\u013d\n("+ + "\3)\3)\3)\2\2*\2\4\6\b\n\f\16\20\22\24\26\30\32\34\36 \"$&(*,.\60\62\64"+ + "\668:<>@BDFHJLNP\2\6\3\2\16\17\3\2$+\3\2,;\4\2>?CC\u0141\2S\3\2\2\2\4"+ + "d\3\2\2\2\6l\3\2\2\2\bn\3\2\2\2\np\3\2\2\2\fs\3\2\2\2\16}\3\2\2\2\20\u0088"+ + "\3\2\2\2\22\u008a\3\2\2\2\24\u008c\3\2\2\2\26\u0091\3\2\2\2\30\u0094\3"+ + "\2\2\2\32\u009c\3\2\2\2\34\u00a0\3\2\2\2\36\u00ab\3\2\2\2 \u00ad\3\2\2"+ + "\2\"\u00b0\3\2\2\2$\u00b5\3\2\2\2&\u00b7\3\2\2\2(\u00bb\3\2\2\2*\u00bf"+ + "\3\2\2\2,\u00c3\3\2\2\2.\u00cb\3\2\2\2\60\u00d4\3\2\2\2\62\u00dd\3\2\2"+ + "\2\64\u00ec\3\2\2\2\66\u00ee\3\2\2\28\u00fe\3\2\2\2:\u0100\3\2\2\2<\u0106"+ + "\3\2\2\2>\u0111\3\2\2\2@\u011b\3\2\2\2B\u0122\3\2\2\2D\u012c\3\2\2\2F"+ + "\u012e\3\2\2\2H\u0132\3\2\2\2J\u0134\3\2\2\2L\u0138\3\2\2\2N\u013c\3\2"+ + "\2\2P\u013e\3\2\2\2RT\5\4\3\2SR\3\2\2\2ST\3\2\2\2TX\3\2\2\2UW\5\b\5\2"+ + "VU\3\2\2\2WZ\3\2\2\2XV\3\2\2\2XY\3\2\2\2Y\\\3\2\2\2ZX\3\2\2\2[]\5\n\6"+ + "\2\\[\3\2\2\2\\]\3\2\2\2]_\3\2\2\2^`\5\f\7\2_^\3\2\2\2_`\3\2\2\2`b\3\2"+ + "\2\2ac\5\24\13\2ba\3\2\2\2bc\3\2\2\2c\3\3\2\2\2df\7\3\2\2eg\5\6\4\2fe"+ + "\3\2\2\2fg\3\2\2\2gh\3\2\2\2hi\7\4\2\2ij\5\34\17\2jk\7\5\2\2k\5\3\2\2"+ + "\2lm\7\6\2\2m\7\3\2\2\2no\5\30\r\2o\t\3\2\2\2pq\7\7\2\2qr\5,\27\2r\13"+ + "\3\2\2\2st\7\b\2\2tu\7\t\2\2uz\5\16\b\2vw\7\n\2\2wy\5\16\b\2xv\3\2\2\2"+ + "y|\3\2\2\2zx\3\2\2\2z{\3\2\2\2{\r\3\2\2\2|z\3\2\2\2}\177\7=\2\2~\u0080"+ + "\5\22\n\2\177~\3\2\2\2\177\u0080\3\2\2\2\u0080\u0082\3\2\2\2\u0081\u0083"+ + "\5\20\t\2\u0082\u0081\3\2\2\2\u0082\u0083\3\2\2\2\u0083\17\3\2\2\2\u0084"+ + "\u0085\7\13\2\2\u0085\u0089\7\f\2\2\u0086\u0087\7\13\2\2\u0087\u0089\7"+ + "\r\2\2\u0088\u0084\3\2\2\2\u0088\u0086\3\2\2\2\u0089\21\3\2\2\2\u008a"+ + "\u008b\t\2\2\2\u008b\23\3\2\2\2\u008c\u008d\7\20\2\2\u008d\u008f\7?\2"+ + "\2\u008e\u0090\5\26\f\2\u008f\u008e\3\2\2\2\u008f\u0090\3\2\2\2\u0090"+ + "\25\3\2\2\2\u0091\u0092\7\21\2\2\u0092\u0093\7?\2\2\u0093\27\3\2\2\2\u0094"+ + "\u0096\7\22\2\2\u0095\u0097\5$\23\2\u0096\u0095\3\2\2\2\u0096\u0097\3"+ + "\2\2\2\u0097\u0098\3\2\2\2\u0098\u009a\7=\2\2\u0099\u009b\5\32\16\2\u009a"+ + "\u0099\3\2\2\2\u009a\u009b\3\2\2\2\u009b\31\3\2\2\2\u009c\u009d\7\4\2"+ + "\2\u009d\u009e\5\34\17\2\u009e\u009f\7\5\2\2\u009f\33\3\2\2\2\u00a0\u00a5"+ + "\5\36\20\2\u00a1\u00a2\7\n\2\2\u00a2\u00a4\5\36\20\2\u00a3\u00a1\3\2\2"+ + "\2\u00a4\u00a7\3\2\2\2\u00a5\u00a3\3\2\2\2\u00a5\u00a6\3\2\2\2\u00a6\35"+ + "\3\2\2\2\u00a7\u00a5\3\2\2\2\u00a8\u00ac\7=\2\2\u00a9\u00ac\5 \21\2\u00aa"+ + "\u00ac\5\"\22\2\u00ab\u00a8\3\2\2\2\u00ab\u00a9\3\2\2\2\u00ab\u00aa\3"+ + "\2\2\2\u00ac\37\3\2\2\2\u00ad\u00ae\7\23\2\2\u00ae\u00af\5&\24\2\u00af"+ + "!\3\2\2\2\u00b0\u00b1\7\23\2\2\u00b1\u00b2\5(\25\2\u00b2#\3\2\2\2\u00b3"+ + "\u00b6\5&\24\2\u00b4\u00b6\5(\25\2\u00b5\u00b3\3\2\2\2\u00b5\u00b4\3\2"+ + "\2\2\u00b6%\3\2\2\2\u00b7\u00b9\7\24\2\2\u00b8\u00ba\5*\26\2\u00b9\u00b8"+ + "\3\2\2\2\u00b9\u00ba\3\2\2\2\u00ba\'\3\2\2\2\u00bb\u00bd\7\25\2\2\u00bc"+ + "\u00be\5*\26\2\u00bd\u00bc\3\2\2\2\u00bd\u00be\3\2\2\2\u00be)\3\2\2\2"+ + "\u00bf\u00c0\7\4\2\2\u00c0\u00c1\7?\2\2\u00c1\u00c2\7\5\2\2\u00c2+\3\2"+ + "\2\2\u00c3\u00c8\5.\30\2\u00c4\u00c5\7\26\2\2\u00c5\u00c7\5.\30\2\u00c6"+ + "\u00c4\3\2\2\2\u00c7\u00ca\3\2\2\2\u00c8\u00c6\3\2\2\2\u00c8\u00c9\3\2"+ + "\2\2\u00c9-\3\2\2\2\u00ca\u00c8\3\2\2\2\u00cb\u00d0\5\60\31\2\u00cc\u00cd"+ + "\7\27\2\2\u00cd\u00cf\5\60\31\2\u00ce\u00cc\3\2\2\2\u00cf\u00d2\3\2\2"+ + "\2\u00d0\u00ce\3\2\2\2\u00d0\u00d1\3\2\2\2\u00d1/\3\2\2\2\u00d2\u00d0"+ + "\3\2\2\2\u00d3\u00d5\7\30\2\2\u00d4\u00d3\3\2\2\2\u00d4\u00d5\3\2\2\2"+ + "\u00d5\u00d6\3\2\2\2\u00d6\u00d7\5\62\32\2\u00d7\61\3\2\2\2\u00d8\u00de"+ + "\5\64\33\2\u00d9\u00da\7\4\2\2\u00da\u00db\5,\27\2\u00db\u00dc\7\5\2\2"+ + "\u00dc\u00de\3\2\2\2\u00dd\u00d8\3\2\2\2\u00dd\u00d9\3\2\2\2\u00de\63"+ + "\3\2\2\2\u00df\u00ed\5J&\2\u00e0\u00ed\5F$\2\u00e1\u00ed\5:\36\2\u00e2"+ + "\u00ed\5<\37\2\u00e3\u00ed\5\66\34\2\u00e4\u00ed\5> \2\u00e5\u00ed\5@"+ + "!\2\u00e6\u00ed\5B\"\2\u00e7\u00ed\5D#\2\u00e8\u00e9\7\4\2\2\u00e9\u00ea"+ + "\5\64\33\2\u00ea\u00eb\7\5\2\2\u00eb\u00ed\3\2\2\2\u00ec\u00df\3\2\2\2"+ + "\u00ec\u00e0\3\2\2\2\u00ec\u00e1\3\2\2\2\u00ec\u00e2\3\2\2\2\u00ec\u00e3"+ + "\3\2\2\2\u00ec\u00e4\3\2\2\2\u00ec\u00e5\3\2\2\2\u00ec\u00e6\3\2\2\2\u00ec"+ + "\u00e7\3\2\2\2\u00ec\u00e8\3\2\2\2\u00ed\65\3\2\2\2\u00ee\u00ef\7=\2\2"+ + "\u00ef\u00f0\7\31\2\2\u00f0\u00f1\58\35\2\u00f1\67\3\2\2\2\u00f2\u00ff"+ + "\7<\2\2\u00f3\u00f4\7\4\2\2\u00f4\u00f9\5N(\2\u00f5\u00f6\7\n\2\2\u00f6"+ + "\u00f8\5N(\2\u00f7\u00f5\3\2\2\2\u00f8\u00fb\3\2\2\2\u00f9\u00f7\3\2\2"+ + "\2\u00f9\u00fa\3\2\2\2\u00fa\u00fc\3\2\2\2\u00fb\u00f9\3\2\2\2\u00fc\u00fd"+ + "\7\5\2\2\u00fd\u00ff\3\2\2\2\u00fe\u00f2\3\2\2\2\u00fe\u00f3\3\2\2\2\u00ff"+ + "9\3\2\2\2\u0100\u0101\7=\2\2\u0101\u0102\7\32\2\2\u0102\u0103\5N(\2\u0103"+ + "\u0104\7\27\2\2\u0104\u0105\5N(\2\u0105;\3\2\2\2\u0106\u0107\5N(\2\u0107"+ + "\u0108\7\32\2\2\u0108\u0109\7=\2\2\u0109\u010a\7\27\2\2\u010a\u010b\7"+ + "=\2\2\u010b=\3\2\2\2\u010c\u010d\7=\2\2\u010d\u010e\7\33\2\2\u010e\u0112"+ + "\7\34\2\2\u010f\u0110\7=\2\2\u0110\u0112\7\35\2\2\u0111\u010c\3\2\2\2"+ + "\u0111\u010f\3\2\2\2\u0112?\3\2\2\2\u0113\u0114\7=\2\2\u0114\u0115\7\33"+ + "\2\2\u0115\u0116\7\30\2\2\u0116\u011c\7\34\2\2\u0117\u0118\7=\2\2\u0118"+ + "\u011c\7\36\2\2\u0119\u011a\7=\2\2\u011a\u011c\7\37\2\2\u011b\u0113\3"+ + "\2\2\2\u011b\u0117\3\2\2\2\u011b\u0119\3\2\2\2\u011cA\3\2\2\2\u011d\u011e"+ + "\7=\2\2\u011e\u011f\7\33\2\2\u011f\u0123\7 \2\2\u0120\u0121\7=\2\2\u0121"+ + "\u0123\7!\2\2\u0122\u011d\3\2\2\2\u0122\u0120\3\2\2\2\u0123C\3\2\2\2\u0124"+ + "\u0125\7=\2\2\u0125\u0126\7\33\2\2\u0126\u0127\7\30\2\2\u0127\u012d\7"+ + " \2\2\u0128\u0129\7=\2\2\u0129\u012d\7\"\2\2\u012a\u012b\7=\2\2\u012b"+ + "\u012d\7#\2\2\u012c\u0124\3\2\2\2\u012c\u0128\3\2\2\2\u012c\u012a\3\2"+ + "\2\2\u012dE\3\2\2\2\u012e\u012f\7=\2\2\u012f\u0130\5H%\2\u0130\u0131\5"+ + "N(\2\u0131G\3\2\2\2\u0132\u0133\t\3\2\2\u0133I\3\2\2\2\u0134\u0135\7="+ + "\2\2\u0135\u0136\5L\'\2\u0136\u0137\5N(\2\u0137K\3\2\2\2\u0138\u0139\t"+ + "\4\2\2\u0139M\3\2\2\2\u013a\u013d\5P)\2\u013b\u013d\7<\2\2\u013c\u013a"+ + "\3\2\2\2\u013c\u013b\3\2\2\2\u013dO\3\2\2\2\u013e\u013f\t\5\2\2\u013f"+ + "Q\3\2\2\2 SX\\_bfz\177\u0082\u0088\u008f\u0096\u009a\u00a5\u00ab\u00b5"+ + "\u00b9\u00bd\u00c8\u00d0\u00d4\u00dd\u00ec\u00f9\u00fe\u0111\u011b\u0122"+ + "\u012c\u013c"; public static final ATN _ATN = new ATNDeserializer().deserialize(_serializedATN.toCharArray()); static { diff --git a/src/test/java/com/avaje/ebeaninternal/server/grammer/EqlParserTest.java b/src/test/java/com/avaje/ebeaninternal/server/grammer/EqlParserTest.java index e490ad0e6..38512ecbf 100644 --- a/src/test/java/com/avaje/ebeaninternal/server/grammer/EqlParserTest.java +++ b/src/test/java/com/avaje/ebeaninternal/server/grammer/EqlParserTest.java @@ -330,6 +330,65 @@ public class EqlParserTest extends BaseTestCase { } } + @Test + public void orderBy() throws Exception { + + ResetBasicData.reset(); + + Query query = parse("order by id"); + query.findList(); + if (isH2()) { + assertThat(query.getGeneratedSql()).contains("from o_customer t0 order by t0.id"); + } + } + + @Test + public void orderBy_desc() throws Exception { + + ResetBasicData.reset(); + + Query query = parse("order by id desc"); + query.findList(); + if (isH2()) { + assertThat(query.getGeneratedSql()).contains("from o_customer t0 order by t0.id desc"); + } + } + + @Test + public void orderBy_nullsLast() throws Exception { + + ResetBasicData.reset(); + + Query query = parse("order by id desc nulls last"); + query.findList(); + if (isH2()) { + assertThat(query.getGeneratedSql()).contains(" from o_customer t0 order by t0.id desc nulls last"); + } + } + + @Test + public void orderBy_nullsFirst() throws Exception { + + ResetBasicData.reset(); + + Query query = parse("order by id nulls first"); + query.findList(); + if (isH2()) { + assertThat(query.getGeneratedSql()).contains(" from o_customer t0 order by t0.id nulls first"); + } + } + + @Test + public void orderBy_multiple() throws Exception { + + ResetBasicData.reset(); + + Query query = parse("order by billingAddress.city desc nulls last, name, id desc nulls last"); + query.findList(); + if (isH2()) { + assertThat(query.getGeneratedSql()).contains(" order by t1.city desc nulls last, t0.name, t0.id desc nulls last"); + } + } private Query parse(String raw) { diff --git a/src/test/java/com/avaje/tests/unitinternal/TestOrderByParse.java b/src/test/java/com/avaje/tests/unitinternal/TestOrderByParse.java index 882128e81..11267f790 100644 --- a/src/test/java/com/avaje/tests/unitinternal/TestOrderByParse.java +++ b/src/test/java/com/avaje/tests/unitinternal/TestOrderByParse.java @@ -54,6 +54,17 @@ public class TestOrderByParse extends BaseTestCase { assertTrue(o1.toStringFormat().equals("id desc nulls high")); } + @Test + public void add_parse() { + + OrderBy o1 = new OrderBy(); + o1.add("id desc nulls high"); + assertTrue(o1.getProperties().size() == 1); + assertTrue(o1.getProperties().get(0).getProperty().equals("id")); + assertTrue(!o1.getProperties().get(0).isAscending()); + assertTrue(o1.toStringFormat().equals("id desc nulls high")); + } + @Test public void parseNullsHigh_with_second() { diff --git a/src/test/resources/EQL.g4 b/src/test/resources/EQL.g4 index f028b3fab..82037c7cc 100644 --- a/src/test/resources/EQL.g4 +++ b/src/test/resources/EQL.g4 @@ -1,7 +1,7 @@ grammar EQL; select_statement - : select_clause? fetch_clause* where_clause? limit_clause? + : select_clause? fetch_clause* where_clause? orderby_clause? limit_clause? ; select_clause @@ -20,6 +20,24 @@ where_clause : 'where' conditional_expression ; +orderby_clause + : 'order' 'by' orderby_property (',' orderby_property)* + ; + +orderby_property + : PATH_VARIABLE asc_desc? nulls_firstlast? + ; + +nulls_firstlast + : 'nulls' 'first' + | 'nulls' 'last' + ; + +asc_desc + : 'asc' + | 'desc' + ; + limit_clause : 'limit' NUMBER_LITERAL offset_clause? ;