use of org.teiid.query.sql.lang.CompoundCriteria in project teiid by teiid.
the class DependentCriteriaProcessor method replaceDependentCriteria.
public Criteria replaceDependentCriteria(AbstractSetCriteria crit, SetState state) throws TeiidComponentException {
if (state.overMax) {
DependentValueSource originalVs = (DependentValueSource) dependentNode.getContext().getVariableContext().getGlobalValue(((DependentSetCriteria) crit).getContextSymbol());
originalVs.setUnused(true);
return QueryRewriter.TRUE_CRITERIA;
}
if (state.replacement.isEmpty()) {
// No values - return criteria that is always false
return QueryRewriter.FALSE_CRITERIA;
}
int numberOfSets = 1;
int setSize = Integer.MAX_VALUE;
if (this.maxSetSize > 0) {
setSize = (int) Math.max(1, this.maxSetSize / state.valueCount);
numberOfSets = state.replacement.size() / setSize + (state.replacement.size() % setSize != 0 ? 1 : 0);
}
Iterator<Constant> iter = state.replacement.iterator();
ArrayList<Criteria> orCrits = new ArrayList<Criteria>(numberOfSets);
for (int i = 0; i < numberOfSets; i++) {
if (setSize == 1 || i + 1 == state.replacement.size()) {
orCrits.add(new CompareCriteria(crit.getExpression(), CompareCriteria.EQ, iter.next()));
} else {
List<Constant> vals = new ArrayList<Constant>(Math.min(state.replacement.size(), setSize));
for (int j = 0; j < setSize && iter.hasNext(); j++) {
Constant val = iter.next();
vals.add(val);
}
SetCriteria sc = new SetCriteria();
sc.setExpression(crit.getExpression());
sc.setValues(vals);
orCrits.add(sc);
}
}
if (orCrits.size() == 1) {
return orCrits.get(0);
}
return new CompoundCriteria(CompoundCriteria.OR, orCrits);
}
use of org.teiid.query.sql.lang.CompoundCriteria in project teiid by teiid.
the class TestCompoundCriteria method testClone2.
public void testClone2() {
// $NON-NLS-1$
ElementSymbol e1 = new ElementSymbol("e1");
// $NON-NLS-1$
CompareCriteria ccrit1 = new CompareCriteria(e1, CompareCriteria.EQ, new Constant("abc"));
CompoundCriteria comp = new CompoundCriteria(CompoundCriteria.AND, ccrit1, null);
UnitTestUtil.helpTestEquivalence(0, comp, comp.clone());
}
use of org.teiid.query.sql.lang.CompoundCriteria in project teiid by teiid.
the class JoinRegion method scoreRegion.
/**
* Will provide an estimate of cost by summing the estimated tuples flowing through
* each intermediate join.
*
* @param joinOrder
* @param metadata
* @return
* @throws TeiidComponentException
* @throws QueryMetadataException
* @throws QueryPlannerException
*/
public double scoreRegion(Object[] joinOrder, int startIndex, QueryMetadataInterface metadata, CapabilitiesFinder capFinder, CommandContext context, boolean partial) throws QueryMetadataException, TeiidComponentException, QueryPlannerException {
List<Map.Entry<PlanNode, PlanNode>> joinSourceEntries = new ArrayList<Map.Entry<PlanNode, PlanNode>>(joinSourceNodes.entrySet());
double totalIntermediatCost = 0;
double cost = 1;
HashSet<PlanNode> criteria = new HashSet<PlanNode>(this.criteriaNodes);
HashSet<GroupSymbol> groups = new HashSet<GroupSymbol>(this.joinSourceNodes.size());
HashSet<GroupSymbol> rightGroups = new HashSet<GroupSymbol>();
List<Expression> leftExpressions = new ArrayList<Expression>();
List<Expression> rightExpressions = new ArrayList<Expression>();
HashSet<Criteria> nonEquiJoinCriteria = new HashSet<Criteria>();
// only calculate up to the second to last as the last is not an intermediate result
for (int i = 0; i < joinOrder.length - (partial ? 0 : 1); i++) {
boolean hasUnknown = false;
boolean shouldFilter = true;
Integer source = (Integer) joinOrder[i];
Map.Entry<PlanNode, PlanNode> entry = joinSourceEntries.get(source.intValue());
PlanNode joinSourceRoot = entry.getValue();
if (i >= startIndex) {
// check to make sure that this group ordering satisfies the access patterns
if (!this.unsatisfiedAccessPatterns.isEmpty() || this.containsNestedTable) {
PlanNode joinSource = entry.getKey();
Collection<GroupSymbol> requiredGroups = (Collection<GroupSymbol>) joinSource.getProperty(NodeConstants.Info.REQUIRED_ACCESS_PATTERN_GROUPS);
if (requiredGroups != null && !groups.containsAll(requiredGroups)) {
return Double.MAX_VALUE;
}
}
}
rightGroups.clear();
rightGroups.addAll(groups);
groups.addAll(joinSourceRoot.getGroups());
if (startIndex > 0 && i < startIndex) {
continue;
}
float sourceCost = joinSourceRoot.getCardinality();
List<PlanNode> applicableCriteria = null;
CompoundCriteria cc = null;
if (!criteria.isEmpty() && i > 0) {
applicableCriteria = getJoinCriteriaForGroups(groups, criteria);
if (applicableCriteria != null && !applicableCriteria.isEmpty()) {
cc = new CompoundCriteria();
for (PlanNode planNode : applicableCriteria) {
cc.addCriteria((Criteria) planNode.getProperty(NodeConstants.Info.SELECT_CRITERIA));
}
}
}
if (sourceCost == NewCalculateCostUtil.UNKNOWN_VALUE) {
sourceCost = UNKNOWN_TUPLE_EST;
hasUnknown = true;
if (cc != null) {
shouldFilter = false;
sourceCost = (float) cost;
criteria.removeAll(applicableCriteria);
if (NewCalculateCostUtil.usesKey(cc, metadata) || (i >= 1 && joinSourceRoot.hasProperty(Info.MAKE_DEP) && !joinSourceRoot.hasBooleanProperty(Info.MAKE_NOT_DEP))) {
sourceCost = Math.min(UNKNOWN_TUPLE_EST, sourceCost * Math.min(NewCalculateCostUtil.UNKNOWN_JOIN_SCALING, sourceCost));
} else {
sourceCost = Math.min(UNKNOWN_TUPLE_EST, sourceCost * NewCalculateCostUtil.UNKNOWN_JOIN_SCALING * 8);
}
}
} else if (Double.isInfinite(sourceCost) || Double.isNaN(sourceCost)) {
return Double.MAX_VALUE;
} else if (i == 1 && applicableCriteria != null && !applicableCriteria.isEmpty()) {
List<Object> key = Arrays.asList(joinOrder[0], joinOrder[1]);
Float depJoinCost = null;
if (depCache != null && depCache.containsKey(key)) {
depJoinCost = depCache.get(key);
} else {
Integer indIndex = (Integer) joinOrder[0];
Map.Entry<PlanNode, PlanNode> indEntry = joinSourceEntries.get(indIndex.intValue());
PlanNode possibleInd = indEntry.getValue();
depJoinCost = getDepJoinCost(metadata, capFinder, context, possibleInd, applicableCriteria, joinSourceRoot);
if (depCache == null) {
depCache = new HashMap<List<Object>, Float>();
}
depCache.put(key, depJoinCost);
}
if (depJoinCost != null) {
sourceCost = depJoinCost;
}
}
if (i > 0 && (applicableCriteria == null || applicableCriteria.isEmpty()) && hasUnknown) {
// cross join penalty
sourceCost *= 10;
}
double rightCost = cost;
cost *= sourceCost;
if (cc != null && applicableCriteria != null && shouldFilter) {
// filter based upon notion of join
leftExpressions.clear();
rightExpressions.clear();
nonEquiJoinCriteria.clear();
Collection<GroupSymbol> leftGroups = joinSourceRoot.getGroups();
RuleChooseJoinStrategy.separateCriteria(leftGroups, rightGroups, leftExpressions, rightExpressions, cc.getCriteria(), nonEquiJoinCriteria);
if (!leftExpressions.isEmpty()) {
float leftNdv = NewCalculateCostUtil.getNDVEstimate(joinSourceRoot, metadata, sourceCost, leftExpressions, null);
float rightNdv = NewCalculateCostUtil.UNKNOWN_VALUE;
if (leftNdv != NewCalculateCostUtil.UNKNOWN_VALUE) {
Set<GroupSymbol> usedRight = GroupsUsedByElementsVisitor.getGroups(rightExpressions);
for (int j = 0; j < i; j++) {
Entry<PlanNode, PlanNode> previousEntry = joinSourceEntries.get((int) joinOrder[j]);
if (previousEntry.getValue().getGroups().containsAll(usedRight)) {
rightNdv = NewCalculateCostUtil.getNDVEstimate(previousEntry.getValue(), metadata, sourceCost, rightExpressions, null);
break;
}
}
}
if (leftNdv != NewCalculateCostUtil.UNKNOWN_VALUE && rightNdv != NewCalculateCostUtil.UNKNOWN_VALUE) {
cost = (sourceCost / leftNdv) * (rightCost / rightNdv) * Math.min(leftNdv, rightNdv);
} else {
// check for a key
// just use the default logic
nonEquiJoinCriteria.clear();
}
} else {
// just use the default logic
nonEquiJoinCriteria.clear();
}
for (PlanNode criteriaNode : applicableCriteria) {
Criteria crit = (Criteria) criteriaNode.getProperty(NodeConstants.Info.SELECT_CRITERIA);
if (!nonEquiJoinCriteria.contains(crit)) {
continue;
}
float filter = ((Float) criteriaNode.getProperty(NodeConstants.Info.EST_SELECTIVITY)).floatValue();
cost *= filter;
}
criteria.removeAll(applicableCriteria);
}
totalIntermediatCost += cost;
}
return totalIntermediatCost;
}
use of org.teiid.query.sql.lang.CompoundCriteria in project teiid by teiid.
the class RulePushSelectCriteria method markDependent.
private void markDependent(PlanNode critNode, PlanNode accessNode, QueryMetadataInterface metadata, CapabilitiesFinder capFinder) throws QueryMetadataException, TeiidComponentException {
// once a dependent crit node is pushed, don't bother pushing it further into the command
// dependent access node will use this as an assumption for where dependent sets can appear in the command
critNode.setProperty(NodeConstants.Info.IS_PUSHED, Boolean.TRUE);
if (createdNodes != null) {
// this is during a planning run and should not cause additional side-effects
return;
}
accessNode.setProperty(NodeConstants.Info.IS_DEPENDENT_SET, Boolean.TRUE);
Criteria crit = (Criteria) critNode.getProperty(NodeConstants.Info.SELECT_CRITERIA);
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));
}
Collection<ElementSymbol> elements = null;
for (PlanNode joinNode : NodeEditor.findAllNodes(accessNode, NodeConstants.Types.JOIN, NodeConstants.Types.SOURCE)) {
List<Criteria> joinCriteria = (List<Criteria>) joinNode.getProperty(Info.JOIN_CRITERIA);
if (joinCriteria == null) {
continue;
}
for (Criteria joinPredicate : joinCriteria) {
if (!(joinPredicate instanceof CompareCriteria)) {
continue;
}
CompareCriteria cc = (CompareCriteria) joinPredicate;
if (!cc.isOptional()) {
continue;
}
if (elements == null) {
elements = ElementCollectorVisitor.getElements((LanguageObject) critNode.getProperty(Info.SELECT_CRITERIA), true);
}
if (!Collections.disjoint(elements, ElementCollectorVisitor.getElements(cc, false))) {
cc.setOptional(false);
}
}
}
}
use of org.teiid.query.sql.lang.CompoundCriteria in project teiid by teiid.
the class RulePushSelectCriteria method getElementsIncriteria.
static Collection<ElementSymbol> getElementsIncriteria(Criteria crit) {
Collection<ElementSymbol> elements = new HashSet<ElementSymbol>();
boolean first = true;
if (crit instanceof CompoundCriteria) {
CompoundCriteria compCrit = (CompoundCriteria) crit;
for (Criteria subCrit : compCrit.getCriteria()) {
if (compCrit.getOperator() == CompoundCriteria.AND || first) {
first = false;
elements.addAll(getElementsIncriteria(subCrit));
} else {
elements.retainAll(getElementsIncriteria(subCrit));
}
}
} else {
elements.addAll(ElementCollectorVisitor.getElements(crit, true));
}
return elements;
}
Aggregations