Search in sources :

Example 1 with ForEachRowPlan

use of org.teiid.query.processor.proc.ForEachRowPlan in project teiid by teiid.

the class SourceTriggerActionPlanner method optimize.

@Override
public ProcessorPlan optimize(Command command, IDGenerator idGenerator, QueryMetadataInterface metadata, CapabilitiesFinder capFinder, AnalysisRecord analysisRecord, CommandContext context) throws QueryPlannerException, QueryMetadataException, TeiidComponentException {
    SourceEventCommand sec = (SourceEventCommand) command;
    Map<Expression, Integer> lookup = new HashMap<Expression, Integer>();
    Map<ElementSymbol, Expression> params = new HashMap<ElementSymbol, Expression>();
    List<Object> tuple = new ArrayList<Object>();
    Map<String, Integer> map = null;
    if (sec.getColumnNames() != null) {
        map = new TreeMap<String, Integer>(String.CASE_INSENSITIVE_ORDER);
        for (String name : sec.getColumnNames()) {
            map.put(name, map.size());
        }
    }
    GroupSymbol changingGroup = new GroupSymbol(ProcedureReservedWords.CHANGING);
    if (sec.newValues != null) {
        GroupSymbol newGroup = new GroupSymbol(SQLConstants.Reserved.NEW);
        newGroup.setMetadataID(sec.table);
        for (int i = 0; i < sec.getTable().getColumns().size(); i++) {
            Column c = sec.getTable().getColumns().get(i);
            Integer index = null;
            if (map != null) {
                index = map.get(c.getName());
            } else {
                index = i;
            }
            ElementSymbol newElement = new ElementSymbol(c.getName(), newGroup);
            newElement.setMetadataID(c);
            ElementSymbol changingElement = new ElementSymbol(c.getName(), changingGroup);
            lookup.put(newElement, tuple.size());
            lookup.put(changingElement, tuple.size() + 1);
            params.put(newElement, newElement);
            params.put(changingElement, changingElement);
            if (index == null) {
                // not changing
                tuple.add(new Constant(null));
                tuple.add(new Constant(Boolean.FALSE));
            } else {
                // changing
                tuple.add(new Constant(DataTypeManager.convertToRuntimeType(sec.newValues[index], true)));
                tuple.add(new Constant(Boolean.TRUE));
            }
        }
    }
    if (sec.oldValues != null) {
        GroupSymbol oldGroup = new GroupSymbol(SQLConstants.Reserved.OLD);
        oldGroup.setMetadataID(sec.table);
        for (int i = 0; i < sec.getTable().getColumns().size(); i++) {
            Column c = sec.getTable().getColumns().get(i);
            Integer index = null;
            if (map != null) {
                index = map.get(c.getName());
            } else {
                index = i;
            }
            ElementSymbol oldElement = new ElementSymbol(c.getName(), oldGroup);
            oldElement.setMetadataID(c);
            lookup.put(oldElement, tuple.size());
            params.put(oldElement, oldElement);
            if (index != null) {
                tuple.add(new Constant(DataTypeManager.convertToRuntimeType(sec.oldValues[index], true)));
            }
        }
    }
    List<ProcessorPlan> plans = new ArrayList<ProcessorPlan>();
    List<String> names = new ArrayList<String>();
    for (Trigger tr : sec.getTable().getTriggers().values()) {
        int updateType = Command.TYPE_UPDATE;
        switch(tr.getEvent()) {
            case DELETE:
                updateType = Command.TYPE_DELETE;
                if (sec.newValues != null) {
                    continue;
                }
                break;
            case INSERT:
                updateType = Command.TYPE_INSERT;
                if (sec.oldValues != null) {
                    continue;
                }
                break;
            case UPDATE:
                if (sec.oldValues == null || sec.newValues == null) {
                    continue;
                }
                break;
        }
        // create plan
        ForEachRowPlan result = new ForEachRowPlan();
        result.setSingleRow(true);
        result.setParams(params);
        TriggerAction parseProcedure;
        GroupSymbol gs = new GroupSymbol(sec.table.getFullName());
        try {
            parseProcedure = (TriggerAction) QueryParser.getQueryParser().parseProcedure(tr.getPlan(), true);
            QueryResolver.resolveCommand(parseProcedure, gs, updateType, metadata.getDesignTimeMetadata(), false);
        } catch (QueryParserException e) {
            // should have been validated
            throw new TeiidComponentException(e);
        } catch (QueryResolverException e) {
            // should have been validated
            throw new TeiidComponentException(e);
        }
        CreateProcedureCommand cpc = new CreateProcedureCommand(parseProcedure.getBlock());
        gs.setMetadataID(sec.table);
        cpc.setVirtualGroup(gs);
        cpc.setUpdateType(updateType);
        ProcedurePlan rowProcedure = (ProcedurePlan) QueryOptimizer.optimizePlan(cpc, metadata, idGenerator, capFinder, analysisRecord, context);
        rowProcedure.setRunInContext(false);
        result.setRowProcedure(rowProcedure);
        result.setLookupMap(lookup);
        result.setTupleSource(new CollectionTupleSource(Arrays.asList(tuple).iterator()));
        plans.add(result);
        names.add(tr.getName());
    }
    return new CompositeProcessorPlan(plans, names, sec.table);
}
Also used : ElementSymbol(org.teiid.query.sql.symbol.ElementSymbol) QueryParserException(org.teiid.api.exception.query.QueryParserException) TriggerAction(org.teiid.query.sql.proc.TriggerAction) CreateProcedureCommand(org.teiid.query.sql.proc.CreateProcedureCommand) HashMap(java.util.HashMap) Constant(org.teiid.query.sql.symbol.Constant) ArrayList(java.util.ArrayList) CollectionTupleSource(org.teiid.query.processor.CollectionTupleSource) QueryResolverException(org.teiid.api.exception.query.QueryResolverException) Trigger(org.teiid.metadata.Trigger) Column(org.teiid.metadata.Column) ForEachRowPlan(org.teiid.query.processor.proc.ForEachRowPlan) Expression(org.teiid.query.sql.symbol.Expression) ProcedurePlan(org.teiid.query.processor.proc.ProcedurePlan) GroupSymbol(org.teiid.query.sql.symbol.GroupSymbol) TeiidComponentException(org.teiid.core.TeiidComponentException) ProcessorPlan(org.teiid.query.processor.ProcessorPlan)

