From b4fc65d11f2100cdaaa750cad29dfb7db5192798 Mon Sep 17 00:00:00 2001 From: "Brian S. O'Neill" Date: Mon, 6 Aug 2007 00:49:18 +0000 Subject: Support filters as joined and not joined from one-to-many properties. --- .../com/amazon/carbonado/filter/AndFilter.java | 19 +++++--- .../java/com/amazon/carbonado/filter/Filter.java | 52 +++++++++++++--------- .../java/com/amazon/carbonado/filter/OrFilter.java | 21 ++++++--- .../amazon/carbonado/filter/PropertyFilter.java | 13 +++--- .../amazon/carbonado/qe/JoinedQueryExecutor.java | 7 ++- 5 files changed, 73 insertions(+), 39 deletions(-) (limited to 'src/main/java') diff --git a/src/main/java/com/amazon/carbonado/filter/AndFilter.java b/src/main/java/com/amazon/carbonado/filter/AndFilter.java index be38800..fb158f3 100644 --- a/src/main/java/com/amazon/carbonado/filter/AndFilter.java +++ b/src/main/java/com/amazon/carbonado/filter/AndFilter.java @@ -67,17 +67,24 @@ public class AndFilter extends BinaryOpFilter { } @Override - NotJoined notJoinedFrom(ChainedProperty joinProperty, - Class joinPropertyType) - { - NotJoined left = mLeft.notJoinedFrom(joinProperty, joinPropertyType); - NotJoined right = mRight.notJoinedFrom(joinProperty, joinPropertyType); + NotJoined notJoinedFromCNF(ChainedProperty joinProperty) { + NotJoined left = mLeft.notJoinedFromCNF(joinProperty); + NotJoined right = mRight.notJoinedFromCNF(joinProperty); // Remove wildcards to shut the compiler up. Filter leftNotJoined = left.getNotJoinedFilter(); Filter rightNotJoined = right.getNotJoinedFilter(); - return new NotJoined(leftNotJoined.and(rightNotJoined), + Filter notJoined; + if (leftNotJoined == null) { + notJoined = rightNotJoined; + } else if (rightNotJoined == null) { + notJoined = leftNotJoined; + } else { + notJoined = leftNotJoined.and(rightNotJoined); + } + + return new NotJoined(notJoined, left.getRemainderFilter().and(right.getRemainderFilter())); } diff --git a/src/main/java/com/amazon/carbonado/filter/Filter.java b/src/main/java/com/amazon/carbonado/filter/Filter.java index cbc37dc..79f0435 100644 --- a/src/main/java/com/amazon/carbonado/filter/Filter.java +++ b/src/main/java/com/amazon/carbonado/filter/Filter.java @@ -574,19 +574,18 @@ public abstract class Filter implements Appender { * * @param joinProperty property to not join from * @return not join result - * @throws IllegalArgumentException if property does not refer to a Storable + * @throws IllegalArgumentException if property is not a join */ public final NotJoined notJoinedFrom(ChainedProperty joinProperty) { - Class type = joinProperty.getType(); - if (!Storable.class.isAssignableFrom(type)) { - throw new IllegalArgumentException - ("Join property type is not a Storable: " + joinProperty); + Class type = joinProperty.getLastProperty().getJoinedType(); + if (type == null) { + throw new IllegalArgumentException("Not a join property: " + joinProperty); } Filter cnf = conjunctiveNormalForm(); - NotJoined nj = cnf.notJoinedFrom(joinProperty, (Class) type); + NotJoined nj = cnf.notJoinedFromCNF(joinProperty); - if (nj.getNotJoinedFilter() instanceof OpenFilter) { + if (nj.getNotJoinedFilter() == null) { // Remainder filter should be same as original, but it might have // expanded with conjunctive normal form. If so, restore to // original, but still bind it to ensure consistent side-effects. @@ -600,11 +599,17 @@ public abstract class Filter implements Appender { // conversion from disjunctive normal form to conjunctive normal // form may make major changes. If original was dnf, restore the // result filters to dnf. - - if (!(nj.getNotJoinedFilter().isDisjunctiveNormalForm()) || - !(nj.getRemainderFilter().isDisjunctiveNormalForm())) - { - nj = new NotJoined(nj.getNotJoinedFilter().disjunctiveNormalForm(), + + boolean isNotJoinedDNF = nj.getNotJoinedFilter() == null + || nj.getNotJoinedFilter().isDisjunctiveNormalForm(); + + boolean isRemainerDNF = nj.getRemainderFilter().isDisjunctiveNormalForm(); + + if (!isNotJoinedDNF || !isRemainerDNF) { + Filter notJoinedDNF = nj.getNotJoinedFilter() == null ? null + : nj.getNotJoinedFilter().disjunctiveNormalForm(); + + nj = new NotJoined(notJoinedDNF, nj.getRemainderFilter().disjunctiveNormalForm()); } } @@ -615,10 +620,8 @@ public abstract class Filter implements Appender { /** * Should only be called on a filter in conjunctive normal form. */ - NotJoined notJoinedFrom(ChainedProperty joinProperty, - Class joinPropertyType) - { - return new NotJoined(getOpenFilter(joinPropertyType), this); + NotJoined notJoinedFromCNF(ChainedProperty joinProperty) { + return new NotJoined(null, this); } abstract Filter buildDisjunctiveNormalForm(); @@ -689,8 +692,11 @@ public abstract class Filter implements Appender { /** * Returns the filter which is no longer as from a join. * - * @return not joined filter or open filter if none + * @return not joined filter or null if none */ + // Design note: Return value might be null since not all join + // properties have an open filter representation. For example, some + // joins return Query objects. public Filter getNotJoinedFilter() { return mNotJoined; } @@ -698,14 +704,18 @@ public abstract class Filter implements Appender { /** * Returns the filter which could not be separated. * - * @return remainder filter or open filter if none + * @return remainder filter or open filter if none */ public Filter getRemainderFilter() { return mRemainder; } public int hashCode() { - return mNotJoined.hashCode() * 31 + mRemainder.hashCode(); + if (mNotJoined == null) { + return mRemainder.hashCode(); + } else { + return mNotJoined.hashCode() * 31 + mRemainder.hashCode(); + } } public boolean equals(Object obj) { @@ -714,7 +724,9 @@ public abstract class Filter implements Appender { } if (obj instanceof Filter.NotJoined) { NotJoined other = (NotJoined) obj; - return mNotJoined.equals(other.mNotJoined) && mRemainder.equals(other.mRemainder); + return (mNotJoined == null ? other.mNotJoined == null + : mNotJoined.equals(other.mNotJoined)) + && mRemainder.equals(other.mRemainder); } return false; } diff --git a/src/main/java/com/amazon/carbonado/filter/OrFilter.java b/src/main/java/com/amazon/carbonado/filter/OrFilter.java index d5748aa..67da5ba 100644 --- a/src/main/java/com/amazon/carbonado/filter/OrFilter.java +++ b/src/main/java/com/amazon/carbonado/filter/OrFilter.java @@ -67,11 +67,9 @@ public class OrFilter extends BinaryOpFilter { } @Override - NotJoined notJoinedFrom(ChainedProperty joinProperty, - Class joinPropertyType) - { - NotJoined left = mLeft.notJoinedFrom(joinProperty, joinPropertyType); - NotJoined right = mRight.notJoinedFrom(joinProperty, joinPropertyType); + NotJoined notJoinedFromCNF(ChainedProperty joinProperty) { + NotJoined left = mLeft.notJoinedFromCNF(joinProperty); + NotJoined right = mRight.notJoinedFromCNF(joinProperty); // Assert that our child nodes are only OrFilter or PropertyFilter. if (!isConjunctiveNormalForm()) { @@ -88,14 +86,23 @@ public class OrFilter extends BinaryOpFilter { if (!(left.getRemainderFilter() instanceof OpenFilter) || !(right.getRemainderFilter() instanceof OpenFilter)) { - return super.notJoinedFrom(joinProperty, joinPropertyType); + return super.notJoinedFromCNF(joinProperty); } // Remove wildcards to shut the compiler up. Filter leftNotJoined = left.getNotJoinedFilter(); Filter rightNotJoined = right.getNotJoinedFilter(); - return new NotJoined(leftNotJoined.or(rightNotJoined), getOpenFilter(getStorableType())); + Filter notJoined; + if (leftNotJoined == null) { + notJoined = rightNotJoined; + } else if (rightNotJoined == null) { + notJoined = leftNotJoined; + } else { + notJoined = leftNotJoined.or(rightNotJoined); + } + + return new NotJoined(notJoined, getOpenFilter(getStorableType())); } Filter buildDisjunctiveNormalForm() { diff --git a/src/main/java/com/amazon/carbonado/filter/PropertyFilter.java b/src/main/java/com/amazon/carbonado/filter/PropertyFilter.java index 9f12095..deb1f21 100644 --- a/src/main/java/com/amazon/carbonado/filter/PropertyFilter.java +++ b/src/main/java/com/amazon/carbonado/filter/PropertyFilter.java @@ -189,7 +189,12 @@ public class PropertyFilter extends Filter { } public PropertyFilter asJoinedFrom(ChainedProperty joinProperty) { - if (joinProperty.getType() != getStorableType()) { + Class type = joinProperty.getLastProperty().getJoinedType(); + if (type == null) { + type = joinProperty.getType(); + } + + if (type != getStorableType()) { throw new IllegalArgumentException ("Property is not of type \"" + getStorableType().getName() + "\": " + joinProperty); @@ -205,9 +210,7 @@ public class PropertyFilter extends Filter { } @Override - NotJoined notJoinedFrom(ChainedProperty joinProperty, - Class joinPropertyType) - { + NotJoined notJoinedFromCNF(ChainedProperty joinProperty) { ChainedProperty notJoinedProp = getChainedProperty(); ChainedProperty jp = joinProperty; @@ -221,7 +224,7 @@ public class PropertyFilter extends Filter { } if (jp != null || notJoinedProp.equals(getChainedProperty())) { - return super.notJoinedFrom(joinProperty, joinPropertyType); + return super.notJoinedFromCNF(joinProperty); } PropertyFilter notJoinedFilter; diff --git a/src/main/java/com/amazon/carbonado/qe/JoinedQueryExecutor.java b/src/main/java/com/amazon/carbonado/qe/JoinedQueryExecutor.java index d947ed7..b1d47e9 100644 --- a/src/main/java/com/amazon/carbonado/qe/JoinedQueryExecutor.java +++ b/src/main/java/com/amazon/carbonado/qe/JoinedQueryExecutor.java @@ -395,7 +395,12 @@ public class JoinedQueryExecutor private static OrderingList expectedOrdering(StorageAccess access, Filter filter, OrderingList ordering) { - List> split = filter.disjunctiveNormalFormSplit(); + List> split; + if (filter == null) { + split = Filter.getOpenFilter(access.getStorableType()).disjunctiveNormalFormSplit(); + } else { + split = filter.disjunctiveNormalFormSplit(); + } Comparator comparator = CompositeScore.fullComparator(); -- cgit v1.2.3