Search in sources :

Example 6 with Determinism

use of org.teiid.metadata.FunctionMethod.Determinism in project teiid by teiid.

the class QueryOptimizer method optimizePlan.

public static ProcessorPlan optimizePlan(Command command, QueryMetadataInterface metadata, IDGenerator idGenerator, CapabilitiesFinder capFinder, AnalysisRecord analysisRecord, CommandContext context) throws QueryMetadataException, TeiidComponentException, QueryPlannerException {
    if (analysisRecord == null) {
        analysisRecord = new AnalysisRecord(false, false);
    }
    if (context == null) {
        context = new CommandContext();
    }
    if (!(capFinder instanceof TempCapabilitiesFinder)) {
        capFinder = new TempCapabilitiesFinder(capFinder);
    }
    boolean debug = analysisRecord.recordDebug();
    if (!(metadata instanceof TempMetadataAdapter)) {
        metadata = new TempMetadataAdapter(metadata, new TempMetadataStore());
    }
    if (context.getMetadata() == null) {
        context.setMetadata(metadata);
    }
    // Create an ID generator that can be used for all plans to generate unique data node IDs
    if (idGenerator == null) {
        idGenerator = new IDGenerator();
    }
    if (debug) {
        // $NON-NLS-1$
        analysisRecord.println("\n----------------------------------------------------------------------------");
        // $NON-NLS-1$
        analysisRecord.println("OPTIMIZE: \n" + command);
    }
    if (command instanceof Insert) {
        Insert insert = (Insert) command;
        if (insert.isUpsert()) {
            // if not supported or there are trigger actions, then rewrite as a procedure
            // we do this here since we're changing the command type.
            // TODO: we could push this back into the rewrite, but it will need to be capabilities aware
            GroupSymbol group = insert.getGroup();
            Object modelId = metadata.getModelID(group.getMetadataID());
            boolean supportsUpsert = CapabilitiesUtil.supports(Capability.UPSERT, modelId, metadata, capFinder);
            if (!supportsUpsert) {
                try {
                    command = QueryRewriter.rewriteAsUpsertProcedure(insert, metadata, context);
                } catch (TeiidProcessingException e) {
                    throw new QueryPlannerException(e);
                }
                if (debug) {
                    // $NON-NLS-1$
                    analysisRecord.println("\n----------------------------------------------------------------------------");
                    // $NON-NLS-1$
                    analysisRecord.println("OPTIMIZE UPSERT PROCEDURE: \n" + command);
                }
            }
        }
    }
    ProcessorPlan result = null;
    switch(command.getType()) {
        case Command.TYPE_UPDATE_PROCEDURE:
            CreateProcedureCommand cupc = (CreateProcedureCommand) command;
            if (cupc.getUpdateType() != Command.TYPE_UNKNOWN || cupc.getVirtualGroup() == null) {
                // row update procedure or anon block
                result = planProcedure(command, metadata, idGenerator, capFinder, analysisRecord, context);
            } else {
                Object pid = cupc.getVirtualGroup().getMetadataID();
                if (pid instanceof TempMetadataID) {
                    TempMetadataID tid = (TempMetadataID) pid;
                    if (tid.getOriginalMetadataID() != null) {
                        pid = tid.getOriginalMetadataID();
                    }
                }
                String fullName = metadata.getFullName(pid);
                // $NON-NLS-1$
                fullName = "procedure cache:" + fullName;
                PreparedPlan pp = context.getPlan(fullName);
                if (pp == null) {
                    Determinism determinismLevel = context.resetDeterminismLevel();
                    try {
                        CommandContext clone = context.clone();
                        ProcessorPlan plan = planProcedure(command, metadata, idGenerator, capFinder, analysisRecord, clone);
                        // note that this is not a full prepared plan.  It is not usable by user queries.
                        if (pid instanceof Procedure) {
                            clone.accessedPlanningObject(pid);
                        }
                        pp = new PreparedPlan();
                        pp.setPlan(plan, clone);
                        context.putPlan(fullName, pp, context.getDeterminismLevel());
                    } finally {
                        context.setDeterminismLevel(determinismLevel);
                    }
                }
                result = pp.getPlan().clone();
                for (Object id : pp.getAccessInfo().getObjectsAccessed()) {
                    context.accessedPlanningObject(id);
                }
            }
            break;
        case Command.TYPE_BATCHED_UPDATE:
            result = BATCHED_UPDATE_PLANNER.optimize(command, idGenerator, metadata, capFinder, analysisRecord, context);
            break;
        case Command.TYPE_ALTER_PROC:
        case Command.TYPE_ALTER_TRIGGER:
        case Command.TYPE_ALTER_VIEW:
            result = DDL_PLANNER.optimize(command, idGenerator, metadata, capFinder, analysisRecord, context);
            break;
        case Command.TYPE_SOURCE_EVENT:
            result = SOURCE_EVENT_PLANNER.optimize(command, idGenerator, metadata, capFinder, analysisRecord, context);
            break;
        default:
            try {
                RelationalPlanner planner = new RelationalPlanner();
                planner.initialize(command, idGenerator, metadata, capFinder, analysisRecord, context);
                result = planner.optimize(command);
            } catch (QueryResolverException e) {
                throw new TeiidRuntimeException(QueryPlugin.Event.TEIID30245, e);
            }
    }
    if (debug) {
        // $NON-NLS-1$
        analysisRecord.println("\n----------------------------------------------------------------------------");
        // $NON-NLS-1$
        analysisRecord.println("OPTIMIZATION COMPLETE:");
        // $NON-NLS-1$
        analysisRecord.println("PROCESSOR PLAN:\n" + result);
        // $NON-NLS-1$
        analysisRecord.println("============================================================================");
    }
    return result;
}
Also used : TempMetadataAdapter(org.teiid.query.metadata.TempMetadataAdapter) AnalysisRecord(org.teiid.query.analysis.AnalysisRecord) Determinism(org.teiid.metadata.FunctionMethod.Determinism) CommandContext(org.teiid.query.util.CommandContext) CreateProcedureCommand(org.teiid.query.sql.proc.CreateProcedureCommand) TempMetadataID(org.teiid.query.metadata.TempMetadataID) TempCapabilitiesFinder(org.teiid.query.metadata.TempCapabilitiesFinder) TeiidRuntimeException(org.teiid.core.TeiidRuntimeException) Insert(org.teiid.query.sql.lang.Insert) QueryResolverException(org.teiid.api.exception.query.QueryResolverException) TeiidProcessingException(org.teiid.core.TeiidProcessingException) RelationalPlanner(org.teiid.query.optimizer.relational.RelationalPlanner) GroupSymbol(org.teiid.query.sql.symbol.GroupSymbol) PreparedPlan(org.teiid.dqp.internal.process.PreparedPlan) Procedure(org.teiid.metadata.Procedure) ProcessorPlan(org.teiid.query.processor.ProcessorPlan) IDGenerator(org.teiid.core.id.IDGenerator) QueryPlannerException(org.teiid.api.exception.query.QueryPlannerException) TempMetadataStore(org.teiid.query.metadata.TempMetadataStore)

