This is an automated email from the ASF dual-hosted git repository. liyang pushed a commit to branch sync in repository https://gitbox.apache.org/repos/asf/kylin.git
commit dc75e171a371c3286d33b124dbd68f4dae62b12c Author: Li Yang <[email protected]> AuthorDate: Tue May 22 12:00:19 2018 +0800 KYLIN-3370 refactor TupleFilter a little --- .../kylin/metadata/filter/CompareTupleFilter.java | 2 +- .../apache/kylin/metadata/filter/TupleFilter.java | 85 ++++++++++++++++------ .../kylin/metadata/filter/TupleFilterTest.java | 54 ++++++++++++++ .../apache/kylin/query/relnode/OLAPFilterRel.java | 24 +++++- 4 files changed, 141 insertions(+), 24 deletions(-) diff --git a/core-metadata/src/main/java/org/apache/kylin/metadata/filter/CompareTupleFilter.java b/core-metadata/src/main/java/org/apache/kylin/metadata/filter/CompareTupleFilter.java index 16f165a..2c75ec1 100644 --- a/core-metadata/src/main/java/org/apache/kylin/metadata/filter/CompareTupleFilter.java +++ b/core-metadata/src/main/java/org/apache/kylin/metadata/filter/CompareTupleFilter.java @@ -33,7 +33,7 @@ import org.apache.kylin.metadata.tuple.IEvaluatableTuple; * @author xjiang */ public class CompareTupleFilter extends TupleFilter implements IOptimizeableTupleFilter { - + public enum CompareResultType { AlwaysTrue, AlwaysFalse, Unknown } diff --git a/core-metadata/src/main/java/org/apache/kylin/metadata/filter/TupleFilter.java b/core-metadata/src/main/java/org/apache/kylin/metadata/filter/TupleFilter.java index 09b41f5..16ea8ee 100644 --- a/core-metadata/src/main/java/org/apache/kylin/metadata/filter/TupleFilter.java +++ b/core-metadata/src/main/java/org/apache/kylin/metadata/filter/TupleFilter.java @@ -20,6 +20,7 @@ package org.apache.kylin.metadata.filter; import java.nio.ByteBuffer; import java.util.Collection; +import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; @@ -81,6 +82,39 @@ public abstract class TupleFilter { SWAP_OP_MAP.put(FilterOperatorEnum.LT, FilterOperatorEnum.GT); SWAP_OP_MAP.put(FilterOperatorEnum.GTE, FilterOperatorEnum.LTE); } + + public static CompareTupleFilter compare(TblColRef col, FilterOperatorEnum op) { + CompareTupleFilter r = new CompareTupleFilter(op); + r.addChild(new ColumnTupleFilter(col)); + return r; + } + + public static CompareTupleFilter compare(TblColRef col, FilterOperatorEnum op, Object val) { + CompareTupleFilter r = new CompareTupleFilter(op); + r.addChild(new ColumnTupleFilter(col)); + r.addChild(new ConstantTupleFilter(val)); + return r; + } + + public static LogicalTupleFilter and(TupleFilter... children) { + LogicalTupleFilter r = new LogicalTupleFilter(FilterOperatorEnum.AND); + r.addChildren(children); + return r; + } + + public static LogicalTupleFilter or(TupleFilter... children) { + LogicalTupleFilter r = new LogicalTupleFilter(FilterOperatorEnum.OR); + r.addChildren(children); + return r; + } + + public static LogicalTupleFilter not(TupleFilter child) { + LogicalTupleFilter r = new LogicalTupleFilter(FilterOperatorEnum.NOT); + r.addChild(child); + return r; + } + + // ============================================================================ protected final List<TupleFilter> children; protected FilterOperatorEnum operator; @@ -245,6 +279,35 @@ public abstract class TupleFilter { } return oldProductFilters; } + + public HashMap<TblColRef, Object> findMustEqualColsAndValues(Collection<TblColRef> lookingForCols) { + HashMap<TblColRef, Object> result = new HashMap<>(); + findMustEqualColsAndValues(this, lookingForCols, result); + return result; + } + + private void findMustEqualColsAndValues(TupleFilter filter, Collection<TblColRef> lookingForCols, HashMap<TblColRef, Object> result) { + if (filter instanceof CompareTupleFilter) { + CompareTupleFilter comp = (CompareTupleFilter) filter; + TblColRef col = comp.getColumn(); + if (lookingForCols.contains(col)) { + if (comp.getOperator() == FilterOperatorEnum.EQ) + result.put(col, comp.getFirstValue()); + else if (comp.getOperator() == FilterOperatorEnum.ISNULL) + result.put(col, null); + } + return; + } + + if (filter instanceof LogicalTupleFilter) { + LogicalTupleFilter logic = (LogicalTupleFilter) filter; + if (logic.getOperator() == FilterOperatorEnum.AND) { + for (TupleFilter child : logic.getChildren()) + findMustEqualColsAndValues(child, lookingForCols, result); + } + return; + } + } public abstract boolean isEvaluable(); @@ -284,26 +347,4 @@ public abstract class TupleFilter { } } - public static TupleFilter and(TupleFilter f1, TupleFilter f2) { - if (f1 == null) - return f2; - if (f2 == null) - return f1; - - if (f1.getOperator() == FilterOperatorEnum.AND) { - f1.addChild(f2); - return f1; - } - - if (f2.getOperator() == FilterOperatorEnum.AND) { - f2.addChild(f1); - return f2; - } - - LogicalTupleFilter and = new LogicalTupleFilter(FilterOperatorEnum.AND); - and.addChild(f1); - and.addChild(f2); - return and; - } - } diff --git a/core-metadata/src/test/java/org/apache/kylin/metadata/filter/TupleFilterTest.java b/core-metadata/src/test/java/org/apache/kylin/metadata/filter/TupleFilterTest.java index e17f4d1..b1e8f62 100644 --- a/core-metadata/src/test/java/org/apache/kylin/metadata/filter/TupleFilterTest.java +++ b/core-metadata/src/test/java/org/apache/kylin/metadata/filter/TupleFilterTest.java @@ -18,9 +18,21 @@ package org.apache.kylin.metadata.filter; +import static org.apache.kylin.metadata.filter.TupleFilter.and; +import static org.apache.kylin.metadata.filter.TupleFilter.compare; +import static org.apache.kylin.metadata.filter.TupleFilter.not; + +import java.util.HashMap; +import java.util.Set; + +import org.apache.kylin.metadata.filter.TupleFilter.FilterOperatorEnum; +import org.apache.kylin.metadata.model.TableDesc; +import org.apache.kylin.metadata.model.TblColRef; import org.junit.Assert; import org.junit.Test; +import com.google.common.collect.Sets; + public class TupleFilterTest { @Test // true ==> true @@ -62,4 +74,46 @@ public class TupleFilterTest { andFilter2.addChildren(ConstantTupleFilter.FALSE, ConstantTupleFilter.FALSE); Assert.assertEquals(andFilter2, andFilter.removeNot()); } + + @Test + public void testFindMustEqualColsAndValues() { + TableDesc tbl = TableDesc.mockup("mockup_table"); + TblColRef colA = TblColRef.mockup(tbl, 0, "A", "bigint"); + TblColRef colB = TblColRef.mockup(tbl, 1, "B", "char(256)"); + Set<TblColRef> cols = Sets.newHashSet(colA, colB); + + { + TupleFilter f = compare(colA, FilterOperatorEnum.EQ, "1234"); + Assert.assertEquals(map(colA, "1234"), f.findMustEqualColsAndValues(cols)); + } + + { + TupleFilter f = compare(colA, FilterOperatorEnum.ISNULL); + Assert.assertEquals(map(colA, null), f.findMustEqualColsAndValues(cols)); + } + + { + TupleFilter f = and(compare(colA, FilterOperatorEnum.ISNULL), compare(colB, FilterOperatorEnum.EQ, "1234")); + Assert.assertEquals(map(colA, null, colB, "1234"), f.findMustEqualColsAndValues(cols)); + Assert.assertTrue(not(f).findMustEqualColsAndValues(cols).isEmpty()); + } + + { + TupleFilter f = compare(colA, FilterOperatorEnum.LT, "1234"); + Assert.assertTrue(f.findMustEqualColsAndValues(cols).isEmpty()); + } + } + + private HashMap<TblColRef, Object> map(TblColRef col, String v) { + HashMap<TblColRef, Object> r = new HashMap<>(); + r.put(col, v); + return r; + } + + private HashMap<TblColRef, Object> map(TblColRef col, String v, TblColRef col2, String v2) { + HashMap<TblColRef, Object> r = new HashMap<>(); + r.put(col, v); + r.put(col2, v2); + return r; + } } diff --git a/query/src/main/java/org/apache/kylin/query/relnode/OLAPFilterRel.java b/query/src/main/java/org/apache/kylin/query/relnode/OLAPFilterRel.java index 39a2669..14e89ea 100644 --- a/query/src/main/java/org/apache/kylin/query/relnode/OLAPFilterRel.java +++ b/query/src/main/java/org/apache/kylin/query/relnode/OLAPFilterRel.java @@ -117,7 +117,29 @@ public class OLAPFilterRel extends Filter implements OLAPRel { } } - context.filter = TupleFilter.and(context.filter, filter); + context.filter = and(context.filter, filter); + } + + private TupleFilter and(TupleFilter f1, TupleFilter f2) { + if (f1 == null) + return f2; + if (f2 == null) + return f1; + + if (f1.getOperator() == FilterOperatorEnum.AND) { + f1.addChild(f2); + return f1; + } + + if (f2.getOperator() == FilterOperatorEnum.AND) { + f2.addChild(f1); + return f2; + } + + LogicalTupleFilter and = new LogicalTupleFilter(FilterOperatorEnum.AND); + and.addChild(f1); + and.addChild(f2); + return and; } @Override
