Search in sources :

Example 1 with VariableContext

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());
}
Also used : ExpressionEvaluationException(org.teiid.api.exception.query.ExpressionEvaluationException) Set(java.util.Set) ValueIterator(org.teiid.query.sql.util.ValueIterator) VariableContext(org.teiid.query.sql.util.VariableContext) TeiidProcessingException(org.teiid.core.TeiidProcessingException) ValueIteratorSource(org.teiid.query.sql.util.ValueIteratorSource) ExceptionExpression(org.teiid.query.sql.proc.ExceptionExpression) LanguageObject(org.teiid.query.sql.LanguageObject)

Example 2 with VariableContext

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;
}
Also used : ElementSymbol(org.teiid.query.sql.symbol.ElementSymbol) Determinism(org.teiid.metadata.FunctionMethod.Determinism) CommandContext(org.teiid.query.util.CommandContext) ContextReference(org.teiid.query.sql.symbol.ContextReference) TupleBuffer(org.teiid.common.buffer.TupleBuffer) ArrayList(java.util.ArrayList) SymbolMap(org.teiid.query.sql.util.SymbolMap) VariableContext(org.teiid.query.sql.util.VariableContext) QueryProcessor(org.teiid.query.processor.QueryProcessor) Expression(org.teiid.query.sql.symbol.Expression) List(java.util.List) ArrayList(java.util.ArrayList) Map(java.util.Map) HashMap(java.util.HashMap) SymbolMap(org.teiid.query.sql.util.SymbolMap)

Example 3 with VariableContext

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;
    }
}
Also used : CommandContext(org.teiid.query.util.CommandContext) VariableContext(org.teiid.query.sql.util.VariableContext)

Example 4 with VariableContext

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);
        }
    }
}
Also used : ElementSymbol(org.teiid.query.sql.symbol.ElementSymbol) TransactionService(org.teiid.dqp.service.TransactionService) CommandContext(org.teiid.query.util.CommandContext) Evaluator(org.teiid.query.eval.Evaluator) VariableContext(org.teiid.query.sql.util.VariableContext) QueryProcessor(org.teiid.query.processor.QueryProcessor) Expression(org.teiid.query.sql.symbol.Expression) TransactionContext(org.teiid.dqp.service.TransactionContext) LinkedHashMap(java.util.LinkedHashMap) Map(java.util.Map) TupleBatch(org.teiid.common.buffer.TupleBatch)

Example 5 with VariableContext

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);
        }
    }
}
Also used : TempTableStore(org.teiid.query.tempdata.TempTableStore) TransactionContext(org.teiid.dqp.service.TransactionContext) VariableContext(org.teiid.query.sql.util.VariableContext)

Aggregations

VariableContext (org.teiid.query.sql.util.VariableContext)22 ElementSymbol (org.teiid.query.sql.symbol.ElementSymbol)6 Expression (org.teiid.query.sql.symbol.Expression)6 List (java.util.List)5 TransactionContext (org.teiid.dqp.service.TransactionContext)5 CommandContext (org.teiid.query.util.CommandContext)5 ArrayList (java.util.ArrayList)4 Map (java.util.Map)3 TeiidProcessingException (org.teiid.core.TeiidProcessingException)3 QueryProcessor (org.teiid.query.processor.QueryProcessor)3 Command (org.teiid.query.sql.lang.Command)3 Constant (org.teiid.query.sql.symbol.Constant)3 LinkedHashMap (java.util.LinkedHashMap)2 LinkedList (java.util.LinkedList)2 ExpressionEvaluationException (org.teiid.api.exception.query.ExpressionEvaluationException)2 QueryValidatorException (org.teiid.api.exception.query.QueryValidatorException)2 XATransactionException (org.teiid.client.xa.XATransactionException)2 BlockedException (org.teiid.common.buffer.BlockedException)2 TupleBatch (org.teiid.common.buffer.TupleBatch)2 TeiidComponentException (org.teiid.core.TeiidComponentException)2