Example 7 with Determinism

use of org.teiid.metadata.FunctionMethod.Determinism in project teiid by teiid.

the class TempTableDataManager method handleCachedProcedure.

private TupleSource handleCachedProcedure(final CommandContext context, StoredProcedure proc) throws TeiidComponentException, QueryMetadataException, TeiidProcessingException {
    String fullName = context.getMetadata().getFullName(proc.getProcedureID());
    // $NON-NLS-1$
    LogManager.logDetail(LogConstants.CTX_DQP, "processing cached procedure request for", fullName);
    LinkedList<Object> vals = new LinkedList<Object>();
    for (SPParameter param : proc.getInputParameters()) {
        vals.add(((Constant) param.getExpression()).getValue());
    }
    // collapse the hash to single byte for the key to restrict the possible results to 256
    int hash = vals.hashCode();
    hash |= (hash >>> 16);
    hash |= (hash >>> 8);
    hash &= 0x000000ff;
    final CacheID cid = new CacheID(new ParseInfo(), fullName + hash, context.getVdbName(), context.getVdbVersion(), context.getConnectionId(), context.getUserName());
    cid.setParameters(vals);
    CachedResults results = cache.get(cid);
    if (results != null) {
        TupleBuffer buffer = results.getResults();
        return buffer.createIndexedTupleSource();
    }
    // construct a query with a no cache hint
    final CacheHint hint = proc.getCacheHint();
    proc.setCacheHint(null);
    Option option = new Option();
    option.setNoCache(true);
    option.addNoCacheGroup(fullName);
    proc.setOption(option);
    StoredProcedure cloneProc = (StoredProcedure) proc.clone();
    int i = 0;
    for (SPParameter param : cloneProc.getInputParameters()) {
        param.setExpression(new Reference(i++));
    }
    final QueryProcessor qp = context.getQueryProcessorFactory().createQueryProcessor(cloneProc.toString(), fullName.toUpperCase(), context, vals.toArray());
    final BatchCollector bc = qp.createBatchCollector();
    return new ProxyTupleSource() {

        boolean success = false;

        @Override
        protected TupleSource createTupleSource() throws TeiidComponentException, TeiidProcessingException {
            TupleBuffer tb = bc.collectTuples();
            CachedResults cr = new CachedResults();
            cr.setResults(tb, qp.getProcessorPlan());
            Determinism determinismLevel = qp.getContext().getDeterminismLevel();
            if (hint != null && hint.getDeterminism() != null) {
                // $NON-NLS-1$ //$NON-NLS-2$
                LogManager.logTrace(LogConstants.CTX_DQP, new Object[] { "Cache hint modified the query determinism from ", determinismLevel, " to ", hint.getDeterminism() });
                determinismLevel = hint.getDeterminism();
            }
            cache.put(cid, determinismLevel, cr, hint != null ? hint.getTtl() : null);
            context.setDeterminismLevel(determinismLevel);
            success = true;
            return tb.createIndexedTupleSource();
        }

        @Override
        public void closeSource() {
            super.closeSource();
            qp.closeProcessing();
            if (!success && bc.getTupleBuffer() != null) {
                bc.getTupleBuffer().remove();
            }
        }
    };
}
Also used : Determinism(org.teiid.metadata.FunctionMethod.Determinism) Reference(org.teiid.query.sql.symbol.Reference) TupleBuffer(org.teiid.common.buffer.TupleBuffer) ParseInfo(org.teiid.query.parser.ParseInfo) LinkedList(java.util.LinkedList) CachedResults(org.teiid.dqp.internal.process.CachedResults) QueryProcessor(org.teiid.query.processor.QueryProcessor) CacheID(org.teiid.dqp.internal.process.SessionAwareCache.CacheID) BatchCollector(org.teiid.query.processor.BatchCollector)

