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 7f3edde57..482581bbc 100644 --- a/src/main/java/com/avaje/ebeaninternal/server/grammer/EqlAdapter.java +++ b/src/main/java/com/avaje/ebeaninternal/server/grammer/EqlAdapter.java @@ -2,6 +2,7 @@ package com.avaje.ebeaninternal.server.grammer; import com.avaje.ebean.Expression; import com.avaje.ebean.ExpressionList; +import com.avaje.ebean.FetchConfig; import com.avaje.ebean.LikeType; import com.avaje.ebeaninternal.api.SpiQuery; import com.avaje.ebeaninternal.server.grammer.antlr.EQLBaseListener; @@ -90,15 +91,24 @@ class EqlAdapter extends EQLBaseListener { @Override public void enterFetch_path(EQLParser.Fetch_pathContext ctx) { + int childCount = ctx.getChildCount(); checkChildren(ctx, 2); String path = child(ctx, 1); - if (childCount == 2) { - query.fetch(path); + + int noPropertiesLength = 2; + + FetchConfig fetchConfig = ParseFetchConfig.parse(path); + if (fetchConfig != null) { + noPropertiesLength = 3; + path = child(ctx, 2); + } + if (childCount == noPropertiesLength) { + query.fetch(path, fetchConfig); } else { - String fetchProperties = trimParenthesis(ctx.getChild(2).getText()); - query.fetch(path, fetchProperties); + String fetchProperties = trimParenthesis(ctx.getChild(noPropertiesLength).getText()); + query.fetch(path, fetchProperties, fetchConfig); } } diff --git a/src/main/java/com/avaje/ebeaninternal/server/grammer/ParseFetchConfig.java b/src/main/java/com/avaje/ebeaninternal/server/grammer/ParseFetchConfig.java new file mode 100644 index 000000000..db014c6c0 --- /dev/null +++ b/src/main/java/com/avaje/ebeaninternal/server/grammer/ParseFetchConfig.java @@ -0,0 +1,49 @@ +package com.avaje.ebeaninternal.server.grammer; + +import com.avaje.ebean.FetchConfig; + +/** + * Parse the path that potentially is a FetchConfig definition. + */ +class ParseFetchConfig { + + /** + * Parse the path that potentially is a FetchConfig definition. + *

+ * Return the FetchConfig if it is and otherwise null. + *

+ */ + static FetchConfig parse(String path) { + + if (path.startsWith("lazy")) { + if (path.length() == 4) { + return new FetchConfig().lazy(); + } else if (path.charAt(4) == '(') { + path = path.substring(5); + int batchSize = parseBatchSize(path); + return new FetchConfig().lazy(batchSize); + } else { + return null; + } + } + + if (path.startsWith("query")) { + if (path.length() == 5) { + return new FetchConfig().query(); + } else if (path.charAt(5) == '(') { + path = path.substring(6); + int batchSize = parseBatchSize(path); + return new FetchConfig().query(batchSize); + } else { + return null; + } + } + + return null; + } + + private static int parseBatchSize(String path) { + path = path.substring(0, path.length()-1); + return Integer.parseInt(path); + } +} 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 174ef1964..482b47e62 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 @@ -42,53 +42,63 @@ T__40=41 T__41=42 T__42=43 T__43=44 -INPUT_VARIABLE=45 -PATH_VARIABLE=46 -BOOLEAN_LITERAL=47 -NUMBER_LITERAL=48 -STRING_LITERAL=49 -WS=50 +T__44=45 +T__45=46 +T__46=47 +INPUT_VARIABLE=48 +PATH_VARIABLE=49 +BOOLEAN_LITERAL=50 +NUMBER_LITERAL=51 +DOUBLE=52 +INT=53 +ZERO=54 +STRING_LITERAL=55 +WS=56 'select'=1 '('=2 ')'=3 'where'=4 'fetch'=5 ','=6 -'or'=7 -'and'=8 -'not'=9 -'in'=10 -'between'=11 -'is'=12 -'null'=13 -'isNull'=14 -'isNotNull'=15 -'notNull'=16 -'empty'=17 -'isEmpty'=18 -'isNotEmpty'=19 -'notEmpty'=20 -'like'=21 -'ilike'=22 -'contains'=23 -'icontains'=24 -'startsWith'=25 -'istartsWith'=26 -'endsWith'=27 -'iendsWith'=28 -'='=29 -'eq'=30 -'>'=31 -'gt'=32 -'>='=33 -'ge'=34 -'gte'=35 -'<'=36 -'lt'=37 -'<='=38 -'le'=39 -'lte'=40 -'<>'=41 -'!='=42 -'ne'=43 -'ieq'=44 +'+'=7 +'query'=8 +'lazy'=9 +'or'=10 +'and'=11 +'not'=12 +'in'=13 +'between'=14 +'is'=15 +'null'=16 +'isNull'=17 +'isNotNull'=18 +'notNull'=19 +'empty'=20 +'isEmpty'=21 +'isNotEmpty'=22 +'notEmpty'=23 +'like'=24 +'ilike'=25 +'contains'=26 +'icontains'=27 +'startsWith'=28 +'istartsWith'=29 +'endsWith'=30 +'iendsWith'=31 +'='=32 +'eq'=33 +'>'=34 +'gt'=35 +'>='=36 +'ge'=37 +'gte'=38 +'<'=39 +'lt'=40 +'<='=41 +'le'=42 +'lte'=43 +'<>'=44 +'!='=45 +'ne'=46 +'ieq'=47 +'0'=54 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 54f2e85ed..77aa4d7dd 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 @@ -107,6 +107,78 @@ public class EQLBaseListener implements EQLListener { *

The default implementation does nothing.

*/ @Override public void exitFetch_property(EQLParser.Fetch_propertyContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterFetch_query_hint(EQLParser.Fetch_query_hintContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitFetch_query_hint(EQLParser.Fetch_query_hintContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterFetch_lazy_hint(EQLParser.Fetch_lazy_hintContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitFetch_lazy_hint(EQLParser.Fetch_lazy_hintContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterFetch_option(EQLParser.Fetch_optionContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitFetch_option(EQLParser.Fetch_optionContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterFetch_query_option(EQLParser.Fetch_query_optionContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitFetch_query_option(EQLParser.Fetch_query_optionContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterFetch_lazy_option(EQLParser.Fetch_lazy_optionContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitFetch_lazy_option(EQLParser.Fetch_lazy_optionContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterFetch_batch_size(EQLParser.Fetch_batch_sizeContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitFetch_batch_size(EQLParser.Fetch_batch_sizeContext 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 9bdd6d282..28142b44e 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 @@ -22,9 +22,9 @@ public class EQLLexer extends Lexer { T__17=18, T__18=19, T__19=20, T__20=21, T__21=22, T__22=23, T__23=24, 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, INPUT_VARIABLE=45, - PATH_VARIABLE=46, BOOLEAN_LITERAL=47, NUMBER_LITERAL=48, STRING_LITERAL=49, - WS=50; + 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, INPUT_VARIABLE=48, PATH_VARIABLE=49, BOOLEAN_LITERAL=50, + NUMBER_LITERAL=51, DOUBLE=52, INT=53, ZERO=54, STRING_LITERAL=55, WS=56; public static String[] modeNames = { "DEFAULT_MODE" }; @@ -35,26 +35,27 @@ public class EQLLexer extends Lexer { "T__17", "T__18", "T__19", "T__20", "T__21", "T__22", "T__23", "T__24", "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", "INPUT_VARIABLE", "PATH_VARIABLE", "BOOLEAN_LITERAL", - "NUMBER_LITERAL", "STRING_LITERAL", "WS" + "T__41", "T__42", "T__43", "T__44", "T__45", "T__46", "INPUT_VARIABLE", + "PATH_VARIABLE", "BOOLEAN_LITERAL", "NUMBER_LITERAL", "DOUBLE", "INT", + "ZERO", "STRING_LITERAL", "WS" }; private static final String[] _LITERAL_NAMES = { - null, "'select'", "'('", "')'", "'where'", "'fetch'", "','", "'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'", "'<'", "'lt'", "'<='", "'le'", "'lte'", "'<>'", "'!='", "'ne'", - "'ieq'" + null, "'select'", "'('", "')'", "'where'", "'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'", "'<'", "'lt'", "'<='", "'le'", "'lte'", "'<>'", + "'!='", "'ne'", "'ieq'", null, null, null, null, null, null, "'0'" }; private static final String[] _SYMBOLIC_NAMES = { 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, null, null, null, null, null, null, "INPUT_VARIABLE", - "PATH_VARIABLE", "BOOLEAN_LITERAL", "NUMBER_LITERAL", "STRING_LITERAL", - "WS" + 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" }; public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES); @@ -111,132 +112,149 @@ 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\64\u0188\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\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\6\3"+ - "\6\3\6\3\6\3\6\3\6\3\7\3\7\3\b\3\b\3\b\3\t\3\t\3\t\3\t\3\n\3\n\3\n\3\n"+ - "\3\13\3\13\3\13\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\f\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\17\3\20\3\20\3\20\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\21\3\21"+ - "\3\22\3\22\3\22\3\22\3\22\3\22\3\23\3\23\3\23\3\23\3\23\3\23\3\23\3\23"+ - "\3\24\3\24\3\24\3\24\3\24\3\24\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\25\3\25\3\26\3\26\3\26\3\26\3\26\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\30\3\30\3\30\3\31\3\31"+ - "\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\33\3\33\3\33\3\34\3\34\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\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."+ - "\7.\u0155\n.\f.\16.\u0158\13.\3/\3/\7/\u015c\n/\f/\16/\u015f\13/\3\60"+ - "\3\60\3\60\3\60\3\60\3\60\3\60\3\60\3\60\5\60\u016a\n\60\3\61\6\61\u016d"+ - "\n\61\r\61\16\61\u016e\3\61\5\61\u0172\n\61\3\61\7\61\u0175\n\61\f\61"+ - "\16\61\u0178\13\61\3\62\3\62\3\62\3\62\7\62\u017e\n\62\f\62\16\62\u0181"+ - "\13\62\3\62\3\62\3\63\3\63\3\63\3\63\2\2\64\3\3\5\4\7\5\t\6\13\7\r\b\17"+ + "\3\u0430\ud6d1\u8206\uad2d\u4417\uaef1\u8d80\uaadd\2:\u01b3\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\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\6\3\6\3\6\3\6\3\6\3\6\3"+ + "\7\3\7\3\b\3\b\3\t\3\t\3\t\3\t\3\t\3\t\3\n\3\n\3\n\3\n\3\n\3\13\3\13\3"+ + "\13\3\f\3\f\3\f\3\f\3\r\3\r\3\r\3\r\3\16\3\16\3\16\3\17\3\17\3\17\3\17"+ + "\3\17\3\17\3\17\3\17\3\20\3\20\3\20\3\21\3\21\3\21\3\21\3\21\3\22\3\22"+ + "\3\22\3\22\3\22\3\22\3\22\3\23\3\23\3\23\3\23\3\23\3\23\3\23\3\23\3\23"+ + "\3\23\3\24\3\24\3\24\3\24\3\24\3\24\3\24\3\24\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\27\3\27\3\27\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\30\3\30"+ + "\3\30\3\31\3\31\3\31\3\31\3\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\33\3\33\3\33\3\34\3\34\3\34\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\35"+ + "\3\36\3\36\3\36\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 \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\60\3\61\3\61\3\61\7\61\u016e\n\61\f\61\16\61\u0171\13\61"+ + "\3\62\3\62\7\62\u0175\n\62\f\62\16\62\u0178\13\62\3\63\3\63\3\63\3\63"+ + "\3\63\3\63\3\63\3\63\3\63\5\63\u0183\n\63\3\64\5\64\u0186\n\64\3\64\3"+ + "\64\5\64\u018a\n\64\3\64\3\64\5\64\u018e\n\64\3\65\6\65\u0191\n\65\r\65"+ + "\16\65\u0192\3\65\3\65\7\65\u0197\n\65\f\65\16\65\u019a\13\65\3\66\3\66"+ + "\7\66\u019e\n\66\f\66\16\66\u01a1\13\66\3\67\3\67\38\38\38\38\78\u01a9"+ + "\n8\f8\168\u01ac\138\38\38\39\39\39\39\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\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\64\3\2\b\5\2C\\aac|\6\2\62;C\\aac|\7\2\60\60"+ - "\62;C\\aac|\3\2\62;\3\2))\5\2\13\f\17\17\"\"\u018f\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\2G\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\2"+ - "Y\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\3g\3\2\2\2\5n\3\2\2\2\7p\3\2\2\2\tr\3\2\2\2\13x\3\2\2\2\r~\3\2"+ - "\2\2\17\u0080\3\2\2\2\21\u0083\3\2\2\2\23\u0087\3\2\2\2\25\u008b\3\2\2"+ - "\2\27\u008e\3\2\2\2\31\u0096\3\2\2\2\33\u0099\3\2\2\2\35\u009e\3\2\2\2"+ - "\37\u00a5\3\2\2\2!\u00af\3\2\2\2#\u00b7\3\2\2\2%\u00bd\3\2\2\2\'\u00c5"+ - "\3\2\2\2)\u00d0\3\2\2\2+\u00d9\3\2\2\2-\u00de\3\2\2\2/\u00e4\3\2\2\2\61"+ - "\u00ed\3\2\2\2\63\u00f7\3\2\2\2\65\u0102\3\2\2\2\67\u010e\3\2\2\29\u0117"+ - "\3\2\2\2;\u0121\3\2\2\2=\u0123\3\2\2\2?\u0126\3\2\2\2A\u0128\3\2\2\2C"+ - "\u012b\3\2\2\2E\u012e\3\2\2\2G\u0131\3\2\2\2I\u0135\3\2\2\2K\u0137\3\2"+ - "\2\2M\u013a\3\2\2\2O\u013d\3\2\2\2Q\u0140\3\2\2\2S\u0144\3\2\2\2U\u0147"+ - "\3\2\2\2W\u014a\3\2\2\2Y\u014d\3\2\2\2[\u0151\3\2\2\2]\u0159\3\2\2\2_"+ - "\u0169\3\2\2\2a\u016c\3\2\2\2c\u0179\3\2\2\2e\u0184\3\2\2\2gh\7u\2\2h"+ - "i\7g\2\2ij\7n\2\2jk\7g\2\2kl\7e\2\2lm\7v\2\2m\4\3\2\2\2no\7*\2\2o\6\3"+ - "\2\2\2pq\7+\2\2q\b\3\2\2\2rs\7y\2\2st\7j\2\2tu\7g\2\2uv\7t\2\2vw\7g\2"+ - "\2w\n\3\2\2\2xy\7h\2\2yz\7g\2\2z{\7v\2\2{|\7e\2\2|}\7j\2\2}\f\3\2\2\2"+ - "~\177\7.\2\2\177\16\3\2\2\2\u0080\u0081\7q\2\2\u0081\u0082\7t\2\2\u0082"+ - "\20\3\2\2\2\u0083\u0084\7c\2\2\u0084\u0085\7p\2\2\u0085\u0086\7f\2\2\u0086"+ - "\22\3\2\2\2\u0087\u0088\7p\2\2\u0088\u0089\7q\2\2\u0089\u008a\7v\2\2\u008a"+ - "\24\3\2\2\2\u008b\u008c\7k\2\2\u008c\u008d\7p\2\2\u008d\26\3\2\2\2\u008e"+ - "\u008f\7d\2\2\u008f\u0090\7g\2\2\u0090\u0091\7v\2\2\u0091\u0092\7y\2\2"+ - "\u0092\u0093\7g\2\2\u0093\u0094\7g\2\2\u0094\u0095\7p\2\2\u0095\30\3\2"+ - "\2\2\u0096\u0097\7k\2\2\u0097\u0098\7u\2\2\u0098\32\3\2\2\2\u0099\u009a"+ - "\7p\2\2\u009a\u009b\7w\2\2\u009b\u009c\7n\2\2\u009c\u009d\7n\2\2\u009d"+ - "\34\3\2\2\2\u009e\u009f\7k\2\2\u009f\u00a0\7u\2\2\u00a0\u00a1\7P\2\2\u00a1"+ - "\u00a2\7w\2\2\u00a2\u00a3\7n\2\2\u00a3\u00a4\7n\2\2\u00a4\36\3\2\2\2\u00a5"+ - "\u00a6\7k\2\2\u00a6\u00a7\7u\2\2\u00a7\u00a8\7P\2\2\u00a8\u00a9\7q\2\2"+ - "\u00a9\u00aa\7v\2\2\u00aa\u00ab\7P\2\2\u00ab\u00ac\7w\2\2\u00ac\u00ad"+ - "\7n\2\2\u00ad\u00ae\7n\2\2\u00ae \3\2\2\2\u00af\u00b0\7p\2\2\u00b0\u00b1"+ - "\7q\2\2\u00b1\u00b2\7v\2\2\u00b2\u00b3\7P\2\2\u00b3\u00b4\7w\2\2\u00b4"+ - "\u00b5\7n\2\2\u00b5\u00b6\7n\2\2\u00b6\"\3\2\2\2\u00b7\u00b8\7g\2\2\u00b8"+ - "\u00b9\7o\2\2\u00b9\u00ba\7r\2\2\u00ba\u00bb\7v\2\2\u00bb\u00bc\7{\2\2"+ - "\u00bc$\3\2\2\2\u00bd\u00be\7k\2\2\u00be\u00bf\7u\2\2\u00bf\u00c0\7G\2"+ - "\2\u00c0\u00c1\7o\2\2\u00c1\u00c2\7r\2\2\u00c2\u00c3\7v\2\2\u00c3\u00c4"+ - "\7{\2\2\u00c4&\3\2\2\2\u00c5\u00c6\7k\2\2\u00c6\u00c7\7u\2\2\u00c7\u00c8"+ - "\7P\2\2\u00c8\u00c9\7q\2\2\u00c9\u00ca\7v\2\2\u00ca\u00cb\7G\2\2\u00cb"+ - "\u00cc\7o\2\2\u00cc\u00cd\7r\2\2\u00cd\u00ce\7v\2\2\u00ce\u00cf\7{\2\2"+ - "\u00cf(\3\2\2\2\u00d0\u00d1\7p\2\2\u00d1\u00d2\7q\2\2\u00d2\u00d3\7v\2"+ - "\2\u00d3\u00d4\7G\2\2\u00d4\u00d5\7o\2\2\u00d5\u00d6\7r\2\2\u00d6\u00d7"+ - "\7v\2\2\u00d7\u00d8\7{\2\2\u00d8*\3\2\2\2\u00d9\u00da\7n\2\2\u00da\u00db"+ - "\7k\2\2\u00db\u00dc\7m\2\2\u00dc\u00dd\7g\2\2\u00dd,\3\2\2\2\u00de\u00df"+ - "\7k\2\2\u00df\u00e0\7n\2\2\u00e0\u00e1\7k\2\2\u00e1\u00e2\7m\2\2\u00e2"+ - "\u00e3\7g\2\2\u00e3.\3\2\2\2\u00e4\u00e5\7e\2\2\u00e5\u00e6\7q\2\2\u00e6"+ - "\u00e7\7p\2\2\u00e7\u00e8\7v\2\2\u00e8\u00e9\7c\2\2\u00e9\u00ea\7k\2\2"+ - "\u00ea\u00eb\7p\2\2\u00eb\u00ec\7u\2\2\u00ec\60\3\2\2\2\u00ed\u00ee\7"+ - "k\2\2\u00ee\u00ef\7e\2\2\u00ef\u00f0\7q\2\2\u00f0\u00f1\7p\2\2\u00f1\u00f2"+ - "\7v\2\2\u00f2\u00f3\7c\2\2\u00f3\u00f4\7k\2\2\u00f4\u00f5\7p\2\2\u00f5"+ - "\u00f6\7u\2\2\u00f6\62\3\2\2\2\u00f7\u00f8\7u\2\2\u00f8\u00f9\7v\2\2\u00f9"+ - "\u00fa\7c\2\2\u00fa\u00fb\7t\2\2\u00fb\u00fc\7v\2\2\u00fc\u00fd\7u\2\2"+ - "\u00fd\u00fe\7Y\2\2\u00fe\u00ff\7k\2\2\u00ff\u0100\7v\2\2\u0100\u0101"+ - "\7j\2\2\u0101\64\3\2\2\2\u0102\u0103\7k\2\2\u0103\u0104\7u\2\2\u0104\u0105"+ - "\7v\2\2\u0105\u0106\7c\2\2\u0106\u0107\7t\2\2\u0107\u0108\7v\2\2\u0108"+ - "\u0109\7u\2\2\u0109\u010a\7Y\2\2\u010a\u010b\7k\2\2\u010b\u010c\7v\2\2"+ - "\u010c\u010d\7j\2\2\u010d\66\3\2\2\2\u010e\u010f\7g\2\2\u010f\u0110\7"+ - "p\2\2\u0110\u0111\7f\2\2\u0111\u0112\7u\2\2\u0112\u0113\7Y\2\2\u0113\u0114"+ - "\7k\2\2\u0114\u0115\7v\2\2\u0115\u0116\7j\2\2\u01168\3\2\2\2\u0117\u0118"+ - "\7k\2\2\u0118\u0119\7g\2\2\u0119\u011a\7p\2\2\u011a\u011b\7f\2\2\u011b"+ - "\u011c\7u\2\2\u011c\u011d\7Y\2\2\u011d\u011e\7k\2\2\u011e\u011f\7v\2\2"+ - "\u011f\u0120\7j\2\2\u0120:\3\2\2\2\u0121\u0122\7?\2\2\u0122<\3\2\2\2\u0123"+ - "\u0124\7g\2\2\u0124\u0125\7s\2\2\u0125>\3\2\2\2\u0126\u0127\7@\2\2\u0127"+ - "@\3\2\2\2\u0128\u0129\7i\2\2\u0129\u012a\7v\2\2\u012aB\3\2\2\2\u012b\u012c"+ - "\7@\2\2\u012c\u012d\7?\2\2\u012dD\3\2\2\2\u012e\u012f\7i\2\2\u012f\u0130"+ - "\7g\2\2\u0130F\3\2\2\2\u0131\u0132\7i\2\2\u0132\u0133\7v\2\2\u0133\u0134"+ - "\7g\2\2\u0134H\3\2\2\2\u0135\u0136\7>\2\2\u0136J\3\2\2\2\u0137\u0138\7"+ - "n\2\2\u0138\u0139\7v\2\2\u0139L\3\2\2\2\u013a\u013b\7>\2\2\u013b\u013c"+ - "\7?\2\2\u013cN\3\2\2\2\u013d\u013e\7n\2\2\u013e\u013f\7g\2\2\u013fP\3"+ - "\2\2\2\u0140\u0141\7n\2\2\u0141\u0142\7v\2\2\u0142\u0143\7g\2\2\u0143"+ - "R\3\2\2\2\u0144\u0145\7>\2\2\u0145\u0146\7@\2\2\u0146T\3\2\2\2\u0147\u0148"+ - "\7#\2\2\u0148\u0149\7?\2\2\u0149V\3\2\2\2\u014a\u014b\7p\2\2\u014b\u014c"+ - "\7g\2\2\u014cX\3\2\2\2\u014d\u014e\7k\2\2\u014e\u014f\7g\2\2\u014f\u0150"+ - "\7s\2\2\u0150Z\3\2\2\2\u0151\u0152\7<\2\2\u0152\u0156\t\2\2\2\u0153\u0155"+ - "\t\3\2\2\u0154\u0153\3\2\2\2\u0155\u0158\3\2\2\2\u0156\u0154\3\2\2\2\u0156"+ - "\u0157\3\2\2\2\u0157\\\3\2\2\2\u0158\u0156\3\2\2\2\u0159\u015d\t\2\2\2"+ - "\u015a\u015c\t\4\2\2\u015b\u015a\3\2\2\2\u015c\u015f\3\2\2\2\u015d\u015b"+ - "\3\2\2\2\u015d\u015e\3\2\2\2\u015e^\3\2\2\2\u015f\u015d\3\2\2\2\u0160"+ - "\u0161\7v\2\2\u0161\u0162\7t\2\2\u0162\u0163\7w\2\2\u0163\u016a\7g\2\2"+ - "\u0164\u0165\7h\2\2\u0165\u0166\7c\2\2\u0166\u0167\7n\2\2\u0167\u0168"+ - "\7u\2\2\u0168\u016a\7g\2\2\u0169\u0160\3\2\2\2\u0169\u0164\3\2\2\2\u016a"+ - "`\3\2\2\2\u016b\u016d\t\5\2\2\u016c\u016b\3\2\2\2\u016d\u016e\3\2\2\2"+ - "\u016e\u016c\3\2\2\2\u016e\u016f\3\2\2\2\u016f\u0171\3\2\2\2\u0170\u0172"+ - "\7\60\2\2\u0171\u0170\3\2\2\2\u0171\u0172\3\2\2\2\u0172\u0176\3\2\2\2"+ - "\u0173\u0175\t\5\2\2\u0174\u0173\3\2\2\2\u0175\u0178\3\2\2\2\u0176\u0174"+ - "\3\2\2\2\u0176\u0177\3\2\2\2\u0177b\3\2\2\2\u0178\u0176\3\2\2\2\u0179"+ - "\u017f\7)\2\2\u017a\u017e\n\6\2\2\u017b\u017c\7)\2\2\u017c\u017e\7)\2"+ - "\2\u017d\u017a\3\2\2\2\u017d\u017b\3\2\2\2\u017e\u0181\3\2\2\2\u017f\u017d"+ - "\3\2\2\2\u017f\u0180\3\2\2\2\u0180\u0182\3\2\2\2\u0181\u017f\3\2\2\2\u0182"+ - "\u0183\7)\2\2\u0183d\3\2\2\2\u0184\u0185\t\7\2\2\u0185\u0186\3\2\2\2\u0186"+ - "\u0187\b\63\2\2\u0187f\3\2\2\2\13\2\u0156\u015d\u0169\u016e\u0171\u0176"+ - "\u017d\u017f\3\b\2\2"; + "U,W-Y.[/]\60_\61a\62c\63e\64g\65i\66k\67m8o9q:\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\"\""+ + "\u01be\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\3s\3\2\2\2\5z\3\2\2\2\7|\3\2\2\2\t~\3"+ + "\2\2\2\13\u0084\3\2\2\2\r\u008a\3\2\2\2\17\u008c\3\2\2\2\21\u008e\3\2"+ + "\2\2\23\u0094\3\2\2\2\25\u0099\3\2\2\2\27\u009c\3\2\2\2\31\u00a0\3\2\2"+ + "\2\33\u00a4\3\2\2\2\35\u00a7\3\2\2\2\37\u00af\3\2\2\2!\u00b2\3\2\2\2#"+ + "\u00b7\3\2\2\2%\u00be\3\2\2\2\'\u00c8\3\2\2\2)\u00d0\3\2\2\2+\u00d6\3"+ + "\2\2\2-\u00de\3\2\2\2/\u00e9\3\2\2\2\61\u00f2\3\2\2\2\63\u00f7\3\2\2\2"+ + "\65\u00fd\3\2\2\2\67\u0106\3\2\2\29\u0110\3\2\2\2;\u011b\3\2\2\2=\u0127"+ + "\3\2\2\2?\u0130\3\2\2\2A\u013a\3\2\2\2C\u013c\3\2\2\2E\u013f\3\2\2\2G"+ + "\u0141\3\2\2\2I\u0144\3\2\2\2K\u0147\3\2\2\2M\u014a\3\2\2\2O\u014e\3\2"+ + "\2\2Q\u0150\3\2\2\2S\u0153\3\2\2\2U\u0156\3\2\2\2W\u0159\3\2\2\2Y\u015d"+ + "\3\2\2\2[\u0160\3\2\2\2]\u0163\3\2\2\2_\u0166\3\2\2\2a\u016a\3\2\2\2c"+ + "\u0172\3\2\2\2e\u0182\3\2\2\2g\u018d\3\2\2\2i\u0190\3\2\2\2k\u019b\3\2"+ + "\2\2m\u01a2\3\2\2\2o\u01a4\3\2\2\2q\u01af\3\2\2\2st\7u\2\2tu\7g\2\2uv"+ + "\7n\2\2vw\7g\2\2wx\7e\2\2xy\7v\2\2y\4\3\2\2\2z{\7*\2\2{\6\3\2\2\2|}\7"+ + "+\2\2}\b\3\2\2\2~\177\7y\2\2\177\u0080\7j\2\2\u0080\u0081\7g\2\2\u0081"+ + "\u0082\7t\2\2\u0082\u0083\7g\2\2\u0083\n\3\2\2\2\u0084\u0085\7h\2\2\u0085"+ + "\u0086\7g\2\2\u0086\u0087\7v\2\2\u0087\u0088\7e\2\2\u0088\u0089\7j\2\2"+ + "\u0089\f\3\2\2\2\u008a\u008b\7.\2\2\u008b\16\3\2\2\2\u008c\u008d\7-\2"+ + "\2\u008d\20\3\2\2\2\u008e\u008f\7s\2\2\u008f\u0090\7w\2\2\u0090\u0091"+ + "\7g\2\2\u0091\u0092\7t\2\2\u0092\u0093\7{\2\2\u0093\22\3\2\2\2\u0094\u0095"+ + "\7n\2\2\u0095\u0096\7c\2\2\u0096\u0097\7|\2\2\u0097\u0098\7{\2\2\u0098"+ + "\24\3\2\2\2\u0099\u009a\7q\2\2\u009a\u009b\7t\2\2\u009b\26\3\2\2\2\u009c"+ + "\u009d\7c\2\2\u009d\u009e\7p\2\2\u009e\u009f\7f\2\2\u009f\30\3\2\2\2\u00a0"+ + "\u00a1\7p\2\2\u00a1\u00a2\7q\2\2\u00a2\u00a3\7v\2\2\u00a3\32\3\2\2\2\u00a4"+ + "\u00a5\7k\2\2\u00a5\u00a6\7p\2\2\u00a6\34\3\2\2\2\u00a7\u00a8\7d\2\2\u00a8"+ + "\u00a9\7g\2\2\u00a9\u00aa\7v\2\2\u00aa\u00ab\7y\2\2\u00ab\u00ac\7g\2\2"+ + "\u00ac\u00ad\7g\2\2\u00ad\u00ae\7p\2\2\u00ae\36\3\2\2\2\u00af\u00b0\7"+ + "k\2\2\u00b0\u00b1\7u\2\2\u00b1 \3\2\2\2\u00b2\u00b3\7p\2\2\u00b3\u00b4"+ + "\7w\2\2\u00b4\u00b5\7n\2\2\u00b5\u00b6\7n\2\2\u00b6\"\3\2\2\2\u00b7\u00b8"+ + "\7k\2\2\u00b8\u00b9\7u\2\2\u00b9\u00ba\7P\2\2\u00ba\u00bb\7w\2\2\u00bb"+ + "\u00bc\7n\2\2\u00bc\u00bd\7n\2\2\u00bd$\3\2\2\2\u00be\u00bf\7k\2\2\u00bf"+ + "\u00c0\7u\2\2\u00c0\u00c1\7P\2\2\u00c1\u00c2\7q\2\2\u00c2\u00c3\7v\2\2"+ + "\u00c3\u00c4\7P\2\2\u00c4\u00c5\7w\2\2\u00c5\u00c6\7n\2\2\u00c6\u00c7"+ + "\7n\2\2\u00c7&\3\2\2\2\u00c8\u00c9\7p\2\2\u00c9\u00ca\7q\2\2\u00ca\u00cb"+ + "\7v\2\2\u00cb\u00cc\7P\2\2\u00cc\u00cd\7w\2\2\u00cd\u00ce\7n\2\2\u00ce"+ + "\u00cf\7n\2\2\u00cf(\3\2\2\2\u00d0\u00d1\7g\2\2\u00d1\u00d2\7o\2\2\u00d2"+ + "\u00d3\7r\2\2\u00d3\u00d4\7v\2\2\u00d4\u00d5\7{\2\2\u00d5*\3\2\2\2\u00d6"+ + "\u00d7\7k\2\2\u00d7\u00d8\7u\2\2\u00d8\u00d9\7G\2\2\u00d9\u00da\7o\2\2"+ + "\u00da\u00db\7r\2\2\u00db\u00dc\7v\2\2\u00dc\u00dd\7{\2\2\u00dd,\3\2\2"+ + "\2\u00de\u00df\7k\2\2\u00df\u00e0\7u\2\2\u00e0\u00e1\7P\2\2\u00e1\u00e2"+ + "\7q\2\2\u00e2\u00e3\7v\2\2\u00e3\u00e4\7G\2\2\u00e4\u00e5\7o\2\2\u00e5"+ + "\u00e6\7r\2\2\u00e6\u00e7\7v\2\2\u00e7\u00e8\7{\2\2\u00e8.\3\2\2\2\u00e9"+ + "\u00ea\7p\2\2\u00ea\u00eb\7q\2\2\u00eb\u00ec\7v\2\2\u00ec\u00ed\7G\2\2"+ + "\u00ed\u00ee\7o\2\2\u00ee\u00ef\7r\2\2\u00ef\u00f0\7v\2\2\u00f0\u00f1"+ + "\7{\2\2\u00f1\60\3\2\2\2\u00f2\u00f3\7n\2\2\u00f3\u00f4\7k\2\2\u00f4\u00f5"+ + "\7m\2\2\u00f5\u00f6\7g\2\2\u00f6\62\3\2\2\2\u00f7\u00f8\7k\2\2\u00f8\u00f9"+ + "\7n\2\2\u00f9\u00fa\7k\2\2\u00fa\u00fb\7m\2\2\u00fb\u00fc\7g\2\2\u00fc"+ + "\64\3\2\2\2\u00fd\u00fe\7e\2\2\u00fe\u00ff\7q\2\2\u00ff\u0100\7p\2\2\u0100"+ + "\u0101\7v\2\2\u0101\u0102\7c\2\2\u0102\u0103\7k\2\2\u0103\u0104\7p\2\2"+ + "\u0104\u0105\7u\2\2\u0105\66\3\2\2\2\u0106\u0107\7k\2\2\u0107\u0108\7"+ + "e\2\2\u0108\u0109\7q\2\2\u0109\u010a\7p\2\2\u010a\u010b\7v\2\2\u010b\u010c"+ + "\7c\2\2\u010c\u010d\7k\2\2\u010d\u010e\7p\2\2\u010e\u010f\7u\2\2\u010f"+ + "8\3\2\2\2\u0110\u0111\7u\2\2\u0111\u0112\7v\2\2\u0112\u0113\7c\2\2\u0113"+ + "\u0114\7t\2\2\u0114\u0115\7v\2\2\u0115\u0116\7u\2\2\u0116\u0117\7Y\2\2"+ + "\u0117\u0118\7k\2\2\u0118\u0119\7v\2\2\u0119\u011a\7j\2\2\u011a:\3\2\2"+ + "\2\u011b\u011c\7k\2\2\u011c\u011d\7u\2\2\u011d\u011e\7v\2\2\u011e\u011f"+ + "\7c\2\2\u011f\u0120\7t\2\2\u0120\u0121\7v\2\2\u0121\u0122\7u\2\2\u0122"+ + "\u0123\7Y\2\2\u0123\u0124\7k\2\2\u0124\u0125\7v\2\2\u0125\u0126\7j\2\2"+ + "\u0126<\3\2\2\2\u0127\u0128\7g\2\2\u0128\u0129\7p\2\2\u0129\u012a\7f\2"+ + "\2\u012a\u012b\7u\2\2\u012b\u012c\7Y\2\2\u012c\u012d\7k\2\2\u012d\u012e"+ + "\7v\2\2\u012e\u012f\7j\2\2\u012f>\3\2\2\2\u0130\u0131\7k\2\2\u0131\u0132"+ + "\7g\2\2\u0132\u0133\7p\2\2\u0133\u0134\7f\2\2\u0134\u0135\7u\2\2\u0135"+ + "\u0136\7Y\2\2\u0136\u0137\7k\2\2\u0137\u0138\7v\2\2\u0138\u0139\7j\2\2"+ + "\u0139@\3\2\2\2\u013a\u013b\7?\2\2\u013bB\3\2\2\2\u013c\u013d\7g\2\2\u013d"+ + "\u013e\7s\2\2\u013eD\3\2\2\2\u013f\u0140\7@\2\2\u0140F\3\2\2\2\u0141\u0142"+ + "\7i\2\2\u0142\u0143\7v\2\2\u0143H\3\2\2\2\u0144\u0145\7@\2\2\u0145\u0146"+ + "\7?\2\2\u0146J\3\2\2\2\u0147\u0148\7i\2\2\u0148\u0149\7g\2\2\u0149L\3"+ + "\2\2\2\u014a\u014b\7i\2\2\u014b\u014c\7v\2\2\u014c\u014d\7g\2\2\u014d"+ + "N\3\2\2\2\u014e\u014f\7>\2\2\u014fP\3\2\2\2\u0150\u0151\7n\2\2\u0151\u0152"+ + "\7v\2\2\u0152R\3\2\2\2\u0153\u0154\7>\2\2\u0154\u0155\7?\2\2\u0155T\3"+ + "\2\2\2\u0156\u0157\7n\2\2\u0157\u0158\7g\2\2\u0158V\3\2\2\2\u0159\u015a"+ + "\7n\2\2\u015a\u015b\7v\2\2\u015b\u015c\7g\2\2\u015cX\3\2\2\2\u015d\u015e"+ + "\7>\2\2\u015e\u015f\7@\2\2\u015fZ\3\2\2\2\u0160\u0161\7#\2\2\u0161\u0162"+ + "\7?\2\2\u0162\\\3\2\2\2\u0163\u0164\7p\2\2\u0164\u0165\7g\2\2\u0165^\3"+ + "\2\2\2\u0166\u0167\7k\2\2\u0167\u0168\7g\2\2\u0168\u0169\7s\2\2\u0169"+ + "`\3\2\2\2\u016a\u016b\7<\2\2\u016b\u016f\t\2\2\2\u016c\u016e\t\3\2\2\u016d"+ + "\u016c\3\2\2\2\u016e\u0171\3\2\2\2\u016f\u016d\3\2\2\2\u016f\u0170\3\2"+ + "\2\2\u0170b\3\2\2\2\u0171\u016f\3\2\2\2\u0172\u0176\t\2\2\2\u0173\u0175"+ + "\t\4\2\2\u0174\u0173\3\2\2\2\u0175\u0178\3\2\2\2\u0176\u0174\3\2\2\2\u0176"+ + "\u0177\3\2\2\2\u0177d\3\2\2\2\u0178\u0176\3\2\2\2\u0179\u017a\7v\2\2\u017a"+ + "\u017b\7t\2\2\u017b\u017c\7w\2\2\u017c\u0183\7g\2\2\u017d\u017e\7h\2\2"+ + "\u017e\u017f\7c\2\2\u017f\u0180\7n\2\2\u0180\u0181\7u\2\2\u0181\u0183"+ + "\7g\2\2\u0182\u0179\3\2\2\2\u0182\u017d\3\2\2\2\u0183f\3\2\2\2\u0184\u0186"+ + "\7/\2\2\u0185\u0184\3\2\2\2\u0185\u0186\3\2\2\2\u0186\u0187\3\2\2\2\u0187"+ + "\u018e\5i\65\2\u0188\u018a\7/\2\2\u0189\u0188\3\2\2\2\u0189\u018a\3\2"+ + "\2\2\u018a\u018b\3\2\2\2\u018b\u018e\5k\66\2\u018c\u018e\5m\67\2\u018d"+ + "\u0185\3\2\2\2\u018d\u0189\3\2\2\2\u018d\u018c\3\2\2\2\u018eh\3\2\2\2"+ + "\u018f\u0191\t\5\2\2\u0190\u018f\3\2\2\2\u0191\u0192\3\2\2\2\u0192\u0190"+ + "\3\2\2\2\u0192\u0193\3\2\2\2\u0193\u0194\3\2\2\2\u0194\u0198\7\60\2\2"+ + "\u0195\u0197\t\5\2\2\u0196\u0195\3\2\2\2\u0197\u019a\3\2\2\2\u0198\u0196"+ + "\3\2\2\2\u0198\u0199\3\2\2\2\u0199j\3\2\2\2\u019a\u0198\3\2\2\2\u019b"+ + "\u019f\t\6\2\2\u019c\u019e\t\5\2\2\u019d\u019c\3\2\2\2\u019e\u01a1\3\2"+ + "\2\2\u019f\u019d\3\2\2\2\u019f\u01a0\3\2\2\2\u01a0l\3\2\2\2\u01a1\u019f"+ + "\3\2\2\2\u01a2\u01a3\7\62\2\2\u01a3n\3\2\2\2\u01a4\u01aa\7)\2\2\u01a5"+ + "\u01a9\n\7\2\2\u01a6\u01a7\7)\2\2\u01a7\u01a9\7)\2\2\u01a8\u01a5\3\2\2"+ + "\2\u01a8\u01a6\3\2\2\2\u01a9\u01ac\3\2\2\2\u01aa\u01a8\3\2\2\2\u01aa\u01ab"+ + "\3\2\2\2\u01ab\u01ad\3\2\2\2\u01ac\u01aa\3\2\2\2\u01ad\u01ae\7)\2\2\u01ae"+ + "p\3\2\2\2\u01af\u01b0\t\b\2\2\u01b0\u01b1\3\2\2\2\u01b1\u01b2\b9\2\2\u01b2"+ + "r\3\2\2\2\16\2\u016f\u0176\u0182\u0185\u0189\u018d\u0192\u0198\u019f\u01a8"+ + "\u01aa\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 174ef1964..482b47e62 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 @@ -42,53 +42,63 @@ T__40=41 T__41=42 T__42=43 T__43=44 -INPUT_VARIABLE=45 -PATH_VARIABLE=46 -BOOLEAN_LITERAL=47 -NUMBER_LITERAL=48 -STRING_LITERAL=49 -WS=50 +T__44=45 +T__45=46 +T__46=47 +INPUT_VARIABLE=48 +PATH_VARIABLE=49 +BOOLEAN_LITERAL=50 +NUMBER_LITERAL=51 +DOUBLE=52 +INT=53 +ZERO=54 +STRING_LITERAL=55 +WS=56 'select'=1 '('=2 ')'=3 'where'=4 'fetch'=5 ','=6 -'or'=7 -'and'=8 -'not'=9 -'in'=10 -'between'=11 -'is'=12 -'null'=13 -'isNull'=14 -'isNotNull'=15 -'notNull'=16 -'empty'=17 -'isEmpty'=18 -'isNotEmpty'=19 -'notEmpty'=20 -'like'=21 -'ilike'=22 -'contains'=23 -'icontains'=24 -'startsWith'=25 -'istartsWith'=26 -'endsWith'=27 -'iendsWith'=28 -'='=29 -'eq'=30 -'>'=31 -'gt'=32 -'>='=33 -'ge'=34 -'gte'=35 -'<'=36 -'lt'=37 -'<='=38 -'le'=39 -'lte'=40 -'<>'=41 -'!='=42 -'ne'=43 -'ieq'=44 +'+'=7 +'query'=8 +'lazy'=9 +'or'=10 +'and'=11 +'not'=12 +'in'=13 +'between'=14 +'is'=15 +'null'=16 +'isNull'=17 +'isNotNull'=18 +'notNull'=19 +'empty'=20 +'isEmpty'=21 +'isNotEmpty'=22 +'notEmpty'=23 +'like'=24 +'ilike'=25 +'contains'=26 +'icontains'=27 +'startsWith'=28 +'istartsWith'=29 +'endsWith'=30 +'iendsWith'=31 +'='=32 +'eq'=33 +'>'=34 +'gt'=35 +'>='=36 +'ge'=37 +'gte'=38 +'<'=39 +'lt'=40 +'<='=41 +'le'=42 +'lte'=43 +'<>'=44 +'!='=45 +'ne'=46 +'ieq'=47 +'0'=54 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 284ef0b49..ee3c2eae0 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 @@ -87,6 +87,66 @@ public interface EQLListener extends ParseTreeListener { * @param ctx the parse tree */ void exitFetch_property(EQLParser.Fetch_propertyContext ctx); + /** + * Enter a parse tree produced by {@link EQLParser#fetch_query_hint}. + * @param ctx the parse tree + */ + void enterFetch_query_hint(EQLParser.Fetch_query_hintContext ctx); + /** + * Exit a parse tree produced by {@link EQLParser#fetch_query_hint}. + * @param ctx the parse tree + */ + void exitFetch_query_hint(EQLParser.Fetch_query_hintContext ctx); + /** + * Enter a parse tree produced by {@link EQLParser#fetch_lazy_hint}. + * @param ctx the parse tree + */ + void enterFetch_lazy_hint(EQLParser.Fetch_lazy_hintContext ctx); + /** + * Exit a parse tree produced by {@link EQLParser#fetch_lazy_hint}. + * @param ctx the parse tree + */ + void exitFetch_lazy_hint(EQLParser.Fetch_lazy_hintContext ctx); + /** + * Enter a parse tree produced by {@link EQLParser#fetch_option}. + * @param ctx the parse tree + */ + void enterFetch_option(EQLParser.Fetch_optionContext ctx); + /** + * Exit a parse tree produced by {@link EQLParser#fetch_option}. + * @param ctx the parse tree + */ + void exitFetch_option(EQLParser.Fetch_optionContext ctx); + /** + * Enter a parse tree produced by {@link EQLParser#fetch_query_option}. + * @param ctx the parse tree + */ + void enterFetch_query_option(EQLParser.Fetch_query_optionContext ctx); + /** + * Exit a parse tree produced by {@link EQLParser#fetch_query_option}. + * @param ctx the parse tree + */ + void exitFetch_query_option(EQLParser.Fetch_query_optionContext ctx); + /** + * Enter a parse tree produced by {@link EQLParser#fetch_lazy_option}. + * @param ctx the parse tree + */ + void enterFetch_lazy_option(EQLParser.Fetch_lazy_optionContext ctx); + /** + * Exit a parse tree produced by {@link EQLParser#fetch_lazy_option}. + * @param ctx the parse tree + */ + void exitFetch_lazy_option(EQLParser.Fetch_lazy_optionContext ctx); + /** + * Enter a parse tree produced by {@link EQLParser#fetch_batch_size}. + * @param ctx the parse tree + */ + void enterFetch_batch_size(EQLParser.Fetch_batch_sizeContext ctx); + /** + * Exit a parse tree produced by {@link EQLParser#fetch_batch_size}. + * @param ctx the parse tree + */ + void exitFetch_batch_size(EQLParser.Fetch_batch_sizeContext ctx); /** * Enter a parse tree produced by {@link EQLParser#conditional_expression}. * @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 8f0c64ac0..a2764d4f7 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 @@ -22,45 +22,49 @@ public class EQLParser extends Parser { T__17=18, T__18=19, T__19=20, T__20=21, T__21=22, T__22=23, T__23=24, 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, INPUT_VARIABLE=45, - PATH_VARIABLE=46, BOOLEAN_LITERAL=47, NUMBER_LITERAL=48, STRING_LITERAL=49, - WS=50; + 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, INPUT_VARIABLE=48, PATH_VARIABLE=49, BOOLEAN_LITERAL=50, + NUMBER_LITERAL=51, DOUBLE=52, INT=53, ZERO=54, STRING_LITERAL=55, WS=56; public static final int RULE_select_statement = 0, RULE_select_clause = 1, RULE_fetch_clause = 2, RULE_where_clause = 3, RULE_fetch_path = 4, RULE_fetch_property_set = 5, - RULE_fetch_property_group = 6, RULE_fetch_property = 7, RULE_conditional_expression = 8, - RULE_conditional_term = 9, RULE_conditional_factor = 10, RULE_conditional_primary = 11, - RULE_any_expression = 12, RULE_in_expression = 13, RULE_in_value = 14, - RULE_between_expression = 15, RULE_propertyBetween_expression = 16, RULE_isNull_expression = 17, - RULE_isNotNull_expression = 18, RULE_isEmpty_expression = 19, RULE_isNotEmpty_expression = 20, - RULE_like_expression = 21, RULE_like_op = 22, RULE_comparison_expression = 23, - RULE_comparison_operator = 24, RULE_value_expression = 25, RULE_literal = 26; + RULE_fetch_property_group = 6, RULE_fetch_property = 7, RULE_fetch_query_hint = 8, + RULE_fetch_lazy_hint = 9, RULE_fetch_option = 10, RULE_fetch_query_option = 11, + RULE_fetch_lazy_option = 12, RULE_fetch_batch_size = 13, RULE_conditional_expression = 14, + RULE_conditional_term = 15, RULE_conditional_factor = 16, RULE_conditional_primary = 17, + RULE_any_expression = 18, RULE_in_expression = 19, RULE_in_value = 20, + RULE_between_expression = 21, RULE_propertyBetween_expression = 22, RULE_isNull_expression = 23, + RULE_isNotNull_expression = 24, RULE_isEmpty_expression = 25, RULE_isNotEmpty_expression = 26, + RULE_like_expression = 27, RULE_like_op = 28, RULE_comparison_expression = 29, + RULE_comparison_operator = 30, RULE_value_expression = 31, RULE_literal = 32; public static final String[] ruleNames = { "select_statement", "select_clause", "fetch_clause", "where_clause", "fetch_path", - "fetch_property_set", "fetch_property_group", "fetch_property", "conditional_expression", - "conditional_term", "conditional_factor", "conditional_primary", "any_expression", - "in_expression", "in_value", "between_expression", "propertyBetween_expression", - "isNull_expression", "isNotNull_expression", "isEmpty_expression", "isNotEmpty_expression", + "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", "in_expression", "in_value", + "between_expression", "propertyBetween_expression", "isNull_expression", + "isNotNull_expression", "isEmpty_expression", "isNotEmpty_expression", "like_expression", "like_op", "comparison_expression", "comparison_operator", "value_expression", "literal" }; private static final String[] _LITERAL_NAMES = { - null, "'select'", "'('", "')'", "'where'", "'fetch'", "','", "'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'", "'<'", "'lt'", "'<='", "'le'", "'lte'", "'<>'", "'!='", "'ne'", - "'ieq'" + null, "'select'", "'('", "')'", "'where'", "'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'", "'<'", "'lt'", "'<='", "'le'", "'lte'", "'<>'", + "'!='", "'ne'", "'ieq'", null, null, null, null, null, null, "'0'" }; private static final String[] _SYMBOLIC_NAMES = { 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, null, null, null, null, null, null, "INPUT_VARIABLE", - "PATH_VARIABLE", "BOOLEAN_LITERAL", "NUMBER_LITERAL", "STRING_LITERAL", - "WS" + 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" }; public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES); @@ -145,34 +149,34 @@ public class EQLParser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(55); + setState(67); _la = _input.LA(1); if (_la==T__0) { { - setState(54); + setState(66); select_clause(); } } - setState(60); + setState(72); _errHandler.sync(this); _la = _input.LA(1); while (_la==T__4) { { { - setState(57); + setState(69); fetch_clause(); } } - setState(62); + setState(74); _errHandler.sync(this); _la = _input.LA(1); } - setState(64); + setState(76); _la = _input.LA(1); if (_la==T__3) { { - setState(63); + setState(75); where_clause(); } } @@ -214,13 +218,13 @@ public class EQLParser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(66); + setState(78); match(T__0); - setState(67); + setState(79); match(T__1); - setState(68); + setState(80); fetch_property_group(); - setState(69); + setState(81); match(T__2); } } @@ -259,7 +263,7 @@ public class EQLParser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(71); + setState(83); fetch_path(); } } @@ -298,9 +302,9 @@ public class EQLParser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(73); + setState(85); match(T__3); - setState(74); + setState(86); conditional_expression(); } } @@ -317,6 +321,9 @@ public class EQLParser extends Parser { public static class Fetch_pathContext extends ParserRuleContext { public TerminalNode PATH_VARIABLE() { return getToken(EQLParser.PATH_VARIABLE, 0); } + public Fetch_optionContext fetch_option() { + return getRuleContext(Fetch_optionContext.class,0); + } public Fetch_property_setContext fetch_property_set() { return getRuleContext(Fetch_property_setContext.class,0); } @@ -341,15 +348,24 @@ public class EQLParser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(76); + setState(88); match(T__4); - setState(77); + setState(90); + _la = _input.LA(1); + if (_la==T__7 || _la==T__8) { + { + setState(89); + fetch_option(); + } + } + + setState(92); match(PATH_VARIABLE); - setState(79); + setState(94); _la = _input.LA(1); if (_la==T__1) { { - setState(78); + setState(93); fetch_property_set(); } } @@ -391,11 +407,11 @@ public class EQLParser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(81); + setState(96); match(T__1); - setState(82); + setState(97); fetch_property_group(); - setState(83); + setState(98); match(T__2); } } @@ -438,21 +454,21 @@ public class EQLParser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(85); + setState(100); fetch_property(); - setState(90); + setState(105); _errHandler.sync(this); _la = _input.LA(1); while (_la==T__5) { { { - setState(86); + setState(101); match(T__5); - setState(87); + setState(102); fetch_property(); } } - setState(92); + setState(107); _errHandler.sync(this); _la = _input.LA(1); } @@ -471,6 +487,12 @@ public class EQLParser extends Parser { public static class Fetch_propertyContext extends ParserRuleContext { public TerminalNode PATH_VARIABLE() { return getToken(EQLParser.PATH_VARIABLE, 0); } + public Fetch_query_hintContext fetch_query_hint() { + return getRuleContext(Fetch_query_hintContext.class,0); + } + public Fetch_lazy_hintContext fetch_lazy_hint() { + return getRuleContext(Fetch_lazy_hintContext.class,0); + } public Fetch_propertyContext(ParserRuleContext parent, int invokingState) { super(parent, invokingState); } @@ -488,11 +510,308 @@ public class EQLParser extends Parser { public final Fetch_propertyContext fetch_property() throws RecognitionException { Fetch_propertyContext _localctx = new Fetch_propertyContext(_ctx, getState()); enterRule(_localctx, 14, RULE_fetch_property); + try { + setState(111); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,6,_ctx) ) { + case 1: + enterOuterAlt(_localctx, 1); + { + setState(108); + match(PATH_VARIABLE); + } + break; + case 2: + enterOuterAlt(_localctx, 2); + { + setState(109); + fetch_query_hint(); + } + break; + case 3: + enterOuterAlt(_localctx, 3); + { + setState(110); + fetch_lazy_hint(); + } + break; + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class Fetch_query_hintContext extends ParserRuleContext { + public Fetch_query_optionContext fetch_query_option() { + return getRuleContext(Fetch_query_optionContext.class,0); + } + public Fetch_query_hintContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_fetch_query_hint; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof EQLListener ) ((EQLListener)listener).enterFetch_query_hint(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof EQLListener ) ((EQLListener)listener).exitFetch_query_hint(this); + } + } + + public final Fetch_query_hintContext fetch_query_hint() throws RecognitionException { + Fetch_query_hintContext _localctx = new Fetch_query_hintContext(_ctx, getState()); + enterRule(_localctx, 16, RULE_fetch_query_hint); try { enterOuterAlt(_localctx, 1); { - setState(93); - match(PATH_VARIABLE); + setState(113); + match(T__6); + setState(114); + fetch_query_option(); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class Fetch_lazy_hintContext extends ParserRuleContext { + public Fetch_lazy_optionContext fetch_lazy_option() { + return getRuleContext(Fetch_lazy_optionContext.class,0); + } + public Fetch_lazy_hintContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_fetch_lazy_hint; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof EQLListener ) ((EQLListener)listener).enterFetch_lazy_hint(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof EQLListener ) ((EQLListener)listener).exitFetch_lazy_hint(this); + } + } + + public final Fetch_lazy_hintContext fetch_lazy_hint() throws RecognitionException { + Fetch_lazy_hintContext _localctx = new Fetch_lazy_hintContext(_ctx, getState()); + enterRule(_localctx, 18, RULE_fetch_lazy_hint); + try { + enterOuterAlt(_localctx, 1); + { + setState(116); + match(T__6); + setState(117); + fetch_lazy_option(); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class Fetch_optionContext extends ParserRuleContext { + public Fetch_query_optionContext fetch_query_option() { + return getRuleContext(Fetch_query_optionContext.class,0); + } + public Fetch_lazy_optionContext fetch_lazy_option() { + return getRuleContext(Fetch_lazy_optionContext.class,0); + } + public Fetch_optionContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_fetch_option; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof EQLListener ) ((EQLListener)listener).enterFetch_option(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof EQLListener ) ((EQLListener)listener).exitFetch_option(this); + } + } + + public final Fetch_optionContext fetch_option() throws RecognitionException { + Fetch_optionContext _localctx = new Fetch_optionContext(_ctx, getState()); + enterRule(_localctx, 20, RULE_fetch_option); + try { + setState(121); + switch (_input.LA(1)) { + case T__7: + enterOuterAlt(_localctx, 1); + { + setState(119); + fetch_query_option(); + } + break; + case T__8: + enterOuterAlt(_localctx, 2); + { + setState(120); + fetch_lazy_option(); + } + break; + default: + throw new NoViableAltException(this); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class Fetch_query_optionContext extends ParserRuleContext { + public Fetch_batch_sizeContext fetch_batch_size() { + return getRuleContext(Fetch_batch_sizeContext.class,0); + } + public Fetch_query_optionContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_fetch_query_option; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof EQLListener ) ((EQLListener)listener).enterFetch_query_option(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof EQLListener ) ((EQLListener)listener).exitFetch_query_option(this); + } + } + + public final Fetch_query_optionContext fetch_query_option() throws RecognitionException { + Fetch_query_optionContext _localctx = new Fetch_query_optionContext(_ctx, getState()); + enterRule(_localctx, 22, RULE_fetch_query_option); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(123); + match(T__7); + setState(125); + _la = _input.LA(1); + if (_la==T__1) { + { + setState(124); + fetch_batch_size(); + } + } + + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class Fetch_lazy_optionContext extends ParserRuleContext { + public Fetch_batch_sizeContext fetch_batch_size() { + return getRuleContext(Fetch_batch_sizeContext.class,0); + } + public Fetch_lazy_optionContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_fetch_lazy_option; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof EQLListener ) ((EQLListener)listener).enterFetch_lazy_option(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof EQLListener ) ((EQLListener)listener).exitFetch_lazy_option(this); + } + } + + public final Fetch_lazy_optionContext fetch_lazy_option() throws RecognitionException { + Fetch_lazy_optionContext _localctx = new Fetch_lazy_optionContext(_ctx, getState()); + enterRule(_localctx, 24, RULE_fetch_lazy_option); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(127); + match(T__8); + setState(129); + _la = _input.LA(1); + if (_la==T__1) { + { + setState(128); + fetch_batch_size(); + } + } + + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class Fetch_batch_sizeContext extends ParserRuleContext { + public TerminalNode NUMBER_LITERAL() { return getToken(EQLParser.NUMBER_LITERAL, 0); } + public Fetch_batch_sizeContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_fetch_batch_size; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof EQLListener ) ((EQLListener)listener).enterFetch_batch_size(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof EQLListener ) ((EQLListener)listener).exitFetch_batch_size(this); + } + } + + public final Fetch_batch_sizeContext fetch_batch_size() throws RecognitionException { + Fetch_batch_sizeContext _localctx = new Fetch_batch_sizeContext(_ctx, getState()); + enterRule(_localctx, 26, RULE_fetch_batch_size); + try { + enterOuterAlt(_localctx, 1); + { + setState(131); + match(T__1); + setState(132); + match(NUMBER_LITERAL); + setState(133); + match(T__2); } } catch (RecognitionException re) { @@ -529,28 +848,28 @@ public class EQLParser extends Parser { public final Conditional_expressionContext conditional_expression() throws RecognitionException { Conditional_expressionContext _localctx = new Conditional_expressionContext(_ctx, getState()); - enterRule(_localctx, 16, RULE_conditional_expression); + enterRule(_localctx, 28, RULE_conditional_expression); int _la; try { enterOuterAlt(_localctx, 1); { { - setState(95); + setState(135); conditional_term(); } - setState(100); + setState(140); _errHandler.sync(this); _la = _input.LA(1); - while (_la==T__6) { + while (_la==T__9) { { { - setState(96); - match(T__6); - setState(97); + setState(136); + match(T__9); + setState(137); conditional_term(); } } - setState(102); + setState(142); _errHandler.sync(this); _la = _input.LA(1); } @@ -590,28 +909,28 @@ public class EQLParser extends Parser { public final Conditional_termContext conditional_term() throws RecognitionException { Conditional_termContext _localctx = new Conditional_termContext(_ctx, getState()); - enterRule(_localctx, 18, RULE_conditional_term); + enterRule(_localctx, 30, RULE_conditional_term); int _la; try { enterOuterAlt(_localctx, 1); { { - setState(103); + setState(143); conditional_factor(); } - setState(108); + setState(148); _errHandler.sync(this); _la = _input.LA(1); - while (_la==T__7) { + while (_la==T__10) { { { - setState(104); - match(T__7); - setState(105); + setState(144); + match(T__10); + setState(145); conditional_factor(); } } - setState(110); + setState(150); _errHandler.sync(this); _la = _input.LA(1); } @@ -648,21 +967,21 @@ public class EQLParser extends Parser { public final Conditional_factorContext conditional_factor() throws RecognitionException { Conditional_factorContext _localctx = new Conditional_factorContext(_ctx, getState()); - enterRule(_localctx, 20, RULE_conditional_factor); + enterRule(_localctx, 32, RULE_conditional_factor); int _la; try { enterOuterAlt(_localctx, 1); { - setState(112); + setState(152); _la = _input.LA(1); - if (_la==T__8) { + if (_la==T__11) { { - setState(111); - match(T__8); + setState(151); + match(T__11); } } - setState(114); + setState(154); conditional_primary(); } } @@ -700,26 +1019,26 @@ public class EQLParser extends Parser { public final Conditional_primaryContext conditional_primary() throws RecognitionException { Conditional_primaryContext _localctx = new Conditional_primaryContext(_ctx, getState()); - enterRule(_localctx, 22, RULE_conditional_primary); + enterRule(_localctx, 34, RULE_conditional_primary); try { - setState(121); + setState(161); _errHandler.sync(this); - switch ( getInterpreter().adaptivePredict(_input,8,_ctx) ) { + switch ( getInterpreter().adaptivePredict(_input,13,_ctx) ) { case 1: enterOuterAlt(_localctx, 1); { - setState(116); + setState(156); any_expression(); } break; case 2: enterOuterAlt(_localctx, 2); { - setState(117); + setState(157); match(T__1); - setState(118); + setState(158); conditional_expression(); - setState(119); + setState(159); match(T__2); } break; @@ -783,82 +1102,82 @@ public class EQLParser extends Parser { public final Any_expressionContext any_expression() throws RecognitionException { Any_expressionContext _localctx = new Any_expressionContext(_ctx, getState()); - enterRule(_localctx, 24, RULE_any_expression); + enterRule(_localctx, 36, RULE_any_expression); try { - setState(136); + setState(176); _errHandler.sync(this); - switch ( getInterpreter().adaptivePredict(_input,9,_ctx) ) { + switch ( getInterpreter().adaptivePredict(_input,14,_ctx) ) { case 1: enterOuterAlt(_localctx, 1); { - setState(123); + setState(163); comparison_expression(); } break; case 2: enterOuterAlt(_localctx, 2); { - setState(124); + setState(164); like_expression(); } break; case 3: enterOuterAlt(_localctx, 3); { - setState(125); + setState(165); between_expression(); } break; case 4: enterOuterAlt(_localctx, 4); { - setState(126); + setState(166); propertyBetween_expression(); } break; case 5: enterOuterAlt(_localctx, 5); { - setState(127); + setState(167); in_expression(); } break; case 6: enterOuterAlt(_localctx, 6); { - setState(128); + setState(168); isNull_expression(); } break; case 7: enterOuterAlt(_localctx, 7); { - setState(129); + setState(169); isNotNull_expression(); } break; case 8: enterOuterAlt(_localctx, 8); { - setState(130); + setState(170); isEmpty_expression(); } break; case 9: enterOuterAlt(_localctx, 9); { - setState(131); + setState(171); isNotEmpty_expression(); } break; case 10: enterOuterAlt(_localctx, 10); { - setState(132); + setState(172); match(T__1); - setState(133); + setState(173); any_expression(); - setState(134); + setState(174); match(T__2); } break; @@ -896,15 +1215,15 @@ public class EQLParser extends Parser { public final In_expressionContext in_expression() throws RecognitionException { In_expressionContext _localctx = new In_expressionContext(_ctx, getState()); - enterRule(_localctx, 26, RULE_in_expression); + enterRule(_localctx, 38, RULE_in_expression); try { enterOuterAlt(_localctx, 1); { - setState(138); + setState(178); match(PATH_VARIABLE); - setState(139); - match(T__9); - setState(140); + setState(179); + match(T__12); + setState(180); in_value(); } } @@ -943,42 +1262,42 @@ public class EQLParser extends Parser { public final In_valueContext in_value() throws RecognitionException { In_valueContext _localctx = new In_valueContext(_ctx, getState()); - enterRule(_localctx, 28, RULE_in_value); + enterRule(_localctx, 40, RULE_in_value); int _la; try { - setState(154); + setState(194); switch (_input.LA(1)) { case INPUT_VARIABLE: enterOuterAlt(_localctx, 1); { - setState(142); + setState(182); match(INPUT_VARIABLE); } break; case T__1: enterOuterAlt(_localctx, 2); { - setState(143); + setState(183); match(T__1); - setState(144); + setState(184); value_expression(); - setState(149); + setState(189); _errHandler.sync(this); _la = _input.LA(1); while (_la==T__5) { { { - setState(145); + setState(185); match(T__5); - setState(146); + setState(186); value_expression(); } } - setState(151); + setState(191); _errHandler.sync(this); _la = _input.LA(1); } - setState(152); + setState(192); match(T__2); } break; @@ -1021,19 +1340,19 @@ public class EQLParser extends Parser { public final Between_expressionContext between_expression() throws RecognitionException { Between_expressionContext _localctx = new Between_expressionContext(_ctx, getState()); - enterRule(_localctx, 30, RULE_between_expression); + enterRule(_localctx, 42, RULE_between_expression); try { enterOuterAlt(_localctx, 1); { - setState(156); + setState(196); match(PATH_VARIABLE); - setState(157); - match(T__10); - setState(158); + setState(197); + match(T__13); + setState(198); value_expression(); - setState(159); - match(T__7); - setState(160); + setState(199); + match(T__10); + setState(200); value_expression(); } } @@ -1072,19 +1391,19 @@ public class EQLParser extends Parser { public final PropertyBetween_expressionContext propertyBetween_expression() throws RecognitionException { PropertyBetween_expressionContext _localctx = new PropertyBetween_expressionContext(_ctx, getState()); - enterRule(_localctx, 32, RULE_propertyBetween_expression); + enterRule(_localctx, 44, RULE_propertyBetween_expression); try { enterOuterAlt(_localctx, 1); { - setState(162); + setState(202); value_expression(); - setState(163); - match(T__10); - setState(164); + setState(203); + match(T__13); + setState(204); match(PATH_VARIABLE); - setState(165); - match(T__7); - setState(166); + setState(205); + match(T__10); + setState(206); match(PATH_VARIABLE); } } @@ -1117,29 +1436,29 @@ public class EQLParser extends Parser { public final IsNull_expressionContext isNull_expression() throws RecognitionException { IsNull_expressionContext _localctx = new IsNull_expressionContext(_ctx, getState()); - enterRule(_localctx, 34, RULE_isNull_expression); + enterRule(_localctx, 46, RULE_isNull_expression); try { - setState(173); + setState(213); _errHandler.sync(this); - switch ( getInterpreter().adaptivePredict(_input,12,_ctx) ) { + switch ( getInterpreter().adaptivePredict(_input,17,_ctx) ) { case 1: enterOuterAlt(_localctx, 1); { - setState(168); + setState(208); match(PATH_VARIABLE); - setState(169); - match(T__11); - setState(170); - match(T__12); + setState(209); + match(T__14); + setState(210); + match(T__15); } break; case 2: enterOuterAlt(_localctx, 2); { - setState(171); + setState(211); match(PATH_VARIABLE); - setState(172); - match(T__13); + setState(212); + match(T__16); } break; } @@ -1173,40 +1492,40 @@ public class EQLParser extends Parser { public final IsNotNull_expressionContext isNotNull_expression() throws RecognitionException { IsNotNull_expressionContext _localctx = new IsNotNull_expressionContext(_ctx, getState()); - enterRule(_localctx, 36, RULE_isNotNull_expression); + enterRule(_localctx, 48, RULE_isNotNull_expression); try { - setState(183); + setState(223); _errHandler.sync(this); - switch ( getInterpreter().adaptivePredict(_input,13,_ctx) ) { + switch ( getInterpreter().adaptivePredict(_input,18,_ctx) ) { case 1: enterOuterAlt(_localctx, 1); { - setState(175); + setState(215); match(PATH_VARIABLE); - setState(176); + setState(216); + match(T__14); + setState(217); match(T__11); - setState(177); - match(T__8); - setState(178); - match(T__12); + setState(218); + match(T__15); } break; case 2: enterOuterAlt(_localctx, 2); { - setState(179); + setState(219); match(PATH_VARIABLE); - setState(180); - match(T__14); + setState(220); + match(T__17); } break; case 3: enterOuterAlt(_localctx, 3); { - setState(181); + setState(221); match(PATH_VARIABLE); - setState(182); - match(T__15); + setState(222); + match(T__18); } break; } @@ -1240,29 +1559,29 @@ public class EQLParser extends Parser { public final IsEmpty_expressionContext isEmpty_expression() throws RecognitionException { IsEmpty_expressionContext _localctx = new IsEmpty_expressionContext(_ctx, getState()); - enterRule(_localctx, 38, RULE_isEmpty_expression); + enterRule(_localctx, 50, RULE_isEmpty_expression); try { - setState(190); + setState(230); _errHandler.sync(this); - switch ( getInterpreter().adaptivePredict(_input,14,_ctx) ) { + switch ( getInterpreter().adaptivePredict(_input,19,_ctx) ) { case 1: enterOuterAlt(_localctx, 1); { - setState(185); + setState(225); match(PATH_VARIABLE); - setState(186); - match(T__11); - setState(187); - match(T__16); + setState(226); + match(T__14); + setState(227); + match(T__19); } break; case 2: enterOuterAlt(_localctx, 2); { - setState(188); + setState(228); match(PATH_VARIABLE); - setState(189); - match(T__17); + setState(229); + match(T__20); } break; } @@ -1296,40 +1615,40 @@ public class EQLParser extends Parser { public final IsNotEmpty_expressionContext isNotEmpty_expression() throws RecognitionException { IsNotEmpty_expressionContext _localctx = new IsNotEmpty_expressionContext(_ctx, getState()); - enterRule(_localctx, 40, RULE_isNotEmpty_expression); + enterRule(_localctx, 52, RULE_isNotEmpty_expression); try { - setState(200); + setState(240); _errHandler.sync(this); - switch ( getInterpreter().adaptivePredict(_input,15,_ctx) ) { + switch ( getInterpreter().adaptivePredict(_input,20,_ctx) ) { case 1: enterOuterAlt(_localctx, 1); { - setState(192); + setState(232); match(PATH_VARIABLE); - setState(193); + setState(233); + match(T__14); + setState(234); match(T__11); - setState(194); - match(T__8); - setState(195); - match(T__16); + setState(235); + match(T__19); } break; case 2: enterOuterAlt(_localctx, 2); { - setState(196); + setState(236); match(PATH_VARIABLE); - setState(197); - match(T__18); + setState(237); + match(T__21); } break; case 3: enterOuterAlt(_localctx, 3); { - setState(198); + setState(238); match(PATH_VARIABLE); - setState(199); - match(T__19); + setState(239); + match(T__22); } break; } @@ -1369,15 +1688,15 @@ public class EQLParser extends Parser { public final Like_expressionContext like_expression() throws RecognitionException { Like_expressionContext _localctx = new Like_expressionContext(_ctx, getState()); - enterRule(_localctx, 42, RULE_like_expression); + enterRule(_localctx, 54, RULE_like_expression); try { enterOuterAlt(_localctx, 1); { - setState(202); + setState(242); match(PATH_VARIABLE); - setState(203); + setState(243); like_op(); - setState(204); + setState(244); value_expression(); } } @@ -1409,14 +1728,14 @@ public class EQLParser extends Parser { public final Like_opContext like_op() throws RecognitionException { Like_opContext _localctx = new Like_opContext(_ctx, getState()); - enterRule(_localctx, 44, RULE_like_op); + enterRule(_localctx, 56, RULE_like_op); int _la; try { enterOuterAlt(_localctx, 1); { - setState(206); + setState(246); _la = _input.LA(1); - if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__20) | (1L << T__21) | (1L << T__22) | (1L << T__23) | (1L << T__24) | (1L << T__25) | (1L << T__26) | (1L << T__27))) != 0)) ) { + if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__23) | (1L << T__24) | (1L << T__25) | (1L << T__26) | (1L << T__27) | (1L << T__28) | (1L << T__29) | (1L << T__30))) != 0)) ) { _errHandler.recoverInline(this); } else { consume(); @@ -1458,15 +1777,15 @@ public class EQLParser extends Parser { public final Comparison_expressionContext comparison_expression() throws RecognitionException { Comparison_expressionContext _localctx = new Comparison_expressionContext(_ctx, getState()); - enterRule(_localctx, 46, RULE_comparison_expression); + enterRule(_localctx, 58, RULE_comparison_expression); try { enterOuterAlt(_localctx, 1); { - setState(208); + setState(248); match(PATH_VARIABLE); - setState(209); + setState(249); comparison_operator(); - setState(210); + setState(250); value_expression(); } } @@ -1498,14 +1817,14 @@ public class EQLParser extends Parser { public final Comparison_operatorContext comparison_operator() throws RecognitionException { Comparison_operatorContext _localctx = new Comparison_operatorContext(_ctx, getState()); - enterRule(_localctx, 48, RULE_comparison_operator); + enterRule(_localctx, 60, RULE_comparison_operator); int _la; try { enterOuterAlt(_localctx, 1); { - setState(212); + setState(252); _la = _input.LA(1); - if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__28) | (1L << T__29) | (1L << T__30) | (1L << T__31) | (1L << T__32) | (1L << T__33) | (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))) != 0)) ) { + if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__31) | (1L << T__32) | (1L << T__33) | (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))) != 0)) ) { _errHandler.recoverInline(this); } else { consume(); @@ -1544,23 +1863,23 @@ public class EQLParser extends Parser { public final Value_expressionContext value_expression() throws RecognitionException { Value_expressionContext _localctx = new Value_expressionContext(_ctx, getState()); - enterRule(_localctx, 50, RULE_value_expression); + enterRule(_localctx, 62, RULE_value_expression); try { - setState(216); + setState(256); switch (_input.LA(1)) { case BOOLEAN_LITERAL: case NUMBER_LITERAL: case STRING_LITERAL: enterOuterAlt(_localctx, 1); { - setState(214); + setState(254); literal(); } break; case INPUT_VARIABLE: enterOuterAlt(_localctx, 2); { - setState(215); + setState(255); match(INPUT_VARIABLE); } break; @@ -1599,12 +1918,12 @@ public class EQLParser extends Parser { public final LiteralContext literal() throws RecognitionException { LiteralContext _localctx = new LiteralContext(_ctx, getState()); - enterRule(_localctx, 52, RULE_literal); + enterRule(_localctx, 64, RULE_literal); int _la; try { enterOuterAlt(_localctx, 1); { - setState(218); + setState(258); _la = _input.LA(1); if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << BOOLEAN_LITERAL) | (1L << NUMBER_LITERAL) | (1L << STRING_LITERAL))) != 0)) ) { _errHandler.recoverInline(this); @@ -1625,75 +1944,90 @@ public class EQLParser extends Parser { } public static final String _serializedATN = - "\3\u0430\ud6d1\u8206\uad2d\u4417\uaef1\u8d80\uaadd\3\64\u00df\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"+ + "\3\u0430\ud6d1\u8206\uad2d\u4417\uaef1\u8d80\uaadd\3:\u0107\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\3\2\5\2:\n\2\3\2\7\2=\n\2\f\2\16\2@\13"+ - "\2\3\2\5\2C\n\2\3\3\3\3\3\3\3\3\3\3\3\4\3\4\3\5\3\5\3\5\3\6\3\6\3\6\5"+ - "\6R\n\6\3\7\3\7\3\7\3\7\3\b\3\b\3\b\7\b[\n\b\f\b\16\b^\13\b\3\t\3\t\3"+ - "\n\3\n\3\n\7\ne\n\n\f\n\16\nh\13\n\3\13\3\13\3\13\7\13m\n\13\f\13\16\13"+ - "p\13\13\3\f\5\fs\n\f\3\f\3\f\3\r\3\r\3\r\3\r\3\r\5\r|\n\r\3\16\3\16\3"+ - "\16\3\16\3\16\3\16\3\16\3\16\3\16\3\16\3\16\3\16\3\16\5\16\u008b\n\16"+ - "\3\17\3\17\3\17\3\17\3\20\3\20\3\20\3\20\3\20\7\20\u0096\n\20\f\20\16"+ - "\20\u0099\13\20\3\20\3\20\5\20\u009d\n\20\3\21\3\21\3\21\3\21\3\21\3\21"+ - "\3\22\3\22\3\22\3\22\3\22\3\22\3\23\3\23\3\23\3\23\3\23\5\23\u00b0\n\23"+ - "\3\24\3\24\3\24\3\24\3\24\3\24\3\24\3\24\5\24\u00ba\n\24\3\25\3\25\3\25"+ - "\3\25\3\25\5\25\u00c1\n\25\3\26\3\26\3\26\3\26\3\26\3\26\3\26\3\26\5\26"+ - "\u00cb\n\26\3\27\3\27\3\27\3\27\3\30\3\30\3\31\3\31\3\31\3\31\3\32\3\32"+ - "\3\33\3\33\5\33\u00db\n\33\3\34\3\34\3\34\2\2\35\2\4\6\b\n\f\16\20\22"+ - "\24\26\30\32\34\36 \"$&(*,.\60\62\64\66\2\5\3\2\27\36\3\2\37.\3\2\61\63"+ - "\u00de\29\3\2\2\2\4D\3\2\2\2\6I\3\2\2\2\bK\3\2\2\2\nN\3\2\2\2\fS\3\2\2"+ - "\2\16W\3\2\2\2\20_\3\2\2\2\22a\3\2\2\2\24i\3\2\2\2\26r\3\2\2\2\30{\3\2"+ - "\2\2\32\u008a\3\2\2\2\34\u008c\3\2\2\2\36\u009c\3\2\2\2 \u009e\3\2\2\2"+ - "\"\u00a4\3\2\2\2$\u00af\3\2\2\2&\u00b9\3\2\2\2(\u00c0\3\2\2\2*\u00ca\3"+ - "\2\2\2,\u00cc\3\2\2\2.\u00d0\3\2\2\2\60\u00d2\3\2\2\2\62\u00d6\3\2\2\2"+ - "\64\u00da\3\2\2\2\66\u00dc\3\2\2\28:\5\4\3\298\3\2\2\29:\3\2\2\2:>\3\2"+ - "\2\2;=\5\6\4\2<;\3\2\2\2=@\3\2\2\2><\3\2\2\2>?\3\2\2\2?B\3\2\2\2@>\3\2"+ - "\2\2AC\5\b\5\2BA\3\2\2\2BC\3\2\2\2C\3\3\2\2\2DE\7\3\2\2EF\7\4\2\2FG\5"+ - "\16\b\2GH\7\5\2\2H\5\3\2\2\2IJ\5\n\6\2J\7\3\2\2\2KL\7\6\2\2LM\5\22\n\2"+ - "M\t\3\2\2\2NO\7\7\2\2OQ\7\60\2\2PR\5\f\7\2QP\3\2\2\2QR\3\2\2\2R\13\3\2"+ - "\2\2ST\7\4\2\2TU\5\16\b\2UV\7\5\2\2V\r\3\2\2\2W\\\5\20\t\2XY\7\b\2\2Y"+ - "[\5\20\t\2ZX\3\2\2\2[^\3\2\2\2\\Z\3\2\2\2\\]\3\2\2\2]\17\3\2\2\2^\\\3"+ - "\2\2\2_`\7\60\2\2`\21\3\2\2\2af\5\24\13\2bc\7\t\2\2ce\5\24\13\2db\3\2"+ - "\2\2eh\3\2\2\2fd\3\2\2\2fg\3\2\2\2g\23\3\2\2\2hf\3\2\2\2in\5\26\f\2jk"+ - "\7\n\2\2km\5\26\f\2lj\3\2\2\2mp\3\2\2\2nl\3\2\2\2no\3\2\2\2o\25\3\2\2"+ - "\2pn\3\2\2\2qs\7\13\2\2rq\3\2\2\2rs\3\2\2\2st\3\2\2\2tu\5\30\r\2u\27\3"+ - "\2\2\2v|\5\32\16\2wx\7\4\2\2xy\5\22\n\2yz\7\5\2\2z|\3\2\2\2{v\3\2\2\2"+ - "{w\3\2\2\2|\31\3\2\2\2}\u008b\5\60\31\2~\u008b\5,\27\2\177\u008b\5 \21"+ - "\2\u0080\u008b\5\"\22\2\u0081\u008b\5\34\17\2\u0082\u008b\5$\23\2\u0083"+ - "\u008b\5&\24\2\u0084\u008b\5(\25\2\u0085\u008b\5*\26\2\u0086\u0087\7\4"+ - "\2\2\u0087\u0088\5\32\16\2\u0088\u0089\7\5\2\2\u0089\u008b\3\2\2\2\u008a"+ - "}\3\2\2\2\u008a~\3\2\2\2\u008a\177\3\2\2\2\u008a\u0080\3\2\2\2\u008a\u0081"+ - "\3\2\2\2\u008a\u0082\3\2\2\2\u008a\u0083\3\2\2\2\u008a\u0084\3\2\2\2\u008a"+ - "\u0085\3\2\2\2\u008a\u0086\3\2\2\2\u008b\33\3\2\2\2\u008c\u008d\7\60\2"+ - "\2\u008d\u008e\7\f\2\2\u008e\u008f\5\36\20\2\u008f\35\3\2\2\2\u0090\u009d"+ - "\7/\2\2\u0091\u0092\7\4\2\2\u0092\u0097\5\64\33\2\u0093\u0094\7\b\2\2"+ - "\u0094\u0096\5\64\33\2\u0095\u0093\3\2\2\2\u0096\u0099\3\2\2\2\u0097\u0095"+ - "\3\2\2\2\u0097\u0098\3\2\2\2\u0098\u009a\3\2\2\2\u0099\u0097\3\2\2\2\u009a"+ - "\u009b\7\5\2\2\u009b\u009d\3\2\2\2\u009c\u0090\3\2\2\2\u009c\u0091\3\2"+ - "\2\2\u009d\37\3\2\2\2\u009e\u009f\7\60\2\2\u009f\u00a0\7\r\2\2\u00a0\u00a1"+ - "\5\64\33\2\u00a1\u00a2\7\n\2\2\u00a2\u00a3\5\64\33\2\u00a3!\3\2\2\2\u00a4"+ - "\u00a5\5\64\33\2\u00a5\u00a6\7\r\2\2\u00a6\u00a7\7\60\2\2\u00a7\u00a8"+ - "\7\n\2\2\u00a8\u00a9\7\60\2\2\u00a9#\3\2\2\2\u00aa\u00ab\7\60\2\2\u00ab"+ - "\u00ac\7\16\2\2\u00ac\u00b0\7\17\2\2\u00ad\u00ae\7\60\2\2\u00ae\u00b0"+ - "\7\20\2\2\u00af\u00aa\3\2\2\2\u00af\u00ad\3\2\2\2\u00b0%\3\2\2\2\u00b1"+ - "\u00b2\7\60\2\2\u00b2\u00b3\7\16\2\2\u00b3\u00b4\7\13\2\2\u00b4\u00ba"+ - "\7\17\2\2\u00b5\u00b6\7\60\2\2\u00b6\u00ba\7\21\2\2\u00b7\u00b8\7\60\2"+ - "\2\u00b8\u00ba\7\22\2\2\u00b9\u00b1\3\2\2\2\u00b9\u00b5\3\2\2\2\u00b9"+ - "\u00b7\3\2\2\2\u00ba\'\3\2\2\2\u00bb\u00bc\7\60\2\2\u00bc\u00bd\7\16\2"+ - "\2\u00bd\u00c1\7\23\2\2\u00be\u00bf\7\60\2\2\u00bf\u00c1\7\24\2\2\u00c0"+ - "\u00bb\3\2\2\2\u00c0\u00be\3\2\2\2\u00c1)\3\2\2\2\u00c2\u00c3\7\60\2\2"+ - "\u00c3\u00c4\7\16\2\2\u00c4\u00c5\7\13\2\2\u00c5\u00cb\7\23\2\2\u00c6"+ - "\u00c7\7\60\2\2\u00c7\u00cb\7\25\2\2\u00c8\u00c9\7\60\2\2\u00c9\u00cb"+ - "\7\26\2\2\u00ca\u00c2\3\2\2\2\u00ca\u00c6\3\2\2\2\u00ca\u00c8\3\2\2\2"+ - "\u00cb+\3\2\2\2\u00cc\u00cd\7\60\2\2\u00cd\u00ce\5.\30\2\u00ce\u00cf\5"+ - "\64\33\2\u00cf-\3\2\2\2\u00d0\u00d1\t\2\2\2\u00d1/\3\2\2\2\u00d2\u00d3"+ - "\7\60\2\2\u00d3\u00d4\5\62\32\2\u00d4\u00d5\5\64\33\2\u00d5\61\3\2\2\2"+ - "\u00d6\u00d7\t\3\2\2\u00d7\63\3\2\2\2\u00d8\u00db\5\66\34\2\u00d9\u00db"+ - "\7/\2\2\u00da\u00d8\3\2\2\2\u00da\u00d9\3\2\2\2\u00db\65\3\2\2\2\u00dc"+ - "\u00dd\t\4\2\2\u00dd\67\3\2\2\2\239>BQ\\fnr{\u008a\u0097\u009c\u00af\u00b9"+ - "\u00c0\u00ca\u00da"; + "\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\"\3\2\5\2F\n\2\3\2\7\2I\n\2\f\2\16\2L\13\2\3\2\5\2O\n\2\3\3"+ + "\3\3\3\3\3\3\3\3\3\4\3\4\3\5\3\5\3\5\3\6\3\6\5\6]\n\6\3\6\3\6\5\6a\n\6"+ + "\3\7\3\7\3\7\3\7\3\b\3\b\3\b\7\bj\n\b\f\b\16\bm\13\b\3\t\3\t\3\t\5\tr"+ + "\n\t\3\n\3\n\3\n\3\13\3\13\3\13\3\f\3\f\5\f|\n\f\3\r\3\r\5\r\u0080\n\r"+ + "\3\16\3\16\5\16\u0084\n\16\3\17\3\17\3\17\3\17\3\20\3\20\3\20\7\20\u008d"+ + "\n\20\f\20\16\20\u0090\13\20\3\21\3\21\3\21\7\21\u0095\n\21\f\21\16\21"+ + "\u0098\13\21\3\22\5\22\u009b\n\22\3\22\3\22\3\23\3\23\3\23\3\23\3\23\5"+ + "\23\u00a4\n\23\3\24\3\24\3\24\3\24\3\24\3\24\3\24\3\24\3\24\3\24\3\24"+ + "\3\24\3\24\5\24\u00b3\n\24\3\25\3\25\3\25\3\25\3\26\3\26\3\26\3\26\3\26"+ + "\7\26\u00be\n\26\f\26\16\26\u00c1\13\26\3\26\3\26\5\26\u00c5\n\26\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\5\31\u00d8\n\31\3\32\3\32\3\32\3\32\3\32\3\32\3\32\3\32\5\32"+ + "\u00e2\n\32\3\33\3\33\3\33\3\33\3\33\5\33\u00e9\n\33\3\34\3\34\3\34\3"+ + "\34\3\34\3\34\3\34\3\34\5\34\u00f3\n\34\3\35\3\35\3\35\3\35\3\36\3\36"+ + "\3\37\3\37\3\37\3\37\3 \3 \3!\3!\5!\u0103\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:<>@B\2\5\3\2\32"+ + "!\3\2\"\61\4\2\64\6599\u0106\2E\3\2\2\2\4P\3\2\2\2\6U\3\2\2\2\bW\3\2\2"+ + "\2\nZ\3\2\2\2\fb\3\2\2\2\16f\3\2\2\2\20q\3\2\2\2\22s\3\2\2\2\24v\3\2\2"+ + "\2\26{\3\2\2\2\30}\3\2\2\2\32\u0081\3\2\2\2\34\u0085\3\2\2\2\36\u0089"+ + "\3\2\2\2 \u0091\3\2\2\2\"\u009a\3\2\2\2$\u00a3\3\2\2\2&\u00b2\3\2\2\2"+ + "(\u00b4\3\2\2\2*\u00c4\3\2\2\2,\u00c6\3\2\2\2.\u00cc\3\2\2\2\60\u00d7"+ + "\3\2\2\2\62\u00e1\3\2\2\2\64\u00e8\3\2\2\2\66\u00f2\3\2\2\28\u00f4\3\2"+ + "\2\2:\u00f8\3\2\2\2<\u00fa\3\2\2\2>\u00fe\3\2\2\2@\u0102\3\2\2\2B\u0104"+ + "\3\2\2\2DF\5\4\3\2ED\3\2\2\2EF\3\2\2\2FJ\3\2\2\2GI\5\6\4\2HG\3\2\2\2I"+ + "L\3\2\2\2JH\3\2\2\2JK\3\2\2\2KN\3\2\2\2LJ\3\2\2\2MO\5\b\5\2NM\3\2\2\2"+ + "NO\3\2\2\2O\3\3\2\2\2PQ\7\3\2\2QR\7\4\2\2RS\5\16\b\2ST\7\5\2\2T\5\3\2"+ + "\2\2UV\5\n\6\2V\7\3\2\2\2WX\7\6\2\2XY\5\36\20\2Y\t\3\2\2\2Z\\\7\7\2\2"+ + "[]\5\26\f\2\\[\3\2\2\2\\]\3\2\2\2]^\3\2\2\2^`\7\63\2\2_a\5\f\7\2`_\3\2"+ + "\2\2`a\3\2\2\2a\13\3\2\2\2bc\7\4\2\2cd\5\16\b\2de\7\5\2\2e\r\3\2\2\2f"+ + "k\5\20\t\2gh\7\b\2\2hj\5\20\t\2ig\3\2\2\2jm\3\2\2\2ki\3\2\2\2kl\3\2\2"+ + "\2l\17\3\2\2\2mk\3\2\2\2nr\7\63\2\2or\5\22\n\2pr\5\24\13\2qn\3\2\2\2q"+ + "o\3\2\2\2qp\3\2\2\2r\21\3\2\2\2st\7\t\2\2tu\5\30\r\2u\23\3\2\2\2vw\7\t"+ + "\2\2wx\5\32\16\2x\25\3\2\2\2y|\5\30\r\2z|\5\32\16\2{y\3\2\2\2{z\3\2\2"+ + "\2|\27\3\2\2\2}\177\7\n\2\2~\u0080\5\34\17\2\177~\3\2\2\2\177\u0080\3"+ + "\2\2\2\u0080\31\3\2\2\2\u0081\u0083\7\13\2\2\u0082\u0084\5\34\17\2\u0083"+ + "\u0082\3\2\2\2\u0083\u0084\3\2\2\2\u0084\33\3\2\2\2\u0085\u0086\7\4\2"+ + "\2\u0086\u0087\7\65\2\2\u0087\u0088\7\5\2\2\u0088\35\3\2\2\2\u0089\u008e"+ + "\5 \21\2\u008a\u008b\7\f\2\2\u008b\u008d\5 \21\2\u008c\u008a\3\2\2\2\u008d"+ + "\u0090\3\2\2\2\u008e\u008c\3\2\2\2\u008e\u008f\3\2\2\2\u008f\37\3\2\2"+ + "\2\u0090\u008e\3\2\2\2\u0091\u0096\5\"\22\2\u0092\u0093\7\r\2\2\u0093"+ + "\u0095\5\"\22\2\u0094\u0092\3\2\2\2\u0095\u0098\3\2\2\2\u0096\u0094\3"+ + "\2\2\2\u0096\u0097\3\2\2\2\u0097!\3\2\2\2\u0098\u0096\3\2\2\2\u0099\u009b"+ + "\7\16\2\2\u009a\u0099\3\2\2\2\u009a\u009b\3\2\2\2\u009b\u009c\3\2\2\2"+ + "\u009c\u009d\5$\23\2\u009d#\3\2\2\2\u009e\u00a4\5&\24\2\u009f\u00a0\7"+ + "\4\2\2\u00a0\u00a1\5\36\20\2\u00a1\u00a2\7\5\2\2\u00a2\u00a4\3\2\2\2\u00a3"+ + "\u009e\3\2\2\2\u00a3\u009f\3\2\2\2\u00a4%\3\2\2\2\u00a5\u00b3\5<\37\2"+ + "\u00a6\u00b3\58\35\2\u00a7\u00b3\5,\27\2\u00a8\u00b3\5.\30\2\u00a9\u00b3"+ + "\5(\25\2\u00aa\u00b3\5\60\31\2\u00ab\u00b3\5\62\32\2\u00ac\u00b3\5\64"+ + "\33\2\u00ad\u00b3\5\66\34\2\u00ae\u00af\7\4\2\2\u00af\u00b0\5&\24\2\u00b0"+ + "\u00b1\7\5\2\2\u00b1\u00b3\3\2\2\2\u00b2\u00a5\3\2\2\2\u00b2\u00a6\3\2"+ + "\2\2\u00b2\u00a7\3\2\2\2\u00b2\u00a8\3\2\2\2\u00b2\u00a9\3\2\2\2\u00b2"+ + "\u00aa\3\2\2\2\u00b2\u00ab\3\2\2\2\u00b2\u00ac\3\2\2\2\u00b2\u00ad\3\2"+ + "\2\2\u00b2\u00ae\3\2\2\2\u00b3\'\3\2\2\2\u00b4\u00b5\7\63\2\2\u00b5\u00b6"+ + "\7\17\2\2\u00b6\u00b7\5*\26\2\u00b7)\3\2\2\2\u00b8\u00c5\7\62\2\2\u00b9"+ + "\u00ba\7\4\2\2\u00ba\u00bf\5@!\2\u00bb\u00bc\7\b\2\2\u00bc\u00be\5@!\2"+ + "\u00bd\u00bb\3\2\2\2\u00be\u00c1\3\2\2\2\u00bf\u00bd\3\2\2\2\u00bf\u00c0"+ + "\3\2\2\2\u00c0\u00c2\3\2\2\2\u00c1\u00bf\3\2\2\2\u00c2\u00c3\7\5\2\2\u00c3"+ + "\u00c5\3\2\2\2\u00c4\u00b8\3\2\2\2\u00c4\u00b9\3\2\2\2\u00c5+\3\2\2\2"+ + "\u00c6\u00c7\7\63\2\2\u00c7\u00c8\7\20\2\2\u00c8\u00c9\5@!\2\u00c9\u00ca"+ + "\7\r\2\2\u00ca\u00cb\5@!\2\u00cb-\3\2\2\2\u00cc\u00cd\5@!\2\u00cd\u00ce"+ + "\7\20\2\2\u00ce\u00cf\7\63\2\2\u00cf\u00d0\7\r\2\2\u00d0\u00d1\7\63\2"+ + "\2\u00d1/\3\2\2\2\u00d2\u00d3\7\63\2\2\u00d3\u00d4\7\21\2\2\u00d4\u00d8"+ + "\7\22\2\2\u00d5\u00d6\7\63\2\2\u00d6\u00d8\7\23\2\2\u00d7\u00d2\3\2\2"+ + "\2\u00d7\u00d5\3\2\2\2\u00d8\61\3\2\2\2\u00d9\u00da\7\63\2\2\u00da\u00db"+ + "\7\21\2\2\u00db\u00dc\7\16\2\2\u00dc\u00e2\7\22\2\2\u00dd\u00de\7\63\2"+ + "\2\u00de\u00e2\7\24\2\2\u00df\u00e0\7\63\2\2\u00e0\u00e2\7\25\2\2\u00e1"+ + "\u00d9\3\2\2\2\u00e1\u00dd\3\2\2\2\u00e1\u00df\3\2\2\2\u00e2\63\3\2\2"+ + "\2\u00e3\u00e4\7\63\2\2\u00e4\u00e5\7\21\2\2\u00e5\u00e9\7\26\2\2\u00e6"+ + "\u00e7\7\63\2\2\u00e7\u00e9\7\27\2\2\u00e8\u00e3\3\2\2\2\u00e8\u00e6\3"+ + "\2\2\2\u00e9\65\3\2\2\2\u00ea\u00eb\7\63\2\2\u00eb\u00ec\7\21\2\2\u00ec"+ + "\u00ed\7\16\2\2\u00ed\u00f3\7\26\2\2\u00ee\u00ef\7\63\2\2\u00ef\u00f3"+ + "\7\30\2\2\u00f0\u00f1\7\63\2\2\u00f1\u00f3\7\31\2\2\u00f2\u00ea\3\2\2"+ + "\2\u00f2\u00ee\3\2\2\2\u00f2\u00f0\3\2\2\2\u00f3\67\3\2\2\2\u00f4\u00f5"+ + "\7\63\2\2\u00f5\u00f6\5:\36\2\u00f6\u00f7\5@!\2\u00f79\3\2\2\2\u00f8\u00f9"+ + "\t\2\2\2\u00f9;\3\2\2\2\u00fa\u00fb\7\63\2\2\u00fb\u00fc\5> \2\u00fc\u00fd"+ + "\5@!\2\u00fd=\3\2\2\2\u00fe\u00ff\t\3\2\2\u00ff?\3\2\2\2\u0100\u0103\5"+ + "B\"\2\u0101\u0103\7\62\2\2\u0102\u0100\3\2\2\2\u0102\u0101\3\2\2\2\u0103"+ + "A\3\2\2\2\u0104\u0105\t\4\2\2\u0105C\3\2\2\2\30EJN\\`kq{\177\u0083\u008e"+ + "\u0096\u009a\u00a3\u00b2\u00bf\u00c4\u00d7\u00e1\u00e8\u00f2\u0102"; 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 c7042d557..afed006a1 100644 --- a/src/test/java/com/avaje/ebeaninternal/server/grammer/EqlParserTest.java +++ b/src/test/java/com/avaje/ebeaninternal/server/grammer/EqlParserTest.java @@ -4,9 +4,11 @@ import com.avaje.ebean.Ebean; import com.avaje.ebean.Query; import com.avaje.ebeaninternal.api.SpiQuery; import com.avaje.tests.model.basic.Customer; +import com.avaje.tests.model.basic.ResetBasicData; import org.junit.Test; import java.util.Arrays; +import java.util.List; import static org.assertj.core.api.Assertions.assertThat; @@ -203,6 +205,15 @@ public class EqlParserTest { assertThat(query.getGeneratedSql()).contains(", t1.id c9, t1.city"); } + @Test + public void fetch_withProperty_noWhitespace() throws Exception { + + Query query = parse("fetch billingAddress(city)"); + query.findList(); + + assertThat(query.getGeneratedSql()).contains(", t1.id c9, t1.city"); + } + @Test public void fetch_basic_multiple() throws Exception { @@ -222,6 +233,58 @@ public class EqlParserTest { assertThat(query.getGeneratedSql()).contains(", t1.id c8, t1.city c9, t2.id c10, t2.city c11"); } + @Test + public void fetch_lazy() throws Exception { + + Query query = parse("fetch lazy billingAddress"); + query.findList(); + + assertThat(query.getGeneratedSql()).doesNotContain(", t1.city "); + } + + @Test + public void fetch_lazy50() throws Exception { + + Query query = parse("fetch lazy(50) billingAddress"); + query.findList(); + + assertThat(query.getGeneratedSql()).doesNotContain(", t1.city "); + } + + @Test + public void fetch_query50() throws Exception { + + ResetBasicData.reset(); + Query query = parse("fetch query(50) billingAddress"); + query.findList(); + + assertThat(query.getGeneratedSql()).doesNotContain(", t1.city "); + } + + @Test + public void fetch_query50_asHint() throws Exception { + + ResetBasicData.reset(); + Query query = parse("fetch billingAddress (+query(50),city)"); + query.findList(); + + assertThat(query.getGeneratedSql()).doesNotContain(", t1.city "); + } + + @Test + public void fetch_lazy50_asHint() throws Exception { + + ResetBasicData.reset(); + Query query = parse("fetch billingAddress (+lazy(50),city)"); + List list = query.findList(); + + assertThat(query.getGeneratedSql()).doesNotContain(", t1.city "); + + Customer customer = list.get(0); + customer.getBillingAddress().getCity(); + + } + private Query parse(String raw) { Query query = Ebean.find(Customer.class); diff --git a/src/test/java/com/avaje/ebeaninternal/server/grammer/ParseFetchConfigTest.java b/src/test/java/com/avaje/ebeaninternal/server/grammer/ParseFetchConfigTest.java new file mode 100644 index 000000000..123f13d1b --- /dev/null +++ b/src/test/java/com/avaje/ebeaninternal/server/grammer/ParseFetchConfigTest.java @@ -0,0 +1,46 @@ +package com.avaje.ebeaninternal.server.grammer; + +import com.avaje.ebean.FetchConfig; +import org.junit.Test; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.Assert.assertNull; + +public class ParseFetchConfigTest { + + @Test + public void parse() throws Exception { + + assertNull(ParseFetchConfig.parse("junk")); + assertNull(ParseFetchConfig.parse("lazyFoo")); + assertNull(ParseFetchConfig.parse("queryFoo")); + } + + @Test + public void parseLazy() throws Exception { + + FetchConfig lazy = ParseFetchConfig.parse("lazy"); + assertThat(lazy.getLazyBatchSize()).isEqualTo(0); + } + + @Test + public void parseLazy100() throws Exception { + + FetchConfig lazy = ParseFetchConfig.parse("lazy(100)"); + assertThat(lazy.getLazyBatchSize()).isEqualTo(100); + } + + @Test + public void parseQuery() throws Exception { + + FetchConfig lazy = ParseFetchConfig.parse("query"); + assertThat(lazy.getQueryBatchSize()).isEqualTo(0); + } + + @Test + public void parseQuery100() throws Exception { + + FetchConfig lazy = ParseFetchConfig.parse("query(50)"); + assertThat(lazy.getQueryBatchSize()).isEqualTo(50); + } +} \ No newline at end of file diff --git a/src/test/resources/EQL.g4 b/src/test/resources/EQL.g4 index af63bbf17..e9a103692 100644 --- a/src/test/resources/EQL.g4 +++ b/src/test/resources/EQL.g4 @@ -17,7 +17,7 @@ where_clause ; fetch_path - : 'fetch' PATH_VARIABLE fetch_property_set? + : 'fetch' fetch_option? PATH_VARIABLE fetch_property_set? ; fetch_property_set @@ -30,8 +30,34 @@ fetch_property_group fetch_property : PATH_VARIABLE + | fetch_query_hint + | fetch_lazy_hint ; +fetch_query_hint + : '+' fetch_query_option + ; + +fetch_lazy_hint + : '+' fetch_lazy_option + ; + +fetch_option + : fetch_query_option + | fetch_lazy_option + ; + +fetch_query_option + : 'query' (fetch_batch_size)? + ; + +fetch_lazy_option + : 'lazy' (fetch_batch_size)? + ; + +fetch_batch_size + : '(' NUMBER_LITERAL ')' + ; conditional_expression : (conditional_term) ('or' conditional_term)* @@ -153,7 +179,18 @@ BOOLEAN_LITERAL ; NUMBER_LITERAL - : [0-9]+ '.'? [0-9]*; + : '-'? DOUBLE + | '-'? INT + | ZERO + ; + +DOUBLE + : [0-9]+ '.' [0-9]*; + +INT + : [1-9] [0-9]*; + +ZERO : '0'; STRING_LITERAL : '\'' ( ~'\'' | '\'\'' )* '\''