use of org.teiid.query.sql.util.VariableContext in project teiid by teiid.
the class Evaluator method evaluate.
private Boolean evaluate(AbstractSetCriteria criteria, List<?> tuple) throws ExpressionEvaluationException, BlockedException, TeiidComponentException {
// Evaluate expression
Object leftValue = null;
try {
leftValue = evaluate(criteria.getExpression(), tuple);
} catch (ExpressionEvaluationException e) {
throw new ExpressionEvaluationException(QueryPlugin.Event.TEIID30323, e, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30323, criteria));
}
Boolean result = Boolean.FALSE;
ValueIterator valueIter = null;
if (criteria instanceof SetCriteria) {
SetCriteria set = (SetCriteria) criteria;
// Shortcut if null
if (leftValue == null) {
if (!set.getValues().isEmpty()) {
return null;
}
return criteria.isNegated();
}
if (set.isAllConstants()) {
boolean exists = set.getValues().contains(new Constant(leftValue, criteria.getExpression().getType()));
if (!exists) {
if (set.getValues().contains(Constant.NULL_CONSTANT)) {
return null;
}
return criteria.isNegated();
}
return !criteria.isNegated();
}
valueIter = new CollectionValueIterator(((SetCriteria) criteria).getValues());
} else if (criteria instanceof DependentSetCriteria) {
DependentSetCriteria ref = (DependentSetCriteria) criteria;
VariableContext vc = getContext(criteria).getVariableContext();
ValueIteratorSource vis = (ValueIteratorSource) vc.getGlobalValue(ref.getContextSymbol());
if (leftValue == null) {
return null;
}
Set<Object> values;
try {
values = vis.getCachedSet(ref.getValueExpression());
} catch (TeiidProcessingException e) {
throw new ExpressionEvaluationException(e);
}
if (values != null) {
return values.contains(leftValue);
}
vis.setUnused(true);
// them in memory
return true;
} else if (criteria instanceof SubquerySetCriteria) {
try {
valueIter = evaluateSubquery((SubquerySetCriteria) criteria, tuple);
} catch (TeiidProcessingException e) {
throw new ExpressionEvaluationException(e);
}
} else {
// $NON-NLS-1$
throw new AssertionError("unknown set criteria type");
}
while (valueIter.hasNext()) {
if (leftValue == null) {
return null;
}
Object possibleValue = valueIter.next();
Object value = null;
if (possibleValue instanceof Expression) {
try {
value = evaluate((Expression) possibleValue, tuple);
} catch (ExpressionEvaluationException e) {
throw new ExpressionEvaluationException(QueryPlugin.Event.TEIID30323, e, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30323, possibleValue));
}
} else {
value = possibleValue;
}
if (value != null) {
if (Constant.COMPARATOR.compare(leftValue, value) == 0) {
return Boolean.valueOf(!criteria.isNegated());
}
// else try next value
} else {
result = null;
}
}
if (result == null) {
return null;
}
return Boolean.valueOf(criteria.isNegated());
}
use of org.teiid.query.sql.util.VariableContext in project teiid by teiid.
the class SubqueryAwareEvaluator method evaluateSubquery.
@Override
protected ValueIterator evaluateSubquery(SubqueryContainer<?> container, List<?> tuple) throws TeiidProcessingException, BlockedException, TeiidComponentException {
ContextReference ref = (ContextReference) container;
String key = ref.getContextSymbol();
SubqueryState state = this.subqueries.get(key);
if (state == null) {
String otherKey = commands.get(container.getCommand());
if (otherKey != null) {
state = this.subqueries.get(otherKey);
if (state != null) {
key = otherKey;
}
}
}
if (state == null) {
state = new SubqueryState();
state.plan = container.getCommand().getProcessorPlan().clone();
if (container.getCommand().getCorrelatedReferences() != null) {
for (ElementSymbol es : container.getCommand().getCorrelatedReferences().getKeys()) {
if (DataTypeManager.isNonComparable(DataTypeManager.getDataTypeName(es.getType()))) {
state.comparable = false;
break;
}
}
}
this.subqueries.put(key, state);
this.commands.put(container.getCommand(), key);
}
SymbolMap correlatedRefs = container.getCommand().getCorrelatedReferences();
VariableContext currentContext = null;
boolean shouldClose = false;
boolean deterministic = true;
if (state.processor != null && correlatedRefs != null) {
Determinism determinism = state.processor.getContext().getDeterminismLevel();
deterministic = Determinism.COMMAND_DETERMINISTIC.compareTo(determinism) <= 0;
}
boolean removeBuffer = true;
if (correlatedRefs != null) {
currentContext = new VariableContext();
for (Map.Entry<ElementSymbol, Expression> entry : container.getCommand().getCorrelatedReferences().asMap().entrySet()) {
currentContext.setValue(entry.getKey(), evaluate(entry.getValue(), tuple));
}
List<Object> refValues = currentContext.getLocalValues();
if (!refValues.equals(state.refValues)) {
if (state.comparable && deterministic) {
if (state.processor != null) {
// cache the old value
TupleBuffer tb = state.collector.collectTuples();
// recheck determinism as the plan may not have been fully processed by the initial check
Determinism determinism = state.processor.getContext().getDeterminismLevel();
deterministic = Determinism.COMMAND_DETERMINISTIC.compareTo(determinism) <= 0;
if (deterministic) {
// allowed to track up to 4x the maximum results size
maxTuples = Math.max((int) Math.min(Integer.MAX_VALUE, tb.getRowCount() << 2), maxTuples);
ArrayList<Object> cacheKey = new ArrayList<Object>(state.refValues);
cacheKey.add(key);
// ensure that we aren't leaving large last batches in memory
tb.saveBatch();
this.cache.put(cacheKey, tb);
removeBuffer = false;
this.currentTuples += tb.getRowCount();
while (this.currentTuples > maxTuples && !cache.isEmpty()) {
Iterator<Map.Entry<List<?>, TupleBuffer>> i = this.cache.entrySet().iterator();
Map.Entry<List<?>, TupleBuffer> entry = i.next();
TupleBuffer buffer = entry.getValue();
if (buffer.getRowCount() <= 2) {
this.smallCache.put(entry.getKey(), buffer);
} else {
buffer.remove();
}
this.currentTuples -= buffer.getRowCount();
i.remove();
}
}
}
// find if we have cached values
List<Object> cacheKey = new ArrayList<Object>(refValues);
cacheKey.add(key);
TupleBuffer cachedResult = cache.get(cacheKey);
if (cachedResult == null) {
cachedResult = smallCache.get(cacheKey);
}
if (cachedResult != null) {
state.close(false);
return new TupleSourceValueIterator(cachedResult.createIndexedTupleSource(), 0);
}
}
state.refValues = refValues;
shouldClose = true;
}
}
if (shouldClose || (!deterministic && !state.blocked)) {
state.close(removeBuffer);
}
state.blocked = true;
if (state.processor == null) {
CommandContext subContext = context.clone();
state.plan.reset();
state.processor = new QueryProcessor(state.plan, subContext, manager, this.dataMgr);
if (currentContext != null) {
state.processor.getContext().pushVariableContext(currentContext);
}
state.collector = state.processor.createBatchCollector();
}
TupleSourceValueIterator iter = new TupleSourceValueIterator(state.collector.collectTuples().createIndexedTupleSource(), 0);
state.blocked = false;
return iter;
}
use of org.teiid.query.sql.util.VariableContext in project teiid by teiid.
the class PlanExecutionNode method open.
public void open() throws TeiidComponentException, TeiidProcessingException {
super.open();
// Initialize plan for execution
CommandContext subContext = getContext().clone();
subContext.pushVariableContext(new VariableContext());
plan.initialize(subContext, getDataManager(), this.getBufferManager());
if (openPlanImmediately() && prepareNextCommand()) {
needsProcessing = true;
plan.open();
isOpen = true;
}
}
use of org.teiid.query.sql.util.VariableContext in project teiid by teiid.
the class ForEachRowPlan method nextBatch.
@Override
public TupleBatch nextBatch() throws BlockedException, TeiidComponentException, TeiidProcessingException {
if (planContext != null) {
this.getContext().getTransactionServer().resume(planContext);
}
try {
while (true) {
if (currentTuple == null) {
if (nextTuple != null) {
currentTuple = nextTuple;
} else if (!nextNull) {
currentTuple = tupleSource.nextTuple();
}
if (currentTuple == null) {
if (this.planContext != null) {
TransactionService ts = this.getContext().getTransactionServer();
ts.commit(this.planContext);
this.planContext = null;
}
TupleBatch result = new TupleBatch(1, new List[] { Arrays.asList((int) Math.min(Integer.MAX_VALUE, updateCount)) });
result.setTerminationFlag(true);
return result;
}
}
if (first) {
TransactionContext tc = this.getContext().getTransactionContext();
if (this.planContext == null && tc != null && tc.getTransactionType() == Scope.NONE) {
Boolean txnRequired = rowProcedure.requiresTransaction(false);
boolean start = false;
if (txnRequired == null) {
nextTuple = tupleSource.nextTuple();
if (nextTuple != null) {
start = true;
} else {
nextNull = true;
}
} else if (Boolean.TRUE.equals(txnRequired)) {
start = true;
}
if (start) {
this.getContext().getTransactionServer().begin(tc);
this.planContext = tc;
}
}
first = false;
}
if (this.rowProcessor == null) {
rowProcedure.reset();
CommandContext context = getContext().clone();
this.rowProcessor = new QueryProcessor(rowProcedure, context, this.bufferMgr, this.dataMgr);
Evaluator eval = new Evaluator(lookupMap, dataMgr, context);
for (Map.Entry<ElementSymbol, Expression> entry : this.params.entrySet()) {
Integer index = this.lookupMap.get(entry.getValue());
if (index != null) {
rowProcedure.getCurrentVariableContext().setValue(entry.getKey(), this.currentTuple.get(index));
} else {
rowProcedure.getCurrentVariableContext().setValue(entry.getKey(), eval.evaluate(entry.getValue(), this.currentTuple));
}
}
}
// save the variable context to get the key information
VariableContext vc = rowProcedure.getCurrentVariableContext();
// just getting the next batch is enough
this.rowProcessor.nextBatch();
if (insert) {
assignGeneratedKey(vc);
}
this.rowProcessor.closeProcessing();
this.rowProcessor = null;
this.currentTuple = null;
this.updateCount++;
}
} finally {
if (planContext != null) {
this.getContext().getTransactionServer().suspend(planContext);
}
}
}
use of org.teiid.query.sql.util.VariableContext in project teiid by teiid.
the class ProcedurePlan method push.
public void push(Program program) throws XATransactionException {
this.evaluator.close();
program.reset(this.getContext().getConnectionId());
program.setTrappingExceptions(program.getExceptionGroup() != null || (!this.programs.isEmpty() && this.programs.peek().isTrappingExceptions()));
TempTableStore tts = getTempTableStore();
getContext().setTempTableStore(program.getTempTableStore());
program.getTempTableStore().setParentTempTableStore(tts);
this.programs.push(program);
VariableContext context = new VariableContext(true);
context.setParentContext(this.currentVarContext);
this.currentVarContext = context;
VariableContext cc = new VariableContext(true);
cc.setParentContext(this.cursorStates);
this.cursorStates = cc;
if (program.isAtomic() && this.blockContext == null) {
TransactionContext tc = this.getContext().getTransactionContext();
if (tc != null && tc.getTransactionType() == Scope.NONE && Boolean.TRUE.equals(program.instructionsRequireTransaction(false))) {
// start a transaction
this.getContext().getTransactionServer().begin(tc);
this.blockContext = tc;
program.setStartedTxn(true);
}
}
}
Aggregations