Search in sources :

Example 26 with TempMetadataAdapter

use of org.teiid.query.metadata.TempMetadataAdapter in project teiid by teiid.

the class RelationalPlanner method addNestedCommand.

private void addNestedCommand(PlanNode node, GroupSymbol group, Command nestedCommand, Command toPlan, boolean merge, boolean isStackEntry) throws TeiidComponentException, QueryMetadataException, TeiidProcessingException {
    if (nestedCommand instanceof QueryCommand) {
        // remove unnecessary order by
        QueryCommand queryCommand = (QueryCommand) nestedCommand;
        if (queryCommand.getLimit() == null) {
            queryCommand.setOrderBy(null);
        }
    }
    Set<PlanningStackEntry> entries = null;
    PlanningStackEntry entry = null;
    if (isStackEntry) {
        entries = planningStack.get();
        entry = createPlanningStackEntry(group, nestedCommand, toPlan.getType() == Command.TYPE_UPDATE_PROCEDURE, entries);
    }
    try {
        node.setProperty(NodeConstants.Info.NESTED_COMMAND, nestedCommand);
        if (merge) {
            mergeTempMetadata(nestedCommand, parentCommand);
            PlanNode childRoot = generatePlan(nestedCommand);
            node.addFirstChild(childRoot);
            List<Expression> projectCols = nestedCommand.getProjectedSymbols();
            SymbolMap map = SymbolMap.createSymbolMap(group, projectCols, metadata);
            node.setProperty(NodeConstants.Info.SYMBOL_MAP, map);
        } else {
            QueryMetadataInterface actualMetadata = metadata;
            if (actualMetadata instanceof TempMetadataAdapter) {
                actualMetadata = ((TempMetadataAdapter) metadata).getMetadata();
            }
            ProcessorPlan plan = QueryOptimizer.optimizePlan(toPlan, actualMetadata, idGenerator, capFinder, analysisRecord, context);
            // hack for the optimizer not knowing the containing command when forming the plan
            if (nestedCommand instanceof StoredProcedure && plan instanceof ProcedurePlan) {
                StoredProcedure container = (StoredProcedure) nestedCommand;
                ProcedurePlan pp = (ProcedurePlan) plan;
                pp.setUpdateCount(container.getUpdateCount());
                if (container.returnParameters()) {
                    List<ElementSymbol> outParams = new LinkedList<ElementSymbol>();
                    for (SPParameter param : container.getParameters()) {
                        if (param.getParameterType() == SPParameter.RETURN_VALUE) {
                            outParams.add(param.getParameterSymbol());
                        }
                    }
                    for (SPParameter param : container.getParameters()) {
                        if (param.getParameterType() == SPParameter.INOUT || param.getParameterType() == SPParameter.OUT) {
                            outParams.add(param.getParameterSymbol());
                        }
                    }
                    if (outParams.size() > 0) {
                        pp.setOutParams(outParams);
                    }
                }
                pp.setParams(container.getProcedureParameters());
            }
            node.setProperty(NodeConstants.Info.PROCESSOR_PLAN, plan);
        }
    } finally {
        if (entries != null) {
            entries.remove(entry);
        }
    }
}
Also used : TempMetadataAdapter(org.teiid.query.metadata.TempMetadataAdapter) SymbolMap(org.teiid.query.sql.util.SymbolMap) PlanNode(org.teiid.query.optimizer.relational.plantree.PlanNode) ProcedurePlan(org.teiid.query.processor.proc.ProcedurePlan) QueryMetadataInterface(org.teiid.query.metadata.QueryMetadataInterface) ProcessorPlan(org.teiid.query.processor.ProcessorPlan)

Example 27 with TempMetadataAdapter

use of org.teiid.query.metadata.TempMetadataAdapter in project teiid by teiid.

the class MetaDataProcessor method processMessage.

/**
 * Process a metadata request message - this is typically either a request
 * for metadata for a prepared statement or a request for full metadata from
 * an already processed command.
 * @param metadataMsg The message from the client
 * @return The message for the client
 * @throws TeiidComponentException
 * @throws TeiidProcessingException
 */
MetadataResult processMessage(RequestID requestId, DQPWorkContext workContext, String preparedSql, boolean allowDoubleQuotedVariable) throws TeiidComponentException, TeiidProcessingException {
    this.requestID = requestId;
    this.metadata = workContext.getVDB().getAttachment(QueryMetadataInterface.class);
    RequestWorkItem workItem = null;
    try {
        workItem = requestManager.getRequestWorkItem(requestID);
    } catch (TeiidProcessingException e) {
        if (preparedSql == null) {
            throw e;
        }
    }
    TempTableStore tempTableStore = null;
    if (requestManager != null) {
        ClientState state = requestManager.getClientState(workContext.getSessionId(), false);
        if (state != null) {
            tempTableStore = state.sessionTables;
        }
    }
    if (tempTableStore != null) {
        metadata = new TempMetadataAdapter(this.metadata, tempTableStore.getMetadataStore());
    }
    if (workItem != null) {
        return getMetadataForCommand(workItem.getOriginalCommand());
    }
    return obtainMetadataForPreparedSql(preparedSql, workContext, allowDoubleQuotedVariable);
}
Also used : TempMetadataAdapter(org.teiid.query.metadata.TempMetadataAdapter) TempTableStore(org.teiid.query.tempdata.TempTableStore) QueryMetadataInterface(org.teiid.query.metadata.QueryMetadataInterface) TeiidProcessingException(org.teiid.core.TeiidProcessingException)

Example 28 with TempMetadataAdapter

