diff options
author | Brian S. O'Neill <bronee@gmail.com> | 2006-09-03 06:14:41 +0000 |
---|---|---|
committer | Brian S. O'Neill <bronee@gmail.com> | 2006-09-03 06:14:41 +0000 |
commit | 39fce59a840b723eb013bc79285687986592b2da (patch) | |
tree | 6ae5e1602fca5bedfe63643286588a1d35575ccc /src/test/java/com/amazon/carbonado/qe | |
parent | 967e17697f343849a4c0e420c813d382b11eda44 (diff) |
More work on query engine.
Diffstat (limited to 'src/test/java/com/amazon/carbonado/qe')
6 files changed, 504 insertions, 42 deletions
diff --git a/src/test/java/com/amazon/carbonado/qe/TestFilteredQueryExecutor.java b/src/test/java/com/amazon/carbonado/qe/TestFilteredQueryExecutor.java index 76ea081..1210bd4 100644 --- a/src/test/java/com/amazon/carbonado/qe/TestFilteredQueryExecutor.java +++ b/src/test/java/com/amazon/carbonado/qe/TestFilteredQueryExecutor.java @@ -52,6 +52,6 @@ public class TestFilteredQueryExecutor extends TestQueryExecutor { assertEquals(0, executor.getOrdering().size());
- compareElements(executor.openCursor(values.with("country_2")), 3, 4);
+ compareElements(executor.fetch(values.with("country_2")), 3, 4);
}
}
diff --git a/src/test/java/com/amazon/carbonado/qe/TestIndexedQueryAnalyzer.java b/src/test/java/com/amazon/carbonado/qe/TestIndexedQueryAnalyzer.java new file mode 100644 index 0000000..85c78cb --- /dev/null +++ b/src/test/java/com/amazon/carbonado/qe/TestIndexedQueryAnalyzer.java @@ -0,0 +1,259 @@ +/*
+ * Copyright 2006 Amazon Technologies, Inc. or its affiliates.
+ * Amazon, Amazon.com and Carbonado are trademarks or registered trademarks
+ * of Amazon Technologies, Inc. or its affiliates. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.amazon.carbonado.qe;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+import com.amazon.carbonado.Repository;
+import com.amazon.carbonado.Storable;
+
+import com.amazon.carbonado.info.StorableIndex;
+
+import com.amazon.carbonado.filter.Filter;
+import com.amazon.carbonado.filter.FilterValues;
+
+import com.amazon.carbonado.repo.toy.ToyRepository;
+
+import com.amazon.carbonado.stored.Address;
+import com.amazon.carbonado.stored.Order;
+import com.amazon.carbonado.stored.Shipment;
+import com.amazon.carbonado.stored.Shipper;
+
+import static com.amazon.carbonado.qe.TestIndexedQueryExecutor.Mock;
+
+/**
+ *
+ *
+ * @author Brian S O'Neill
+ */
+public class TestIndexedQueryAnalyzer extends TestCase {
+ public static void main(String[] args) {
+ junit.textui.TestRunner.run(suite());
+ }
+
+ public static TestSuite suite() {
+ return new TestSuite(TestIndexedQueryAnalyzer.class);
+ }
+
+ static <S extends Storable> StorableIndex<S> makeIndex(Class<S> type, String... props) {
+ return TestOrderingScore.makeIndex(type, props);
+ }
+
+ public TestIndexedQueryAnalyzer(String name) {
+ super(name);
+ }
+
+ // Note: these tests don't perform exhaustive tests to find the best index, as those tests
+ // are performed by TestFilteringScore and TestOrderingScore.
+
+ public void testFullScan() throws Exception {
+ IndexedQueryAnalyzer iqa = new IndexedQueryAnalyzer(Address.class, IxProvider.INSTANCE);
+ Filter<Address> filter = Filter.filterFor(Address.class, "addressZip = ?");
+ filter = filter.bind();
+ IndexedQueryAnalyzer.Result result = iqa.analyze(filter);
+
+ assertFalse(result.handlesAnything());
+ assertEquals(filter, result.getCompositeScore().getFilteringScore().getRemainderFilter());
+ assertEquals(makeIndex(Address.class, "addressID"), result.getLocalIndex());
+ assertEquals(null, result.getForeignIndex());
+ assertEquals(null, result.getForeignProperty());
+ }
+
+ public void testIndexScan() throws Exception {
+ IndexedQueryAnalyzer iqa = new IndexedQueryAnalyzer(Address.class, IxProvider.INSTANCE);
+ Filter<Address> filter = Filter.filterFor(Address.class, "addressID = ?");
+ filter = filter.bind();
+ IndexedQueryAnalyzer.Result result = iqa.analyze(filter);
+
+ assertTrue(result.handlesAnything());
+ assertEquals(filter, result.getCompositeScore().getFilteringScore().getIdentityFilter());
+ assertEquals(makeIndex(Address.class, "addressID"), result.getLocalIndex());
+ assertEquals(null, result.getForeignIndex());
+ assertEquals(null, result.getForeignProperty());
+ }
+
+ public void testBasic() throws Exception {
+ IndexedQueryAnalyzer iqa = new IndexedQueryAnalyzer(Shipment.class, IxProvider.INSTANCE);
+ Filter<Shipment> filter = Filter.filterFor(Shipment.class, "shipmentID = ?");
+ filter = filter.bind();
+ IndexedQueryAnalyzer.Result result = iqa.analyze(filter);
+
+ assertTrue(result.handlesAnything());
+ assertEquals(filter, result.getCompositeScore().getFilteringScore().getIdentityFilter());
+ assertEquals(makeIndex(Shipment.class, "shipmentID"), result.getLocalIndex());
+ assertEquals(null, result.getForeignIndex());
+ assertEquals(null, result.getForeignProperty());
+
+ filter = Filter.filterFor(Shipment.class, "orderID = ?");
+ filter = filter.bind();
+ result = iqa.analyze(filter);
+
+ assertTrue(result.handlesAnything());
+ assertEquals(filter, result.getCompositeScore().getFilteringScore().getIdentityFilter());
+ assertEquals(makeIndex(Shipment.class, "orderID"), result.getLocalIndex());
+ assertEquals(null, result.getForeignIndex());
+ assertEquals(null, result.getForeignProperty());
+ }
+
+ public void testSimpleJoin() throws Exception {
+ IndexedQueryAnalyzer iqa = new IndexedQueryAnalyzer(Shipment.class, IxProvider.INSTANCE);
+ Filter<Shipment> filter = Filter.filterFor(Shipment.class, "order.orderTotal >= ?");
+ filter = filter.bind();
+ IndexedQueryAnalyzer.Result result = iqa.analyze(filter);
+
+ assertTrue(result.handlesAnything());
+ assertTrue(result.getCompositeScore().getFilteringScore().hasRangeStart());
+ assertEquals(null, result.getLocalIndex());
+ assertEquals(makeIndex(Order.class, "orderTotal"), result.getForeignIndex());
+ assertEquals("order", result.getForeignProperty().toString());
+ }
+
+ public void testJoinPriority() throws Exception {
+ // Selects foreign index because filter score is better.
+
+ IndexedQueryAnalyzer iqa = new IndexedQueryAnalyzer(Shipment.class, IxProvider.INSTANCE);
+ Filter<Shipment> filter = Filter.filterFor
+ (Shipment.class, "shipmentNotes = ? & order.orderTotal >= ?");
+ filter = filter.bind();
+ IndexedQueryAnalyzer.Result result = iqa.analyze(filter);
+
+ assertTrue(result.handlesAnything());
+ assertTrue(result.getCompositeScore().getFilteringScore().hasRangeStart());
+ assertEquals(Filter.filterFor(Shipment.class, "shipmentNotes = ?").bind(),
+ result.getCompositeScore().getFilteringScore().getRemainderFilter());
+ assertEquals(null, result.getLocalIndex());
+ assertEquals(makeIndex(Order.class, "orderTotal"), result.getForeignIndex());
+ assertEquals("order", result.getForeignProperty().toString());
+ }
+
+ public void testJoinNonPriority() throws Exception {
+ // Selects local index because filter score is just as good and local
+ // indexes are preferred.
+
+ IndexedQueryAnalyzer iqa = new IndexedQueryAnalyzer(Shipment.class, IxProvider.INSTANCE);
+ Filter<Shipment> filter = Filter.filterFor
+ (Shipment.class, "orderID >= ? & order.orderTotal >= ?");
+ filter = filter.bind();
+ IndexedQueryAnalyzer.Result result = iqa.analyze(filter);
+
+ assertTrue(result.handlesAnything());
+ assertTrue(result.getCompositeScore().getFilteringScore().hasRangeStart());
+ assertEquals(Filter.filterFor(Shipment.class, "order.orderTotal >= ?").bind(),
+ result.getCompositeScore().getFilteringScore().getRemainderFilter());
+ assertEquals(makeIndex(Shipment.class, "orderID"), result.getLocalIndex());
+ assertEquals(null, result.getForeignIndex());
+ assertEquals(null, result.getForeignProperty());
+ }
+
+ public void testChainedJoin() throws Exception {
+ IndexedQueryAnalyzer iqa = new IndexedQueryAnalyzer(Shipment.class, IxProvider.INSTANCE);
+ Filter<Shipment> filter = Filter.filterFor
+ (Shipment.class, "order.address.addressState = ?");
+ filter = filter.bind();
+ IndexedQueryAnalyzer.Result result = iqa.analyze(filter);
+
+ assertTrue(result.handlesAnything());
+ assertEquals(filter, result.getCompositeScore().getFilteringScore().getIdentityFilter());
+ assertEquals(null, result.getLocalIndex());
+ assertEquals(makeIndex(Address.class, "addressState"), result.getForeignIndex());
+ assertEquals("order.address", result.getForeignProperty().toString());
+ }
+
+ public void testChainedJoinExecutor() throws Exception {
+ Repository repo = new ToyRepository();
+
+ IndexedQueryAnalyzer<Shipment> iqa =
+ new IndexedQueryAnalyzer<Shipment>(Shipment.class, IxProvider.INSTANCE);
+ Filter<Shipment> filter = Filter.filterFor
+ (Shipment.class, "order.address.addressState = ? & order.address.addressZip = ?");
+ FilterValues<Shipment> values = filter.initialFilterValues();
+ filter = values.getFilter();
+ IndexedQueryAnalyzer.Result result = iqa.analyze(filter);
+
+ assertTrue(result.handlesAnything());
+ assertEquals(Filter.filterFor(Shipment.class, "order.address.addressState = ?").bind(),
+ result.getCompositeScore().getFilteringScore().getIdentityFilter());
+ assertEquals(Filter.filterFor(Shipment.class, "order.address.addressZip = ?").bind(),
+ result.getCompositeScore().getFilteringScore().getRemainderFilter());
+ assertEquals(null, result.getLocalIndex());
+ assertEquals(makeIndex(Address.class, "addressState"), result.getForeignIndex());
+ assertEquals("order.address", result.getForeignProperty().toString());
+
+ Mock ixExec = new Mock(result.getForeignIndex(), result.getCompositeScore());
+
+ QueryExecutor joinExec = new JoinedQueryExecutor
+ (repo, result.getForeignProperty(), ixExec);
+
+ QueryExecutor filteredExec = new FilteredQueryExecutor
+ (joinExec, result.getCompositeScore().getFilteringScore().getRemainderFilter());
+
+ //System.out.println();
+ //filteredExec.printPlan(System.out, 0, null);
+
+ joinExec.fetch(values.with("WA"));
+
+ assertEquals(1, ixExec.mIdentityValues.length);
+ assertEquals("WA", ixExec.mIdentityValues[0]);
+ assertEquals(BoundaryType.OPEN, ixExec.mRangeStartBoundary);
+ assertEquals(null, ixExec.mRangeStartValue);
+ assertEquals(BoundaryType.OPEN, ixExec.mRangeEndBoundary);
+ assertEquals(null, ixExec.mRangeEndValue);
+ assertFalse(ixExec.mReverseRange);
+ assertFalse(ixExec.mReverseOrder);
+ }
+
+ static class IxProvider implements IndexProvider {
+ static final IxProvider INSTANCE = new IxProvider();
+
+ public <S extends Storable> Collection<StorableIndex<S>> indexesFor(Class<S> type) {
+ StorableIndex<S>[] indexes;
+
+ if (Address.class.isAssignableFrom(type)) {
+ indexes = new StorableIndex[] {
+ makeIndex(type, "addressID"),
+ makeIndex(type, "addressState")
+ };
+ } else if (Order.class.isAssignableFrom(type)) {
+ indexes = new StorableIndex[] {
+ makeIndex(type, "orderID"),
+ makeIndex(type, "orderTotal"),
+ makeIndex(type, "addressID")
+ };
+ } else if (Shipment.class.isAssignableFrom(type)) {
+ indexes = new StorableIndex[] {
+ makeIndex(type, "shipmentID"),
+ makeIndex(type, "orderID"),
+ };
+ } else if (Shipper.class.isAssignableFrom(type)) {
+ indexes = new StorableIndex[] {
+ makeIndex(type, "shipperID")
+ };
+ } else {
+ indexes = new StorableIndex[0];
+ }
+
+ return Arrays.asList(indexes);
+ }
+ }
+}
diff --git a/src/test/java/com/amazon/carbonado/qe/TestIndexedQueryExecutor.java b/src/test/java/com/amazon/carbonado/qe/TestIndexedQueryExecutor.java index a039e63..3f865e6 100644 --- a/src/test/java/com/amazon/carbonado/qe/TestIndexedQueryExecutor.java +++ b/src/test/java/com/amazon/carbonado/qe/TestIndexedQueryExecutor.java @@ -78,7 +78,7 @@ public class TestIndexedQueryExecutor extends TestCase { Mock<StorableTestBasic> executor = new Mock(index, score);
- executor.openCursor(values.with(100));
+ executor.fetch(values.with(100));
assertEquals(1, executor.mIdentityValues.length);
assertEquals(100, executor.mIdentityValues[0]);
@@ -98,7 +98,7 @@ public class TestIndexedQueryExecutor extends TestCase { executor = new Mock(index, score);
- executor.openCursor(values.with(100).with(5));
+ executor.fetch(values.with(100).with(5));
assertEquals(2, executor.mIdentityValues.length);
assertEquals(100, executor.mIdentityValues[0]);
@@ -119,7 +119,7 @@ public class TestIndexedQueryExecutor extends TestCase { executor = new Mock(index, score);
- executor.openCursor(values.with(200));
+ executor.fetch(values.with(200));
assertEquals(null, executor.mIdentityValues);
assertEquals(BoundaryType.OPEN, executor.mRangeStartBoundary);
@@ -142,7 +142,7 @@ public class TestIndexedQueryExecutor extends TestCase { Mock<StorableTestBasic> executor = new Mock(index, score);
- executor.openCursor(values.with(100));
+ executor.fetch(values.with(100));
assertEquals(null, executor.mIdentityValues);
assertEquals(BoundaryType.EXCLUSIVE, executor.mRangeStartBoundary);
@@ -161,7 +161,7 @@ public class TestIndexedQueryExecutor extends TestCase { executor = new Mock(index, score);
- executor.openCursor(values.with(100));
+ executor.fetch(values.with(100));
assertEquals(null, executor.mIdentityValues);
assertEquals(BoundaryType.INCLUSIVE, executor.mRangeStartBoundary);
@@ -180,7 +180,7 @@ public class TestIndexedQueryExecutor extends TestCase { executor = new Mock(index, score);
- executor.openCursor(values.with(10).with(30));
+ executor.fetch(values.with(10).with(30));
assertEquals(null, executor.mIdentityValues);
assertEquals(BoundaryType.EXCLUSIVE, executor.mRangeStartBoundary);
@@ -199,7 +199,7 @@ public class TestIndexedQueryExecutor extends TestCase { executor = new Mock(index, score);
- executor.openCursor(values.with(10).with(30));
+ executor.fetch(values.with(10).with(30));
assertEquals(null, executor.mIdentityValues);
assertEquals(BoundaryType.EXCLUSIVE, executor.mRangeStartBoundary);
@@ -218,7 +218,7 @@ public class TestIndexedQueryExecutor extends TestCase { executor = new Mock(index, score);
- executor.openCursor(values.with(10).with(10));
+ executor.fetch(values.with(10).with(10));
assertEquals(null, executor.mIdentityValues);
assertEquals(BoundaryType.EXCLUSIVE, executor.mRangeStartBoundary);
@@ -237,7 +237,7 @@ public class TestIndexedQueryExecutor extends TestCase { executor = new Mock(index, score);
- executor.openCursor(values.with(30).with(10));
+ executor.fetch(values.with(30).with(10));
assertEquals(null, executor.mIdentityValues);
assertEquals(BoundaryType.INCLUSIVE, executor.mRangeStartBoundary);
@@ -257,7 +257,7 @@ public class TestIndexedQueryExecutor extends TestCase { executor = new Mock(index, score);
- executor.openCursor(values.with(100).with(30));
+ executor.fetch(values.with(100).with(30));
assertEquals(null, executor.mIdentityValues);
assertEquals(BoundaryType.EXCLUSIVE, executor.mRangeStartBoundary);
@@ -278,7 +278,7 @@ public class TestIndexedQueryExecutor extends TestCase { executor = new Mock(index, score);
- executor.openCursor(values.with(100));
+ executor.fetch(values.with(100));
assertEquals(null, executor.mIdentityValues);
assertEquals(BoundaryType.EXCLUSIVE, executor.mRangeStartBoundary);
@@ -298,7 +298,7 @@ public class TestIndexedQueryExecutor extends TestCase { executor = new Mock(index, score);
- executor.openCursor(values.with(100));
+ executor.fetch(values.with(100));
assertEquals(null, executor.mIdentityValues);
assertEquals(BoundaryType.EXCLUSIVE, executor.mRangeStartBoundary);
@@ -318,7 +318,7 @@ public class TestIndexedQueryExecutor extends TestCase { executor = new Mock(index, score);
- executor.openCursor(values.with(100));
+ executor.fetch(values.with(100));
assertEquals(null, executor.mIdentityValues);
assertEquals(BoundaryType.EXCLUSIVE, executor.mRangeStartBoundary);
@@ -341,7 +341,7 @@ public class TestIndexedQueryExecutor extends TestCase { Mock<StorableTestBasic> executor = new Mock(index, score);
- executor.openCursor(values.with(100));
+ executor.fetch(values.with(100));
assertEquals(null, executor.mIdentityValues);
assertEquals(BoundaryType.OPEN, executor.mRangeStartBoundary);
@@ -360,7 +360,7 @@ public class TestIndexedQueryExecutor extends TestCase { executor = new Mock(index, score);
- executor.openCursor(values.with(100));
+ executor.fetch(values.with(100));
assertEquals(null, executor.mIdentityValues);
assertEquals(BoundaryType.OPEN, executor.mRangeStartBoundary);
@@ -379,7 +379,7 @@ public class TestIndexedQueryExecutor extends TestCase { executor = new Mock(index, score);
- executor.openCursor(values.with(10).with(30));
+ executor.fetch(values.with(10).with(30));
assertEquals(null, executor.mIdentityValues);
assertEquals(BoundaryType.OPEN, executor.mRangeStartBoundary);
@@ -398,7 +398,7 @@ public class TestIndexedQueryExecutor extends TestCase { executor = new Mock(index, score);
- executor.openCursor(values.with(10).with(30));
+ executor.fetch(values.with(10).with(30));
assertEquals(null, executor.mIdentityValues);
assertEquals(BoundaryType.OPEN, executor.mRangeStartBoundary);
@@ -417,7 +417,7 @@ public class TestIndexedQueryExecutor extends TestCase { executor = new Mock(index, score);
- executor.openCursor(values.with(10).with(10));
+ executor.fetch(values.with(10).with(10));
assertEquals(null, executor.mIdentityValues);
assertEquals(BoundaryType.OPEN, executor.mRangeStartBoundary);
@@ -436,7 +436,7 @@ public class TestIndexedQueryExecutor extends TestCase { executor = new Mock(index, score);
- executor.openCursor(values.with(30).with(10));
+ executor.fetch(values.with(30).with(10));
assertEquals(null, executor.mIdentityValues);
assertEquals(BoundaryType.OPEN, executor.mRangeStartBoundary);
@@ -456,7 +456,7 @@ public class TestIndexedQueryExecutor extends TestCase { executor = new Mock(index, score);
- executor.openCursor(values.with(100).with(30));
+ executor.fetch(values.with(100).with(30));
assertEquals(null, executor.mIdentityValues);
assertEquals(BoundaryType.OPEN, executor.mRangeStartBoundary);
@@ -477,7 +477,7 @@ public class TestIndexedQueryExecutor extends TestCase { executor = new Mock(index, score);
- executor.openCursor(values.with(100));
+ executor.fetch(values.with(100));
assertEquals(null, executor.mIdentityValues);
assertEquals(BoundaryType.OPEN, executor.mRangeStartBoundary);
@@ -497,7 +497,7 @@ public class TestIndexedQueryExecutor extends TestCase { executor = new Mock(index, score);
- executor.openCursor(values.with(100));
+ executor.fetch(values.with(100));
assertEquals(null, executor.mIdentityValues);
assertEquals(BoundaryType.OPEN, executor.mRangeStartBoundary);
@@ -517,7 +517,7 @@ public class TestIndexedQueryExecutor extends TestCase { executor = new Mock(index, score);
- executor.openCursor(values.with(100));
+ executor.fetch(values.with(100));
assertEquals(null, executor.mIdentityValues);
assertEquals(BoundaryType.OPEN, executor.mRangeStartBoundary);
@@ -543,7 +543,7 @@ public class TestIndexedQueryExecutor extends TestCase { Mock<StorableTestBasic> executor = new Mock(index, score);
- executor.openCursor(values.with(100).with(200));
+ executor.fetch(values.with(100).with(200));
assertEquals(null, executor.mIdentityValues);
assertEquals(BoundaryType.EXCLUSIVE, executor.mRangeStartBoundary);
@@ -562,7 +562,7 @@ public class TestIndexedQueryExecutor extends TestCase { executor = new Mock(index, score);
- executor.openCursor(values.with(100).with(10));
+ executor.fetch(values.with(100).with(10));
assertEquals(null, executor.mIdentityValues);
assertEquals(BoundaryType.INCLUSIVE, executor.mRangeStartBoundary);
@@ -582,7 +582,7 @@ public class TestIndexedQueryExecutor extends TestCase { executor = new Mock(index, score);
- executor.openCursor(values.with(10).with(100).with(30));
+ executor.fetch(values.with(10).with(100).with(30));
assertEquals(null, executor.mIdentityValues);
assertEquals(BoundaryType.EXCLUSIVE, executor.mRangeStartBoundary);
@@ -614,7 +614,7 @@ public class TestIndexedQueryExecutor extends TestCase { executor = new Mock(index, score);
- executor.openCursor(values.with(3).with(56.5).with(200.2));
+ executor.fetch(values.with(3).with(56.5).with(200.2));
assertEquals(3, executor.mIdentityValues[0]);
assertEquals(BoundaryType.EXCLUSIVE, executor.mRangeStartBoundary);
@@ -630,7 +630,7 @@ public class TestIndexedQueryExecutor extends TestCase { executor = new Mock(index, score);
- executor.openCursor(values.with(3).with(56.5).with(200.2));
+ executor.fetch(values.with(3).with(56.5).with(200.2));
assertEquals(3, executor.mIdentityValues[0]);
assertEquals(BoundaryType.EXCLUSIVE, executor.mRangeStartBoundary);
@@ -646,7 +646,7 @@ public class TestIndexedQueryExecutor extends TestCase { executor = new Mock(index, score);
- executor.openCursor(values.with(3).with(56.5).with(200.2));
+ executor.fetch(values.with(3).with(56.5).with(200.2));
assertEquals(3, executor.mIdentityValues[0]);
assertEquals(BoundaryType.EXCLUSIVE, executor.mRangeStartBoundary);
@@ -667,7 +667,7 @@ public class TestIndexedQueryExecutor extends TestCase { executor = new Mock(index, score);
- executor.openCursor(values.with(3).with(56.5).with("foo"));
+ executor.fetch(values.with(3).with(56.5).with("foo"));
assertEquals(3, executor.mIdentityValues[0]);
assertEquals(56.5, executor.mIdentityValues[1]);
@@ -701,14 +701,14 @@ public class TestIndexedQueryExecutor extends TestCase { super(index, score);
}
- protected Cursor<S> openCursor(StorableIndex<S> index,
- Object[] identityValues,
- BoundaryType rangeStartBoundary,
- Object rangeStartValue,
- BoundaryType rangeEndBoundary,
- Object rangeEndValue,
- boolean reverseRange,
- boolean reverseOrder)
+ protected Cursor<S> fetch(StorableIndex<S> index,
+ Object[] identityValues,
+ BoundaryType rangeStartBoundary,
+ Object rangeStartValue,
+ BoundaryType rangeEndBoundary,
+ Object rangeEndValue,
+ boolean reverseRange,
+ boolean reverseOrder)
{
mIdentityValues = identityValues;
mRangeStartBoundary = rangeStartBoundary;
diff --git a/src/test/java/com/amazon/carbonado/qe/TestJoinedQueryExecutor.java b/src/test/java/com/amazon/carbonado/qe/TestJoinedQueryExecutor.java new file mode 100644 index 0000000..8a82758 --- /dev/null +++ b/src/test/java/com/amazon/carbonado/qe/TestJoinedQueryExecutor.java @@ -0,0 +1,203 @@ +/*
+ * Copyright 2006 Amazon Technologies, Inc. or its affiliates.
+ * Amazon, Amazon.com and Carbonado are trademarks or registered trademarks
+ * of Amazon Technologies, Inc. or its affiliates. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.amazon.carbonado.qe;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import junit.framework.TestSuite;
+
+import com.amazon.carbonado.Cursor;
+import com.amazon.carbonado.FetchException;
+import com.amazon.carbonado.Query;
+import com.amazon.carbonado.Repository;
+import com.amazon.carbonado.Storable;
+import com.amazon.carbonado.Storage;
+
+import com.amazon.carbonado.filter.Filter;
+import com.amazon.carbonado.filter.FilterValues;
+
+import com.amazon.carbonado.info.OrderedProperty;
+import com.amazon.carbonado.info.StorableIntrospector;
+import com.amazon.carbonado.info.StorableProperty;
+
+import com.amazon.carbonado.repo.toy.ToyRepository;
+
+import com.amazon.carbonado.stored.UserAddress;
+import com.amazon.carbonado.stored.UserInfo;
+
+/**
+ *
+ *
+ * @author Brian S O'Neill
+ */
+public class TestJoinedQueryExecutor extends TestQueryExecutor {
+ public static void main(String[] args) {
+ junit.textui.TestRunner.run(suite());
+ }
+
+ public static TestSuite suite() {
+ return new TestSuite(TestJoinedQueryExecutor.class);
+ }
+
+ private Repository mRepository;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ mRepository = new ToyRepository();
+ }
+
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ public void testJoin() throws Exception {
+ QueryExecutor<UserAddress> addressExecutor = addressExecutor();
+
+ QueryExecutor<UserInfo> userExecutor = new JoinedQueryExecutor<UserAddress, UserInfo>
+ (mRepository, UserInfo.class, "address", addressExecutor);
+
+ assertEquals("address.state = ?", userExecutor.getFilter().toString());
+ assertEquals("address.country", userExecutor.getOrdering().get(0).toString());
+
+ // Create some addresses
+ Storage<UserAddress> addressStorage = mRepository.storageFor(UserAddress.class);
+ UserAddress addr = addressStorage.prepare();
+ addr.setAddressID(1);
+ addr.setLine1("4567, 123 Street");
+ addr.setCity("Springfield");
+ addr.setState("IL");
+ addr.setCountry("USA");
+ addr.insert();
+
+ addr = addressStorage.prepare();
+ addr.setAddressID(2);
+ addr.setLine1("1111 Apt 1, 1st Ave");
+ addr.setCity("Somewhere");
+ addr.setState("AA");
+ addr.setCountry("USA");
+ addr.setNeighborAddressID(1);
+ addr.insert();
+
+ addr = addressStorage.prepare();
+ addr.setAddressID(3);
+ addr.setLine1("9999");
+ addr.setCity("Chicago");
+ addr.setState("IL");
+ addr.setCountry("USA");
+ addr.insert();
+
+ // Create some users
+ Storage<UserInfo> userStorage = mRepository.storageFor(UserInfo.class);
+ UserInfo user = userStorage.prepare();
+ user.setUserID(1);
+ user.setStateID(1);
+ user.setFirstName("Bob");
+ user.setLastName("Loblaw");
+ user.setAddressID(1);
+ user.insert();
+
+ user = userStorage.prepare();
+ user.setUserID(2);
+ user.setStateID(1);
+ user.setFirstName("Deb");
+ user.setLastName("Loblaw");
+ user.setAddressID(1);
+ user.insert();
+
+ user = userStorage.prepare();
+ user.setUserID(3);
+ user.setStateID(1);
+ user.setFirstName("No");
+ user.setLastName("Body");
+ user.setAddressID(2);
+ user.insert();
+
+ // Now do a basic join, finding everyone in IL.
+
+ FilterValues<UserInfo> values = Filter
+ .filterFor(UserInfo.class, "address.state = ?").initialFilterValues().with("IL");
+
+ Cursor<UserInfo> cursor = userExecutor.fetch(values);
+ assertTrue(cursor.hasNext());
+ assertEquals(1, cursor.next().getUserID());
+ assertEquals(2, cursor.next().getUserID());
+ assertFalse(cursor.hasNext());
+ cursor.close();
+
+ assertEquals(2L, userExecutor.count(values));
+
+ // Now do a multi join, finding everyone with an explicit neighbor in IL.
+
+ userExecutor = new JoinedQueryExecutor<UserAddress, UserInfo>
+ (mRepository, UserInfo.class, "address.neighbor", addressExecutor);
+
+ assertEquals("address.neighbor.state = ?", userExecutor.getFilter().toString());
+ assertEquals("address.neighbor.country", userExecutor.getOrdering().get(0).toString());
+
+ values = Filter
+ .filterFor(UserInfo.class, "address.neighbor.state = ?")
+ .initialFilterValues().with("IL");
+
+ cursor = userExecutor.fetch(values);
+ assertTrue(cursor.hasNext());
+ assertEquals(3, cursor.next().getUserID());
+ assertFalse(cursor.hasNext());
+ cursor.close();
+
+ assertEquals(1L, userExecutor.count(values));
+
+ }
+
+ protected QueryExecutor<UserAddress> addressExecutor() throws Exception {
+ Storage<UserAddress> addressStorage = mRepository.storageFor(UserAddress.class);
+
+ QueryExecutor<UserAddress> addressExecutor =
+ new ScanQueryExecutor<UserAddress>(addressStorage.query());
+
+ addressExecutor = new FilteredQueryExecutor<UserAddress>
+ (addressExecutor, Filter.filterFor(UserAddress.class, "state = ?"));
+
+ StorableProperty<UserAddress> prop = StorableIntrospector
+ .examine(UserAddress.class).getAllProperties().get("country");
+
+ List<OrderedProperty<UserAddress>> orderings =
+ new ArrayList<OrderedProperty<UserAddress>>();
+
+ orderings.add(OrderedProperty.get(prop, null));
+
+ addressExecutor = new ArraySortedQueryExecutor<UserAddress>
+ (addressExecutor, null, orderings);
+
+ return addressExecutor;
+ }
+
+ static class ScanQueryExecutor<S extends Storable> extends FullScanQueryExecutor<S> {
+ private final Query<S> mQuery;
+
+ ScanQueryExecutor(Query<S> query) {
+ super(query.getStorableType());
+ mQuery = query;
+ }
+
+ protected Cursor<S> fetch() throws FetchException {
+ return mQuery.fetch();
+ }
+ }
+}
diff --git a/src/test/java/com/amazon/carbonado/qe/TestSortedQueryExecutor.java b/src/test/java/com/amazon/carbonado/qe/TestSortedQueryExecutor.java index 0972e94..9e9906f 100644 --- a/src/test/java/com/amazon/carbonado/qe/TestSortedQueryExecutor.java +++ b/src/test/java/com/amazon/carbonado/qe/TestSortedQueryExecutor.java @@ -58,7 +58,7 @@ public class TestSortedQueryExecutor extends TestQueryExecutor { assertEquals(ordered, executor.getOrdering());
- compareElements(executor.openCursor(values), 1, 2, 3, 4);
+ compareElements(executor.fetch(values), 1, 2, 3, 4);
}
public void testBasicFinisherSorting() throws Exception {
@@ -79,6 +79,6 @@ public class TestSortedQueryExecutor extends TestQueryExecutor { assertEquals(handled.get(0), executor.getOrdering().get(0));
assertEquals(finisher.get(0), executor.getOrdering().get(1));
- compareElements(executor.openCursor(values), 1, 2, 3, 4);
+ compareElements(executor.fetch(values), 1, 2, 3, 4);
}
}
diff --git a/src/test/java/com/amazon/carbonado/qe/TestUnionQueryExecutor.java b/src/test/java/com/amazon/carbonado/qe/TestUnionQueryExecutor.java index 639176c..07716bb 100644 --- a/src/test/java/com/amazon/carbonado/qe/TestUnionQueryExecutor.java +++ b/src/test/java/com/amazon/carbonado/qe/TestUnionQueryExecutor.java @@ -70,6 +70,6 @@ public class TestUnionQueryExecutor extends TestQueryExecutor { assertEquals(primary.getOrdering(), union.getOrdering());
- compareElements(union.openCursor(values), 1, 2, 3, 7, 8);
+ compareElements(union.fetch(values), 1, 2, 3, 7, 8);
}
}
|