use of org.teiid.query.sql.lang.DependentSetCriteria in project teiid by teiid.
the class RulePushSelectCriteria method splitDependentSetCriteria.
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);
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);
}
return crits;
}
use of org.teiid.query.sql.lang.DependentSetCriteria in project teiid by teiid.
the class RulePushSelectCriteria method moveCriteriaIntoOnClause.
/**
* @param critNode
* @param joinNode
*/
private boolean moveCriteriaIntoOnClause(PlanNode critNode, PlanNode joinNode) {
NodeEditor.removeChildNode(critNode.getParent(), critNode);
List joinCriteria = (List) joinNode.getProperty(NodeConstants.Info.JOIN_CRITERIA);
Criteria criteria = (Criteria) critNode.getProperty(NodeConstants.Info.SELECT_CRITERIA);
// since the parser uses EMPTY_LIST, check for size 0 also
if (joinCriteria == null || joinCriteria.size() == 0) {
joinCriteria = new LinkedList();
joinNode.setProperty(NodeConstants.Info.JOIN_CRITERIA, joinCriteria);
}
if (joinCriteria.contains(criteria)) {
return false;
}
boolean moved = false;
if (critNode.hasBooleanProperty(NodeConstants.Info.IS_DEPENDENT_SET)) {
if (criteria instanceof DependentSetCriteria) {
DependentSetCriteria dsc = (DependentSetCriteria) criteria;
if (dsc.hasMultipleAttributes()) {
// split the array based upon the join children.
List<DependentSetCriteria.AttributeComparison> joinExprs = new ArrayList<DependentSetCriteria.AttributeComparison>();
List<DependentSetCriteria.AttributeComparison> leftExprs = new ArrayList<DependentSetCriteria.AttributeComparison>();
List<DependentSetCriteria.AttributeComparison> rightExprs = new ArrayList<DependentSetCriteria.AttributeComparison>();
PlanNode leftJoinSource = FrameUtil.findJoinSourceNode(joinNode.getFirstChild());
PlanNode rightJoinSource = FrameUtil.findJoinSourceNode(joinNode.getLastChild());
for (int i = 0; i < dsc.getAttributes().size(); i++) {
DependentSetCriteria.AttributeComparison comp = dsc.getAttributes().get(i);
Set<GroupSymbol> groups = GroupsUsedByElementsVisitor.getGroups(comp.dep);
if (leftJoinSource.getGroups().containsAll(groups)) {
leftExprs.add(comp);
} else if (rightJoinSource.getGroups().containsAll(groups)) {
rightExprs.add(comp);
} else {
joinExprs.add(comp);
}
}
criteria = RuleChooseDependent.createDependentSetCriteria(dsc.getContextSymbol(), joinExprs);
PlanNode left = RuleChooseDependent.createDependentSetNode(dsc.getContextSymbol(), leftExprs);
if (left != null) {
moved = true;
joinNode.getFirstChild().addAsParent(left);
}
PlanNode right = RuleChooseDependent.createDependentSetNode(dsc.getContextSymbol(), rightExprs);
if (right != null) {
moved = true;
joinNode.getLastChild().addAsParent(right);
}
}
}
if (criteria != null) {
joinNode.setProperty(NodeConstants.Info.IS_DEPENDENT_SET, Boolean.TRUE);
}
}
if (criteria != null) {
joinCriteria.add(criteria);
}
if (!joinCriteria.isEmpty() && joinNode.getProperty(Info.JOIN_TYPE) == JoinType.JOIN_CROSS) {
joinNode.setProperty(NodeConstants.Info.JOIN_TYPE, JoinType.JOIN_INNER);
}
return moved;
}
use of org.teiid.query.sql.lang.DependentSetCriteria in project teiid by teiid.
the class DependentCriteriaProcessor method prepareCriteria.
public Criteria prepareCriteria() throws TeiidComponentException, TeiidProcessingException {
if (phase == SORT) {
for (TupleState state : dependentState.values()) {
state.sort();
if (state.dvs.getTupleBuffer().getRowCount() == 0) {
return QueryRewriter.FALSE_CRITERIA;
}
}
// init total predicates and max size
totalPredicates = setStates.size();
if (this.maxPredicates > 0) {
// We have a bin packing problem if totalPredicates < sources - We'll address that case later.
// TODO: better handling for the correlated composite case
totalPredicates = Math.max(totalPredicates, this.maxPredicates);
}
long maxParams = this.maxPredicates * this.maxSetSize;
maxSize = Integer.MAX_VALUE;
if (this.maxSetSize > 0) {
maxSize = this.maxSetSize;
if (this.maxPredicates > 0 && totalPredicates > this.maxPredicates) {
// scale the max based upon the number of predicates - this is not perfect, but sufficient for most situations
maxSize = Math.max(1, maxParams / totalPredicates);
}
}
// determine push down handling
if (pushdown) {
List<Criteria> newCriteria = new ArrayList<Criteria>();
long params = 0;
int sets = 0;
for (Criteria criteria : queryCriteria) {
if (!(criteria instanceof DependentSetCriteria)) {
newCriteria.add(criteria);
continue;
}
sets++;
DependentSetCriteria dsc = (DependentSetCriteria) criteria;
TupleState ts = dependentState.get(dsc.getContextSymbol());
DependentValueSource dvs = ts.dvs;
// check if this has more rows than we want to push
if ((dsc.getMaxNdv() != -1 && dvs.getTupleBuffer().getRowCount() > dsc.getMaxNdv()) || (dsc.getMakeDepOptions() != null && dsc.getMakeDepOptions().getMax() != null && dvs.getTupleBuffer().getRowCount() > dsc.getMakeDepOptions().getMax())) {
// don't try to pushdown
continue;
}
int cols = 1;
if (dsc.getExpression() instanceof Array) {
cols = ((Array) dsc.getExpression()).getExpressions().size();
}
dsc = dsc.clone();
// determine if this will be more than 1 source query
params += cols * dvs.getTupleBuffer().getRowCount();
// TODO: this assumes that if any one of the dependent
// joins are pushed, then they all are
dsc.setDependentValueSource(dvs);
newCriteria.add(dsc);
}
// TODO: see if this should be a source tunable parameter
int maxParamThreshold = 3;
// generally this value accounts for the additional overhead of temp table creation
if (params > maxParams && (sets > 1 || complexQuery || params > maxParams * maxParamThreshold)) {
// and only if the we could produce a cross set or have a complex query
return Criteria.combineCriteria(newCriteria);
}
}
// proceed with set based processing
phase = SET_PROCESSING;
}
replaceDependentValueIterators();
LinkedList<Criteria> crits = new LinkedList<Criteria>();
for (int i = 0; i < queryCriteria.size(); i++) {
SetState state = this.setStates.get(i);
Criteria criteria = queryCriteria.get(i);
if (state == null) {
if (criteria != QueryRewriter.TRUE_CRITERIA) {
crits.add((Criteria) criteria.clone());
}
} else {
Criteria crit = replaceDependentCriteria((AbstractSetCriteria) criteria, state);
if (crit == QueryRewriter.FALSE_CRITERIA) {
return QueryRewriter.FALSE_CRITERIA;
}
if (crit != QueryRewriter.TRUE_CRITERIA) {
crits.add(crit);
}
}
}
if (crits.size() == 1) {
return crits.get(0);
}
return new CompoundCriteria(CompoundCriteria.AND, crits);
}
use of org.teiid.query.sql.lang.DependentSetCriteria in project teiid by teiid.
the class TestDependentSetCriteria method example.
private DependentSetCriteria example() {
// $NON-NLS-1$
ElementSymbol e1 = new ElementSymbol("pm1.g1.e1");
// $NON-NLS-1$
DependentSetCriteria dsc = new DependentSetCriteria(e1, "");
// $NON-NLS-1$
final ElementSymbol e2 = new ElementSymbol("pm2.g1.e2");
dsc.setValueExpression(e2);
return dsc;
}
use of org.teiid.query.sql.lang.DependentSetCriteria in project teiid by teiid.
the class TestDependentSetCriteria method testEquivalence1.
public void testEquivalence1() {
DependentSetCriteria dsc = example();
DependentSetCriteria dsc1 = example();
// $NON-NLS-1$
dsc1.setValueExpression(new ElementSymbol("foo"));
assertNotSame(dsc, dsc1);
}
Aggregations