diff --git a/src/main/antlr4/org/s1ck/gdl/GDL.g4 b/src/main/antlr4/org/s1ck/gdl/GDL.g4 index f843a98..9dcb950 100644 --- a/src/main/antlr4/org/s1ck/gdl/GDL.g4 +++ b/src/main/antlr4/org/s1ck/gdl/GDL.g4 @@ -180,6 +180,7 @@ complexIntervalArgument timePoint : timeLiteral | timeSelector + | complexTimePoint ; timeLiteral @@ -194,6 +195,16 @@ timeSelector | TimeProp ; +complexTimePoint + : 'MAX(' complexTimePointArgument ',' complexTimePointArgument (','complexTimePointArgument) ')' + | 'MIN(' complexTimePointArgument ',' complexTimePointArgument (','complexTimePointArgument) ')' + ; + +complexTimePointArgument + : timeLiteral + | timeSelector + ; + intervalFunc : overlapsIntervallOperator | fromToOperator diff --git a/src/main/java/org/s1ck/gdl/GDLLoader.java b/src/main/java/org/s1ck/gdl/GDLLoader.java index acfca34..5fd64f9 100644 --- a/src/main/java/org/s1ck/gdl/GDLLoader.java +++ b/src/main/java/org/s1ck/gdl/GDLLoader.java @@ -806,15 +806,50 @@ private Predicate createAfterPredicates(TimePoint from, GDLParser.AfterPointOper */ private TimePoint buildTimePoint(GDLParser.TimePointContext ctx) { if (ctx.timeLiteral() != null){ - return new TimeLiteral(ctx.getText()); + return buildTimeLiteral(ctx.timeLiteral()); } else if (ctx.timeSelector()!=null){ - GDLParser.TimeSelectorContext ts = ctx.timeSelector(); - // checks whether ID is even there (is a vertex or edge) and returns its variable - String var = ts.Identifier()!=null ? - resolveIdentifier(ts.Identifier().getText()) : TimeSelector.GLOBAL_SELECTOR; - String field = ts.TimeProp().getText(); - return new TimeSelector(var, field); + return buildTimeSelector(ctx.timeSelector()); + } + else if (ctx.complexTimePoint()!=null){ + return buildComplexTimePoint(ctx.complexTimePoint()); + } + return null; + } + + private TimeLiteral buildTimeLiteral(GDLParser.TimeLiteralContext ctx){ + return new TimeLiteral(ctx.getText().trim()); + } + + private TimeSelector buildTimeSelector(GDLParser.TimeSelectorContext ctx){ + // checks whether ID is even there (is a vertex or edge) and returns its variable + String var = ctx.Identifier()!=null ? + resolveIdentifier(ctx.Identifier().getText()) : TimeSelector.GLOBAL_SELECTOR; + String field = ctx.TimeProp().getText(); + return new TimeSelector(var, field); + } + + private TimePoint buildComplexTimePoint(GDLParser.ComplexTimePointContext ctx){ + + List argumentContexts = + ctx.complexTimePointArgument(); + TimePoint[] args = new TimePoint[argumentContexts.size()]; + + for(int i=0; i(b) " + + "WHERE MIN(a.tx_from, b.tx_from, e.tx_from).before(2020-05-05)"); + Predicate expected = new Or( + new Or( + new Comparison(aTxFrom, LT, literal1), + new Comparison(bTxFrom, LT, literal1) + ), + new Comparison(eTxFrom, LT, literal1) + ); + assertPredicateEquals(loader.getPredicates().get(), expected); + + loader = getLoaderFromGDLString("MATCH (a)-[e]->(b) " + + "WHERE MAX(a.tx_from, b.tx_from, e.tx_from).before(2020-05-05)"); + expected = new And( + new And( + new Comparison(aTxFrom, LT, literal1), + new Comparison(bTxFrom, LT, literal1) + ), + new Comparison(eTxFrom, LT, literal1) + ); + assertPredicateEquals(loader.getPredicates().get(), expected); + loader = getLoaderFromGDLString("MATCH (a)-[e]->(b) " + + "WHERE MAX(a.tx_from, b.tx_from, e.tx_from).after(" + + "MIN(a.val_to, b.val_to, e.val_to))"); + expected = new Or( + //a, b + new Or( + // a + new Or(new Or( + new Comparison(aTxFrom, GT, aValTo), + new Comparison(aTxFrom, GT, bValTo) + ), + new Comparison(aTxFrom, GT, eValTo) + ), + // b + new Or( + new Or( + new Comparison(bTxFrom, GT, aValTo), + new Comparison(bTxFrom, GT, bValTo) + ), + new Comparison(bTxFrom, GT, eValTo) + ) + ), + //e + new Or( + new Or( + new Comparison(eTxFrom, GT, aValTo), + new Comparison(eTxFrom, GT, bValTo) + ), + new Comparison(eTxFrom, GT, eValTo) + ) + ); + assertPredicateEquals(loader.getPredicates().get(), expected); + loader = getLoaderFromGDLString("MATCH (a)-[e]->(b) " + + "WHERE MIN(a.tx_from, b.tx_from, e.tx_from).before(2020-05-05) AND" + + " a.tx.succeeds(b.tx)"); + expected = new And( + new Or( + new Or( + new Comparison(aTxFrom, LT, literal1), + new Comparison(bTxFrom, LT, literal1) + ), + new Comparison(eTxFrom, LT, literal1) + ), + new Comparison(aTxFrom, GTE, new TimeSelector("b", TX_TO)) + ); + assertPredicateEquals(loader.getPredicates().get(), expected); + System.out.println(loader.getPredicates().get()); + + } + /** * Does not fail iff {@code result==expected} or {@code result.switchSides()==expected} * @param result predicate to compare