Example 2 with ForEachRowPlan

use of org.teiid.query.processor.proc.ForEachRowPlan in project teiid by teiid.

the class TriggerActionPlanner method optimize.

public ProcessorPlan optimize(ProcedureContainer userCommand, TriggerAction ta, IDGenerator idGenerator, QueryMetadataInterface metadata, CapabilitiesFinder capFinder, AnalysisRecord analysisRecord, CommandContext context) throws QueryMetadataException, TeiidComponentException, QueryResolverException, TeiidProcessingException {
    // TODO consider caching the plans without using the changing vars
    QueryRewriter.rewrite(ta, metadata, context, QueryResolver.getVariableValues(userCommand, true, metadata));
    QueryCommand query = null;
    Map<ElementSymbol, Expression> params = new HashMap<ElementSymbol, Expression>();
    Map<ElementSymbol, Expression> mapping = QueryResolver.getVariableValues(userCommand, false, metadata);
    for (Map.Entry<ElementSymbol, Expression> entry : mapping.entrySet()) {
        entry.setValue(QueryRewriter.rewriteExpression(entry.getValue(), context, metadata));
    }
    boolean singleRow = false;
    if (userCommand instanceof Insert) {
        Insert insert = (Insert) userCommand;
        if (insert.getQueryExpression() != null) {
            query = insert.getQueryExpression();
        } else {
            singleRow = true;
            query = new Query();
            ((Query) query).setSelect(new Select(RuleChooseJoinStrategy.createExpressionSymbols(insert.getValues())));
        }
        ProcessorPlan plan = rewritePlan(ta, idGenerator, metadata, capFinder, analysisRecord, context, query, mapping, insert);
        if (plan != null) {
            return plan;
        }
    } else if (userCommand instanceof Delete) {
        query = createOldQuery(userCommand, ta, metadata, params);
    } else if (userCommand instanceof Update) {
        query = createOldQuery(userCommand, ta, metadata, params);
    } else {
        throw new AssertionError();
    }
    for (Map.Entry<ElementSymbol, Expression> entry : mapping.entrySet()) {
        Expression value = entry.getValue();
        params.put(entry.getKey(), value);
        if (entry.getKey().getGroupSymbol().getShortName().equalsIgnoreCase(SQLConstants.Reserved.NEW) && userCommand instanceof Update) {
            ((Query) query).getSelect().addSymbol(value);
        }
    }
    ForEachRowPlan result = new ForEachRowPlan();
    result.setSingleRow(singleRow);
    result.setParams(params);
    ProcessorPlan queryPlan = QueryOptimizer.optimizePlan(query, metadata, idGenerator, capFinder, analysisRecord, context);
    result.setQueryPlan(queryPlan);
    result.setLookupMap(RelationalNode.createLookupMap(query.getProjectedSymbols()));
    CreateProcedureCommand command = new CreateProcedureCommand(ta.getBlock());
    command.setVirtualGroup(ta.getView());
    command.setUpdateType(userCommand.getType());
    ProcedurePlan rowProcedure = (ProcedurePlan) QueryOptimizer.optimizePlan(command, metadata, idGenerator, capFinder, analysisRecord, context);
    rowProcedure.setRunInContext(false);
    result.setRowProcedure(rowProcedure);
    return result;
}
Also used : ElementSymbol(org.teiid.query.sql.symbol.ElementSymbol) CreateProcedureCommand(org.teiid.query.sql.proc.CreateProcedureCommand) HashMap(java.util.HashMap) ForEachRowPlan(org.teiid.query.processor.proc.ForEachRowPlan) Expression(org.teiid.query.sql.symbol.Expression) ProcedurePlan(org.teiid.query.processor.proc.ProcedurePlan) ProcessorPlan(org.teiid.query.processor.ProcessorPlan) HashMap(java.util.HashMap) Map(java.util.Map) SymbolMap(org.teiid.query.sql.util.SymbolMap)

