use of org.teiid.query.sql.lang.CompoundCriteria in project teiid by teiid.
the class FrameUtil method convertNode.
// If newGroup == null, this will be performing a straight symbol swap - that is,
// an oldGroup is undergoing a name change and that is the only difference in the
// symbols. In that case, some additional work can be done because we can assume
// that an oldElement isn't being replaced by an expression using elements from
// multiple new groups.
static void convertNode(PlanNode node, GroupSymbol oldGroup, Set<GroupSymbol> newGroups, Map symbolMap, QueryMetadataInterface metadata, boolean rewrite) throws QueryPlannerException {
if (node.getType() == NodeConstants.Types.GROUP) {
correctSymbolMap(symbolMap, node);
}
// Convert expressions from correlated subquery references;
List<SymbolMap> refMaps = node.getAllReferences();
LinkedList<Expression> correlatedExpression = new LinkedList<Expression>();
for (SymbolMap refs : refMaps) {
for (Map.Entry<ElementSymbol, Expression> ref : refs.asUpdatableMap().entrySet()) {
Expression expr = ref.getValue();
Expression convertedExpr = convertExpression(expr, symbolMap);
ref.setValue(convertedExpr);
correlatedExpression.add(convertedExpr);
}
}
// Update groups for current node
Set<GroupSymbol> groups = node.getGroups();
boolean hasOld = groups.remove(oldGroup);
int type = node.getType();
boolean singleMapping = newGroups != null && newGroups.size() == 1;
if (singleMapping) {
if (!hasOld) {
return;
}
groups.addAll(newGroups);
} else if ((type & (NodeConstants.Types.ACCESS | NodeConstants.Types.JOIN | NodeConstants.Types.SOURCE)) == type) {
if (newGroups != null) {
groups.addAll(newGroups);
}
} else {
groups.clear();
}
groups.addAll(GroupsUsedByElementsVisitor.getGroups(correlatedExpression));
if (type == NodeConstants.Types.SELECT) {
Criteria crit = (Criteria) node.getProperty(NodeConstants.Info.SELECT_CRITERIA);
crit = convertCriteria(crit, symbolMap, metadata, rewrite);
node.setProperty(NodeConstants.Info.SELECT_CRITERIA, crit);
if (!singleMapping) {
GroupsUsedByElementsVisitor.getGroups(crit, groups);
}
} else if (type == NodeConstants.Types.PROJECT) {
List<Expression> projectedSymbols = (List<Expression>) node.getProperty(NodeConstants.Info.PROJECT_COLS);
Select select = new Select(projectedSymbols);
ExpressionMappingVisitor.mapExpressions(select, symbolMap);
if (rewrite) {
for (LanguageObject expr : select.getSymbols()) {
rewriteSingleElementSymbol(metadata, (Expression) expr);
}
}
node.setProperty(NodeConstants.Info.PROJECT_COLS, select.getSymbols());
if (!singleMapping) {
GroupsUsedByElementsVisitor.getGroups(select, groups);
}
} else if (type == NodeConstants.Types.JOIN) {
// Convert join criteria property
List<Criteria> joinCrits = (List<Criteria>) node.getProperty(NodeConstants.Info.JOIN_CRITERIA);
if (joinCrits != null && !joinCrits.isEmpty()) {
Criteria crit = new CompoundCriteria(joinCrits);
crit = convertCriteria(crit, symbolMap, metadata, rewrite);
if (crit instanceof CompoundCriteria && ((CompoundCriteria) crit).getOperator() == CompoundCriteria.AND) {
node.setProperty(NodeConstants.Info.JOIN_CRITERIA, ((CompoundCriteria) crit).getCriteria());
} else {
joinCrits = new ArrayList<Criteria>();
joinCrits.add(crit);
node.setProperty(NodeConstants.Info.JOIN_CRITERIA, joinCrits);
}
}
convertAccessPatterns(symbolMap, node);
} else if (type == NodeConstants.Types.SORT) {
OrderBy orderBy = (OrderBy) node.getProperty(NodeConstants.Info.SORT_ORDER);
ExpressionMappingVisitor.mapExpressions(orderBy, symbolMap);
if (rewrite) {
for (OrderByItem item : orderBy.getOrderByItems()) {
rewriteSingleElementSymbol(metadata, item.getSymbol());
}
}
if (!singleMapping) {
GroupsUsedByElementsVisitor.getGroups(orderBy, groups);
}
} else if (type == NodeConstants.Types.GROUP) {
List<Expression> groupCols = (List<Expression>) node.getProperty(NodeConstants.Info.GROUP_COLS);
if (groupCols != null) {
GroupBy groupBy = new GroupBy(groupCols);
ExpressionMappingVisitor.mapExpressions(groupBy, symbolMap);
node.setProperty(NodeConstants.Info.GROUP_COLS, groupBy.getSymbols());
if (!singleMapping) {
GroupsUsedByElementsVisitor.getGroups(groupBy, groups);
}
}
if (!singleMapping) {
// add back the anon group
SymbolMap property = (SymbolMap) node.getProperty(Info.SYMBOL_MAP);
if (!property.asMap().isEmpty()) {
groups.add(property.asMap().keySet().iterator().next().getGroupSymbol());
}
}
} else if (type == NodeConstants.Types.SOURCE || type == NodeConstants.Types.ACCESS) {
convertAccessPatterns(symbolMap, node);
}
}
use of org.teiid.query.sql.lang.CompoundCriteria in project teiid by teiid.
the class DependentCriteriaProcessor method prepareCriteria.
public Criteria prepareCriteria() throws TeiidComponentException, TeiidProcessingException {
if (phase == SORT) {
for (TupleState state : dependentState.values()) {
state.sort();
if (state.dvs.getTupleBuffer().getRowCount() == 0) {
return QueryRewriter.FALSE_CRITERIA;
}
}
// init total predicates and max size
totalPredicates = setStates.size();
if (this.maxPredicates > 0) {
// We have a bin packing problem if totalPredicates < sources - We'll address that case later.
// TODO: better handling for the correlated composite case
totalPredicates = Math.max(totalPredicates, this.maxPredicates);
}
long maxParams = this.maxPredicates * this.maxSetSize;
maxSize = Integer.MAX_VALUE;
if (this.maxSetSize > 0) {
maxSize = this.maxSetSize;
if (this.maxPredicates > 0 && totalPredicates > this.maxPredicates) {
// scale the max based upon the number of predicates - this is not perfect, but sufficient for most situations
maxSize = Math.max(1, maxParams / totalPredicates);
}
}
// determine push down handling
if (pushdown) {
List<Criteria> newCriteria = new ArrayList<Criteria>();
long params = 0;
int sets = 0;
for (Criteria criteria : queryCriteria) {
if (!(criteria instanceof DependentSetCriteria)) {
newCriteria.add(criteria);
continue;
}
sets++;
DependentSetCriteria dsc = (DependentSetCriteria) criteria;
TupleState ts = dependentState.get(dsc.getContextSymbol());
DependentValueSource dvs = ts.dvs;
// check if this has more rows than we want to push
if ((dsc.getMaxNdv() != -1 && dvs.getTupleBuffer().getRowCount() > dsc.getMaxNdv()) || (dsc.getMakeDepOptions() != null && dsc.getMakeDepOptions().getMax() != null && dvs.getTupleBuffer().getRowCount() > dsc.getMakeDepOptions().getMax())) {
// don't try to pushdown
continue;
}
int cols = 1;
if (dsc.getExpression() instanceof Array) {
cols = ((Array) dsc.getExpression()).getExpressions().size();
}
dsc = dsc.clone();
// determine if this will be more than 1 source query
params += cols * dvs.getTupleBuffer().getRowCount();
// TODO: this assumes that if any one of the dependent
// joins are pushed, then they all are
dsc.setDependentValueSource(dvs);
newCriteria.add(dsc);
}
// TODO: see if this should be a source tunable parameter
int maxParamThreshold = 3;
// generally this value accounts for the additional overhead of temp table creation
if (params > maxParams && (sets > 1 || complexQuery || params > maxParams * maxParamThreshold)) {
// and only if the we could produce a cross set or have a complex query
return Criteria.combineCriteria(newCriteria);
}
}
// proceed with set based processing
phase = SET_PROCESSING;
}
replaceDependentValueIterators();
LinkedList<Criteria> crits = new LinkedList<Criteria>();
for (int i = 0; i < queryCriteria.size(); i++) {
SetState state = this.setStates.get(i);
Criteria criteria = queryCriteria.get(i);
if (state == null) {
if (criteria != QueryRewriter.TRUE_CRITERIA) {
crits.add((Criteria) criteria.clone());
}
} else {
Criteria crit = replaceDependentCriteria((AbstractSetCriteria) criteria, state);
if (crit == QueryRewriter.FALSE_CRITERIA) {
return QueryRewriter.FALSE_CRITERIA;
}
if (crit != QueryRewriter.TRUE_CRITERIA) {
crits.add(crit);
}
}
}
if (crits.size() == 1) {
return crits.get(0);
}
return new CompoundCriteria(CompoundCriteria.AND, crits);
}
use of org.teiid.query.sql.lang.CompoundCriteria in project teiid by teiid.
the class BaseIndexInfo method processCriteria.
private void processCriteria(Criteria condition, boolean primary) {
List<Criteria> crits = Criteria.separateCriteriaByAnd(condition);
if (!primary) {
for (Iterator<Criteria> critIter = crits.iterator(); critIter.hasNext(); ) {
Criteria criteria = critIter.next();
if (table.getColumnMap().keySet().containsAll(ElementCollectorVisitor.getElements(criteria, false))) {
if (coveredCriteria == null) {
coveredCriteria = new CompoundCriteria();
}
coveredCriteria.addCriteria(criteria);
} else {
covering = false;
if (nonCoveredCriteria == null) {
nonCoveredCriteria = new CompoundCriteria();
}
nonCoveredCriteria.addCriteria(criteria);
critIter.remove();
}
}
}
for (int i = 0; i < table.getPkLength(); i++) {
for (Iterator<Criteria> critIter = crits.iterator(); critIter.hasNext(); ) {
Criteria criteria = critIter.next();
if (criteria instanceof CompareCriteria) {
CompareCriteria cc = (CompareCriteria) criteria;
Object matchResult = table.matchesPkColumn(i, cc.getLeftExpression());
if (Boolean.FALSE.equals(matchResult)) {
continue;
}
if (cc.getOperator() != CompareCriteria.EQ && !table.supportsOrdering(i, cc.getLeftExpression())) {
critIter.remove();
continue;
}
this.addCondition(i, matchResult, (Constant) cc.getRightExpression(), cc.getOperator());
critIter.remove();
} else if (criteria instanceof IsNullCriteria) {
IsNullCriteria inc = (IsNullCriteria) criteria;
Object matchResult = table.matchesPkColumn(i, inc.getExpression());
if (Boolean.FALSE.equals(matchResult)) {
continue;
}
this.addCondition(i, matchResult, new Constant(null), CompareCriteria.EQ);
critIter.remove();
} else if (criteria instanceof MatchCriteria) {
MatchCriteria matchCriteria = (MatchCriteria) criteria;
Object matchResult = table.matchesPkColumn(i, matchCriteria.getLeftExpression());
if (Boolean.FALSE.equals(matchResult)) {
continue;
}
Constant value = (Constant) matchCriteria.getRightExpression();
String pattern = (String) value.getValue();
boolean escaped = false;
char escapeChar = matchCriteria.getEscapeChar();
if (matchCriteria.getMode() == MatchMode.REGEX) {
escapeChar = '\\';
}
StringBuilder prefix = new StringBuilder();
if (pattern.length() > 0 && matchCriteria.getMode() == MatchMode.REGEX && pattern.charAt(0) != '^') {
// make the assumption that we require an anchor
continue;
}
for (int j = matchCriteria.getMode() == MatchMode.REGEX ? 1 : 0; j < pattern.length(); j++) {
char character = pattern.charAt(j);
if (character == escapeChar && character != MatchCriteria.NULL_ESCAPE_CHAR) {
if (escaped) {
prefix.append(character);
escaped = false;
} else {
escaped = true;
}
continue;
}
if (!escaped) {
if (matchCriteria.getMode() == MatchMode.LIKE) {
if (character == MatchCriteria.WILDCARD_CHAR || character == MatchCriteria.MATCH_CHAR) {
break;
}
} else {
int index = Arrays.binarySearch(Evaluator.REGEX_RESERVED, character);
if (index >= 0 && pattern.length() > 0) {
getRegexPrefix(pattern, escapeChar, prefix, j, character);
break;
}
}
} else {
escaped = false;
}
prefix.append(character);
}
if (prefix.length() > 0) {
this.addCondition(i, matchResult, new Constant(prefix.toString()), CompareCriteria.GE);
if (matchCriteria.getLeftExpression() instanceof Function && table.supportsOrdering(i, matchCriteria.getLeftExpression())) {
// this comparison needs to be aware of case
this.addCondition(i, matchResult, new Constant(prefix.substring(0, prefix.length() - 1) + (char) (Character.toLowerCase(prefix.charAt(prefix.length() - 1)) + 1)), CompareCriteria.LE);
} else {
this.addCondition(i, matchResult, new Constant(prefix.substring(0, prefix.length() - 1) + (char) (prefix.charAt(prefix.length() - 1) + 1)), CompareCriteria.LE);
}
} else {
critIter.remove();
}
} else if (criteria instanceof SetCriteria) {
SetCriteria setCriteria = (SetCriteria) criteria;
if (setCriteria.isNegated()) {
continue;
}
Object matchResult = table.matchesPkColumn(i, setCriteria.getExpression());
if (Boolean.FALSE.equals(matchResult)) {
continue;
}
Collection<Constant> values = (Collection<Constant>) setCriteria.getValues();
this.addSet(i, matchResult, values);
critIter.remove();
}
}
}
}
use of org.teiid.query.sql.lang.CompoundCriteria in project teiid by teiid.
the class TestCompoundCriteria method testClone1.
public void testClone1() {
// $NON-NLS-1$
ElementSymbol e1 = new ElementSymbol("e1");
// $NON-NLS-1$
CompareCriteria ccrit1 = new CompareCriteria(e1, CompareCriteria.EQ, new Constant("abc"));
// $NON-NLS-1$
ElementSymbol e2 = new ElementSymbol("e2");
// $NON-NLS-1$
CompareCriteria ccrit2 = new CompareCriteria(e2, CompareCriteria.EQ, new Constant("xyz"));
CompoundCriteria comp = new CompoundCriteria(CompoundCriteria.AND, ccrit1, ccrit2);
UnitTestUtil.helpTestEquivalence(0, comp, comp.clone());
}
Aggregations