Skip to content

Commit

Permalink
TEIID-4005 allowing predicates to be split
Browse files Browse the repository at this point in the history
  • Loading branch information
shawkins committed Feb 26, 2016
1 parent aba9b63 commit 8feabe0
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 17 deletions.
Expand Up @@ -22,15 +22,7 @@

package org.teiid.query.optimizer.relational.rules;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.Stack;
import java.util.*;

import org.teiid.api.exception.query.QueryMetadataException;
import org.teiid.api.exception.query.QueryPlannerException;
Expand Down Expand Up @@ -391,7 +383,7 @@ private boolean splitSet(PlanNode critNode, DependentNodeTest test, DependentSet
throws QueryMetadataException, TeiidComponentException,
QueryPlannerException {
boolean result = false;
List<DependentSetCriteria> dscList = splitDependentSetCriteria(dscOrig);
List<DependentSetCriteria> dscList = splitDependentSetCriteria(dscOrig, false, null);
List<DependentSetCriteria.AttributeComparison> pushable = new ArrayList<AttributeComparison>();
List<DependentSetCriteria.AttributeComparison> nonPushable = new ArrayList<AttributeComparison>();
for (DependentSetCriteria dsc : dscList) {
Expand Down Expand Up @@ -519,10 +511,9 @@ private void markDependent(PlanNode critNode, PlanNode accessNode, QueryMetadata
}
accessNode.setProperty(NodeConstants.Info.IS_DEPENDENT_SET, Boolean.TRUE);
Criteria crit = (Criteria) critNode.getProperty(NodeConstants.Info.SELECT_CRITERIA);
if (isMultiAttributeDependentSet(crit)
&& !CapabilitiesUtil.supports(Capability.ARRAY_TYPE, RuleRaiseAccess.getModelIDFromAccess(accessNode, metadata), metadata, capFinder)) {
//split the criteria into individual predicates
List<DependentSetCriteria> crits = splitDependentSetCriteria((DependentSetCriteria) crit);
if (isMultiAttributeDependentSet(crit)) {
//split the criteria as needed
List<DependentSetCriteria> crits = splitDependentSetCriteria((DependentSetCriteria) crit, CapabilitiesUtil.supports(Capability.ARRAY_TYPE, RuleRaiseAccess.getModelIDFromAccess(accessNode, metadata), metadata, capFinder), metadata);
critNode.setProperty(NodeConstants.Info.SELECT_CRITERIA, new CompoundCriteria(crits));
}

Expand Down Expand Up @@ -550,12 +541,38 @@ private void markDependent(PlanNode critNode, PlanNode accessNode, QueryMetadata
}
}

private List<DependentSetCriteria> splitDependentSetCriteria(DependentSetCriteria dsc) {
private List<DependentSetCriteria> splitDependentSetCriteria(DependentSetCriteria dsc, boolean supportsArray, QueryMetadataInterface metadata) throws QueryMetadataException, TeiidComponentException {
List<AttributeComparison> attributes = dsc.getAttributes();
List<DependentSetCriteria> crits = new ArrayList<DependentSetCriteria>(attributes.size());

Map<Object, List<AttributeComparison>> splits = new LinkedHashMap<Object, List<AttributeComparison>>();

for (int i = 0; i < attributes.size(); i++) {
Object key = null;
DependentSetCriteria.AttributeComparison comp = attributes.get(i);
DependentSetCriteria crit = RuleChooseDependent.createDependentSetCriteria(dsc.getContextSymbol(), Arrays.asList(comp));
if (supportsArray && (comp.dep instanceof ElementSymbol)) {
ElementSymbol es = (ElementSymbol)comp.dep;
GroupSymbol group = es.getGroupSymbol();
if (!metadata.isVirtualGroup(group.getMetadataID())) {
key = group;
}
//TODO: we could try to determine further if this is allowable
//for now since we are pushing as far as we can, this is a good indication,
//that it will need split
}
if (key == null) {
key = splits.size();
}
List<AttributeComparison> comps = splits.get(key);
if (comps == null) {
comps = new ArrayList<DependentSetCriteria.AttributeComparison>(2);
splits.put(key, comps);
}
comps.add(comp);
}

for (List<AttributeComparison> comps : splits.values()) {
DependentSetCriteria crit = RuleChooseDependent.createDependentSetCriteria(dsc.getContextSymbol(), comps);
crit.setMakeDepOptions(dsc.getMakeDepOptions());
crits.add(crit);
}
Expand Down
Expand Up @@ -965,7 +965,7 @@ static PlanNode raiseAccessOverJoin(PlanNode joinNode, PlanNode accessNode, Obje

// Combine hints if necessary
RulePlaceAccess.copyDependentHints(other, accessNode);
RulePlaceAccess.copyDependentHints(joinNode, other);
RulePlaceAccess.copyDependentHints(joinNode, accessNode);
combineSourceHints(accessNode, other);

if (other.hasBooleanProperty(Info.IS_MULTI_SOURCE)) {
Expand Down
Expand Up @@ -1376,4 +1376,32 @@ private void helpTestMax(String sql) {
new String[] { "SELECT g_0.e1 AS c_0, g_0.e2 AS c_1 FROM pm2.g1 AS g_0 ORDER BY c_0", "SELECT g_1.e1 AS c_0, g_0.e1 AS c_1, g_1.e2 AS c_2 FROM pm1.g2 AS g_0, pm1.g1 AS g_1 WHERE (g_0.e1 = g_1.e1) AND (g_1.e1 IN (<dependent values>)) ORDER BY c_0" }, new DefaultCapabilitiesFinder(caps), TestOptimizer.ComparisonMode.EXACT_COMMAND_STRING ); //$NON-NLS-1$ //$NON-NLS-2$
}

@Test public void testSplitPredicateSameTable() throws Exception {
// Create query
String sql = "SELECT a.e1, b.e3 FROM /*+ makedep */ (select pm1.g1.e1, pm1.g1.e2 from pm1.g1, pm1.g2 where pm1.g1.e3 = pm1.g2.e3) as a, "
+ "(select pm2.g1.e1, pm2.g1.e2, pm2.g2.e3 from pm2.g1, pm2.g2 where pm2.g1.e3 = pm2.g2.e3) as b WHERE a.e1=b.e1 AND a.e2=b.e2"; //$NON-NLS-1$

BasicSourceCapabilities bsc = TestOptimizer.getTypicalCapabilities();
bsc.setCapabilitySupport(Capability.ARRAY_TYPE, true);

// Run query
TestOptimizer.helpPlan(sql, RealMetadataFactory.example1Cached(), new String[] {
"SELECT g_0.e1 AS c_0, g_0.e2 AS c_1 FROM pm1.g1 AS g_0, pm1.g2 AS g_1 WHERE (g_0.e3 = g_1.e3) AND ((g_0.e1, g_0.e2) IN (<dependent values>)) ORDER BY c_0, c_1",
"SELECT g_0.e1 AS c_0, g_0.e2 AS c_1, g_1.e3 AS c_2 FROM pm2.g1 AS g_0, pm2.g2 AS g_1 WHERE g_0.e3 = g_1.e3 ORDER BY c_0, c_1"}, new DefaultCapabilitiesFinder(bsc), ComparisonMode.EXACT_COMMAND_STRING);
}

@Test public void testSplitPredicateDifferentTable() throws Exception {
// Create query
String sql = "SELECT a.e1, b.e3 FROM /*+ makedep */ (select pm1.g1.e1, pm1.g2.e2 from pm1.g1, pm1.g2 where pm1.g1.e3 = pm1.g2.e3) as a, "
+ "(select pm2.g1.e1, pm2.g1.e2, pm2.g2.e3 from pm2.g1, pm2.g2 where pm2.g1.e3 = pm2.g2.e3) as b WHERE a.e1=b.e1 AND a.e2=b.e2"; //$NON-NLS-1$

BasicSourceCapabilities bsc = TestOptimizer.getTypicalCapabilities();
bsc.setCapabilitySupport(Capability.ARRAY_TYPE, true);

// Run query
TestOptimizer.helpPlan(sql, RealMetadataFactory.example1Cached(), new String[] {
"SELECT g_0.e1 AS c_0, g_0.e2 AS c_1, g_1.e3 AS c_2 FROM pm2.g1 AS g_0, pm2.g2 AS g_1 WHERE g_0.e3 = g_1.e3 ORDER BY c_0, c_1"
, "SELECT g_0.e1 AS c_0, g_1.e2 AS c_1 FROM pm1.g1 AS g_0, pm1.g2 AS g_1 WHERE (g_0.e3 = g_1.e3) AND (g_0.e1 IN (<dependent values>)) AND (g_1.e2 IN (<dependent values>)) ORDER BY c_0, c_1"}, new DefaultCapabilitiesFinder(bsc), ComparisonMode.EXACT_COMMAND_STRING);
}

}

0 comments on commit 8feabe0

Please sign in to comment.