Search in sources :

Example 6 with ParseInfo

use of org.teiid.query.parser.ParseInfo in project teiid by teiid.

the class CommandContext method getPlan.

public PreparedPlan getPlan(String key) {
    if (this.globalState.planCache == null) {
        return null;
    }
    CacheID id = new CacheID(new ParseInfo(), key, getVdbName(), getVdbVersion(), getConnectionId(), getUserName());
    PreparedPlan pp = this.globalState.planCache.get(id);
    if (pp != null) {
        if (id.getSessionId() != null) {
            setDeterminismLevel(Determinism.USER_DETERMINISTIC);
        } else if (id.getUserName() != null) {
            setDeterminismLevel(Determinism.SESSION_DETERMINISTIC);
        }
        return pp;
    }
    return null;
}
Also used : CacheID(org.teiid.dqp.internal.process.SessionAwareCache.CacheID) PreparedPlan(org.teiid.dqp.internal.process.PreparedPlan) ParseInfo(org.teiid.query.parser.ParseInfo)

Example 7 with ParseInfo

use of org.teiid.query.parser.ParseInfo in project teiid by teiid.

the class MetaDataProcessor method obtainMetadataForPreparedSql.

private MetadataResult obtainMetadataForPreparedSql(String sql, DQPWorkContext workContext, boolean isDoubleQuotedVariablesAllowed) throws QueryParserException, QueryResolverException, TeiidComponentException {
    Command command = null;
    ParseInfo info = new ParseInfo();
    // Defect 19747 - the parser needs the following connection property to decide whether to treat double-quoted strings as variable names
    info.ansiQuotedIdentifiers = isDoubleQuotedVariablesAllowed;
    CacheID id = new CacheID(workContext, info, sql);
    PreparedPlan plan = planCache.get(id);
    if (plan != null) {
        command = plan.getCommand();
    } else {
        command = QueryParser.getQueryParser().parseCommand(sql, info);
        QueryResolver.resolveCommand(command, this.metadata);
    }
    return getMetadataForCommand(command);
}
Also used : Command(org.teiid.query.sql.lang.Command) CacheID(org.teiid.dqp.internal.process.SessionAwareCache.CacheID) ParseInfo(org.teiid.query.parser.ParseInfo)

Example 8 with ParseInfo

use of org.teiid.query.parser.ParseInfo in project teiid by teiid.

the class QueryProcessorFactoryImpl method getPreparedPlan.

@Override
public PreparedPlan getPreparedPlan(String query, String recursionGroup, CommandContext commandContext, QueryMetadataInterface metadata) throws TeiidComponentException, TeiidProcessingException {
    if (recursionGroup != null) {
        commandContext.pushCall(recursionGroup);
    }
    PreparedPlan pp = commandContext.getPlan(query);
    if (pp == null) {
        ParseInfo parseInfo = new ParseInfo();
        Command newCommand = QueryParser.getQueryParser().parseCommand(query, parseInfo);
        QueryResolver.resolveCommand(newCommand, metadata);
        List<Reference> references = ReferenceCollectorVisitor.getReferences(newCommand);
        AbstractValidationVisitor visitor = new ValidationVisitor();
        Request.validateWithVisitor(visitor, metadata, newCommand);
        newCommand = QueryRewriter.rewrite(newCommand, metadata, commandContext);
        AnalysisRecord record = new AnalysisRecord(false, false);
        ProcessorPlan plan = QueryOptimizer.optimizePlan(newCommand, metadata, idGenerator, finder, record, commandContext);
        pp = new PreparedPlan();
        pp.setPlan(plan, commandContext);
        pp.setReferences(references);
        pp.setAnalysisRecord(record);
        pp.setCommand(newCommand);
        commandContext.putPlan(query, pp, commandContext.getDeterminismLevel());
    }
    return pp;
}
Also used : AbstractValidationVisitor(org.teiid.query.validator.AbstractValidationVisitor) ValidationVisitor(org.teiid.query.validator.ValidationVisitor) AnalysisRecord(org.teiid.query.analysis.AnalysisRecord) Command(org.teiid.query.sql.lang.Command) Reference(org.teiid.query.sql.symbol.Reference) ParseInfo(org.teiid.query.parser.ParseInfo) AbstractValidationVisitor(org.teiid.query.validator.AbstractValidationVisitor) ProcessorPlan(org.teiid.query.processor.ProcessorPlan)