use of org.teiid.query.metadata.TempMetadataAdapter in project teiid by teiid.

the class RulePushAggregates method defineNewGroup.

static List<ElementSymbol> defineNewGroup(GroupSymbol group, List<? extends Expression> virtualElements, QueryMetadataInterface metadata) throws TeiidComponentException, QueryMetadataException {
    TempMetadataStore store = new TempMetadataStore();
    TempMetadataAdapter tma = new TempMetadataAdapter(metadata, store);
    try {
        group.setMetadataID(ResolverUtil.addTempGroup(tma, group, virtualElements, false));
    } catch (QueryResolverException e) {
        throw new TeiidComponentException(QueryPlugin.Event.TEIID30265, e);
    }
    List<ElementSymbol> projectedSymbols = ResolverUtil.resolveElementsInGroup(group, metadata);
    return projectedSymbols;
}
Also used : TempMetadataAdapter(org.teiid.query.metadata.TempMetadataAdapter) TeiidComponentException(org.teiid.core.TeiidComponentException) TempMetadataStore(org.teiid.query.metadata.TempMetadataStore) QueryResolverException(org.teiid.api.exception.query.QueryResolverException)

Example 29 with TempMetadataAdapter

use of org.teiid.query.metadata.TempMetadataAdapter in project teiid by teiid.

the class RelationalPlanner method buildGroupingNode.

/**
 * Build a grouping node that introduces a anon group (without a inline view source node)
 */
public static SymbolMap buildGroupingNode(Collection<AggregateSymbol> aggs, List<? extends Expression> groupingCols, PlanNode groupNode, CommandContext cc, IDGenerator idGenerator) throws QueryMetadataException, TeiidComponentException {
    SymbolMap map = new SymbolMap();
    aggs = LanguageObject.Util.deepClone(aggs, AggregateSymbol.class);
    groupingCols = LanguageObject.Util.deepClone(groupingCols, Expression.class);
    // $NON-NLS-1$
    GroupSymbol group = new GroupSymbol("anon_grp" + idGenerator.nextInt());
    if (!cc.getGroups().add(group.getName())) {
        group = RulePlaceAccess.recontextSymbol(group, cc.getGroups());
    }
    TempMetadataStore tms = new TempMetadataStore();
    int i = 0;
    List<AliasSymbol> symbols = new LinkedList<AliasSymbol>();
    List<Expression> targets = new LinkedList<Expression>();
    if (groupingCols != null) {
        groupNode.setProperty(NodeConstants.Info.GROUP_COLS, groupingCols);
        groupNode.addGroups(GroupsUsedByElementsVisitor.getGroups(groupingCols));
        for (Expression ex : groupingCols) {
            // $NON-NLS-1$ //$NON-NLS-2$
            AliasSymbol as = new AliasSymbol("gcol" + i++, new ExpressionSymbol("expr", ex));
            targets.add(ex);
            symbols.add(as);
        }
    }
    i = 0;
    for (AggregateSymbol ex : aggs) {
        // $NON-NLS-1$ //$NON-NLS-2$
        AliasSymbol as = new AliasSymbol("agg" + i++, new ExpressionSymbol("expr", ex));
        targets.add(ex);
        symbols.add(as);
    }
    group.setMetadataID(tms.addTempGroup(group.getName(), symbols, true, false));
    Iterator<Expression> targetIter = targets.iterator();
    for (ElementSymbol es : ResolverUtil.resolveElementsInGroup(group, new TempMetadataAdapter(new BasicQueryMetadata(), tms))) {
        Expression target = targetIter.next();
        es.setAggregate(target instanceof AggregateSymbol);
        map.addMapping(es, target);
    }
    groupNode.setProperty(NodeConstants.Info.SYMBOL_MAP, map);
    groupNode.addGroup(group);
    return map;
}
Also used : TempMetadataAdapter(org.teiid.query.metadata.TempMetadataAdapter) SymbolMap(org.teiid.query.sql.util.SymbolMap) BasicQueryMetadata(org.teiid.query.metadata.BasicQueryMetadata) TempMetadataStore(org.teiid.query.metadata.TempMetadataStore)

Example 30 with TempMetadataAdapter

use of org.teiid.query.metadata.TempMetadataAdapter 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)

Aggregations

TempMetadataAdapter (org.teiid.query.metadata.TempMetadataAdapter)53 TempMetadataStore (org.teiid.query.metadata.TempMetadataStore)45 Test (org.junit.Test)32 ProcessorPlan (org.teiid.query.processor.ProcessorPlan)32 Ignore (org.junit.Ignore)21 QueryMetadataInterface (org.teiid.query.metadata.QueryMetadataInterface)9 CommandContext (org.teiid.query.util.CommandContext)6 List (java.util.List)4 QueryResolverException (org.teiid.api.exception.query.QueryResolverException)4 TempMetadataID (org.teiid.query.metadata.TempMetadataID)4 Command (org.teiid.query.sql.lang.Command)4 GroupSymbol (org.teiid.query.sql.symbol.GroupSymbol)4 TeiidComponentException (org.teiid.core.TeiidComponentException)3 TeiidProcessingException (org.teiid.core.TeiidProcessingException)3 AnalysisRecord (org.teiid.query.analysis.AnalysisRecord)3 TempCapabilitiesFinder (org.teiid.query.metadata.TempCapabilitiesFinder)3 TransformationMetadata (org.teiid.query.metadata.TransformationMetadata)3 GroupContext (org.teiid.query.sql.lang.GroupContext)3 TempTableStore (org.teiid.query.tempdata.TempTableStore)3 ArrayList (java.util.ArrayList)2