Example 8 with Determinism

use of org.teiid.metadata.FunctionMethod.Determinism in project teiid by teiid.

the class TempTableDataManager method loadGlobalTable.

private TupleSource loadGlobalTable(final CommandContext context, final GroupSymbol group, final String tableName, final GlobalTableStore globalStore) throws TeiidComponentException, TeiidProcessingException {
    LogManager.logInfo(LogConstants.CTX_MATVIEWS, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30013, tableName));
    final QueryMetadataInterface metadata = context.getMetadata();
    final List<ElementSymbol> allColumns = ResolverUtil.resolveElementsInGroup(group, metadata);
    final TempTable table = globalStore.createMatTable(tableName, group);
    table.setUpdatable(false);
    return new ProxyTupleSource() {

        TupleSource insertTupleSource;

        boolean success;

        QueryProcessor qp;

        boolean closed;

        boolean errored;

        @Override
        protected TupleSource createTupleSource() throws TeiidComponentException, TeiidProcessingException {
            long rowCount = -1;
            try {
                if (insertTupleSource == null) {
                    String fullName = metadata.getFullName(group.getMetadataID());
                    String transformation = metadata.getVirtualPlan(group.getMetadataID()).getQuery();
                    qp = context.getQueryProcessorFactory().createQueryProcessor(transformation, fullName, context);
                    insertTupleSource = new BatchCollector.BatchProducerTupleSource(qp);
                }
                table.insert(insertTupleSource, allColumns, false, false, null);
                table.getTree().compact();
                rowCount = table.getRowCount();
                Determinism determinism = qp.getContext().getDeterminismLevel();
                context.setDeterminismLevel(determinism);
                // TODO: could pre-process indexes to remove overlap
                for (Object index : metadata.getIndexesInGroup(group.getMetadataID())) {
                    List<ElementSymbol> columns = GlobalTableStoreImpl.resolveIndex(metadata, allColumns, index);
                    table.addIndex(columns, false);
                }
                for (Object key : metadata.getUniqueKeysInGroup(group.getMetadataID())) {
                    List<ElementSymbol> columns = GlobalTableStoreImpl.resolveIndex(metadata, allColumns, key);
                    table.addIndex(columns, true);
                }
                CacheHint hint = table.getCacheHint();
                if (hint != null && table.getPkLength() > 0) {
                    table.setUpdatable(hint.isUpdatable(false));
                }
                if (determinism.compareTo(Determinism.VDB_DETERMINISTIC) < 0 && (hint == null || hint.getScope() == null || Scope.VDB.compareTo(hint.getScope()) <= 0)) {
                    // $NON-NLS-1$
                    LogManager.logInfo(LogConstants.CTX_DQP, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID31143, determinism, tableName));
                }
                globalStore.loaded(tableName, table);
                success = true;
                LogManager.logInfo(LogConstants.CTX_MATVIEWS, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30014, tableName, rowCount));
                return CollectionTupleSource.createUpdateCountTupleSource((int) Math.min(Integer.MAX_VALUE, rowCount));
            } catch (BlockedException e) {
                throw e;
            } catch (Exception e) {
                errored = true;
                if (executor == null || !executor.isShutdown()) {
                    // if we're shutting down, no need to log
                    LogManager.logError(LogConstants.CTX_MATVIEWS, e, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30015, tableName));
                }
                closeSource();
                rethrow(e);
                throw new AssertionError();
            }
        }

        @Override
        public void closeSource() {
            if (closed) {
                return;
            }
            if (!errored && !success) {
                LogManager.logInfo(LogConstants.CTX_MATVIEWS, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID31153, tableName));
            }
            closed = true;
            if (!success) {
                globalStore.failedLoad(tableName);
                table.remove();
            }
            if (qp != null) {
                qp.closeProcessing();
            }
            super.closeSource();
        }
    };
}
Also used : ElementSymbol(org.teiid.query.sql.symbol.ElementSymbol) Determinism(org.teiid.metadata.FunctionMethod.Determinism) BlockedException(org.teiid.common.buffer.BlockedException) QueryProcessor(org.teiid.query.processor.QueryProcessor) QueryProcessingException(org.teiid.api.exception.query.QueryProcessingException) TeiidComponentException(org.teiid.core.TeiidComponentException) TransformationException(org.teiid.core.types.TransformationException) QueryMetadataException(org.teiid.api.exception.query.QueryMetadataException) TeiidProcessingException(org.teiid.core.TeiidProcessingException) BlockedException(org.teiid.common.buffer.BlockedException) RejectedExecutionException(java.util.concurrent.RejectedExecutionException) QueryValidatorException(org.teiid.api.exception.query.QueryValidatorException) ExpressionEvaluationException(org.teiid.api.exception.query.ExpressionEvaluationException) QueryResolverException(org.teiid.api.exception.query.QueryResolverException) TeiidRuntimeException(org.teiid.core.TeiidRuntimeException) CollectionTupleSource(org.teiid.query.processor.CollectionTupleSource) TupleSource(org.teiid.common.buffer.TupleSource) QueryMetadataInterface(org.teiid.query.metadata.QueryMetadataInterface) BatchCollector(org.teiid.query.processor.BatchCollector)

