summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrian S. O'Neill <bronee@gmail.com>2007-08-06 00:49:18 +0000
committerBrian S. O'Neill <bronee@gmail.com>2007-08-06 00:49:18 +0000
commitb4fc65d11f2100cdaaa750cad29dfb7db5192798 (patch)
tree500bd80d31a617dfae796a0cfd3d11c180a8fe09
parent2e3ff3f65bbc9bd762d56cdf47d079e2c05286ba (diff)
Support filters as joined and not joined from one-to-many properties.
-rw-r--r--src/main/java/com/amazon/carbonado/filter/AndFilter.java19
-rw-r--r--src/main/java/com/amazon/carbonado/filter/Filter.java52
-rw-r--r--src/main/java/com/amazon/carbonado/filter/OrFilter.java21
-rw-r--r--src/main/java/com/amazon/carbonado/filter/PropertyFilter.java13
-rw-r--r--src/main/java/com/amazon/carbonado/qe/JoinedQueryExecutor.java7
5 files changed, 73 insertions, 39 deletions
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<S extends Storable> extends BinaryOpFilter<S> {
}
@Override
- NotJoined notJoinedFrom(ChainedProperty<S> joinProperty,
- Class<? extends Storable> joinPropertyType)
- {
- NotJoined left = mLeft.notJoinedFrom(joinProperty, joinPropertyType);
- NotJoined right = mRight.notJoinedFrom(joinProperty, joinPropertyType);
+ NotJoined notJoinedFromCNF(ChainedProperty<S> 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<S extends Storable> 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<S> joinProperty) {
- Class<?> type = joinProperty.getType();
- if (!Storable.class.isAssignableFrom(type)) {
- throw new IllegalArgumentException
- ("Join property type is not a Storable: " + joinProperty);
+ Class<? extends Storable> type = joinProperty.getLastProperty().getJoinedType();
+ if (type == null) {
+ throw new IllegalArgumentException("Not a join property: " + joinProperty);
}
Filter<S> cnf = conjunctiveNormalForm();
- NotJoined nj = cnf.notJoinedFrom(joinProperty, (Class<Storable>) 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<S extends Storable> 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<S extends Storable> implements Appender {
/**
* Should only be called on a filter in conjunctive normal form.
*/
- NotJoined notJoinedFrom(ChainedProperty<S> joinProperty,
- Class<? extends Storable> joinPropertyType)
- {
- return new NotJoined(getOpenFilter(joinPropertyType), this);
+ NotJoined notJoinedFromCNF(ChainedProperty<S> joinProperty) {
+ return new NotJoined(null, this);
}
abstract Filter<S> buildDisjunctiveNormalForm();
@@ -689,8 +692,11 @@ public abstract class Filter<S extends Storable> 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 <i>null</i> 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<S extends Storable> implements Appender {
/**
* Returns the filter which could not be separated.
*
- * @return remainder filter or open filter if none
+ * @return remainder filter or <i>open filter</i> if none
*/
public Filter<S> 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<S extends Storable> 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<S extends Storable> extends BinaryOpFilter<S> {
}
@Override
- NotJoined notJoinedFrom(ChainedProperty<S> joinProperty,
- Class<? extends Storable> joinPropertyType)
- {
- NotJoined left = mLeft.notJoinedFrom(joinProperty, joinPropertyType);
- NotJoined right = mRight.notJoinedFrom(joinProperty, joinPropertyType);
+ NotJoined notJoinedFromCNF(ChainedProperty<S> 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<S extends Storable> extends BinaryOpFilter<S> {
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<S> 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<S extends Storable> extends Filter<S> {
}
public <T extends Storable> PropertyFilter<T> asJoinedFrom(ChainedProperty<T> 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<S extends Storable> extends Filter<S> {
}
@Override
- NotJoined notJoinedFrom(ChainedProperty<S> joinProperty,
- Class<? extends Storable> joinPropertyType)
- {
+ NotJoined notJoinedFromCNF(ChainedProperty<S> joinProperty) {
ChainedProperty<?> notJoinedProp = getChainedProperty();
ChainedProperty<?> jp = joinProperty;
@@ -221,7 +224,7 @@ public class PropertyFilter<S extends Storable> extends Filter<S> {
}
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<S extends Storable, T extends Storable>
private static <T extends Storable> OrderingList<T>
expectedOrdering(StorageAccess<T> access, Filter<T> filter, OrderingList<T> ordering)
{
- List<Filter<T>> split = filter.disjunctiveNormalFormSplit();
+ List<Filter<T>> split;
+ if (filter == null) {
+ split = Filter.getOpenFilter(access.getStorableType()).disjunctiveNormalFormSplit();
+ } else {
+ split = filter.disjunctiveNormalFormSplit();
+ }
Comparator comparator = CompositeScore.fullComparator();