use of org.teiid.query.sql.lang.Criteria in project teiid by teiid.
the class RulePushSelectCriteria method pushTowardOriginatingNode.
/**
* @param critNode
* @param metadata
* @param capFinder
* @throws QueryPlannerException
* @throws QueryMetadataException
* @throws TeiidComponentException
*/
boolean pushTowardOriginatingNode(PlanNode sourceNode, PlanNode critNode, final QueryMetadataInterface metadata, final CapabilitiesFinder capFinder) throws QueryPlannerException, QueryMetadataException, TeiidComponentException {
boolean groupSelects = sourceNode.getParent().getType() == NodeConstants.Types.SELECT && sourceNode.getChildCount() == 0;
// to keep a stable criteria ordering, move the sourceNode to the top of the criteria chain
while (sourceNode.getParent().getType() == NodeConstants.Types.SELECT) {
sourceNode = sourceNode.getParent();
if (sourceNode == critNode) {
return false;
}
}
// See how far we can move it towards the SOURCE node
final PlanNode destination = examinePath(critNode, sourceNode, metadata, capFinder);
boolean result = false;
if (createdNodes == null & destination.getType() == NodeConstants.Types.ACCESS && isDependentFinalDestination(critNode, destination)) {
Criteria crit = (Criteria) critNode.getProperty(NodeConstants.Info.SELECT_CRITERIA);
if (isMultiAttributeDependentSet(crit)) {
result = splitSet(critNode, new DependentNodeTest() {
@Override
public boolean isValid(PlanNode copyNode) throws QueryMetadataException, QueryPlannerException, TeiidComponentException {
return RuleRaiseAccess.canRaiseOverSelect(destination, metadata, capFinder, copyNode, null);
}
}, (DependentSetCriteria) crit, destination);
}
}
NodeEditor.removeChildNode(critNode.getParent(), critNode);
destination.addAsParent(critNode);
if (groupSelects && destination == sourceNode && !critNode.hasBooleanProperty(Info.IS_TEMPORARY) && !destination.hasBooleanProperty(Info.IS_TEMPORARY)) {
// Help with the detection of composite keys in pushed criteria
RuleMergeCriteria.mergeChain(critNode, metadata);
}
return result;
}
use of org.teiid.query.sql.lang.Criteria in project teiid by teiid.
the class RulePushSelectCriteria method satisfyConditions.
/**
* @param critNode
* @param sourceNode
* @throws TeiidComponentException
* @throws QueryMetadataException
*/
static void satisfyConditions(PlanNode critNode, PlanNode sourceNode, QueryMetadataInterface metadata) throws QueryMetadataException, TeiidComponentException {
List aps = (List) sourceNode.getProperty(NodeConstants.Info.ACCESS_PATTERNS);
Criteria crit = (Criteria) critNode.getProperty(NodeConstants.Info.SELECT_CRITERIA);
if (sourceNode.hasBooleanProperty(Info.IS_MULTI_SOURCE) && crit instanceof CompareCriteria) {
CompareCriteria cc = (CompareCriteria) crit;
if (cc.getLeftExpression() instanceof ElementSymbol && cc.getRightExpression() instanceof Constant) {
ElementSymbol es = (ElementSymbol) cc.getLeftExpression();
if (metadata.isMultiSourceElement(es.getMetadataID())) {
sourceNode.setProperty(Info.IS_MULTI_SOURCE, false);
sourceNode.setProperty(Info.SOURCE_NAME, ((Constant) cc.getRightExpression()).getValue());
}
}
}
if (aps == null) {
return;
}
Collection<ElementSymbol> elements = getElementsIncriteria(crit);
boolean removeAps = satisfyAccessPatterns(aps, elements);
if (removeAps) {
sourceNode.removeProperty(NodeConstants.Info.ACCESS_PATTERNS);
return;
}
Collections.sort(aps);
}
use of org.teiid.query.sql.lang.Criteria 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;
}
use of org.teiid.query.sql.lang.Criteria 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.Criteria in project teiid by teiid.
the class RulePushSelectCriteria method copyNode.
PlanNode copyNode(PlanNode critNode) {
// Create new copy node
PlanNode copyNode = NodeFactory.getNewNode(NodeConstants.Types.SELECT);
// Copy criteria
Criteria crit = (Criteria) critNode.getProperty(NodeConstants.Info.SELECT_CRITERIA);
Criteria copyCrit = (Criteria) crit.clone();
copyNode.setProperty(NodeConstants.Info.SELECT_CRITERIA, copyCrit);
copyNode.addGroups(critNode.getGroups());
if (critNode.hasBooleanProperty(NodeConstants.Info.IS_DEPENDENT_SET)) {
copyNode.setProperty(NodeConstants.Info.IS_DEPENDENT_SET, Boolean.TRUE);
}
if (critNode.hasBooleanProperty(NodeConstants.Info.IS_TEMPORARY)) {
copyNode.setProperty(NodeConstants.Info.IS_TEMPORARY, Boolean.TRUE);
}
if (createdNodes != null) {
createdNodes.add(copyNode);
}
return copyNode;
}
Aggregations