Example 9 with Determinism

use of org.teiid.metadata.FunctionMethod.Determinism in project teiid by teiid.

the class CommandContext method resetDeterminismLevel.

public Determinism resetDeterminismLevel(boolean detach) {
    Determinism result = determinismLevel[0];
    if (detach) {
        determinismLevel = new Determinism[1];
    }
    determinismLevel[0] = Determinism.DETERMINISTIC;
    return result;
}
Also used : Determinism(org.teiid.metadata.FunctionMethod.Determinism)

Aggregations

Determinism (org.teiid.metadata.FunctionMethod.Determinism)9 QueryProcessor (org.teiid.query.processor.QueryProcessor)3 QueryMetadataException (org.teiid.api.exception.query.QueryMetadataException)2 QueryResolverException (org.teiid.api.exception.query.QueryResolverException)2 TupleBuffer (org.teiid.common.buffer.TupleBuffer)2 TeiidComponentException (org.teiid.core.TeiidComponentException)2 TeiidProcessingException (org.teiid.core.TeiidProcessingException)2 TeiidRuntimeException (org.teiid.core.TeiidRuntimeException)2 CacheID (org.teiid.dqp.internal.process.SessionAwareCache.CacheID)2 BatchCollector (org.teiid.query.processor.BatchCollector)2 ProcessorPlan (org.teiid.query.processor.ProcessorPlan)2 ElementSymbol (org.teiid.query.sql.symbol.ElementSymbol)2 ArrayList (java.util.ArrayList)1 HashMap (java.util.HashMap)1 LinkedList (java.util.LinkedList)1 List (java.util.List)1 Map (java.util.Map)1 RejectedExecutionException (java.util.concurrent.RejectedExecutionException)1 ExpressionEvaluationException (org.teiid.api.exception.query.ExpressionEvaluationException)1 QueryPlannerException (org.teiid.api.exception.query.QueryPlannerException)1