use of org.teiid.query.sql.lang.CompareCriteria in project teiid by teiid.
the class RuleChooseDependent method handleDuplicate.
private void handleDuplicate(PlanNode joinNode, boolean isLeft, List independentExpressions, List dependentExpressions) {
Map<Expression, Integer> seen = new HashMap<Expression, Integer>();
for (int i = 0; i < dependentExpressions.size(); i++) {
Expression ex = (Expression) dependentExpressions.get(i);
Integer index = seen.get(ex);
if (index == null) {
seen.put(ex, i);
} else {
Expression e1 = (Expression) independentExpressions.get(i);
Expression e2 = (Expression) independentExpressions.get(index);
CompareCriteria cc = new CompareCriteria(e1, CompareCriteria.EQ, e2);
PlanNode impliedCriteria = RelationalPlanner.createSelectNode(cc, false);
if (isLeft) {
joinNode.getLastChild().addAsParent(impliedCriteria);
} else {
joinNode.getFirstChild().addAsParent(impliedCriteria);
}
independentExpressions.remove(i);
dependentExpressions.remove(i);
i--;
}
}
}
use of org.teiid.query.sql.lang.CompareCriteria in project teiid by teiid.
the class RuleChooseJoinStrategy method separateCriteria.
public static void separateCriteria(Collection<GroupSymbol> leftGroups, Collection<GroupSymbol> rightGroups, List<Expression> leftExpressions, List<Expression> rightExpressions, List<Criteria> crits, Collection<Criteria> nonEquiJoinCriteria) {
for (Criteria theCrit : crits) {
Set<GroupSymbol> critGroups = GroupsUsedByElementsVisitor.getGroups(theCrit);
if (leftGroups.containsAll(critGroups) || rightGroups.containsAll(critGroups)) {
nonEquiJoinCriteria.add(theCrit);
continue;
}
if (!(theCrit instanceof CompareCriteria)) {
nonEquiJoinCriteria.add(theCrit);
continue;
}
CompareCriteria crit = (CompareCriteria) theCrit;
if (crit.getOperator() != CompareCriteria.EQ) {
nonEquiJoinCriteria.add(theCrit);
continue;
}
Expression leftExpr = crit.getLeftExpression();
Expression rightExpr = crit.getRightExpression();
Set<GroupSymbol> leftExprGroups = GroupsUsedByElementsVisitor.getGroups(leftExpr);
Set<GroupSymbol> rightExprGroups = GroupsUsedByElementsVisitor.getGroups(rightExpr);
if (leftGroups.isEmpty() || rightGroups.isEmpty()) {
nonEquiJoinCriteria.add(theCrit);
} else if (leftGroups.containsAll(leftExprGroups) && rightGroups.containsAll(rightExprGroups)) {
leftExpressions.add(leftExpr);
rightExpressions.add(rightExpr);
} else if (rightGroups.containsAll(leftExprGroups) && leftGroups.containsAll(rightExprGroups)) {
leftExpressions.add(rightExpr);
rightExpressions.add(leftExpr);
} else {
nonEquiJoinCriteria.add(theCrit);
}
}
}
use of org.teiid.query.sql.lang.CompareCriteria in project teiid by teiid.
the class RuleCopyCriteria method copyCriteria.
/**
* Given a criteria and a map of elements to values try to create a new single group criteria
*
* If the new criteria does not have exactly one group or already exists in the combined criteria,
* it will not be added.
*
* @param crit
* @param tgtMap
* @param joinCriteria
* @param combinedCriteria
* @return number of remaining groups if the copy was successful
*/
private Integer copyCriteria(Criteria crit, Map<Expression, Expression> tgtMap, List<Criteria> joinCriteria, Set<Criteria> combinedCriteria, boolean checkForGroupReduction, QueryMetadataInterface metadata, boolean underAccess) {
int startGroups = GroupsUsedByElementsVisitor.getGroups(crit).size();
Criteria tgtCrit = (Criteria) crit.clone();
try {
tgtCrit = FrameUtil.convertCriteria(tgtCrit, tgtMap, metadata, true);
} catch (QueryPlannerException err) {
// $NON-NLS-1$
LogManager.logDetail(LogConstants.CTX_QUERY_PLANNER, err, "Could not remap target criteria in RuleCopyCriteria");
return null;
}
if (tgtCrit instanceof IsNullCriteria && ((IsNullCriteria) tgtCrit).isNegated()) {
return null;
}
int endGroups = GroupsUsedByElementsVisitor.getGroups(tgtCrit).size();
if (checkForGroupReduction) {
if (endGroups >= startGroups) {
return null;
}
} else if (endGroups > startGroups) {
return null;
}
boolean isNew = combinedCriteria.add(tgtCrit);
if (underAccess) {
if (!isNew || checkForGroupReduction || endGroups > 1) {
return null;
}
if (!COPY_ALL) {
boolean use = false;
Collection<ElementSymbol> cols = ElementCollectorVisitor.getElements(tgtCrit, true);
// use only if it could be used to further rewrite predicates
for (Criteria existing : combinedCriteria) {
if (existing.equals(tgtCrit)) {
continue;
}
Collection<ElementSymbol> elements = ElementCollectorVisitor.getElements(existing, true);
if (GroupsUsedByElementsVisitor.getGroups(elements).size() > 1) {
continue;
}
if (elements.containsAll(cols)) {
use = true;
break;
}
}
if (!use) {
return null;
}
}
}
// if this is unique or it a duplicate but reduced a current join conjunct, return true
if (isNew) {
joinCriteria.add(tgtCrit);
if (tgtCrit instanceof CompareCriteria) {
CompareCriteria cc = (CompareCriteria) tgtCrit;
if (!EvaluatableVisitor.willBecomeConstant(cc.getRightExpression()) && !EvaluatableVisitor.willBecomeConstant(cc.getRightExpression())) {
((CompareCriteria) tgtCrit).setOptional(true);
}
}
return endGroups;
} else if (checkForGroupReduction && endGroups < 2) {
return endGroups;
}
return null;
}
use of org.teiid.query.sql.lang.CompareCriteria in project teiid by teiid.
the class RuleCopyCriteria method buildElementMap.
/**
* Construct a mapping of element symbol to value map based upon equality CompareCriteria in crits
*
* @param crits
* @param newJoinCrits
* @param metadata
* @return
*/
Map<Expression, Expression> buildElementMap(Collection<Criteria> crits, List<Criteria> newJoinCrits, Set<Criteria> allCriteria, QueryMetadataInterface metadata, boolean underAccess) {
Map<Expression, Expression> srcToTgt = null;
for (Iterator<Criteria> iter = crits.iterator(); iter.hasNext(); ) {
Criteria theCrit = iter.next();
if (theCrit instanceof IsNullCriteria) {
IsNullCriteria isNull = (IsNullCriteria) theCrit;
if (!isNull.isNegated() && isNull.getExpression() instanceof ElementSymbol) {
if (srcToTgt == null) {
srcToTgt = new HashMap<Expression, Expression>();
}
srcToTgt.put(isNull.getExpression(), new Constant(null, isNull.getExpression().getType()));
}
continue;
}
if (!(theCrit instanceof CompareCriteria)) {
continue;
}
CompareCriteria crit = (CompareCriteria) theCrit;
if (crit.getOperator() == CompareCriteria.EQ) {
if (srcToTgt == null) {
srcToTgt = new HashMap<Expression, Expression>();
}
Expression oldValue = srcToTgt.put(crit.getLeftExpression(), crit.getRightExpression());
boolean removed = false;
if (checkWithinJoin(crit, newJoinCrits, allCriteria, oldValue, crit.getRightExpression(), metadata, underAccess)) {
iter.remove();
removed = true;
}
oldValue = srcToTgt.put(crit.getRightExpression(), crit.getLeftExpression());
if (checkWithinJoin(crit, newJoinCrits, allCriteria, oldValue, crit.getLeftExpression(), metadata, underAccess) && !removed) {
iter.remove();
}
}
}
if (srcToTgt == null) {
return Collections.emptyMap();
}
return srcToTgt;
}
use of org.teiid.query.sql.lang.CompareCriteria in project teiid by teiid.
the class PartitionAnalyzer method extractPartitionInfo.
private static Map<ElementSymbol, Set<Constant>> extractPartitionInfo(Query query, List<ElementSymbol> projectedSymbols) {
List<Expression> projected = query.getSelect().getProjectedSymbols();
List<Criteria> crits = Criteria.separateCriteriaByAnd(query.getCriteria());
Map<Expression, Set<Constant>> inMap = new HashMap<Expression, Set<Constant>>();
for (Criteria criteria : crits) {
if (criteria instanceof CompareCriteria) {
CompareCriteria cc = (CompareCriteria) criteria;
if (cc.getOperator() != CompareCriteria.EQ) {
continue;
}
if (cc.getLeftExpression() instanceof Constant) {
inMap.put(cc.getRightExpression(), new HashSet<Constant>(Arrays.asList((Constant) cc.getLeftExpression())));
} else if (cc.getRightExpression() instanceof Constant) {
inMap.put(cc.getLeftExpression(), new HashSet<Constant>(Arrays.asList((Constant) cc.getRightExpression())));
}
continue;
}
if (!(criteria instanceof SetCriteria)) {
continue;
}
SetCriteria sc = (SetCriteria) criteria;
HashSet<Constant> values = new HashSet<Constant>();
boolean allConstants = true;
for (Expression exp : (Collection<Expression>) sc.getValues()) {
if (exp instanceof Constant) {
values.add((Constant) exp);
} else {
allConstants = false;
break;
}
}
if (allConstants) {
inMap.put(sc.getExpression(), values);
}
}
Map<ElementSymbol, Set<Constant>> result = new HashMap<ElementSymbol, Set<Constant>>();
for (int i = 0; i < projected.size(); i++) {
Expression ex = SymbolMap.getExpression(projected.get(i));
if (DataTypeManager.isNonComparable(DataTypeManager.getDataTypeName(ex.getType()))) {
continue;
}
if (ex instanceof Constant) {
result.put(projectedSymbols.get(i), Collections.singleton((Constant) ex));
} else {
Set<Constant> values = inMap.get(ex);
if (values != null) {
result.put(projectedSymbols.get(i), values);
}
}
}
return result;
}
Aggregations