use of org.teiid.query.sql.lang.Criteria 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.Criteria 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.Criteria in project teiid by teiid.
the class UpdateProcedureResolver method resolveStatement.
private void resolveStatement(CreateProcedureCommand command, Statement statement, GroupContext externalGroups, GroupSymbol variables, TempMetadataAdapter metadata) throws QueryResolverException, QueryMetadataException, TeiidComponentException {
// $NON-NLS-1$
LogManager.logTrace(org.teiid.logging.LogConstants.CTX_QUERY_RESOLVER, new Object[] { "Resolving statement", statement });
switch(statement.getType()) {
case Statement.TYPE_IF:
IfStatement ifStmt = (IfStatement) statement;
Criteria ifCrit = ifStmt.getCondition();
for (SubqueryContainer container : ValueIteratorProviderCollectorVisitor.getValueIteratorProviders(ifCrit)) {
resolveEmbeddedCommand(metadata, externalGroups, container.getCommand());
}
ResolverVisitor.resolveLanguageObject(ifCrit, null, externalGroups, metadata);
resolveBlock(command, ifStmt.getIfBlock(), externalGroups, metadata);
if (ifStmt.hasElseBlock()) {
resolveBlock(command, ifStmt.getElseBlock(), externalGroups, metadata);
}
break;
case Statement.TYPE_COMMAND:
CommandStatement cmdStmt = (CommandStatement) statement;
Command subCommand = cmdStmt.getCommand();
TempMetadataStore discoveredMetadata = resolveEmbeddedCommand(metadata, externalGroups, subCommand);
if (subCommand instanceof StoredProcedure) {
StoredProcedure sp = (StoredProcedure) subCommand;
for (SPParameter param : sp.getParameters()) {
switch(param.getParameterType()) {
case ParameterInfo.OUT:
case ParameterInfo.RETURN_VALUE:
if (param.getExpression() != null) {
if (!isAssignable(metadata, param)) {
throw new QueryResolverException(QueryPlugin.Event.TEIID30121, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30121, param.getExpression()));
}
sp.setCallableStatement(true);
}
break;
case ParameterInfo.INOUT:
if (!isAssignable(metadata, param)) {
continue;
}
sp.setCallableStatement(true);
break;
}
}
}
if (discoveredMetadata != null) {
metadata.getMetadataStore().getData().putAll(discoveredMetadata.getData());
}
// dynamic commands need to be updated as to their implicitly expected projected symbols
if (subCommand instanceof DynamicCommand) {
DynamicCommand dynCommand = (DynamicCommand) subCommand;
if (dynCommand.getIntoGroup() == null && !dynCommand.isAsClauseSet()) {
if ((command.getResultSetColumns() != null && command.getResultSetColumns().isEmpty()) || !cmdStmt.isReturnable() || command.getResultSetColumns() == null) {
// we're not interested in the resultset
dynCommand.setAsColumns(Collections.EMPTY_LIST);
} else {
// should match the procedure
dynCommand.setAsColumns(command.getResultSetColumns());
}
}
}
if (command.getResultSetColumns() == null && cmdStmt.isReturnable() && subCommand.returnsResultSet() && subCommand.getResultSetColumns() != null && !subCommand.getResultSetColumns().isEmpty()) {
command.setResultSetColumns(subCommand.getResultSetColumns());
if (command.getProjectedSymbols().isEmpty()) {
command.setProjectedSymbols(subCommand.getResultSetColumns());
}
}
break;
case Statement.TYPE_ERROR:
case Statement.TYPE_ASSIGNMENT:
case Statement.TYPE_DECLARE:
case Statement.TYPE_RETURN:
ExpressionStatement exprStmt = (ExpressionStatement) statement;
// first resolve the value. this ensures the value cannot use the variable being defined
if (exprStmt.getExpression() != null) {
Expression expr = exprStmt.getExpression();
for (SubqueryContainer container : ValueIteratorProviderCollectorVisitor.getValueIteratorProviders(expr)) {
resolveEmbeddedCommand(metadata, externalGroups, container.getCommand());
}
ResolverVisitor.resolveLanguageObject(expr, null, externalGroups, metadata);
}
// second resolve the variable
switch(statement.getType()) {
case Statement.TYPE_DECLARE:
collectDeclareVariable((DeclareStatement) statement, variables, metadata, externalGroups);
break;
case Statement.TYPE_ASSIGNMENT:
AssignmentStatement assStmt = (AssignmentStatement) statement;
ResolverVisitor.resolveLanguageObject(assStmt.getVariable(), null, externalGroups, metadata);
if (!metadata.elementSupports(assStmt.getVariable().getMetadataID(), SupportConstants.Element.UPDATE)) {
throw new QueryResolverException(QueryPlugin.Event.TEIID30121, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30121, assStmt.getVariable()));
}
// don't allow variable assignments to be external
assStmt.getVariable().setIsExternalReference(false);
break;
case Statement.TYPE_RETURN:
ReturnStatement rs = (ReturnStatement) statement;
if (rs.getExpression() != null) {
if (command.getReturnVariable() == null) {
throw new QueryResolverException(QueryPlugin.Event.TEIID31125, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID31125, rs));
}
rs.setVariable(command.getReturnVariable().clone());
}
// else - we don't currently require the use of return for backwards compatibility
break;
}
// third ensure the type matches
if (exprStmt.getExpression() != null) {
Class<?> varType = exprStmt.getExpectedType();
Class<?> exprType = exprStmt.getExpression().getType();
if (exprType == null) {
throw new QueryResolverException(QueryPlugin.Event.TEIID30123, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30123));
}
String varTypeName = DataTypeManager.getDataTypeName(varType);
exprStmt.setExpression(ResolverUtil.convertExpression(exprStmt.getExpression(), varTypeName, metadata));
if (statement.getType() == Statement.TYPE_ERROR) {
ResolverVisitor.checkException(exprStmt.getExpression());
}
}
break;
case Statement.TYPE_WHILE:
WhileStatement whileStmt = (WhileStatement) statement;
Criteria whileCrit = whileStmt.getCondition();
for (SubqueryContainer container : ValueIteratorProviderCollectorVisitor.getValueIteratorProviders(whileCrit)) {
resolveEmbeddedCommand(metadata, externalGroups, container.getCommand());
}
ResolverVisitor.resolveLanguageObject(whileCrit, null, externalGroups, metadata);
resolveBlock(command, whileStmt.getBlock(), externalGroups, metadata);
break;
case Statement.TYPE_LOOP:
LoopStatement loopStmt = (LoopStatement) statement;
String groupName = loopStmt.getCursorName();
isValidGroup(metadata, groupName);
Command cmd = loopStmt.getCommand();
resolveEmbeddedCommand(metadata, externalGroups, cmd);
List<Expression> symbols = cmd.getProjectedSymbols();
// add the loop cursor group into its own context
TempMetadataStore store = metadata.getMetadataStore().clone();
metadata = new TempMetadataAdapter(metadata.getMetadata(), store);
externalGroups = new GroupContext(externalGroups, null);
ProcedureContainerResolver.addScalarGroup(groupName, store, externalGroups, symbols, false);
resolveBlock(command, loopStmt.getBlock(), externalGroups, metadata);
break;
case Statement.TYPE_COMPOUND:
resolveBlock(command, (Block) statement, externalGroups, metadata);
break;
}
}
use of org.teiid.query.sql.lang.Criteria in project teiid by teiid.
the class WhileStatement method clone.
/**
* Deep clone statement to produce a new identical statement.
* @return Deep clone
*/
public Object clone() {
Block otherBlock = this.whileBlock.clone();
Criteria otherCrit = (Criteria) this.condition.clone();
WhileStatement ws = new WhileStatement(otherCrit, otherBlock);
ws.setLabel(label);
return ws;
}
use of org.teiid.query.sql.lang.Criteria 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