From a8e3ebeece7c811b156b47aa789527bf5bb55b56 Mon Sep 17 00:00:00 2001 From: "Brian S. O'Neill" Date: Sat, 13 Dec 2008 04:21:03 +0000 Subject: Allow 'dot' syntax for property chains against one-to-many joins. --- .../com/amazon/carbonado/filter/FilterParser.java | 45 +++++++++++++++------- .../com/amazon/carbonado/qe/FilteringScore.java | 4 +- 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 { mPos--; ChainedProperty 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 { subFilter = null; } else { mPos--; - subFilter = parseChainedFilter(chained); + subFilter = parseChainedFilter(chained, false); c = nextCharIgnoreWhitespace(); if (c != ')') { mPos--; @@ -244,10 +249,17 @@ class FilterParser { } @SuppressWarnings("unchecked") - private Filter parseChainedFilter(ChainedProperty chained) { + private Filter parseChainedFilter(ChainedProperty 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 { } } - 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> chain = new ArrayList>(4); - Class type = prime.getType(); + StorableProperty prop = prime; + Class type = prop.getType(); while (true) { lastOuterJoinPos = -1; @@ -323,14 +340,14 @@ class FilterParser { StorableInfo info = StorableIntrospector.examine((Class) type); Map> 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 { } } - if (nextCharIgnoreWhitespace() != '.') { + if (nextCharIgnoreWhitespace() != '.' || prop.isQuery()) { mPos--; break; } @@ -351,11 +368,11 @@ class FilterParser { 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 { } private boolean isProvidedByIndex(Filter filter) { - return filter.accept(new Visitor() { + Boolean result = filter.accept(new Visitor() { @Override public Boolean visit(OrFilter filter, Object param) { return filter.getLeftFilter().accept(this, param) @@ -791,6 +791,8 @@ public class FilteringScore { return false; } }, null); + + return result == null ? false : result; } private static class Range implements Comparator> { -- cgit v1.2.3