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