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);
}
Aggregations