Example 9 with ParseInfo

use of org.teiid.query.parser.ParseInfo in project teiid by teiid.

the class Request method createParseInfo.

public static ParseInfo createParseInfo(RequestMessage requestMsg, SessionMetadata sessionMetadata) {
    ParseInfo parseInfo = new ParseInfo();
    parseInfo.ansiQuotedIdentifiers = requestMsg.isAnsiQuotedIdentifiers();
    // $NON-NLS-1$
    Object value = sessionMetadata.getSessionVariables().get("backslashDefaultMatchEscape");
    try {
        if (value != null && Boolean.TRUE.equals(DataTypeManager.transformValue(value, DataTypeManager.DefaultDataClasses.BOOLEAN))) {
            parseInfo.setBackslashDefaultMatchEscape(true);
        }
    } catch (TransformationException e) {
    }
    return parseInfo;
}
Also used : TransformationException(org.teiid.core.types.TransformationException) ParseInfo(org.teiid.query.parser.ParseInfo)

Example 10 with ParseInfo

use of org.teiid.query.parser.ParseInfo in project teiid by teiid.

the class RequestWorkItem method processNew.

protected void processNew() throws TeiidProcessingException, TeiidComponentException {
    planningStart = System.currentTimeMillis();
    SessionAwareCache<CachedResults> rsCache = dqpCore.getRsCache();
    boolean cachable = false;
    CacheID cacheId = null;
    if (rsCache != null) {
        boolean canUseCache = true;
        if (requestMsg.getRequestOptions().isContinuous()) {
            canUseCache = false;
            // $NON-NLS-1$
            LogManager.logDetail(LogConstants.CTX_DQP, requestID, "Command is continuous, result set caching will not be used");
        } else if (!requestMsg.useResultSetCache() && getCacheHint() == null) {
            canUseCache = false;
            // $NON-NLS-1$
            LogManager.logDetail(LogConstants.CTX_DQP, requestID, "Command has no cache hint and result set cache mode is not on.");
        }
        if (canUseCache) {
            ParseInfo pi = Request.createParseInfo(requestMsg, this.dqpWorkContext.getSession());
            cacheId = new CacheID(this.dqpWorkContext, pi, requestMsg.getCommandString());
            cachable = cacheId.setParameters(requestMsg.getParameterValues());
            if (cachable) {
                // allow cache to be transactionally aware
                if (rsCache.isTransactional()) {
                    TransactionContext tc = request.getTransactionContext(false);
                    if (tc != null && tc.getTransactionType() != Scope.NONE) {
                        initTransactionState(tc);
                        resume();
                    }
                }
                CachedResults cr = rsCache.get(cacheId);
                // TODO: possibly ignore max rows for caching
                if (cr != null && (cr.getRowLimit() == 0 || (requestMsg.getRowLimit() != 0 && requestMsg.getRowLimit() <= cr.getRowLimit()))) {
                    request.initMetadata();
                    this.originalCommand = cr.getCommand(requestMsg.getCommandString(), request.metadata, pi);
                    if (!request.validateAccess(requestMsg.getCommands(), this.originalCommand, CommandType.CACHED)) {
                        // $NON-NLS-1$
                        LogManager.logDetail(LogConstants.CTX_DQP, requestID, "Using result set cached results", cacheId);
                        this.resultsBuffer = cr.getResults();
                        doneProducingBatches();
                        return;
                    }
                    // $NON-NLS-1$
                    LogManager.logDetail(LogConstants.CTX_DQP, requestID, "Cached result command to be modified, will not use the cached results", cacheId);
                }
            } else {
                // $NON-NLS-1$
                LogManager.logDetail(LogConstants.CTX_DQP, requestID, "Parameters are not serializable - cache cannot be used for", cacheId);
            }
        }
    } else {
        // $NON-NLS-1$
        LogManager.logDetail(LogConstants.CTX_DQP, requestID, "Result set caching is disabled.");
    }
    try {
        request.processRequest();
    } finally {
        analysisRecord = request.analysisRecord;
    }
    originalCommand = request.userCommand;
    if (cachable && (requestMsg.useResultSetCache() || originalCommand.getCacheHint() != null) && rsCache != null && originalCommand.areResultsCachable()) {
        this.cid = cacheId;
        // turn on the collection of data objects used
        request.processor.getContext().setDataObjects(new HashSet<Object>(4));
    }
    request.processor.getContext().setWorkItem(this);
    processor = request.processor;
    planningEnd = System.currentTimeMillis();
    this.dqpCore.logMMCommand(this, Event.PLAN, null, null);
    collector = new BatchCollector(processor, processor.getBufferManager(), this.request.context, isForwardOnly()) {

        int maxRows = 0;

        @Override
        protected void flushBatchDirect(TupleBatch batch, boolean add) throws TeiidComponentException, TeiidProcessingException {
            resultsBuffer = getTupleBuffer();
            if (maxRows == 0) {
                maxRows = OUTPUT_BUFFER_MAX_BATCHES * resultsBuffer.getBatchSize();
            }
            if (cid != null) {
                super.flushBatchDirect(batch, add);
            }
            synchronized (lobStreams) {
                if (cid == null && resultsBuffer.isLobs()) {
                    super.flushBatchDirect(batch, false);
                }
                if (batch.getTerminationFlag()) {
                    done();
                }
                add = sendResultsIfNeeded(batch);
                if (cid != null) {
                    return;
                }
                super.flushBatchDirect(batch, add);
                if (!add && !processor.hasBuffer()) {
                    resultsBuffer.setRowCount(batch.getEndRow());
                }
                if (transactionState != TransactionState.ACTIVE && (requestMsg.getRequestOptions().isContinuous() || (useCallingThread && isForwardOnly()))) {
                    synchronized (this) {
                        if (resultsReceiver == null) {
                            // $NON-NLS-1$
                            throw BlockedException.block(requestID, "Blocking to allow asynch processing");
                        }
                    }
                    if (add && !returnsUpdateCount) {
                        // $NON-NLS-1$
                        throw new AssertionError("Should not add batch to buffer");
                    }
                }
                if (add) {
                    flowControl(batch);
                }
            }
        }

        private void flowControl(TupleBatch batch) throws BlockedException {
            if (processor.hasBuffer() || batch.getTerminationFlag() || transactionState == TransactionState.ACTIVE) {
                return;
            }
            synchronized (this) {
                if (!isForwardOnly() && resultsReceiver != null && begin > resultsBuffer.getRowCount()) {
                    // a valid request beyond the processed range
                    return;
                }
            }
            if (resultsBuffer.getManagedRowCount() < maxRows) {
                // continue to buffer
                return;
            }
            int timeOut = 500;
            if (!connectorInfo.isEmpty()) {
                if (explicitSourceClose) {
                    for (DataTierTupleSource ts : getConnectorRequests()) {
                        if (!ts.isExplicitClose()) {
                            timeOut = 100;
                            break;
                        }
                    }
                } else {
                    timeOut = 100;
                }
            }
            if (dqpCore.blockOnOutputBuffer(RequestWorkItem.this)) {
                if (moreWorkTask != null) {
                    moreWorkTask.cancel(false);
                    moreWorkTask = null;
                }
                if (getThreadState() != ThreadState.MORE_WORK) {
                    // we schedule the work to ensure that an idle client won't just indefinitely hold resources
                    moreWorkTask = scheduleWork(timeOut);
                }
                throw // $NON-NLS-1$
                BlockedException.block(// $NON-NLS-1$
                requestID, // $NON-NLS-1$
                "Blocking due to full results TupleBuffer", this.getTupleBuffer(), "rows", this.getTupleBuffer().getManagedRowCount(), "batch size", // $NON-NLS-1$ //$NON-NLS-2$
                this.getTupleBuffer().getBatchSize());
            }
            if (LogManager.isMessageToBeRecorded(LogConstants.CTX_DQP, MessageLevel.DETAIL)) {
                // $NON-NLS-1$
                LogManager.logDetail(LogConstants.CTX_DQP, requestID, "Exceeding buffer limit since there are pending active plans or this is using the calling thread.");
            }
        }
    };
    if (!request.addedLimit && this.requestMsg.getRowLimit() > 0 && this.requestMsg.getRowLimit() < Integer.MAX_VALUE) {
        // covers maxrows for commands that already have a limit, are prepared, or are a stored procedure
        this.collector.setRowLimit(this.requestMsg.getRowLimit());
        this.collector.setSaveLastRow(request.isReturingParams());
    }
    this.resultsBuffer = collector.getTupleBuffer();
    if (this.resultsBuffer == null) {
        // This is just a dummy result it will get replaced by collector source
        resultsBuffer = this.processor.getBufferManager().createTupleBuffer(this.originalCommand.getProjectedSymbols(), this.request.context.getConnectionId(), TupleSourceType.FINAL);
    } else if (this.requestMsg.getRequestOptions().isContinuous()) {
        // TODO: this is based upon continuous being an embedded connection otherwise we have to do something like
        // forcing inlining, but truncating or erroring over a given size (similar to odbc handling)
        resultsBuffer.removeLobTracking();
    }
    initTransactionState(request.transactionContext);
    if (requestMsg.isNoExec()) {
        doneProducingBatches();
        resultsBuffer.close();
        this.cid = null;
    }
    this.returnsUpdateCount = request.returnsUpdateCount;
    if (this.returnsUpdateCount && this.requestMsg.getRequestOptions().isContinuous()) {
        // $NON-NLS-1$
        throw new IllegalStateException("Continuous requests are not allowed to be updates.");
    }
    request = null;
}
Also used : ParseInfo(org.teiid.query.parser.ParseInfo) BlockedException(org.teiid.common.buffer.BlockedException) CacheHint(org.teiid.query.sql.lang.CacheHint) TeiidProcessingException(org.teiid.core.TeiidProcessingException) CacheID(org.teiid.dqp.internal.process.SessionAwareCache.CacheID) TransactionContext(org.teiid.dqp.service.TransactionContext) TeiidComponentException(org.teiid.core.TeiidComponentException) BatchCollector(org.teiid.query.processor.BatchCollector) TupleBatch(org.teiid.common.buffer.TupleBatch)

Aggregations

ParseInfo (org.teiid.query.parser.ParseInfo)16 CacheID (org.teiid.dqp.internal.process.SessionAwareCache.CacheID)11 Test (org.junit.Test)6 Cachable (org.teiid.cache.Cachable)6 Command (org.teiid.query.sql.lang.Command)4 ArrayList (java.util.ArrayList)3 Client (org.teiid.odata.api.Client)2 BatchCollector (org.teiid.query.processor.BatchCollector)2 Reference (org.teiid.query.sql.symbol.Reference)2 LinkedList (java.util.LinkedList)1 List (java.util.List)1 BlockedException (org.teiid.common.buffer.BlockedException)1 TupleBatch (org.teiid.common.buffer.TupleBatch)1 TupleBuffer (org.teiid.common.buffer.TupleBuffer)1 TeiidComponentException (org.teiid.core.TeiidComponentException)1 TeiidProcessingException (org.teiid.core.TeiidProcessingException)1 TransformationException (org.teiid.core.types.TransformationException)1 CachedResults (org.teiid.dqp.internal.process.CachedResults)1 PreparedPlan (org.teiid.dqp.internal.process.PreparedPlan)1 TransactionContext (org.teiid.dqp.service.TransactionContext)1