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 3a64d6d53..7f3edde57 100644 --- a/src/main/java/com/avaje/ebeaninternal/server/grammer/EqlAdapter.java +++ b/src/main/java/com/avaje/ebeaninternal/server/grammer/EqlAdapter.java @@ -88,6 +88,28 @@ 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); + + } else { + String fetchProperties = trimParenthesis(ctx.getChild(2).getText()); + query.fetch(path, fetchProperties); + } + } + + /** + * Trim leading '(' and trailing ')' + */ + private String trimParenthesis(String text) { + text = text.substring(1); + text = text.substring(0, text.length()-1); + return text; + } private String getLeftHandSidePath(ParserRuleContext ctx) { TerminalNode pathToken = ctx.getToken(EQLLexer.PATH_VARIABLE, 0); @@ -128,7 +150,7 @@ class EqlAdapter extends EQLBaseListener { int childCount = ctx.getChildCount(); for (int i = 0; i < childCount; i++) { String text = child(ctx, i); - if (isInValue(text)) { + if (isValue(text)) { inValues.add(helper.bind(text)); } } @@ -139,7 +161,7 @@ class EqlAdapter extends EQLBaseListener { return child.getText(); } - private boolean isInValue(String text) { + private boolean isValue(String text) { if (text.length() == 1 && (text.equals("(") || text.equals(")") || text.equals(","))) { return false; } 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 112c6a773..54f2e85ed 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,18 @@ public class EQLBaseListener implements EQLListener { *

The default implementation does nothing.

*/ @Override public void exitFetch_path(EQLParser.Fetch_pathContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterFetch_property_set(EQLParser.Fetch_property_setContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitFetch_property_set(EQLParser.Fetch_property_setContext ctx) { } /** * {@inheritDoc} * 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 44e90d625..284ef0b49 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,16 @@ public interface EQLListener extends ParseTreeListener { * @param ctx the parse tree */ void exitFetch_path(EQLParser.Fetch_pathContext ctx); + /** + * Enter a parse tree produced by {@link EQLParser#fetch_property_set}. + * @param ctx the parse tree + */ + void enterFetch_property_set(EQLParser.Fetch_property_setContext ctx); + /** + * Exit a parse tree produced by {@link EQLParser#fetch_property_set}. + * @param ctx the parse tree + */ + void exitFetch_property_set(EQLParser.Fetch_property_setContext ctx); /** * Enter a parse tree produced by {@link EQLParser#fetch_property_group}. * @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 8e87e7047..8f0c64ac0 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 @@ -27,20 +27,20 @@ public class EQLParser extends Parser { WS=50; 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_group = 5, - RULE_fetch_property = 6, RULE_conditional_expression = 7, RULE_conditional_term = 8, - RULE_conditional_factor = 9, RULE_conditional_primary = 10, RULE_any_expression = 11, - RULE_in_expression = 12, RULE_in_value = 13, RULE_between_expression = 14, - RULE_propertyBetween_expression = 15, RULE_isNull_expression = 16, RULE_isNotNull_expression = 17, - RULE_isEmpty_expression = 18, RULE_isNotEmpty_expression = 19, RULE_like_expression = 20, - RULE_like_op = 21, RULE_comparison_expression = 22, RULE_comparison_operator = 23, - RULE_value_expression = 24, RULE_literal = 25; + 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; public static final String[] ruleNames = { "select_statement", "select_clause", "fetch_clause", "where_clause", "fetch_path", - "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", "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" }; @@ -115,8 +115,11 @@ public class EQLParser extends Parser { public Select_clauseContext select_clause() { return getRuleContext(Select_clauseContext.class,0); } - public Fetch_clauseContext fetch_clause() { - return getRuleContext(Fetch_clauseContext.class,0); + public List fetch_clause() { + return getRuleContexts(Fetch_clauseContext.class); + } + public Fetch_clauseContext fetch_clause(int i) { + return getRuleContext(Fetch_clauseContext.class,i); } public Where_clauseContext where_clause() { return getRuleContext(Where_clauseContext.class,0); @@ -142,29 +145,34 @@ public class EQLParser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(53); + setState(55); _la = _input.LA(1); if (_la==T__0) { { - setState(52); + setState(54); select_clause(); } } - setState(56); + setState(60); + _errHandler.sync(this); _la = _input.LA(1); - if (_la==T__4) { + while (_la==T__4) { { - setState(55); + { + setState(57); fetch_clause(); } + } + setState(62); + _errHandler.sync(this); + _la = _input.LA(1); } - - setState(59); + setState(64); _la = _input.LA(1); if (_la==T__3) { { - setState(58); + setState(63); where_clause(); } } @@ -206,13 +214,13 @@ public class EQLParser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(61); + setState(66); match(T__0); - setState(62); + setState(67); match(T__1); - setState(63); + setState(68); fetch_property_group(); - setState(64); + setState(69); match(T__2); } } @@ -251,7 +259,7 @@ public class EQLParser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(66); + setState(71); fetch_path(); } } @@ -290,9 +298,9 @@ public class EQLParser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(68); + setState(73); match(T__3); - setState(69); + setState(74); conditional_expression(); } } @@ -309,8 +317,8 @@ public class EQLParser extends Parser { public static class Fetch_pathContext extends ParserRuleContext { public TerminalNode PATH_VARIABLE() { return getToken(EQLParser.PATH_VARIABLE, 0); } - public Fetch_property_groupContext fetch_property_group() { - return getRuleContext(Fetch_property_groupContext.class,0); + public Fetch_property_setContext fetch_property_set() { + return getRuleContext(Fetch_property_setContext.class,0); } public Fetch_pathContext(ParserRuleContext parent, int invokingState) { super(parent, invokingState); @@ -329,18 +337,65 @@ public class EQLParser extends Parser { public final Fetch_pathContext fetch_path() throws RecognitionException { Fetch_pathContext _localctx = new Fetch_pathContext(_ctx, getState()); enterRule(_localctx, 8, RULE_fetch_path); + int _la; try { enterOuterAlt(_localctx, 1); { - setState(71); + setState(76); match(T__4); - setState(72); + setState(77); match(PATH_VARIABLE); - setState(73); + setState(79); + _la = _input.LA(1); + if (_la==T__1) { + { + setState(78); + fetch_property_set(); + } + } + + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class Fetch_property_setContext extends ParserRuleContext { + public Fetch_property_groupContext fetch_property_group() { + return getRuleContext(Fetch_property_groupContext.class,0); + } + public Fetch_property_setContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_fetch_property_set; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof EQLListener ) ((EQLListener)listener).enterFetch_property_set(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof EQLListener ) ((EQLListener)listener).exitFetch_property_set(this); + } + } + + public final Fetch_property_setContext fetch_property_set() throws RecognitionException { + Fetch_property_setContext _localctx = new Fetch_property_setContext(_ctx, getState()); + enterRule(_localctx, 10, RULE_fetch_property_set); + try { + enterOuterAlt(_localctx, 1); + { + setState(81); match(T__1); - setState(74); + setState(82); fetch_property_group(); - setState(75); + setState(83); match(T__2); } } @@ -378,26 +433,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, 10, RULE_fetch_property_group); + enterRule(_localctx, 12, RULE_fetch_property_group); int _la; try { enterOuterAlt(_localctx, 1); { - setState(77); + setState(85); fetch_property(); - setState(82); + setState(90); _errHandler.sync(this); _la = _input.LA(1); while (_la==T__5) { { { - setState(78); + setState(86); match(T__5); - setState(79); + setState(87); fetch_property(); } } - setState(84); + setState(92); _errHandler.sync(this); _la = _input.LA(1); } @@ -432,11 +487,11 @@ public class EQLParser extends Parser { public final Fetch_propertyContext fetch_property() throws RecognitionException { Fetch_propertyContext _localctx = new Fetch_propertyContext(_ctx, getState()); - enterRule(_localctx, 12, RULE_fetch_property); + enterRule(_localctx, 14, RULE_fetch_property); try { enterOuterAlt(_localctx, 1); { - setState(85); + setState(93); match(PATH_VARIABLE); } } @@ -474,28 +529,28 @@ public class EQLParser extends Parser { public final Conditional_expressionContext conditional_expression() throws RecognitionException { Conditional_expressionContext _localctx = new Conditional_expressionContext(_ctx, getState()); - enterRule(_localctx, 14, RULE_conditional_expression); + enterRule(_localctx, 16, RULE_conditional_expression); int _la; try { enterOuterAlt(_localctx, 1); { { - setState(87); + setState(95); conditional_term(); } - setState(92); + setState(100); _errHandler.sync(this); _la = _input.LA(1); while (_la==T__6) { { { - setState(88); + setState(96); match(T__6); - setState(89); + setState(97); conditional_term(); } } - setState(94); + setState(102); _errHandler.sync(this); _la = _input.LA(1); } @@ -535,28 +590,28 @@ public class EQLParser extends Parser { public final Conditional_termContext conditional_term() throws RecognitionException { Conditional_termContext _localctx = new Conditional_termContext(_ctx, getState()); - enterRule(_localctx, 16, RULE_conditional_term); + enterRule(_localctx, 18, RULE_conditional_term); int _la; try { enterOuterAlt(_localctx, 1); { { - setState(95); + setState(103); conditional_factor(); } - setState(100); + setState(108); _errHandler.sync(this); _la = _input.LA(1); while (_la==T__7) { { { - setState(96); + setState(104); match(T__7); - setState(97); + setState(105); conditional_factor(); } } - setState(102); + setState(110); _errHandler.sync(this); _la = _input.LA(1); } @@ -593,21 +648,21 @@ public class EQLParser extends Parser { public final Conditional_factorContext conditional_factor() throws RecognitionException { Conditional_factorContext _localctx = new Conditional_factorContext(_ctx, getState()); - enterRule(_localctx, 18, RULE_conditional_factor); + enterRule(_localctx, 20, RULE_conditional_factor); int _la; try { enterOuterAlt(_localctx, 1); { - setState(104); + setState(112); _la = _input.LA(1); if (_la==T__8) { { - setState(103); + setState(111); match(T__8); } } - setState(106); + setState(114); conditional_primary(); } } @@ -645,26 +700,26 @@ public class EQLParser extends Parser { public final Conditional_primaryContext conditional_primary() throws RecognitionException { Conditional_primaryContext _localctx = new Conditional_primaryContext(_ctx, getState()); - enterRule(_localctx, 20, RULE_conditional_primary); + enterRule(_localctx, 22, RULE_conditional_primary); try { - setState(113); + setState(121); _errHandler.sync(this); - switch ( getInterpreter().adaptivePredict(_input,7,_ctx) ) { + switch ( getInterpreter().adaptivePredict(_input,8,_ctx) ) { case 1: enterOuterAlt(_localctx, 1); { - setState(108); + setState(116); any_expression(); } break; case 2: enterOuterAlt(_localctx, 2); { - setState(109); + setState(117); match(T__1); - setState(110); + setState(118); conditional_expression(); - setState(111); + setState(119); match(T__2); } break; @@ -728,82 +783,82 @@ public class EQLParser extends Parser { public final Any_expressionContext any_expression() throws RecognitionException { Any_expressionContext _localctx = new Any_expressionContext(_ctx, getState()); - enterRule(_localctx, 22, RULE_any_expression); + enterRule(_localctx, 24, RULE_any_expression); try { - setState(128); + setState(136); _errHandler.sync(this); - switch ( getInterpreter().adaptivePredict(_input,8,_ctx) ) { + switch ( getInterpreter().adaptivePredict(_input,9,_ctx) ) { case 1: enterOuterAlt(_localctx, 1); { - setState(115); + setState(123); comparison_expression(); } break; case 2: enterOuterAlt(_localctx, 2); { - setState(116); + setState(124); like_expression(); } break; case 3: enterOuterAlt(_localctx, 3); { - setState(117); + setState(125); between_expression(); } break; case 4: enterOuterAlt(_localctx, 4); { - setState(118); + setState(126); propertyBetween_expression(); } break; case 5: enterOuterAlt(_localctx, 5); { - setState(119); + setState(127); in_expression(); } break; case 6: enterOuterAlt(_localctx, 6); { - setState(120); + setState(128); isNull_expression(); } break; case 7: enterOuterAlt(_localctx, 7); { - setState(121); + setState(129); isNotNull_expression(); } break; case 8: enterOuterAlt(_localctx, 8); { - setState(122); + setState(130); isEmpty_expression(); } break; case 9: enterOuterAlt(_localctx, 9); { - setState(123); + setState(131); isNotEmpty_expression(); } break; case 10: enterOuterAlt(_localctx, 10); { - setState(124); + setState(132); match(T__1); - setState(125); + setState(133); any_expression(); - setState(126); + setState(134); match(T__2); } break; @@ -841,15 +896,15 @@ public class EQLParser extends Parser { public final In_expressionContext in_expression() throws RecognitionException { In_expressionContext _localctx = new In_expressionContext(_ctx, getState()); - enterRule(_localctx, 24, RULE_in_expression); + enterRule(_localctx, 26, RULE_in_expression); try { enterOuterAlt(_localctx, 1); { - setState(130); + setState(138); match(PATH_VARIABLE); - setState(131); + setState(139); match(T__9); - setState(132); + setState(140); in_value(); } } @@ -888,42 +943,42 @@ public class EQLParser extends Parser { public final In_valueContext in_value() throws RecognitionException { In_valueContext _localctx = new In_valueContext(_ctx, getState()); - enterRule(_localctx, 26, RULE_in_value); + enterRule(_localctx, 28, RULE_in_value); int _la; try { - setState(146); + setState(154); switch (_input.LA(1)) { case INPUT_VARIABLE: enterOuterAlt(_localctx, 1); { - setState(134); + setState(142); match(INPUT_VARIABLE); } break; case T__1: enterOuterAlt(_localctx, 2); { - setState(135); + setState(143); match(T__1); - setState(136); + setState(144); value_expression(); - setState(141); + setState(149); _errHandler.sync(this); _la = _input.LA(1); while (_la==T__5) { { { - setState(137); + setState(145); match(T__5); - setState(138); + setState(146); value_expression(); } } - setState(143); + setState(151); _errHandler.sync(this); _la = _input.LA(1); } - setState(144); + setState(152); match(T__2); } break; @@ -966,19 +1021,19 @@ public class EQLParser extends Parser { public final Between_expressionContext between_expression() throws RecognitionException { Between_expressionContext _localctx = new Between_expressionContext(_ctx, getState()); - enterRule(_localctx, 28, RULE_between_expression); + enterRule(_localctx, 30, RULE_between_expression); try { enterOuterAlt(_localctx, 1); { - setState(148); + setState(156); match(PATH_VARIABLE); - setState(149); + setState(157); match(T__10); - setState(150); + setState(158); value_expression(); - setState(151); + setState(159); match(T__7); - setState(152); + setState(160); value_expression(); } } @@ -1017,19 +1072,19 @@ public class EQLParser extends Parser { public final PropertyBetween_expressionContext propertyBetween_expression() throws RecognitionException { PropertyBetween_expressionContext _localctx = new PropertyBetween_expressionContext(_ctx, getState()); - enterRule(_localctx, 30, RULE_propertyBetween_expression); + enterRule(_localctx, 32, RULE_propertyBetween_expression); try { enterOuterAlt(_localctx, 1); { - setState(154); + setState(162); value_expression(); - setState(155); + setState(163); match(T__10); - setState(156); + setState(164); match(PATH_VARIABLE); - setState(157); + setState(165); match(T__7); - setState(158); + setState(166); match(PATH_VARIABLE); } } @@ -1062,28 +1117,28 @@ public class EQLParser extends Parser { public final IsNull_expressionContext isNull_expression() throws RecognitionException { IsNull_expressionContext _localctx = new IsNull_expressionContext(_ctx, getState()); - enterRule(_localctx, 32, RULE_isNull_expression); + enterRule(_localctx, 34, RULE_isNull_expression); try { - setState(165); + setState(173); _errHandler.sync(this); - switch ( getInterpreter().adaptivePredict(_input,11,_ctx) ) { + switch ( getInterpreter().adaptivePredict(_input,12,_ctx) ) { case 1: enterOuterAlt(_localctx, 1); { - setState(160); + setState(168); match(PATH_VARIABLE); - setState(161); + setState(169); match(T__11); - setState(162); + setState(170); match(T__12); } break; case 2: enterOuterAlt(_localctx, 2); { - setState(163); + setState(171); match(PATH_VARIABLE); - setState(164); + setState(172); match(T__13); } break; @@ -1118,39 +1173,39 @@ public class EQLParser extends Parser { public final IsNotNull_expressionContext isNotNull_expression() throws RecognitionException { IsNotNull_expressionContext _localctx = new IsNotNull_expressionContext(_ctx, getState()); - enterRule(_localctx, 34, RULE_isNotNull_expression); + enterRule(_localctx, 36, RULE_isNotNull_expression); try { - setState(175); + setState(183); _errHandler.sync(this); - switch ( getInterpreter().adaptivePredict(_input,12,_ctx) ) { + switch ( getInterpreter().adaptivePredict(_input,13,_ctx) ) { case 1: enterOuterAlt(_localctx, 1); { - setState(167); + setState(175); match(PATH_VARIABLE); - setState(168); + setState(176); match(T__11); - setState(169); + setState(177); match(T__8); - setState(170); + setState(178); match(T__12); } break; case 2: enterOuterAlt(_localctx, 2); { - setState(171); + setState(179); match(PATH_VARIABLE); - setState(172); + setState(180); match(T__14); } break; case 3: enterOuterAlt(_localctx, 3); { - setState(173); + setState(181); match(PATH_VARIABLE); - setState(174); + setState(182); match(T__15); } break; @@ -1185,28 +1240,28 @@ public class EQLParser extends Parser { public final IsEmpty_expressionContext isEmpty_expression() throws RecognitionException { IsEmpty_expressionContext _localctx = new IsEmpty_expressionContext(_ctx, getState()); - enterRule(_localctx, 36, RULE_isEmpty_expression); + enterRule(_localctx, 38, RULE_isEmpty_expression); try { - setState(182); + setState(190); _errHandler.sync(this); - switch ( getInterpreter().adaptivePredict(_input,13,_ctx) ) { + switch ( getInterpreter().adaptivePredict(_input,14,_ctx) ) { case 1: enterOuterAlt(_localctx, 1); { - setState(177); + setState(185); match(PATH_VARIABLE); - setState(178); + setState(186); match(T__11); - setState(179); + setState(187); match(T__16); } break; case 2: enterOuterAlt(_localctx, 2); { - setState(180); + setState(188); match(PATH_VARIABLE); - setState(181); + setState(189); match(T__17); } break; @@ -1241,39 +1296,39 @@ public class EQLParser extends Parser { public final IsNotEmpty_expressionContext isNotEmpty_expression() throws RecognitionException { IsNotEmpty_expressionContext _localctx = new IsNotEmpty_expressionContext(_ctx, getState()); - enterRule(_localctx, 38, RULE_isNotEmpty_expression); + enterRule(_localctx, 40, RULE_isNotEmpty_expression); try { - setState(192); + setState(200); _errHandler.sync(this); - switch ( getInterpreter().adaptivePredict(_input,14,_ctx) ) { + switch ( getInterpreter().adaptivePredict(_input,15,_ctx) ) { case 1: enterOuterAlt(_localctx, 1); { - setState(184); + setState(192); match(PATH_VARIABLE); - setState(185); + setState(193); match(T__11); - setState(186); + setState(194); match(T__8); - setState(187); + setState(195); match(T__16); } break; case 2: enterOuterAlt(_localctx, 2); { - setState(188); + setState(196); match(PATH_VARIABLE); - setState(189); + setState(197); match(T__18); } break; case 3: enterOuterAlt(_localctx, 3); { - setState(190); + setState(198); match(PATH_VARIABLE); - setState(191); + setState(199); match(T__19); } break; @@ -1314,15 +1369,15 @@ public class EQLParser extends Parser { public final Like_expressionContext like_expression() throws RecognitionException { Like_expressionContext _localctx = new Like_expressionContext(_ctx, getState()); - enterRule(_localctx, 40, RULE_like_expression); + enterRule(_localctx, 42, RULE_like_expression); try { enterOuterAlt(_localctx, 1); { - setState(194); + setState(202); match(PATH_VARIABLE); - setState(195); + setState(203); like_op(); - setState(196); + setState(204); value_expression(); } } @@ -1354,12 +1409,12 @@ public class EQLParser extends Parser { public final Like_opContext like_op() throws RecognitionException { Like_opContext _localctx = new Like_opContext(_ctx, getState()); - enterRule(_localctx, 42, RULE_like_op); + enterRule(_localctx, 44, RULE_like_op); int _la; try { enterOuterAlt(_localctx, 1); { - setState(198); + setState(206); _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)) ) { _errHandler.recoverInline(this); @@ -1403,15 +1458,15 @@ public class EQLParser extends Parser { public final Comparison_expressionContext comparison_expression() throws RecognitionException { Comparison_expressionContext _localctx = new Comparison_expressionContext(_ctx, getState()); - enterRule(_localctx, 44, RULE_comparison_expression); + enterRule(_localctx, 46, RULE_comparison_expression); try { enterOuterAlt(_localctx, 1); { - setState(200); + setState(208); match(PATH_VARIABLE); - setState(201); + setState(209); comparison_operator(); - setState(202); + setState(210); value_expression(); } } @@ -1443,12 +1498,12 @@ public class EQLParser extends Parser { public final Comparison_operatorContext comparison_operator() throws RecognitionException { Comparison_operatorContext _localctx = new Comparison_operatorContext(_ctx, getState()); - enterRule(_localctx, 46, RULE_comparison_operator); + enterRule(_localctx, 48, RULE_comparison_operator); int _la; try { enterOuterAlt(_localctx, 1); { - setState(204); + setState(212); _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)) ) { _errHandler.recoverInline(this); @@ -1489,23 +1544,23 @@ public class EQLParser extends Parser { public final Value_expressionContext value_expression() throws RecognitionException { Value_expressionContext _localctx = new Value_expressionContext(_ctx, getState()); - enterRule(_localctx, 48, RULE_value_expression); + enterRule(_localctx, 50, RULE_value_expression); try { - setState(208); + setState(216); switch (_input.LA(1)) { case BOOLEAN_LITERAL: case NUMBER_LITERAL: case STRING_LITERAL: enterOuterAlt(_localctx, 1); { - setState(206); + setState(214); literal(); } break; case INPUT_VARIABLE: enterOuterAlt(_localctx, 2); { - setState(207); + setState(215); match(INPUT_VARIABLE); } break; @@ -1544,12 +1599,12 @@ public class EQLParser extends Parser { public final LiteralContext literal() throws RecognitionException { LiteralContext _localctx = new LiteralContext(_ctx, getState()); - enterRule(_localctx, 50, RULE_literal); + enterRule(_localctx, 52, RULE_literal); int _la; try { enterOuterAlt(_localctx, 1); { - setState(210); + setState(218); _la = _input.LA(1); if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << BOOLEAN_LITERAL) | (1L << NUMBER_LITERAL) | (1L << STRING_LITERAL))) != 0)) ) { _errHandler.recoverInline(this); @@ -1570,72 +1625,75 @@ public class EQLParser extends Parser { } public static final String _serializedATN = - "\3\u0430\ud6d1\u8206\uad2d\u4417\uaef1\u8d80\uaadd\3\64\u00d7\4\2\t\2"+ + "\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"+ "\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\3\2\5\28\n\2\3\2\5\2;\n\2\3\2\5\2>\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\3\6\3\6\3\6\3\7\3\7\3\7\7\7"+ - "S\n\7\f\7\16\7V\13\7\3\b\3\b\3\t\3\t\3\t\7\t]\n\t\f\t\16\t`\13\t\3\n\3"+ - "\n\3\n\7\ne\n\n\f\n\16\nh\13\n\3\13\5\13k\n\13\3\13\3\13\3\f\3\f\3\f\3"+ - "\f\3\f\5\ft\n\f\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\5"+ - "\r\u0083\n\r\3\16\3\16\3\16\3\16\3\17\3\17\3\17\3\17\3\17\7\17\u008e\n"+ - "\17\f\17\16\17\u0091\13\17\3\17\3\17\5\17\u0095\n\17\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\22\3\22\3\22\5"+ - "\22\u00a8\n\22\3\23\3\23\3\23\3\23\3\23\3\23\3\23\3\23\5\23\u00b2\n\23"+ - "\3\24\3\24\3\24\3\24\3\24\5\24\u00b9\n\24\3\25\3\25\3\25\3\25\3\25\3\25"+ - "\3\25\3\25\5\25\u00c3\n\25\3\26\3\26\3\26\3\26\3\27\3\27\3\30\3\30\3\30"+ - "\3\30\3\31\3\31\3\32\3\32\5\32\u00d3\n\32\3\33\3\33\3\33\2\2\34\2\4\6"+ - "\b\n\f\16\20\22\24\26\30\32\34\36 \"$&(*,.\60\62\64\2\5\3\2\27\36\3\2"+ - "\37.\3\2\61\63\u00d6\2\67\3\2\2\2\4?\3\2\2\2\6D\3\2\2\2\bF\3\2\2\2\nI"+ - "\3\2\2\2\fO\3\2\2\2\16W\3\2\2\2\20Y\3\2\2\2\22a\3\2\2\2\24j\3\2\2\2\26"+ - "s\3\2\2\2\30\u0082\3\2\2\2\32\u0084\3\2\2\2\34\u0094\3\2\2\2\36\u0096"+ - "\3\2\2\2 \u009c\3\2\2\2\"\u00a7\3\2\2\2$\u00b1\3\2\2\2&\u00b8\3\2\2\2"+ - "(\u00c2\3\2\2\2*\u00c4\3\2\2\2,\u00c8\3\2\2\2.\u00ca\3\2\2\2\60\u00ce"+ - "\3\2\2\2\62\u00d2\3\2\2\2\64\u00d4\3\2\2\2\668\5\4\3\2\67\66\3\2\2\2\67"+ - "8\3\2\2\28:\3\2\2\29;\5\6\4\2:9\3\2\2\2:;\3\2\2\2;=\3\2\2\2<>\5\b\5\2"+ - "=<\3\2\2\2=>\3\2\2\2>\3\3\2\2\2?@\7\3\2\2@A\7\4\2\2AB\5\f\7\2BC\7\5\2"+ - "\2C\5\3\2\2\2DE\5\n\6\2E\7\3\2\2\2FG\7\6\2\2GH\5\20\t\2H\t\3\2\2\2IJ\7"+ - "\7\2\2JK\7\60\2\2KL\7\4\2\2LM\5\f\7\2MN\7\5\2\2N\13\3\2\2\2OT\5\16\b\2"+ - "PQ\7\b\2\2QS\5\16\b\2RP\3\2\2\2SV\3\2\2\2TR\3\2\2\2TU\3\2\2\2U\r\3\2\2"+ - "\2VT\3\2\2\2WX\7\60\2\2X\17\3\2\2\2Y^\5\22\n\2Z[\7\t\2\2[]\5\22\n\2\\"+ - "Z\3\2\2\2]`\3\2\2\2^\\\3\2\2\2^_\3\2\2\2_\21\3\2\2\2`^\3\2\2\2af\5\24"+ - "\13\2bc\7\n\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\2ik\7\13\2\2ji\3\2\2\2jk\3\2\2\2kl\3\2\2\2lm\5\26\f\2"+ - "m\25\3\2\2\2nt\5\30\r\2op\7\4\2\2pq\5\20\t\2qr\7\5\2\2rt\3\2\2\2sn\3\2"+ - "\2\2so\3\2\2\2t\27\3\2\2\2u\u0083\5.\30\2v\u0083\5*\26\2w\u0083\5\36\20"+ - "\2x\u0083\5 \21\2y\u0083\5\32\16\2z\u0083\5\"\22\2{\u0083\5$\23\2|\u0083"+ - "\5&\24\2}\u0083\5(\25\2~\177\7\4\2\2\177\u0080\5\30\r\2\u0080\u0081\7"+ - "\5\2\2\u0081\u0083\3\2\2\2\u0082u\3\2\2\2\u0082v\3\2\2\2\u0082w\3\2\2"+ - "\2\u0082x\3\2\2\2\u0082y\3\2\2\2\u0082z\3\2\2\2\u0082{\3\2\2\2\u0082|"+ - "\3\2\2\2\u0082}\3\2\2\2\u0082~\3\2\2\2\u0083\31\3\2\2\2\u0084\u0085\7"+ - "\60\2\2\u0085\u0086\7\f\2\2\u0086\u0087\5\34\17\2\u0087\33\3\2\2\2\u0088"+ - "\u0095\7/\2\2\u0089\u008a\7\4\2\2\u008a\u008f\5\62\32\2\u008b\u008c\7"+ - "\b\2\2\u008c\u008e\5\62\32\2\u008d\u008b\3\2\2\2\u008e\u0091\3\2\2\2\u008f"+ - "\u008d\3\2\2\2\u008f\u0090\3\2\2\2\u0090\u0092\3\2\2\2\u0091\u008f\3\2"+ - "\2\2\u0092\u0093\7\5\2\2\u0093\u0095\3\2\2\2\u0094\u0088\3\2\2\2\u0094"+ - "\u0089\3\2\2\2\u0095\35\3\2\2\2\u0096\u0097\7\60\2\2\u0097\u0098\7\r\2"+ - "\2\u0098\u0099\5\62\32\2\u0099\u009a\7\n\2\2\u009a\u009b\5\62\32\2\u009b"+ - "\37\3\2\2\2\u009c\u009d\5\62\32\2\u009d\u009e\7\r\2\2\u009e\u009f\7\60"+ - "\2\2\u009f\u00a0\7\n\2\2\u00a0\u00a1\7\60\2\2\u00a1!\3\2\2\2\u00a2\u00a3"+ - "\7\60\2\2\u00a3\u00a4\7\16\2\2\u00a4\u00a8\7\17\2\2\u00a5\u00a6\7\60\2"+ - "\2\u00a6\u00a8\7\20\2\2\u00a7\u00a2\3\2\2\2\u00a7\u00a5\3\2\2\2\u00a8"+ - "#\3\2\2\2\u00a9\u00aa\7\60\2\2\u00aa\u00ab\7\16\2\2\u00ab\u00ac\7\13\2"+ - "\2\u00ac\u00b2\7\17\2\2\u00ad\u00ae\7\60\2\2\u00ae\u00b2\7\21\2\2\u00af"+ - "\u00b0\7\60\2\2\u00b0\u00b2\7\22\2\2\u00b1\u00a9\3\2\2\2\u00b1\u00ad\3"+ - "\2\2\2\u00b1\u00af\3\2\2\2\u00b2%\3\2\2\2\u00b3\u00b4\7\60\2\2\u00b4\u00b5"+ - "\7\16\2\2\u00b5\u00b9\7\23\2\2\u00b6\u00b7\7\60\2\2\u00b7\u00b9\7\24\2"+ - "\2\u00b8\u00b3\3\2\2\2\u00b8\u00b6\3\2\2\2\u00b9\'\3\2\2\2\u00ba\u00bb"+ - "\7\60\2\2\u00bb\u00bc\7\16\2\2\u00bc\u00bd\7\13\2\2\u00bd\u00c3\7\23\2"+ - "\2\u00be\u00bf\7\60\2\2\u00bf\u00c3\7\25\2\2\u00c0\u00c1\7\60\2\2\u00c1"+ - "\u00c3\7\26\2\2\u00c2\u00ba\3\2\2\2\u00c2\u00be\3\2\2\2\u00c2\u00c0\3"+ - "\2\2\2\u00c3)\3\2\2\2\u00c4\u00c5\7\60\2\2\u00c5\u00c6\5,\27\2\u00c6\u00c7"+ - "\5\62\32\2\u00c7+\3\2\2\2\u00c8\u00c9\t\2\2\2\u00c9-\3\2\2\2\u00ca\u00cb"+ - "\7\60\2\2\u00cb\u00cc\5\60\31\2\u00cc\u00cd\5\62\32\2\u00cd/\3\2\2\2\u00ce"+ - "\u00cf\t\3\2\2\u00cf\61\3\2\2\2\u00d0\u00d3\5\64\33\2\u00d1\u00d3\7/\2"+ - "\2\u00d2\u00d0\3\2\2\2\u00d2\u00d1\3\2\2\2\u00d3\63\3\2\2\2\u00d4\u00d5"+ - "\t\4\2\2\u00d5\65\3\2\2\2\22\67:=T^fjs\u0082\u008f\u0094\u00a7\u00b1\u00b8"+ - "\u00c2\u00d2"; + "\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"; 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 0344dea96..c7042d557 100644 --- a/src/test/java/com/avaje/ebeaninternal/server/grammer/EqlParserTest.java +++ b/src/test/java/com/avaje/ebeaninternal/server/grammer/EqlParserTest.java @@ -185,6 +185,43 @@ public class EqlParserTest { assertThat(query.getGeneratedSql()).contains("where ? between t0.name and t0.smallnote"); } + @Test + public void fetch_basic() throws Exception { + + Query query = parse("fetch billingAddress"); + query.findList(); + + assertThat(query.getGeneratedSql()).contains(", t1.id c9"); + } + + @Test + public void fetch_withProperty() 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 { + + Query query = parse("fetch billingAddress fetch shippingAddress"); + query.findList(); + + assertThat(query.getGeneratedSql()).contains(", t1.city "); + assertThat(query.getGeneratedSql()).contains(", t2.city "); + } + + @Test + public void fetch_basic_multiple_withProperties() throws Exception { + + Query query = parse("fetch billingAddress (city) fetch shippingAddress (city)"); + query.findList(); + + assertThat(query.getGeneratedSql()).contains(", t1.id c8, t1.city c9, t2.id c10, t2.city c11"); + } + private Query parse(String raw) { Query query = Ebean.find(Customer.class); diff --git a/src/test/resources/EQL.g4 b/src/test/resources/EQL.g4 index d7a8c68e8..af63bbf17 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)? + : (select_clause)? (fetch_clause)* (where_clause)? ; select_clause @@ -17,7 +17,11 @@ where_clause ; fetch_path - : 'fetch' PATH_VARIABLE '(' fetch_property_group ')' + : 'fetch' PATH_VARIABLE fetch_property_set? + ; + +fetch_property_set + : '(' fetch_property_group ')' ; fetch_property_group