Aggregations

HashMap (java.util.HashMap)2 ProcessorPlan (org.teiid.query.processor.ProcessorPlan)2 ForEachRowPlan (org.teiid.query.processor.proc.ForEachRowPlan)2 ProcedurePlan (org.teiid.query.processor.proc.ProcedurePlan)2 CreateProcedureCommand (org.teiid.query.sql.proc.CreateProcedureCommand)2 ElementSymbol (org.teiid.query.sql.symbol.ElementSymbol)2 Expression (org.teiid.query.sql.symbol.Expression)2 ArrayList (java.util.ArrayList)1 Map (java.util.Map)1 QueryParserException (org.teiid.api.exception.query.QueryParserException)1 QueryResolverException (org.teiid.api.exception.query.QueryResolverException)1 TeiidComponentException (org.teiid.core.TeiidComponentException)1 Column (org.teiid.metadata.Column)1 Trigger (org.teiid.metadata.Trigger)1 CollectionTupleSource (org.teiid.query.processor.CollectionTupleSource)1 TriggerAction (org.teiid.query.sql.proc.TriggerAction)1 Constant (org.teiid.query.sql.symbol.Constant)1 GroupSymbol (org.teiid.query.sql.symbol.GroupSymbol)1 SymbolMap (org.teiid.query.sql.util.SymbolMap)1