use of org.teiid.query.sql.lang.DependentSetCriteria in project teiid by teiid.
the class RuleChooseDependent method createDependentSetCriteria.
static DependentSetCriteria createDependentSetCriteria(String id, List<DependentSetCriteria.AttributeComparison> expressions) {
if (expressions.isEmpty()) {
return null;
}
Expression indEx = null;
Expression depEx = null;
float maxNdv = NewCalculateCostUtil.UNKNOWN_VALUE;
float ndv = NewCalculateCostUtil.UNKNOWN_VALUE;
if (expressions.size() == 1) {
AttributeComparison attributeComparison = expressions.get(0);
indEx = attributeComparison.ind;
depEx = attributeComparison.dep;
maxNdv = attributeComparison.maxNdv;
ndv = attributeComparison.ndv;
} else {
List<Expression> indExprs = new ArrayList<Expression>(expressions.size());
List<Expression> depExprs = new ArrayList<Expression>(expressions.size());
boolean unknown = false;
for (DependentSetCriteria.AttributeComparison comp : expressions) {
indExprs.add(comp.ind);
depExprs.add(comp.dep);
if (comp.ndv == NewCalculateCostUtil.UNKNOWN_VALUE) {
ndv = NewCalculateCostUtil.UNKNOWN_VALUE;
maxNdv = NewCalculateCostUtil.UNKNOWN_VALUE;
unknown = true;
} else if (!unknown) {
ndv = Math.max(ndv, comp.ndv);
maxNdv = Math.max(maxNdv, comp.maxNdv);
}
}
// TODO: detect a base type
indEx = new Array(DefaultDataClasses.OBJECT, indExprs);
depEx = new Array(DefaultDataClasses.OBJECT, depExprs);
}
DependentSetCriteria crit = new DependentSetCriteria(depEx, id);
crit.setValueExpression(indEx);
crit.setAttributes(expressions);
crit.setMaxNdv(maxNdv);
crit.setNdv(ndv);
return crit;
}
use of org.teiid.query.sql.lang.DependentSetCriteria in project teiid by teiid.
the class RuleChooseDependent method createDependentSetNode.
static PlanNode createDependentSetNode(String id, List<DependentSetCriteria.AttributeComparison> expressions) {
DependentSetCriteria crit = createDependentSetCriteria(id, expressions);
PlanNode selectNode = RelationalPlanner.createSelectNode(crit, false);
selectNode.setProperty(NodeConstants.Info.IS_DEPENDENT_SET, Boolean.TRUE);
return selectNode;
}
use of org.teiid.query.sql.lang.DependentSetCriteria in project teiid by teiid.
the class RulePlanProcedures method findInputNodes.
private void findInputNodes(final HashSet<ElementSymbol> inputs, PlanNode critNode, final List<Criteria> conjuncts, final Set<ElementSymbol> params) {
while (critNode.getType() == NodeConstants.Types.SELECT) {
final PlanNode currentNode = critNode;
final Criteria crit = (Criteria) currentNode.getProperty(NodeConstants.Info.SELECT_CRITERIA);
critNode = currentNode.getParent();
if (!currentNode.getGroups().isEmpty()) {
continue;
}
LanguageVisitor visitor = new LanguageVisitor() {
public void visit(CompareCriteria compCrit) {
if (compCrit.getOperator() == CompareCriteria.EQ && checkForInput(compCrit.getLeftExpression()) && !checkForAnyInput(compCrit.getRightExpression())) {
addInputNode((Reference) compCrit.getLeftExpression());
}
}
private void addInputNode(Reference param) {
params.add(param.getExpression());
conjuncts.add(crit);
NodeEditor.removeChildNode(currentNode.getParent(), currentNode);
}
public void visit(IsNullCriteria isNull) {
if (!isNull.isNegated() && checkForInput(isNull.getExpression())) {
addInputNode((Reference) isNull.getExpression());
}
}
public void visit(SetCriteria obj) {
if (!obj.isNegated() && checkForInput(obj.getExpression()) && !checkForAnyInput(obj.getValues())) {
addInputNode((Reference) obj.getExpression());
}
}
public void visit(DependentSetCriteria obj) {
if (obj.isNegated()) {
// just a sanity check
return;
}
if (obj.hasMultipleAttributes()) {
for (AttributeComparison comp : obj.getAttributes()) {
if (!checkForInput(comp.dep)) {
return;
}
}
for (AttributeComparison comp : obj.getAttributes()) {
params.add(((Reference) comp.dep).getExpression());
}
conjuncts.add(crit);
NodeEditor.removeChildNode(currentNode.getParent(), currentNode);
} else if (checkForInput(obj.getExpression())) {
addInputNode((Reference) obj.getExpression());
}
}
boolean checkForInput(Expression expr) {
if (!(expr instanceof Reference)) {
return false;
}
// if the expr is a function containing a reference should give a warning
Reference ref = (Reference) expr;
return inputs.contains(ref.getExpression());
}
boolean checkForAnyInput(LanguageObject expr) {
for (Reference ref : ReferenceCollectorVisitor.getReferences(expr)) {
if (checkForInput(ref)) {
return true;
}
}
return false;
}
boolean checkForAnyInput(Collection<Expression> expressions) {
for (Expression expr : expressions) {
if (checkForAnyInput(expr)) {
return true;
}
}
return false;
}
};
for (Criteria conjunct : Criteria.separateCriteriaByAnd(crit)) {
conjunct.acceptVisitor(visitor);
}
}
}
use of org.teiid.query.sql.lang.DependentSetCriteria in project teiid by teiid.
the class RuleChooseDependent method getDependentCriteriaNode.
/**
* @param independentExpressions
* @param dependentExpressions
* @param makeDep
* @return
* @throws TeiidComponentException
* @throws QueryMetadataException
* @since 4.3
*/
public static PlanNode getDependentCriteriaNode(String id, List<Expression> independentExpressions, List<Expression> dependentExpressions, PlanNode indNode, QueryMetadataInterface metadata, DependentCostAnalysis dca, Boolean bound, MakeDep makeDep) throws QueryMetadataException, TeiidComponentException {
Float cardinality = null;
List<DependentSetCriteria.AttributeComparison> expressions = new ArrayList<DependentSetCriteria.AttributeComparison>(dependentExpressions.size());
for (int i = 0; i < dependentExpressions.size(); i++) {
Expression depExpr = dependentExpressions.get(i);
Expression indExpr = independentExpressions.get(i);
DependentSetCriteria.AttributeComparison comp = new DependentSetCriteria.AttributeComparison();
if (dca != null && dca.expectedNdv[i] != null) {
if (dca.expectedNdv[i] > 4 * dca.maxNdv[i]) {
// not necessary to use
continue;
}
comp.ndv = dca.expectedNdv[i];
comp.maxNdv = dca.maxNdv[i];
} else {
Collection<ElementSymbol> elems = ElementCollectorVisitor.getElements(indExpr, true);
if (cardinality == null) {
cardinality = NewCalculateCostUtil.computeCostForTree(indNode, metadata);
}
comp.ndv = NewCalculateCostUtil.getNDVEstimate(indNode, metadata, cardinality, elems, true);
if (bound) {
if (dca != null) {
comp.maxNdv = Math.max(comp.ndv * 4, dca.expectedCardinality * 2);
} else {
comp.maxNdv = Math.max(UNKNOWN_INDEPENDENT_CARDINALITY, comp.ndv * 4);
}
}
}
comp.ind = indExpr;
comp.dep = SymbolMap.getExpression(depExpr);
expressions.add(comp);
}
PlanNode result = createDependentSetNode(id, expressions);
if (makeDep != null) {
DependentSetCriteria dsc = (DependentSetCriteria) result.getProperty(Info.SELECT_CRITERIA);
dsc.setMakeDepOptions(makeDep);
}
return result;
}
use of org.teiid.query.sql.lang.DependentSetCriteria 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;
}
Aggregations