summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBrian S. O'Neill <bronee@gmail.com>2008-12-13 04:21:03 +0000
committerBrian S. O'Neill <bronee@gmail.com>2008-12-13 04:21:03 +0000
commita8e3ebeece7c811b156b47aa789527bf5bb55b56 (patch)
tree83eb03f19fd42bc97d36561eb3675803be52d329 /src
parent3f184dc28d1744bab131af067fe5c709659fb416 (diff)
Allow 'dot' syntax for property chains against one-to-many joins.
Diffstat (limited to 'src')
-rw-r--r--src/main/java/com/amazon/carbonado/filter/FilterParser.java45
-rw-r--r--src/main/java/com/amazon/carbonado/qe/FilteringScore.java4
2 files changed, 34 insertions, 15 deletions
diff --git a/src/main/java/com/amazon/carbonado/filter/FilterParser.java b/src/main/java/com/amazon/carbonado/filter/FilterParser.java
index ed9cec6..cda9dc3 100644
--- a/src/main/java/com/amazon/carbonado/filter/FilterParser.java
+++ b/src/main/java/com/amazon/carbonado/filter/FilterParser.java
@@ -142,8 +142,13 @@ class FilterParser<S extends Storable> {
mPos--;
ChainedProperty<S> chained = parseChainedProperty();
+
c = nextCharIgnoreWhitespace();
- if (c != '(') {
+ if (c == '.') {
+ // Convert chain against a query property into sub filter form.
+ Filter<?> subFilter = parseChainedFilter(chained, true);
+ return ExistsFilter.build(chained, subFilter, false);
+ } else if (c != '(') {
mPos--;
return parsePropertyFilter(chained);
}
@@ -154,7 +159,7 @@ class FilterParser<S extends Storable> {
subFilter = null;
} else {
mPos--;
- subFilter = parseChainedFilter(chained);
+ subFilter = parseChainedFilter(chained, false);
c = nextCharIgnoreWhitespace();
if (c != ')') {
mPos--;
@@ -244,10 +249,17 @@ class FilterParser<S extends Storable> {
}
@SuppressWarnings("unchecked")
- private Filter<?> parseChainedFilter(ChainedProperty<S> chained) {
+ private Filter<?> parseChainedFilter(ChainedProperty<S> chained, boolean oneEntity) {
FilterParser<?> chainedParser = new FilterParser
(chained.getLastProperty().getJoinedType(), mFilter, mPos);
- Filter<?> chainedFilter = chainedParser.parseFilter();
+
+ Filter<?> chainedFilter;
+ if (oneEntity) {
+ chainedFilter = chainedParser.parseEntityFilter();
+ } else {
+ chainedFilter = chainedParser.parseFilter();
+ }
+
mPos = chainedParser.mPos;
return chainedFilter;
}
@@ -282,19 +294,24 @@ class FilterParser<S extends Storable> {
}
}
- if (nextCharIgnoreWhitespace() != '.') {
+ if (nextCharIgnoreWhitespace() != '.' || prime.isQuery()) {
mPos--;
if (outerJoinList != null && outerJoinList.get(0)) {
- if (lastOuterJoinPos >= 0) {
- mPos = lastOuterJoinPos;
+ if (prime.isQuery()) {
+ return ChainedProperty.get(prime, null, new boolean[] {true});
+ } else {
+ if (lastOuterJoinPos >= 0) {
+ mPos = lastOuterJoinPos;
+ }
+ throw error("Outer join not allowed for non-join property");
}
- throw error("Outer join not allowed for non-chained property");
}
return ChainedProperty.get(prime);
}
List<StorableProperty<?>> chain = new ArrayList<StorableProperty<?>>(4);
- Class<?> type = prime.getType();
+ StorableProperty<?> prop = prime;
+ Class<?> type = prop.getType();
while (true) {
lastOuterJoinPos = -1;
@@ -323,14 +340,14 @@ class FilterParser<S extends Storable> {
StorableInfo<?> info =
StorableIntrospector.examine((Class<? extends Storable>) type);
Map<String, ? extends StorableProperty<?>> props = info.getAllProperties();
- StorableProperty<?> prop = props.get(ident);
+ prop = props.get(ident);
if (prop == null) {
mPos -= ident.length();
throw error("Property \"" + ident + "\" not found for type: \"" +
type.getName() + '"');
}
chain.add(prop);
- type = prop.isJoin() ? prop.getJoinedType() : prop.getType();
+ type = prop.getType();
} else {
throw error("Property \"" + ident + "\" not found for type \"" +
type.getName() + "\" because it has no properties");
@@ -343,7 +360,7 @@ class FilterParser<S extends Storable> {
}
}
- if (nextCharIgnoreWhitespace() != '.') {
+ if (nextCharIgnoreWhitespace() != '.' || prop.isQuery()) {
mPos--;
break;
}
@@ -351,11 +368,11 @@ class FilterParser<S extends Storable> {
boolean[] outerJoin = null;
if (outerJoinList != null) {
- if (outerJoinList.get(outerJoinList.size() - 1)) {
+ if (!prop.isQuery() && outerJoinList.get(outerJoinList.size() - 1)) {
if (lastOuterJoinPos >= 0) {
mPos = lastOuterJoinPos;
}
- throw error("Outer join not allowed for last property in chain");
+ throw error("Outer join not allowed for non-join property");
}
outerJoin = new boolean[outerJoinList.size()];
for (int i=outerJoinList.size(); --i>=0; ) {
diff --git a/src/main/java/com/amazon/carbonado/qe/FilteringScore.java b/src/main/java/com/amazon/carbonado/qe/FilteringScore.java
index 6fa6ca0..b1709c9 100644
--- a/src/main/java/com/amazon/carbonado/qe/FilteringScore.java
+++ b/src/main/java/com/amazon/carbonado/qe/FilteringScore.java
@@ -767,7 +767,7 @@ public class FilteringScore<S extends Storable> {
}
private boolean isProvidedByIndex(Filter<S> filter) {
- return filter.accept(new Visitor<S, Boolean, Object>() {
+ Boolean result = filter.accept(new Visitor<S, Boolean, Object>() {
@Override
public Boolean visit(OrFilter<S> filter, Object param) {
return filter.getLeftFilter().accept(this, param)
@@ -791,6 +791,8 @@ public class FilteringScore<S extends Storable> {
return false;
}
}, null);
+
+ return result == null ? false : result;
}
private static class Range implements Comparator<FilteringScore<?>> {