use of org.teiid.query.sql.lang.IsNullCriteria in project teiid by teiid.
the class RuleCopyCriteria method buildElementMap.
/**
* Construct a mapping of element symbol to value map based upon equality CompareCriteria in crits
*
* @param crits
* @param newJoinCrits
* @param metadata
* @return
*/
Map<Expression, Expression> buildElementMap(Collection<Criteria> crits, List<Criteria> newJoinCrits, Set<Criteria> allCriteria, QueryMetadataInterface metadata, boolean underAccess) {
Map<Expression, Expression> srcToTgt = null;
for (Iterator<Criteria> iter = crits.iterator(); iter.hasNext(); ) {
Criteria theCrit = iter.next();
if (theCrit instanceof IsNullCriteria) {
IsNullCriteria isNull = (IsNullCriteria) theCrit;
if (!isNull.isNegated() && isNull.getExpression() instanceof ElementSymbol) {
if (srcToTgt == null) {
srcToTgt = new HashMap<Expression, Expression>();
}
srcToTgt.put(isNull.getExpression(), new Constant(null, isNull.getExpression().getType()));
}
continue;
}
if (!(theCrit instanceof CompareCriteria)) {
continue;
}
CompareCriteria crit = (CompareCriteria) theCrit;
if (crit.getOperator() == CompareCriteria.EQ) {
if (srcToTgt == null) {
srcToTgt = new HashMap<Expression, Expression>();
}
Expression oldValue = srcToTgt.put(crit.getLeftExpression(), crit.getRightExpression());
boolean removed = false;
if (checkWithinJoin(crit, newJoinCrits, allCriteria, oldValue, crit.getRightExpression(), metadata, underAccess)) {
iter.remove();
removed = true;
}
oldValue = srcToTgt.put(crit.getRightExpression(), crit.getLeftExpression());
if (checkWithinJoin(crit, newJoinCrits, allCriteria, oldValue, crit.getLeftExpression(), metadata, underAccess) && !removed) {
iter.remove();
}
}
}
if (srcToTgt == null) {
return Collections.emptyMap();
}
return srcToTgt;
}
use of org.teiid.query.sql.lang.IsNullCriteria 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.IsNullCriteria in project teiid by teiid.
the class RulePushAggregates method addUnionGroupBy.
private void addUnionGroupBy(List<Expression> groupingExpressions, LinkedHashSet<AggregateSymbol> aggregates, SymbolMap parentMap, QueryMetadataInterface metadata, CapabilitiesFinder capFinder, GroupSymbol group, boolean first, PlanNode planNode, boolean viewOnly, boolean partitioned) throws QueryMetadataException, TeiidComponentException, QueryPlannerException, QueryResolverException {
List<Expression> groupingColumns = LanguageObject.Util.deepClone(groupingExpressions, Expression.class);
// branches other than the first need to have their projected column names updated
if (!first) {
PlanNode sortNode = NodeEditor.findNodePreOrder(planNode, NodeConstants.Types.SORT, NodeConstants.Types.SOURCE);
List<Expression> sortOrder = null;
OrderBy orderBy = null;
if (sortNode != null) {
orderBy = (OrderBy) sortNode.getProperty(Info.SORT_ORDER);
sortOrder = orderBy.getSortKeys();
}
List<Expression> projectCols = FrameUtil.findTopCols(planNode);
List<ElementSymbol> virtualElements = parentMap.getKeys();
for (int i = 0; i < virtualElements.size(); i++) {
ElementSymbol virtualElem = virtualElements.get(i);
Expression projectedSymbol = projectCols.get(i);
if (!Symbol.getShortName(projectedSymbol).equals(Symbol.getShortName(virtualElem))) {
if (sortOrder != null) {
int sortIndex = sortOrder.indexOf(projectedSymbol);
if (sortIndex > -1) {
updateSymbolName(sortOrder, sortIndex, virtualElem, sortOrder.get(sortIndex));
orderBy.getOrderByItems().get(sortIndex).setSymbol(sortOrder.get(sortIndex));
}
}
updateSymbolName(projectCols, i, virtualElem, projectedSymbol);
}
}
}
PlanNode view = RuleDecomposeJoin.createSource(group, planNode, parentMap);
PlanNode projectPlanNode = NodeFactory.getNewNode(NodeConstants.Types.PROJECT);
Select allSymbols = new Select();
for (Expression expr : groupingColumns) {
// $NON-NLS-1$
allSymbols.addSymbol(new ExpressionSymbol("expr", expr));
}
if (viewOnly) {
for (AggregateSymbol agg : aggregates) {
agg = (AggregateSymbol) agg.clone();
if (agg.getAggregateFunction() == Type.COUNT) {
if (isCountStar(agg)) {
// $NON-NLS-1$
allSymbols.addSymbol(new ExpressionSymbol("stagedAgg", new Constant(1)));
} else {
SearchedCaseExpression count = new SearchedCaseExpression(Arrays.asList(new IsNullCriteria(agg.getArg(0))), Arrays.asList(new Constant(Integer.valueOf(0))));
count.setElseExpression(new Constant(Integer.valueOf(1)));
count.setType(DataTypeManager.DefaultDataClasses.INTEGER);
// $NON-NLS-1$
allSymbols.addSymbol(new ExpressionSymbol("stagedAgg", count));
}
} else {
// prior canStage should ensure this is true
assert agg.getArgs().length == 1;
Expression ex = agg.getArg(0);
ex = ResolverUtil.convertExpression(ex, DataTypeManager.getDataTypeName(agg.getType()), metadata);
// $NON-NLS-1$
allSymbols.addSymbol(new ExpressionSymbol("stagedAgg", ex));
}
}
} else {
allSymbols.addSymbols(aggregates);
}
if (first) {
QueryRewriter.makeSelectUnique(allSymbols, false);
}
projectPlanNode.setProperty(NodeConstants.Info.PROJECT_COLS, allSymbols.getSymbols());
projectPlanNode.addGroups(view.getGroups());
view.addAsParent(projectPlanNode);
if (!viewOnly) {
addGroupBy(view, groupingColumns, aggregates, metadata, projectPlanNode.getParent(), capFinder, true, groupingColumns.isEmpty() && (partitioned || containsNullDependent(aggregates)));
}
}
use of org.teiid.query.sql.lang.IsNullCriteria in project teiid by teiid.
the class DependentProcedureCriteriaProcessor method prepareNextCommand.
protected boolean prepareNextCommand(VariableContext context) throws BlockedException, TeiidComponentException, TeiidProcessingException {
if (this.critInProgress == null) {
critInProgress = prepareCriteria();
}
for (int j = 0; j < inputReferences.size(); j++) {
Reference ref = (Reference) inputReferences.get(j);
context.remove(ref.getExpression());
}
if (critInProgress == QueryRewriter.FALSE_CRITERIA) {
critInProgress = null;
consumedCriteria();
return false;
}
boolean validRow = true;
for (Iterator<Criteria> i = Criteria.separateCriteriaByAnd(critInProgress).iterator(); i.hasNext() && validRow; ) {
Criteria crit = i.next();
Object value = null;
boolean nullAllowed = false;
Reference parameter = null;
if (crit instanceof IsNullCriteria) {
parameter = (Reference) ((IsNullCriteria) crit).getExpression();
nullAllowed = true;
} else if (crit instanceof CompareCriteria) {
CompareCriteria compare = (CompareCriteria) crit;
value = compare.getRightExpression();
if (compare.getLeftExpression() instanceof Array) {
Array array = (Array) compare.getLeftExpression();
if (value instanceof Expression) {
value = eval.evaluate((Expression) value, null);
}
if (value == null) {
validRow = false;
break;
}
ArrayImpl valueArray = (ArrayImpl) value;
for (int j = 0; j < array.getExpressions().size(); j++) {
validRow = setParam(context, valueArray.getValues()[j], nullAllowed, (Reference) array.getExpressions().get(j));
if (!validRow) {
break;
}
}
continue;
}
parameter = (Reference) compare.getLeftExpression();
} else {
// $NON-NLS-1$
Assertion.failed("Unknown predicate type");
}
validRow = setParam(context, value, nullAllowed, parameter);
}
critInProgress = null;
consumedCriteria();
if (!validRow) {
return false;
}
for (int j = 0; j < inputReferences.size(); j++) {
Object defaultValue = inputDefaults.get(j);
Reference ref = (Reference) inputReferences.get(j);
if (defaultValue != null && !context.containsVariable(ref.getExpression())) {
context.setValue(ref.getExpression(), defaultValue);
}
}
return true;
}
use of org.teiid.query.sql.lang.IsNullCriteria 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();
}
}
}
}
Aggregations