use of org.teiid.query.sql.lang.DependentSetCriteria.AttributeComparison in project teiid by teiid.
the class RulePushSelectCriteria method splitSet.
private boolean splitSet(PlanNode critNode, DependentNodeTest test, DependentSetCriteria dscOrig, PlanNode destination) throws QueryMetadataException, TeiidComponentException, QueryPlannerException {
boolean result = false;
List<DependentSetCriteria> dscList = splitDependentSetCriteria(dscOrig, false, null);
List<DependentSetCriteria.AttributeComparison> pushable = new ArrayList<AttributeComparison>();
List<DependentSetCriteria.AttributeComparison> nonPushable = new ArrayList<AttributeComparison>();
for (DependentSetCriteria dsc : dscList) {
PlanNode copyNode = copyNode(critNode);
setCriteria(dsc, copyNode);
if (test.isValid(copyNode)) {
pushable.add(dsc.getAttributes().get(0));
} else {
nonPushable.add(dsc.getAttributes().get(0));
}
}
if (!pushable.isEmpty()) {
// signal that we should run again
result = true;
if (nonPushable.isEmpty()) {
// $NON-NLS-1$
throw new AssertionError("should not be completely pushed");
}
setCriteria(RuleChooseDependent.createDependentSetCriteria(dscOrig.getContextSymbol(), nonPushable), critNode);
PlanNode copyNode = copyNode(critNode);
setCriteria(RuleChooseDependent.createDependentSetCriteria(dscOrig.getContextSymbol(), pushable), copyNode);
// it should be pushed in the next run
destination.addAsParent(copyNode);
}
return result;
}
use of org.teiid.query.sql.lang.DependentSetCriteria.AttributeComparison 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.AttributeComparison 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.AttributeComparison in project teiid by teiid.
the class RulePushSelectCriteria method splitDependentSetCriteria.
private List<DependentSetCriteria> splitDependentSetCriteria(DependentSetCriteria dsc, boolean supportsArray, QueryMetadataInterface metadata) throws QueryMetadataException, TeiidComponentException {
List<AttributeComparison> attributes = dsc.getAttributes();
List<DependentSetCriteria> crits = new ArrayList<DependentSetCriteria>(attributes.size());
Map<Object, List<AttributeComparison>> splits = new LinkedHashMap<Object, List<AttributeComparison>>();
for (int i = 0; i < attributes.size(); i++) {
Object key = null;
DependentSetCriteria.AttributeComparison comp = attributes.get(i);
if (supportsArray && (comp.dep instanceof ElementSymbol)) {
ElementSymbol es = (ElementSymbol) comp.dep;
GroupSymbol group = es.getGroupSymbol();
if (!metadata.isVirtualGroup(group.getMetadataID())) {
key = group;
}
// TODO: we could try to determine further if this is allowable
// for now since we are pushing as far as we can, this is a good indication,
// that it will need split
}
if (key == null) {
key = splits.size();
}
List<AttributeComparison> comps = splits.get(key);
if (comps == null) {
comps = new ArrayList<DependentSetCriteria.AttributeComparison>(2);
splits.put(key, comps);
}
comps.add(comp);
}
for (List<AttributeComparison> comps : splits.values()) {
DependentSetCriteria crit = RuleChooseDependent.createDependentSetCriteria(dsc.getContextSymbol(), comps);
crit.setMakeDepOptions(dsc.getMakeDepOptions());
crits.add(crit);
}
return crits;
}
Aggregations