use of org.teiid.query.sql.lang.Criteria in project teiid by teiid.
the class RulePushLargeIn method execute.
@Override
public PlanNode execute(PlanNode plan, QueryMetadataInterface metadata, CapabilitiesFinder capabilitiesFinder, RuleStack rules, AnalysisRecord analysisRecord, CommandContext context) throws QueryPlannerException, QueryMetadataException, TeiidComponentException {
for (PlanNode critNode : NodeEditor.findAllNodes(plan, NodeConstants.Types.SELECT, NodeConstants.Types.ACCESS)) {
if (critNode.hasBooleanProperty(NodeConstants.Info.IS_HAVING) || critNode.hasBooleanProperty(NodeConstants.Info.IS_PHANTOM)) {
continue;
}
Criteria crit = (Criteria) critNode.getProperty(NodeConstants.Info.SELECT_CRITERIA);
if (!(crit instanceof SetCriteria)) {
continue;
}
SetCriteria setCriteria = (SetCriteria) crit;
if (setCriteria.isNegated() || !setCriteria.isAllConstants()) {
continue;
}
// we need to be directly over an access node
PlanNode childAccess = critNode.getFirstChild();
accessLoop: while (true) {
switch(childAccess.getType()) {
case NodeConstants.Types.ACCESS:
break accessLoop;
case NodeConstants.Types.SELECT:
break;
default:
break accessLoop;
}
childAccess = childAccess.getFirstChild();
}
if (childAccess.getType() != NodeConstants.Types.ACCESS) {
continue;
}
// use a dummy value to test if we can raise
critNode.setProperty(NodeConstants.Info.SELECT_CRITERIA, new SetCriteria(setCriteria.getExpression(), Collections.EMPTY_LIST));
boolean canRaise = RuleRaiseAccess.canRaiseOverSelect(childAccess, metadata, capabilitiesFinder, critNode, analysisRecord);
critNode.setProperty(NodeConstants.Info.SELECT_CRITERIA, crit);
if (!canRaise) {
continue;
}
// push the crit node and mark as dependent set
critNode.getParent().replaceChild(critNode, critNode.getFirstChild());
childAccess.addAsParent(critNode);
RuleRaiseAccess.performRaise(plan, childAccess, critNode);
childAccess.setProperty(NodeConstants.Info.IS_DEPENDENT_SET, true);
childAccess.setProperty(NodeConstants.Info.EST_CARDINALITY, null);
}
return plan;
}
use of org.teiid.query.sql.lang.Criteria in project teiid by teiid.
the class RulePushLimit method getMinValue.
/**
* @param limitNode
* @param child
* @throws TeiidComponentException
* @throws BlockedException
* @throws ExpressionEvaluationException
*/
static Expression getMinValue(Expression expr1, Expression expr2) {
if (expr1 == null) {
return expr2;
}
if (expr2 == null) {
return expr1;
}
Criteria crit = new CompareCriteria(expr1, CompareCriteria.LT, expr2);
SearchedCaseExpression sce = new SearchedCaseExpression(Arrays.asList(new Object[] { crit }), Arrays.asList(new Object[] { expr1 }));
sce.setElseExpression(expr2);
sce.setType(expr1.getType());
return evaluateIfPossible(sce);
}
use of org.teiid.query.sql.lang.Criteria in project teiid by teiid.
the class RulePushNonJoinCriteria method execute.
/**
* Execute the rule as described in the class comments.
* @param plan Incoming query plan, may be modified during method and may be returned from method
* @param metadata Metadata source
* @param rules Rules from optimizer rule stack, may be manipulated during method
* @return Updated query plan if rule fired, else original query plan
*/
public PlanNode execute(PlanNode plan, QueryMetadataInterface metadata, CapabilitiesFinder capFinder, RuleStack rules, AnalysisRecord analysisRecord, CommandContext context) throws QueryPlannerException, QueryMetadataException, TeiidComponentException {
boolean treeChanged = false;
boolean removeCopiedFlag = false;
boolean pushRuleRaiseNull = false;
for (PlanNode node : NodeEditor.findAllNodes(plan, NodeConstants.Types.JOIN)) {
List criteria = (List) node.getProperty(NodeConstants.Info.JOIN_CRITERIA);
JoinType joinType = (JoinType) node.getProperty(NodeConstants.Info.JOIN_TYPE);
// criteria cannot be pushed out of a full outer join clause
if (joinType == JoinType.JOIN_FULL_OUTER || joinType == JoinType.JOIN_CROSS) {
continue;
}
Iterator crits = criteria.iterator();
while (crits.hasNext()) {
Criteria crit = (Criteria) crits.next();
// special case handling for true/false criteria
if (crit.equals(QueryRewriter.FALSE_CRITERIA) || crit.equals(QueryRewriter.UNKNOWN_CRITERIA)) {
if (joinType == JoinType.JOIN_INNER) {
FrameUtil.replaceWithNullNode(node);
} else {
// must be a left or right outer join, replace the inner side with null
FrameUtil.replaceWithNullNode(JoinUtil.getInnerSideJoinNodes(node)[0]);
removeCopiedFlag = true;
}
// since a null node has been created, raise it to its highest point
pushRuleRaiseNull = true;
treeChanged = true;
break;
} else if (crit.equals(QueryRewriter.TRUE_CRITERIA)) {
crits.remove();
break;
}
if (pushCriteria(node, crit, crits, metadata)) {
treeChanged = true;
}
}
// degrade the join if there is no criteria left
if (criteria.isEmpty() && joinType == JoinType.JOIN_INNER) {
node.setProperty(NodeConstants.Info.JOIN_TYPE, JoinType.JOIN_CROSS);
treeChanged = true;
}
if (removeCopiedFlag) {
// allow the criteria above the join to be eligible for pushing and copying
PlanNode parent = node.getParent();
while (parent != null && parent.getType() == NodeConstants.Types.SELECT) {
parent.setProperty(NodeConstants.Info.IS_COPIED, Boolean.FALSE);
parent = parent.getParent();
}
}
}
if (treeChanged) {
rules.push(RuleConstants.PUSH_SELECT_CRITERIA);
}
if (pushRuleRaiseNull) {
rules.push(RuleConstants.RAISE_NULL);
}
return plan;
}
use of org.teiid.query.sql.lang.Criteria in project teiid by teiid.
the class RulePushSelectCriteria method moveNodeAcrossFrame.
Boolean moveNodeAcrossFrame(PlanNode critNode, PlanNode sourceNode, final QueryMetadataInterface metadata) throws QueryPlannerException, QueryMetadataException, TeiidComponentException {
// Check that sourceNode has a child to push across
if (sourceNode.getChildCount() == 0) {
return false;
}
final PlanNode projectNode = NodeEditor.findNodePreOrder(sourceNode.getFirstChild(), NodeConstants.Types.PROJECT, NodeConstants.Types.SOURCE);
if (FrameUtil.isProcedure(projectNode)) {
return false;
}
final SymbolMap symbolMap = (SymbolMap) sourceNode.getProperty(NodeConstants.Info.SYMBOL_MAP);
final GroupSymbol sourceGroup = sourceNode.getGroups().iterator().next();
if (!placeConvertedSelectNode(critNode, sourceGroup, projectNode, symbolMap, metadata)) {
if (createdNodes == null) {
Criteria crit = (Criteria) critNode.getProperty(NodeConstants.Info.SELECT_CRITERIA);
if (isMultiAttributeDependentSet(crit) && splitSet(critNode, new DependentNodeTest() {
@Override
public boolean isValid(PlanNode copyNode) throws QueryMetadataException, QueryPlannerException, TeiidComponentException {
return createConvertedSelectNode(copyNode, sourceGroup, projectNode, symbolMap, metadata) != null;
}
}, (DependentSetCriteria) crit, sourceNode)) {
return null;
}
}
return false;
}
if (createdNodes == null) {
satisfyConditions(critNode, sourceNode, metadata);
}
// Mark critNode as a "phantom"
critNode.setProperty(NodeConstants.Info.IS_PHANTOM, Boolean.TRUE);
return true;
}
use of org.teiid.query.sql.lang.Criteria 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);
}
}
}
}
Aggregations