From 2062d9432045c65fb2df06f55947838b24ad2613 Mon Sep 17 00:00:00 2001 From: "Brian S. O'Neill" Date: Wed, 20 Sep 2006 20:33:16 +0000 Subject: Print plan shows multi-way joins. --- .../amazon/carbonado/qe/JoinedQueryExecutor.java | 217 +++++++++++---------- 1 file changed, 115 insertions(+), 102 deletions(-) (limited to 'src/main/java/com/amazon/carbonado') diff --git a/src/main/java/com/amazon/carbonado/qe/JoinedQueryExecutor.java b/src/main/java/com/amazon/carbonado/qe/JoinedQueryExecutor.java index ebcb60a..11df215 100644 --- a/src/main/java/com/amazon/carbonado/qe/JoinedQueryExecutor.java +++ b/src/main/java/com/amazon/carbonado/qe/JoinedQueryExecutor.java @@ -42,186 +42,199 @@ import com.amazon.carbonado.info.ChainedProperty; import com.amazon.carbonado.info.OrderedProperty; import com.amazon.carbonado.info.StorableInfo; import com.amazon.carbonado.info.StorableIntrospector; +import com.amazon.carbonado.info.StorableProperty; /** - * QueryExecutor which wraps an executor for type A, follows a join, and - * produces type B. + * QueryExecutor which wraps an executor for type source, follows a + * join, and produces type target. * * @author Brian S O'Neill * @see JoinedCursorFactory + * @param source type + * @param target type */ -public class JoinedQueryExecutor - extends AbstractQueryExecutor +public class JoinedQueryExecutor + extends AbstractQueryExecutor { - private static OrderingList - transformOrdering(Class bType, - String bToAProperty, - QueryExecutor aExecutor) + private static OrderingList + transformOrdering(Class targetType, + String targetToSourceProperty, + QueryExecutor sourceExecutor) { - StorableInfo bInfo = StorableIntrospector.examine(bType); + StorableInfo targetInfo = StorableIntrospector.examine(targetType); - OrderingList aOrdering = aExecutor.getOrdering(); - int size = aOrdering.size(); - OrderedProperty[] bOrdering = new OrderedProperty[size]; + OrderingList sourceOrdering = sourceExecutor.getOrdering(); + int size = sourceOrdering.size(); + OrderedProperty[] targetOrdering = new OrderedProperty[size]; for (int i=0; i aProp = aOrdering.get(i); - String bName = bToAProperty + '.' + aProp.getChainedProperty(); - OrderedProperty bProp = OrderedProperty - .get(ChainedProperty.parse(bInfo, bName), aProp.getDirection()); - bOrdering[i] = bProp; + OrderedProperty sourceProp = sourceOrdering.get(i); + String targetName = targetToSourceProperty + '.' + sourceProp.getChainedProperty(); + OrderedProperty targetProp = OrderedProperty + .get(ChainedProperty.parse(targetInfo, targetName), sourceProp.getDirection()); + targetOrdering[i] = targetProp; } - return OrderingList.get(bOrdering); + return OrderingList.get(targetOrdering); } - private final JoinedCursorFactory mFactory; - private final QueryExecutor mAExecutor; + private final ChainedProperty mTargetToSourceProperty; + private final JoinedCursorFactory mFactory; + private final QueryExecutor mSourceExecutor; - private final FilterValues mAFilterValues; - private final Filter mBFilter; - private final OrderingList mBOrdering; + private final FilterValues mSourceFilterValues; + private final Filter mTargetFilter; + private final OrderingList mTargetOrdering; /** * @param repo access to storage instances for properties - * @param bType type of B instances - * @param bToAProperty property of B type which maps to instances of - * A type. - * @param aExecutor executor for A instances - * @throws IllegalArgumentException if property type is not A + * @param targetType type of target instances + * @param targetToSourceProperty property of target type which maps + * to instances of source type. + * @param sourceExecutor executor for source instances + * @throws IllegalArgumentException if property type is not source */ public JoinedQueryExecutor(Repository repo, - Class bType, - String bToAProperty, - QueryExecutor aExecutor) + Class targetType, + String targetToSourceProperty, + QueryExecutor sourceExecutor) throws SupportException, FetchException, RepositoryException { - mFactory = new JoinedCursorFactory - (repo, bType, bToAProperty, aExecutor.getStorableType()); - mAExecutor = aExecutor; - - Filter aFilter = aExecutor.getFilter(); - - mAFilterValues = aFilter.initialFilterValues(); - mBFilter = aFilter.accept(new FilterTransformer(bType, bToAProperty), null); - - mBOrdering = transformOrdering(bType, bToAProperty, aExecutor); + this(repo, + ChainedProperty.parse(StorableIntrospector.examine(targetType), + targetToSourceProperty), + sourceExecutor); } /** * @param repo access to storage instances for properties - * @param bToAProperty property of B type which maps to instances of - * A type. + * @param targetToSourceProperty property of target type which maps + * to instances of source type. * @param aExecutor executor for A instances * @throws IllegalArgumentException if property type is not A */ public JoinedQueryExecutor(Repository repo, - ChainedProperty bToAProperty, - QueryExecutor aExecutor) + ChainedProperty targetToSourceProperty, + QueryExecutor sourceExecutor) throws SupportException, FetchException, RepositoryException { - mFactory = new JoinedCursorFactory - (repo, bToAProperty, aExecutor.getStorableType()); - mAExecutor = aExecutor; + mTargetToSourceProperty = targetToSourceProperty; + mFactory = new JoinedCursorFactory + (repo, targetToSourceProperty, sourceExecutor.getStorableType()); + mSourceExecutor = sourceExecutor; - Filter aFilter = aExecutor.getFilter(); + Filter sourceFilter = sourceExecutor.getFilter(); - mAFilterValues = aFilter.initialFilterValues(); - mBFilter = aFilter.accept(new FilterTransformer(bToAProperty), null); + mSourceFilterValues = sourceFilter.initialFilterValues(); + mTargetFilter = sourceFilter.accept(new FilterTransformer(), null); - mBOrdering = transformOrdering(bToAProperty.getPrimeProperty().getEnclosingType(), - bToAProperty.toString(), aExecutor); + mTargetOrdering = transformOrdering + (targetToSourceProperty.getPrimeProperty().getEnclosingType(), + targetToSourceProperty.toString(), sourceExecutor); } - public Filter getFilter() { - return mBFilter; + public Filter getFilter() { + return mTargetFilter; } - public Cursor fetch(FilterValues values) throws FetchException { - return mFactory.join(mAExecutor.fetch(transferValues(values))); + public Cursor fetch(FilterValues values) throws FetchException { + return mFactory.join(mSourceExecutor.fetch(transferValues(values))); } - public OrderingList getOrdering() { - return mBOrdering; + public OrderingList getOrdering() { + return mTargetOrdering; } - public boolean printPlan(Appendable app, int indentLevel, FilterValues values) + public boolean printPlan(Appendable app, int indentLevel, FilterValues values) throws IOException { - indent(app, indentLevel); - app.append("join: "); - // FIXME: split multi-way join into more nested levels - app.append(getStorableType().getName()); - newline(app); - mAExecutor.printPlan(app, increaseIndent(indentLevel), transferValues(values)); + int chainCount = mTargetToSourceProperty.getChainCount(); + + for (int i = -1; i < chainCount; i++) { + indent(app, indentLevel); + app.append("join: "); + + StorableProperty prop; + if (i == -1) { + prop = mTargetToSourceProperty.getPrimeProperty(); + } else { + prop = mTargetToSourceProperty.getChainedProperty(i); + } + + app.append(prop.getEnclosingType().getName()); + newline(app); + indent(app, indentLevel); + app.append("...via property: "); + app.append(prop.getName()); + newline(app); + indentLevel = increaseIndent(indentLevel); + } + + mSourceExecutor.printPlan(app, indentLevel, transferValues(values)); return true; } - private FilterValues transferValues(FilterValues values) { - if (values == null || mAFilterValues == null) { + private FilterValues transferValues(FilterValues values) { + if (values == null || mSourceFilterValues == null) { return null; } - return mAFilterValues.withValues(values.getSuppliedValues()); + return mSourceFilterValues.withValues(values.getSuppliedValues()); } - private class FilterTransformer extends Visitor, Object> { - private final Class mBType; - private final String mBToAProperty; - - FilterTransformer(Class bType, String bToAProperty) { - mBType = bType; - mBToAProperty = bToAProperty; - } + private class FilterTransformer extends Visitor, Object> { + private final Class mTargetType; - FilterTransformer(ChainedProperty bToAProperty) { - mBType = bToAProperty.getPrimeProperty().getEnclosingType(); - mBToAProperty = bToAProperty.toString(); + FilterTransformer() { + mTargetType = mTargetToSourceProperty.getPrimeProperty().getEnclosingType(); } - public Filter visit(OrFilter aFilter, Object param) { - return aFilter.getLeftFilter().accept(this, param) - .and(aFilter.getRightFilter().accept(this, param)); + public Filter visit(OrFilter sourceFilter, Object param) { + return sourceFilter.getLeftFilter().accept(this, param) + .and(sourceFilter.getRightFilter().accept(this, param)); } - public Filter visit(AndFilter aFilter, Object param) { - return aFilter.getLeftFilter().accept(this, param) - .or(aFilter.getRightFilter().accept(this, param)); + public Filter visit(AndFilter sourceFilter, Object param) { + return sourceFilter.getLeftFilter().accept(this, param) + .or(sourceFilter.getRightFilter().accept(this, param)); } - public Filter visit(PropertyFilter aFilter, Object param) { + public Filter visit(PropertyFilter sourceFilter, Object param) { String name; - ChainedProperty aChainedProp = aFilter.getChainedProperty(); - if (mBType == aChainedProp.getPrimeProperty().getEnclosingType()) { - // If type if A is already B, (which violates generic type + ChainedProperty sourceChainedProp = sourceFilter.getChainedProperty(); + if (mTargetType == sourceChainedProp.getPrimeProperty().getEnclosingType()) { + // If type of S is already T, (which violates generic type // signature) then it came from join index analysis. - name = aChainedProp.toString(); + name = sourceChainedProp.toString(); } else { - StringBuilder nameBuilder = new StringBuilder(mBToAProperty).append('.'); + StringBuilder nameBuilder = new StringBuilder(); try { - aChainedProp.appendTo(nameBuilder); + mTargetToSourceProperty.appendTo(nameBuilder); + nameBuilder.append('.'); + sourceChainedProp.appendTo(nameBuilder); } catch (IOException e) { // Not gonna happen } name = nameBuilder.toString(); } - Filter bFilter = Filter.getOpenFilter(mBType); - if (aFilter.isConstant()) { - bFilter = bFilter.and(name, aFilter.getOperator(), aFilter.constant()); + Filter targetFilter = Filter.getOpenFilter(mTargetType); + if (sourceFilter.isConstant()) { + targetFilter = targetFilter + .and(name, sourceFilter.getOperator(), sourceFilter.constant()); } else { - bFilter = bFilter.and(name, aFilter.getOperator()); + targetFilter = targetFilter.and(name, sourceFilter.getOperator()); } - return bFilter; + return targetFilter; } - public Filter visit(OpenFilter aFilter, Object param) { - return Filter.getOpenFilter(mBType); + public Filter visit(OpenFilter sourceFilter, Object param) { + return Filter.getOpenFilter(mTargetType); } - public Filter visit(ClosedFilter aFilter, Object param) { - return Filter.getClosedFilter(mBType); + public Filter visit(ClosedFilter sourceFilter, Object param) { + return Filter.getClosedFilter(mTargetType); } } } -- cgit v1.2.3