Search in sources :

Example 1 with Trigger

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

Aggregations

ArrayList (java.util.ArrayList)1 HashMap (java.util.HashMap)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 ProcessorPlan (org.teiid.query.processor.ProcessorPlan)1 ForEachRowPlan (org.teiid.query.processor.proc.ForEachRowPlan)1 ProcedurePlan (org.teiid.query.processor.proc.ProcedurePlan)1 CreateProcedureCommand (org.teiid.query.sql.proc.CreateProcedureCommand)1 TriggerAction (org.teiid.query.sql.proc.TriggerAction)1 Constant (org.teiid.query.sql.symbol.Constant)1 ElementSymbol (org.teiid.query.sql.symbol.ElementSymbol)1 Expression (org.teiid.query.sql.symbol.Expression)1 GroupSymbol (org.teiid.query.sql.symbol.GroupSymbol)1