From d02429fe46cac7acd79a6cd63351fc4fb94ac364 Mon Sep 17 00:00:00 2001 From: lc0197 Date: Thu, 7 May 2020 15:04:17 +0200 Subject: [PATCH] changed query processing to only translate global predicates --- pom.xml | 1 + src/main/java/org/s1ck/gdl/GDLHandler.java | 18 ++++++++- src/main/java/org/s1ck/gdl/GDLLoader.java | 9 +++++ .../comparables/ComparableExpression.java | 21 ++++++++++ .../model/comparables/ElementSelector.java | 21 ++++++++-- .../s1ck/gdl/model/comparables/Literal.java | 20 ++++++++-- .../model/comparables/PropertySelector.java | 21 ++++++++-- .../model/comparables/time/MaxTimePoint.java | 16 ++++++++ .../model/comparables/time/MinTimePoint.java | 16 ++++++++ .../model/comparables/time/PlusTimePoint.java | 13 +++++- .../model/comparables/time/TimeLiteral.java | 16 +++++++- .../gdl/model/comparables/time/TimePoint.java | 16 -------- .../model/comparables/time/TimeSelector.java | 40 +++++++++++++++---- .../gdl/model/comparables/time/TimeTerm.java | 9 +++-- .../s1ck/gdl/model/predicates/Predicate.java | 11 +++++ .../gdl/model/predicates/booleans/And.java | 6 +++ .../gdl/model/predicates/booleans/Not.java | 5 +++ .../gdl/model/predicates/booleans/Or.java | 6 +++ .../gdl/model/predicates/booleans/Xor.java | 6 +++ .../predicates/expressions/Comparison.java | 11 ++++- .../org/s1ck/gdl/GDLLoaderTemporalTest.java | 12 ++++-- .../gdl/comparables/time/MaxTimeTest.java | 17 +++++++- .../gdl/comparables/time/MinTimeTest.java | 14 +++++++ .../gdl/comparables/time/PlusTimeTest.java | 21 +++++++++- .../gdl/comparables/time/TimeLiteralTest.java | 4 ++ .../comparables/time/TimeSelectorTest.java | 29 +++++++++++++- 26 files changed, 327 insertions(+), 52 deletions(-) diff --git a/pom.xml b/pom.xml index 18a5473..01ea288 100644 --- a/pom.xml +++ b/pom.xml @@ -7,6 +7,7 @@ 0.3.5-SNAPSHOT + GDL - Graph Definition Language ANTLR Grammar for the definition of extended property graphs. http://github.com/s1ck/gdl.git diff --git a/src/main/java/org/s1ck/gdl/GDLHandler.java b/src/main/java/org/s1ck/gdl/GDLHandler.java index 745e885..087b950 100644 --- a/src/main/java/org/s1ck/gdl/GDLHandler.java +++ b/src/main/java/org/s1ck/gdl/GDLHandler.java @@ -199,6 +199,11 @@ public static class Builder { */ private boolean useDefaultEdgeLabel = true; + /** + * Flag to indicate if the query should be postprocessed, i.e. reduced to simple comparisons. + */ + private boolean processQuery = true; + /** * Strategy for handling parser errors. */ @@ -308,6 +313,17 @@ public Builder setErrorStrategy(ANTLRErrorStrategy errorStrategy) { return this; } + /** + * Sets the processQuery parameter for the {@link GDLLoader}. + * + * @param processQuery processQuery flag (true iff query should be postprocessed) + * @return builder + */ + public Builder setProcessQuery(boolean processQuery){ + this.processQuery = processQuery; + return this; + } + /** * Initialize GDL Handler from given ASCII String. * @@ -367,7 +383,7 @@ private GDLHandler build(ANTLRInputStream antlrInputStream) { parser.setErrorHandler(errorStrategy); GDLLoader loader = new GDLLoader(graphLabel, vertexLabel, edgeLabel, - useDefaultGraphLabel, useDefaultVertexLabel, useDefaultEdgeLabel); + useDefaultGraphLabel, useDefaultVertexLabel, useDefaultEdgeLabel, processQuery); new ParseTreeWalker().walk(loader, parser.database()); return new GDLHandler(loader); } diff --git a/src/main/java/org/s1ck/gdl/GDLLoader.java b/src/main/java/org/s1ck/gdl/GDLLoader.java index c981119..689b450 100644 --- a/src/main/java/org/s1ck/gdl/GDLLoader.java +++ b/src/main/java/org/s1ck/gdl/GDLLoader.java @@ -352,6 +352,15 @@ public void exitQuery(GDLParser.QueryContext ctx) { if(processPredicates) { postprocessPredicates(); } + ArrayList vars = new ArrayList<>(); + vars.addAll(userEdgeCache.keySet()); + vars.addAll(userVertexCache.keySet()); + vars.addAll(autoEdgeCache.keySet()); + vars.addAll(autoVertexCache.keySet()); + vars.remove(TimeSelector.GLOBAL_SELECTOR); + if(predicates!=null) { + predicates = predicates.replaceGlobalByLocal(vars); + } for(Vertex v : vertices) { addPredicates(Predicate.fromGraphElement(v, getDefaultVertexLabel())); } diff --git a/src/main/java/org/s1ck/gdl/model/comparables/ComparableExpression.java b/src/main/java/org/s1ck/gdl/model/comparables/ComparableExpression.java index 6ff9e7d..60fbde4 100644 --- a/src/main/java/org/s1ck/gdl/model/comparables/ComparableExpression.java +++ b/src/main/java/org/s1ck/gdl/model/comparables/ComparableExpression.java @@ -17,12 +17,22 @@ package org.s1ck.gdl.model.comparables; import org.s1ck.gdl.model.comparables.time.TimeSelector; +import org.s1ck.gdl.model.predicates.Predicate; import java.io.Serializable; +import java.util.List; +import java.util.Set; public interface ComparableExpression extends Serializable{ + /** + * Returns the variables of the expression + * @return variable + */ + public Set getVariables(); + /** * Returns the variable of the expression + * Same functionality is given by {@code getVariables}, kept for downward compatibility * @return variable */ public String getVariable(); @@ -40,4 +50,15 @@ public interface ComparableExpression extends Serializable{ */ boolean isGlobal(); + /** + * Replaces global time selectors like __global.val_from by their equivalent expressions + * over all local variables. + * E.g., {@code __global.val_from} would be replaced by {@code MAX(v1.val_from,..., + * vn.val_from)} for variables {@code v1,...,vn}. + * @param variables all query variables + * @return comparable with global selector replaced by their local variable equivalent + * expressions. If comparable is not a global time selector, identity function. + */ + ComparableExpression replaceGlobalByLocal(List variables); + } diff --git a/src/main/java/org/s1ck/gdl/model/comparables/ElementSelector.java b/src/main/java/org/s1ck/gdl/model/comparables/ElementSelector.java index cb563c5..e37ef4b 100644 --- a/src/main/java/org/s1ck/gdl/model/comparables/ElementSelector.java +++ b/src/main/java/org/s1ck/gdl/model/comparables/ElementSelector.java @@ -18,6 +18,11 @@ import org.s1ck.gdl.model.comparables.time.TimeSelector; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + /** * Used to compare elements (by id) */ @@ -37,15 +42,23 @@ public ElementSelector(String variable) { this.variable = variable; } - /** - * Returns the variable which references the element - * @return variable name - */ + @Override + public Set getVariables() { + HashSet var = new HashSet<>(); + var.add(variable); + return var; + } + @Override public String getVariable() { return this.variable; } + @Override + public ComparableExpression replaceGlobalByLocal(List variables) { + return this; + } + @Override public boolean containsSelectorType(TimeSelector.TimeField type){ return false; diff --git a/src/main/java/org/s1ck/gdl/model/comparables/Literal.java b/src/main/java/org/s1ck/gdl/model/comparables/Literal.java index 6db250e..dd72999 100644 --- a/src/main/java/org/s1ck/gdl/model/comparables/Literal.java +++ b/src/main/java/org/s1ck/gdl/model/comparables/Literal.java @@ -18,6 +18,11 @@ import org.s1ck.gdl.model.comparables.time.TimeSelector; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + /** * Represents a literal like String, Integer, ... */ @@ -41,10 +46,17 @@ public Object getValue() { return value; } - /** - * Returns null since this does not reference a variable - * @return null - */ + + @Override + public Set getVariables() { + return new HashSet(); + } + + @Override + public ComparableExpression replaceGlobalByLocal(List variables) { + return this; + } + @Override public String getVariable() { return null; diff --git a/src/main/java/org/s1ck/gdl/model/comparables/PropertySelector.java b/src/main/java/org/s1ck/gdl/model/comparables/PropertySelector.java index c1e4b1c..658c80c 100644 --- a/src/main/java/org/s1ck/gdl/model/comparables/PropertySelector.java +++ b/src/main/java/org/s1ck/gdl/model/comparables/PropertySelector.java @@ -18,6 +18,11 @@ import org.s1ck.gdl.model.comparables.time.TimeSelector; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + /** * Selects a property of a variable */ @@ -47,10 +52,13 @@ public String getPropertyName() { return propertyName; } - /** - * Returns the variable which references the element - * @return variable name - */ + @Override + public Set getVariables() { + HashSet var = new HashSet<>(); + var.add(variable); + return var; + } + @Override public String getVariable() { return this.variable; @@ -66,6 +74,11 @@ public boolean isGlobal(){ return false; } + @Override + public ComparableExpression replaceGlobalByLocal(List variables) { + return this; + } + @Override public String toString() { return variable + "." + propertyName; diff --git a/src/main/java/org/s1ck/gdl/model/comparables/time/MaxTimePoint.java b/src/main/java/org/s1ck/gdl/model/comparables/time/MaxTimePoint.java index 878beb2..4fe23fb 100644 --- a/src/main/java/org/s1ck/gdl/model/comparables/time/MaxTimePoint.java +++ b/src/main/java/org/s1ck/gdl/model/comparables/time/MaxTimePoint.java @@ -1,5 +1,6 @@ package org.s1ck.gdl.model.comparables.time; +import org.s1ck.gdl.model.comparables.ComparableExpression; import org.s1ck.gdl.model.predicates.Predicate; import org.s1ck.gdl.model.predicates.booleans.And; import org.s1ck.gdl.model.predicates.booleans.Not; @@ -8,6 +9,7 @@ import org.s1ck.gdl.utils.Comparator; import java.util.ArrayList; +import java.util.List; /** * Represents a MAX(p1,...,pn) term, where p1...pn are TimePoints @@ -70,6 +72,11 @@ public long getUpperBound(){ return res; } + @Override + public String getVariable() { + return null; + } + @Override public boolean containsSelectorType(TimeSelector.TimeField type){ for(TimePoint p: args){ @@ -186,6 +193,15 @@ protected Predicate unfoldLTE(TimePoint arg){ return disjGt; } + @Override + public ComparableExpression replaceGlobalByLocal(List variables) { + TimePoint[] newArgs = new TimePoint[args.size()]; + for(int i=0; i variables) { + TimePoint[] newArgs = new TimePoint[args.size()]; + for(int i=0; i getVariables() { + public Set getVariables() { return timePoint.getVariables(); } + @Override + public String getVariable() { + return timePoint.getVariable(); + } + @Override public long evaluate(){ long tp = timePoint.evaluate(); @@ -293,4 +299,9 @@ private Predicate forAllVariables(Comparator comp, ComparableExpression rhs, Lis public boolean isGlobal(){ return timePoint.isGlobal(); } + + @Override + public ComparableExpression replaceGlobalByLocal(List variables) { + return new PlusTimePoint((TimePoint)timePoint.replaceGlobalByLocal(variables), constant); + } } diff --git a/src/main/java/org/s1ck/gdl/model/comparables/time/TimeLiteral.java b/src/main/java/org/s1ck/gdl/model/comparables/time/TimeLiteral.java index e8febc3..c486d06 100644 --- a/src/main/java/org/s1ck/gdl/model/comparables/time/TimeLiteral.java +++ b/src/main/java/org/s1ck/gdl/model/comparables/time/TimeLiteral.java @@ -6,7 +6,9 @@ import java.time.*; import java.util.ArrayList; +import java.util.HashSet; import java.util.List; +import java.util.Set; import org.s1ck.gdl.utils.Comparator; @@ -124,8 +126,13 @@ public int getSecond(){ @Override - public ArrayList getVariables(){ - return new ArrayList<>(); + public Set getVariables(){ + return new HashSet<>(); + } + + @Override + public String getVariable() { + return null; } @Override @@ -182,4 +189,9 @@ public Predicate unfoldGlobal(Comparator comp, ComparableExpression rhs, List variables) { + return this; + } } diff --git a/src/main/java/org/s1ck/gdl/model/comparables/time/TimePoint.java b/src/main/java/org/s1ck/gdl/model/comparables/time/TimePoint.java index f435b73..5bcab48 100644 --- a/src/main/java/org/s1ck/gdl/model/comparables/time/TimePoint.java +++ b/src/main/java/org/s1ck/gdl/model/comparables/time/TimePoint.java @@ -17,22 +17,6 @@ public abstract class TimePoint implements ComparableExpression { */ public static final long UNDEFINED = -1L; - /** - * Returns null, no variable involved in a timestamp by default - * Not often used in implementations, as typically more than one variable can be involved - * @return null - */ - @Override - public String getVariable() { - return null; - } - - /** - * all variables involved in the expression - * @return ArrayList of variable names (potentially empty) - */ - public abstract ArrayList getVariables(); - /** * calculates the value of the timestamp (UNIX epoch long), if possible. * E.g., a timestamp like v.VAL_FROM can not be assigned a unique long value diff --git a/src/main/java/org/s1ck/gdl/model/comparables/time/TimeSelector.java b/src/main/java/org/s1ck/gdl/model/comparables/time/TimeSelector.java index 4166cce..57d4071 100644 --- a/src/main/java/org/s1ck/gdl/model/comparables/time/TimeSelector.java +++ b/src/main/java/org/s1ck/gdl/model/comparables/time/TimeSelector.java @@ -8,7 +8,9 @@ import org.s1ck.gdl.utils.Comparator; import java.util.ArrayList; +import java.util.HashSet; import java.util.List; +import java.util.Set; import static org.s1ck.gdl.utils.Comparator.*; @@ -82,18 +84,19 @@ public TimeSelector(String variable, String field){ this(variable, stringToField(field)); } - @Override - public String getVariable() { - return variable; - } @Override - public ArrayList getVariables(){ - ArrayList ls = new ArrayList<>(); + public Set getVariables(){ + Set ls = new HashSet<>(); ls.add(variable); return ls; } + @Override + public String getVariable() { + return variable; + } + /** * Returns the TimeField (VAL_FROM, VAL_TO, TX_FROM, TX_TO) * @return the TimeField @@ -330,6 +333,29 @@ public boolean isGlobal(){ return variable.equals(GLOBAL_SELECTOR); } + @Override + public ComparableExpression replaceGlobalByLocal(List variables) { + if(!variable.equals(GLOBAL_SELECTOR)){ + return this; + } + + TimeSelector[] selectors = new TimeSelector[variables.size()]; + for(int i=0; i args){ } @Override - public ArrayList getVariables(){ - ArrayList vars = new ArrayList<>(); + public Set getVariables(){ + HashSet vars = new HashSet<>(); for (TimePoint tp: args){ vars.addAll(tp.getVariables()); } return vars; } + /** * String representation of the operator (e.g. "MIN", "MAX",...) * @return operator string diff --git a/src/main/java/org/s1ck/gdl/model/predicates/Predicate.java b/src/main/java/org/s1ck/gdl/model/predicates/Predicate.java index 56a9dba..1dfeffa 100644 --- a/src/main/java/org/s1ck/gdl/model/predicates/Predicate.java +++ b/src/main/java/org/s1ck/gdl/model/predicates/Predicate.java @@ -175,4 +175,15 @@ static Predicate translateGlobalPredicates(Predicate predicate, ArrayList variables); + /** + * Replaces global selectors like __global.val_from by their equivalent expressions + * over all local variables. + * E.g., {@code __global.val_from} would be replaced by {@code MAX(v1.val_from,..., + * vn.val_from)} for variables {@code v1,...,vn}. + * @param variables all query variables + * @return predicate with global selectors replaced by their local variable equivalent + * expressions + */ + Predicate replaceGlobalByLocal(List variables); + } diff --git a/src/main/java/org/s1ck/gdl/model/predicates/booleans/And.java b/src/main/java/org/s1ck/gdl/model/predicates/booleans/And.java index b4414ac..f642635 100644 --- a/src/main/java/org/s1ck/gdl/model/predicates/booleans/And.java +++ b/src/main/java/org/s1ck/gdl/model/predicates/booleans/And.java @@ -82,6 +82,12 @@ public boolean isGlobal(){ return lhs.isGlobal() || rhs.isGlobal(); } + @Override + public Predicate replaceGlobalByLocal(List variables) { + return new And(lhs.replaceGlobalByLocal(variables), + rhs.replaceGlobalByLocal(variables)); + } + @Override public String toString() { return String.format("(%s AND %s)", lhs, rhs); diff --git a/src/main/java/org/s1ck/gdl/model/predicates/booleans/Not.java b/src/main/java/org/s1ck/gdl/model/predicates/booleans/Not.java index 9a41793..4a12b69 100644 --- a/src/main/java/org/s1ck/gdl/model/predicates/booleans/Not.java +++ b/src/main/java/org/s1ck/gdl/model/predicates/booleans/Not.java @@ -80,6 +80,11 @@ public boolean isGlobal(){ return expression.isGlobal(); } + @Override + public Predicate replaceGlobalByLocal(List variables) { + return new Not(expression.replaceGlobalByLocal(variables)); + } + @Override public boolean equals(Object o){ if(o==null){ diff --git a/src/main/java/org/s1ck/gdl/model/predicates/booleans/Or.java b/src/main/java/org/s1ck/gdl/model/predicates/booleans/Or.java index 0ce115a..40142f5 100644 --- a/src/main/java/org/s1ck/gdl/model/predicates/booleans/Or.java +++ b/src/main/java/org/s1ck/gdl/model/predicates/booleans/Or.java @@ -77,6 +77,12 @@ public Predicate unfoldGlobalLeft(List variables) { return new Or(lhs.unfoldGlobalLeft(variables), rhs.unfoldGlobalLeft(variables)); } + @Override + public Predicate replaceGlobalByLocal(List variables) { + return new Or(lhs.replaceGlobalByLocal(variables), + rhs.replaceGlobalByLocal(variables)); + } + @Override public boolean isGlobal(){ return lhs.isGlobal() || rhs.isGlobal(); diff --git a/src/main/java/org/s1ck/gdl/model/predicates/booleans/Xor.java b/src/main/java/org/s1ck/gdl/model/predicates/booleans/Xor.java index e485a98..e1f1c77 100644 --- a/src/main/java/org/s1ck/gdl/model/predicates/booleans/Xor.java +++ b/src/main/java/org/s1ck/gdl/model/predicates/booleans/Xor.java @@ -77,6 +77,12 @@ public Predicate unfoldGlobalLeft(List variables) { return new Xor(lhs.unfoldGlobalLeft(variables), rhs.unfoldGlobalLeft(variables)); } + @Override + public Predicate replaceGlobalByLocal(List variables) { + return new Xor(lhs.replaceGlobalByLocal(variables), + rhs.replaceGlobalByLocal(variables)); + } + @Override public boolean isGlobal(){ return lhs.isGlobal() || rhs.isGlobal(); diff --git a/src/main/java/org/s1ck/gdl/model/predicates/expressions/Comparison.java b/src/main/java/org/s1ck/gdl/model/predicates/expressions/Comparison.java index 1f96cc6..1a89eb3 100644 --- a/src/main/java/org/s1ck/gdl/model/predicates/expressions/Comparison.java +++ b/src/main/java/org/s1ck/gdl/model/predicates/expressions/Comparison.java @@ -96,6 +96,13 @@ public Predicate unfoldGlobalLeft(List variables) { } + @Override + public Predicate replaceGlobalByLocal(List variables) { + return new Comparison(lhs.replaceGlobalByLocal(variables), + comparator, + rhs.replaceGlobalByLocal(variables)); + } + @Override public Predicate unfoldTemporalComparisonsLeft(){ if (!isTemporal()){ @@ -139,8 +146,8 @@ else if(comparator == Comparator.LT){ @Override public Set getVariables() { Set variables = new HashSet<>(); - if(lhs.getVariable() != null) variables.add(lhs.getVariable()); - if(rhs.getVariable() != null) variables.add(rhs.getVariable()); + if(lhs.getVariables() != null) variables.addAll(lhs.getVariables()); + if(rhs.getVariables() != null) variables.addAll(rhs.getVariables()); return variables; } diff --git a/src/test/java/org/s1ck/gdl/GDLLoaderTemporalTest.java b/src/test/java/org/s1ck/gdl/GDLLoaderTemporalTest.java index 981d5cc..49324b4 100644 --- a/src/test/java/org/s1ck/gdl/GDLLoaderTemporalTest.java +++ b/src/test/java/org/s1ck/gdl/GDLLoaderTemporalTest.java @@ -248,8 +248,12 @@ public void globalPredicateTest(){ TimeSelector eFrom = new TimeSelector("e", TX_FROM); TimeSelector eTo = new TimeSelector("e", TX_TO); - TimeSelector globalFrom = new TimeSelector(TimeSelector.GLOBAL_SELECTOR, TX_FROM); - TimeSelector globalTo = new TimeSelector(TimeSelector.GLOBAL_SELECTOR, TX_TO); + MaxTimePoint globalFrom = new MaxTimePoint( + eFrom, aFrom, bFrom + ); + MinTimePoint globalTo = new MinTimePoint( + eTo, aTo, bTo + ); // only lhs global GDLLoader loaderDoProcess = getLoaderFromGDLString("MATCH (a)-[e]->(b) " + "WHERE tx.between(1970-01-01, 2020-05-01)"); @@ -307,7 +311,9 @@ public void globalPredicateTest(){ TimeSelector aValTo = new TimeSelector("a", VAL_TO); TimeSelector bValTo = new TimeSelector("b", VAL_TO); TimeSelector eValTo = new TimeSelector("e", VAL_TO); - TimeSelector globalValTo = new TimeSelector(TimeSelector.GLOBAL_SELECTOR, VAL_TO); + MinTimePoint globalValTo = new MinTimePoint( + eValTo, bValTo, eValTo + ); Predicate resultProcessed3 = loaderDoProcess.getPredicates().get(); Predicate expectedProcessed3 = new And( new And( diff --git a/src/test/java/org/s1ck/gdl/comparables/time/MaxTimeTest.java b/src/test/java/org/s1ck/gdl/comparables/time/MaxTimeTest.java index a5ce0f6..2e1fc6d 100644 --- a/src/test/java/org/s1ck/gdl/comparables/time/MaxTimeTest.java +++ b/src/test/java/org/s1ck/gdl/comparables/time/MaxTimeTest.java @@ -7,6 +7,9 @@ import org.s1ck.gdl.model.predicates.expressions.Comparison; import org.s1ck.gdl.utils.Comparator; +import java.util.ArrayList; +import java.util.Arrays; + import static org.junit.Assert.*; public class MaxTimeTest { @@ -303,9 +306,21 @@ public void containsTxToTest(){ public void globalTest(){ TimeSelector s1 = new TimeSelector("a", "val_to"); TimeLiteral l = new TimeLiteral("2020-04-28"); - TimeSelector global = new TimeSelector(TimeSelector.GLOBAL_SELECTOR, TimeSelector.TimeField.VAL_TO); + TimeSelector global = new TimeSelector(TimeSelector.GLOBAL_SELECTOR, + TimeSelector.TimeField.VAL_TO); assertTrue(new MaxTimePoint(s1, l, global).isGlobal()); assertFalse(new MaxTimePoint(s1,l,l,s1).isGlobal()); + + ArrayList variables = new ArrayList<>(Arrays.asList("a","b")); + MinTimePoint mn = new MinTimePoint( + new TimeSelector("a", TimeSelector.TimeField.VAL_TO), + new TimeSelector("b", TimeSelector.TimeField.VAL_TO) + ); + + MaxTimePoint test = new MaxTimePoint(global, l); + MaxTimePoint expected = new MaxTimePoint(mn, l); + + assertEquals(expected, test.replaceGlobalByLocal(variables)); } } diff --git a/src/test/java/org/s1ck/gdl/comparables/time/MinTimeTest.java b/src/test/java/org/s1ck/gdl/comparables/time/MinTimeTest.java index c5a8800..062ee6d 100644 --- a/src/test/java/org/s1ck/gdl/comparables/time/MinTimeTest.java +++ b/src/test/java/org/s1ck/gdl/comparables/time/MinTimeTest.java @@ -12,6 +12,9 @@ import org.s1ck.gdl.model.predicates.expressions.Comparison; import org.s1ck.gdl.utils.Comparator; +import java.util.ArrayList; +import java.util.Arrays; + import static org.junit.Assert.*; public class MinTimeTest { @@ -313,6 +316,17 @@ public void globalTest(){ TimeLiteral l = new TimeLiteral("2020-04-28"); TimeSelector global = new TimeSelector(TimeSelector.GLOBAL_SELECTOR, "tx_from"); + ArrayList variables = new ArrayList<>(Arrays.asList("a","b")); + MaxTimePoint mx = new MaxTimePoint( + new TimeSelector("a", TimeSelector.TimeField.TX_FROM), + new TimeSelector("b", TimeSelector.TimeField.TX_FROM) + ); + + MinTimePoint test = new MinTimePoint(global, l); + MinTimePoint expected = new MinTimePoint(mx, l); + + assertEquals(expected, test.replaceGlobalByLocal(variables)); + assertTrue(new MinTimePoint(s1,global, l, global).isGlobal()); assertFalse(new MinTimePoint(s1,l).isGlobal()); } diff --git a/src/test/java/org/s1ck/gdl/comparables/time/PlusTimeTest.java b/src/test/java/org/s1ck/gdl/comparables/time/PlusTimeTest.java index 14b7bee..78f2ee2 100644 --- a/src/test/java/org/s1ck/gdl/comparables/time/PlusTimeTest.java +++ b/src/test/java/org/s1ck/gdl/comparables/time/PlusTimeTest.java @@ -6,6 +6,9 @@ import org.s1ck.gdl.model.predicates.expressions.Comparison; import org.s1ck.gdl.utils.Comparator; +import java.util.ArrayList; +import java.util.Arrays; + import static org.junit.Assert.*; public class PlusTimeTest { @@ -35,7 +38,7 @@ public void selectorPlusTest(){ assertEquals(p.getUpperBound(), Long.MAX_VALUE); assertEquals(p.getVariables().size(),1); - assertEquals(p.getVariables().get(0), "p"); + assertEquals(new ArrayList(p.getVariables()).get(0), "p"); } @Test @@ -121,6 +124,22 @@ public void globalTest(){ TimeSelector s1 = new TimeSelector("a", "val_from"); TimeSelector global = new TimeSelector(TimeSelector.GLOBAL_SELECTOR, "val_to"); + ArrayList variables = new ArrayList<>(Arrays.asList("a","b")); + + assertEquals(new PlusTimePoint(s1, c).replaceGlobalByLocal(variables), + new PlusTimePoint(s1,c)); + + PlusTimePoint expectedGlobal = new PlusTimePoint( + new MinTimePoint( + new TimeSelector("a", TimeSelector.TimeField.VAL_TO), + new TimeSelector("b", TimeSelector.TimeField.VAL_TO) + ), + c + ); + + assertEquals(new PlusTimePoint(global, c).replaceGlobalByLocal(variables), + expectedGlobal); + assertFalse(new PlusTimePoint(s1,c).isGlobal()); assertTrue(new PlusTimePoint(global, c).isGlobal()); } diff --git a/src/test/java/org/s1ck/gdl/comparables/time/TimeLiteralTest.java b/src/test/java/org/s1ck/gdl/comparables/time/TimeLiteralTest.java index 6305f2d..8510d65 100644 --- a/src/test/java/org/s1ck/gdl/comparables/time/TimeLiteralTest.java +++ b/src/test/java/org/s1ck/gdl/comparables/time/TimeLiteralTest.java @@ -8,6 +8,8 @@ import java.time.Instant; import java.time.LocalDateTime; import java.time.ZoneOffset; +import java.util.ArrayList; +import java.util.Arrays; import java.util.Date; import static org.junit.Assert.*; @@ -100,5 +102,7 @@ public void globalTest(){ TimeLiteral literal1 = new TimeLiteral(); TimeLiteral literal2 = new TimeLiteral("2020-05-06"); assertFalse(literal1.isGlobal() || literal2.isGlobal()); + assertEquals(literal1.replaceGlobalByLocal(new ArrayList<>(Arrays.asList("a"))), + literal1); } } diff --git a/src/test/java/org/s1ck/gdl/comparables/time/TimeSelectorTest.java b/src/test/java/org/s1ck/gdl/comparables/time/TimeSelectorTest.java index 2585cd0..9ac0d5b 100644 --- a/src/test/java/org/s1ck/gdl/comparables/time/TimeSelectorTest.java +++ b/src/test/java/org/s1ck/gdl/comparables/time/TimeSelectorTest.java @@ -1,5 +1,7 @@ package org.s1ck.gdl.comparables.time; import org.junit.Test; +import org.s1ck.gdl.model.comparables.time.MaxTimePoint; +import org.s1ck.gdl.model.comparables.time.MinTimePoint; import org.s1ck.gdl.model.comparables.time.TimeLiteral; import org.s1ck.gdl.model.comparables.time.TimeSelector; import org.s1ck.gdl.model.predicates.Predicate; @@ -9,6 +11,7 @@ import org.s1ck.gdl.utils.Comparator; import java.util.ArrayList; +import java.util.Arrays; import static org.junit.Assert.*; import static org.s1ck.gdl.utils.Comparator.*; @@ -18,9 +21,9 @@ public class TimeSelectorTest { @Test public void selectorTest(){ TimeSelector selector = new TimeSelector("var", TimeSelector.TimeField.TX_FROM); - assertEquals(selector.getVariable(), "var"); + assertEquals(new ArrayList(selector.getVariables()).get(0), "var"); assertEquals(selector.getVariables().size(), 1); - assertEquals(selector.getVariables().get(0), "var"); + assertEquals(new ArrayList(selector.getVariables()).get(0), "var"); assertEquals(selector.getLowerBound(), 0); assertEquals(selector.getUpperBound(), Long.MAX_VALUE); assertEquals(selector.getTimeProp(), TimeSelector.TimeField.TX_FROM); @@ -224,7 +227,29 @@ public void containsTxToTest(){ public void globalTest(){ TimeSelector valF = new TimeSelector("a", "val_from"); assertFalse(valF.isGlobal()); + assertEquals(valF.replaceGlobalByLocal(new ArrayList<>(Arrays.asList("a"))), + valF); TimeSelector global = new TimeSelector(TimeSelector.GLOBAL_SELECTOR, "val_to"); + ArrayList vars = new ArrayList<>(Arrays.asList("a", "b", "e")); + MinTimePoint expected = new MinTimePoint( + new TimeSelector("a", TimeSelector.TimeField.VAL_TO), + new TimeSelector("b", TimeSelector.TimeField.VAL_TO), + new TimeSelector("e", TimeSelector.TimeField.VAL_TO) + ); + assertEquals(expected, global.replaceGlobalByLocal(vars)); + + TimeSelector global2 = new TimeSelector(TimeSelector.GLOBAL_SELECTOR, "tx_from"); + MaxTimePoint expected2 = new MaxTimePoint( + new TimeSelector("a", TimeSelector.TimeField.TX_FROM), + new TimeSelector("b", TimeSelector.TimeField.TX_FROM), + new TimeSelector("e", TimeSelector.TimeField.TX_FROM) + ); + assertEquals(expected2, global2.replaceGlobalByLocal(vars)); + // only one variable -> no max/min, but single selector + ArrayList singleVar = new ArrayList<>(Arrays.asList("a")); + TimeSelector expectedSingle = new TimeSelector("a", "tx_from"); + assertEquals(global2.replaceGlobalByLocal(singleVar), expectedSingle); assertTrue(global.isGlobal()); } + }