use of org.teiid.query.sql.visitor.ExpressionMappingVisitor in project teiid by teiid.
the class RuleCollapseSource method prepareSubquery.
public static void prepareSubquery(SubqueryContainer container) {
RelationalPlan subqueryPlan = (RelationalPlan) container.getCommand().getProcessorPlan();
AccessNode aNode = CriteriaCapabilityValidatorVisitor.getAccessNode(subqueryPlan);
QueryCommand command = CriteriaCapabilityValidatorVisitor.getQueryCommand(aNode);
if (command == null) {
return;
}
final SymbolMap map = container.getCommand().getCorrelatedReferences();
if (map != null) {
ExpressionMappingVisitor visitor = new RuleMergeCriteria.ReferenceReplacementVisitor(map);
DeepPostOrderNavigator.doVisit(command, visitor);
}
command.setProcessorPlan(container.getCommand().getProcessorPlan());
boolean removeLimit = false;
if (container instanceof ExistsCriteria) {
removeLimit = !((ExistsCriteria) container).shouldEvaluate();
} else if (container instanceof ScalarSubquery) {
removeLimit = !((ScalarSubquery) container).shouldEvaluate();
}
if (removeLimit && command.getLimit() != null && command.getLimit().isImplicit()) {
command.setLimit(null);
}
container.setCommand(command);
}
use of org.teiid.query.sql.visitor.ExpressionMappingVisitor in project teiid by teiid.
the class TriggerActionPlanner method rewritePlan.
/**
* look for the simple case of a mapping to a single insert statement trigger action - and reconstruct the plan as a single insert
* TODO: need internal primitives for delete/update batching in a loop for delete/update cases
*/
private ProcessorPlan rewritePlan(TriggerAction ta, IDGenerator idGenerator, QueryMetadataInterface metadata, CapabilitiesFinder capFinder, AnalysisRecord analysisRecord, CommandContext context, QueryCommand query, Map<ElementSymbol, Expression> mapping, Insert insert) throws QueryMetadataException, QueryResolverException, TeiidComponentException, QueryPlannerException {
if (ta.getBlock().getStatements().size() != 1) {
return null;
}
Statement s = ta.getBlock().getStatements().get(0);
if (!(s instanceof CommandStatement)) {
return null;
}
CommandStatement cs = (CommandStatement) s;
if (!(cs.getCommand() instanceof Insert)) {
return null;
}
Insert mapped = (Insert) cs.getCommand();
if (mapped.getQueryExpression() != null) {
return null;
}
if (insert.getQueryExpression() != null) {
// use a unique inline view name to make the final remapping easier
GroupSymbol group = new GroupSymbol("X");
Collection<GroupSymbol> groups = GroupCollectorVisitor.getGroups(query, true);
for (int i = 0; groups.contains(group); i++) {
group.setName("X_" + i);
}
List<Expression> projectedSymbols = query.getProjectedSymbols();
Query queryExpression = QueryRewriter.createInlineViewQuery(group, query, metadata, projectedSymbols);
List<Expression> viewSymbols = new ArrayList<Expression>(queryExpression.getSelect().getSymbols());
// switch to the values
queryExpression.getSelect().clearSymbols();
List<Expression> values = mapped.getValues();
queryExpression.getSelect().addSymbols(values);
values.clear();
// update the mapping to the view symbols
for (int i = 0; i < projectedSymbols.size(); i++) {
ElementSymbol es = insert.getVariables().get(i);
mapping.put(new ElementSymbol(es.getShortName(), new GroupSymbol(SQLConstants.Reserved.NEW)), SymbolMap.getExpression(viewSymbols.get(i)));
}
// map to the query form - changes references back to element form
SymbolMap queryMapping = new SymbolMap();
queryMapping.asUpdatableMap().putAll(mapping);
ExpressionMappingVisitor visitor = new RuleMergeCriteria.ReferenceReplacementVisitor(queryMapping);
DeepPostOrderNavigator.doVisit(queryExpression.getSelect(), visitor);
// now we can return a plan based off a single insert statement
mapped.setQueryExpression(queryExpression);
return QueryOptimizer.optimizePlan(mapped, metadata, idGenerator, capFinder, analysisRecord, context);
}
List<Expression> values = mapped.getValues();
SymbolMap queryMapping = new SymbolMap();
queryMapping.asUpdatableMap().putAll(mapping);
ExpressionMappingVisitor visitor = new RuleMergeCriteria.ReferenceReplacementVisitor(queryMapping);
Select select = new Select();
select.addSymbols(values);
DeepPostOrderNavigator.doVisit(select, visitor);
values.clear();
for (Expression ex : select.getSymbols()) {
try {
values.add(QueryRewriter.rewriteExpression(SymbolMap.getExpression(ex), context, metadata));
} catch (TeiidProcessingException e) {
throw new QueryPlannerException(e);
}
}
return QueryOptimizer.optimizePlan(mapped, metadata, idGenerator, capFinder, analysisRecord, context);
}
use of org.teiid.query.sql.visitor.ExpressionMappingVisitor in project teiid by teiid.
the class QueryRewriter method rewriteForWriteThrough.
private Command rewriteForWriteThrough(ProcedureContainer update) throws TeiidComponentException, QueryMetadataException, QueryResolverException, TeiidProcessingException {
if (processing || update.hasTag(WRITE_THROUGH) || !metadata.hasMaterialization(update.getGroup().getMetadataID()) || !Boolean.valueOf(metadata.getExtensionProperty(update.getGroup().getMetadataID(), MaterializationMetadataRepository.MATVIEW_WRITE_THROUGH, false))) {
return null;
}
// internal
// update view ... where predicate - mark as write through
// loop on (select pk from view where predicate) - mark as write through, it's ok that this will use cache
// refreshMatView ...
// end
// external
// update view ... where predicate - mark as write through
// update target ... where predicate - mark as write through
Block block = new Block();
block.setAtomic(true);
ProcedureContainer clone = (ProcedureContainer) update.clone();
// $NON-NLS-1$
GroupSymbol temp = new GroupSymbol("#temp");
if (context.getGroups().contains(temp.getName())) {
temp = RulePlaceAccess.recontextSymbol(temp, context.getGroups());
temp.setDefinition(null);
}
Query q = new Query();
q.setSelect(new Select(Arrays.asList(new MultipleElementSymbol())));
q.setFrom(new From(Arrays.asList(new UnaryFromClause(temp))));
update.addTag(WRITE_THROUGH);
block.addStatement(new CommandStatement(update));
ElementSymbol rowCount = new ElementSymbol(ProcedureReservedWords.ROWCOUNT);
// $NON-NLS-1$
ElementSymbol val = new ElementSymbol("val");
DeclareStatement ds = new DeclareStatement(val, DataTypeManager.DefaultDataTypes.INTEGER, rowCount);
block.addStatement(ds);
final Object gid = update.getGroup().getMetadataID();
Object target = metadata.getMaterialization(gid);
if (target != null) {
final GroupSymbol newGroup = new GroupSymbol(metadata.getFullName(target));
newGroup.setMetadataID(target);
ExpressionMappingVisitor emv = new ExpressionMappingVisitor(null) {
public Expression replaceExpression(Expression element) {
if (element instanceof ElementSymbol) {
ElementSymbol es = (ElementSymbol) element;
if (es.getGroupSymbol().getMetadataID() == gid) {
es.setGroupSymbol(newGroup);
}
}
return element;
}
};
if (clone instanceof Update) {
Update u = (Update) clone;
for (SetClause sc : u.getChangeList().getClauses()) {
sc.setSymbol(new ElementSymbol(sc.getSymbol().getShortName(), newGroup.clone()));
PreOrPostOrderNavigator.doVisit(sc, emv, PreOrPostOrderNavigator.POST_ORDER);
}
u.setGroup(newGroup);
} else {
((Delete) clone).setGroup(newGroup);
}
PreOrPostOrderNavigator.doVisit(((FilteredCommand) clone).getCriteria(), emv, PreOrPostOrderNavigator.POST_ORDER);
clone.setUpdateInfo(null);
clone.addTag(WRITE_THROUGH);
block.addStatement(new CommandStatement(clone));
} else {
Object key = metadata.getPrimaryKey(update.getGroup().getMetadataID());
if (key == null) {
// we need a key for this logic to work
return null;
}
Block b = new Block();
List<Object> ids = metadata.getElementIDsInKey(key);
Select select = new Select();
for (Object id : ids) {
select.addSymbol(new ElementSymbol(metadata.getName(id)));
}
if (clone instanceof Update) {
Update u = (Update) clone;
for (SetClause sc : u.getChangeList().getClauses()) {
if (ids.contains(sc.getSymbol().getMetadataID())) {
// corner case of an update manipulating the primary key
return null;
}
}
}
Query keys = new Query();
keys.setSelect(select);
keys.setFrom(new From(Arrays.asList(new UnaryFromClause(update.getGroup()))));
if (((FilteredCommand) clone).getCriteria() != null) {
keys.setCriteria((Criteria) ((FilteredCommand) clone).getCriteria().clone());
}
// $NON-NLS-1$
LoopStatement loop = new LoopStatement(b, keys, "x");
StoredProcedure sp = new StoredProcedure();
// $NON-NLS-1$
sp.setProcedureName("SYSAdmin.refreshMatViewRow");
sp.setParameter(new SPParameter(1, new Constant(metadata.getFullName(update.getGroup().getMetadataID()))));
int index = 2;
for (Object id : ids) {
sp.setParameter(new SPParameter(index++, new ElementSymbol(metadata.getName(id))));
}
b.addStatement(new CommandStatement(sp));
block.addStatement(loop);
}
Query result = new Query();
result.setSelect(new Select(Arrays.asList(val)));
block.addStatement(new CommandStatement(result));
CreateProcedureCommand command = new CreateProcedureCommand(block);
QueryResolver.resolveCommand(command, metadata);
return rewriteCommand(command, false);
}
use of org.teiid.query.sql.visitor.ExpressionMappingVisitor in project teiid by teiid.
the class QueryRewriter method rewriteInherentDelete.
private Command rewriteInherentDelete(Delete delete, UpdateInfo info) throws QueryMetadataException, TeiidComponentException, QueryResolverException, TeiidProcessingException {
UpdateMapping mapping = info.getDeleteTarget();
if (info.isSimple()) {
Collection<ElementSymbol> elements = getAllElementsUsed(delete, delete.getGroup());
UpdateMapping fullMapping = info.findUpdateMapping(elements, false);
if (fullMapping != null) {
delete.setGroup(mapping.getGroup().clone());
// TODO: properly handle correlated references
DeepPostOrderNavigator.doVisit(delete, new ExpressionMappingVisitor(mapping.getUpdatableViewSymbols(), true));
delete.setUpdateInfo(ProcedureContainerResolver.getUpdateInfo(delete.getGroup(), metadata, Command.TYPE_DELETE, true));
if (info.getViewDefinition().getCriteria() != null) {
delete.setCriteria(Criteria.combineCriteria(delete.getCriteria(), (Criteria) info.getViewDefinition().getCriteria().clone()));
}
return rewriteDelete(delete);
}
}
Query query = (Query) info.getViewDefinition().clone();
query.setOrderBy(null);
SymbolMap expressionMapping = SymbolMap.createSymbolMap(delete.getGroup(), query.getProjectedSymbols(), metadata);
query.setSelect(new Select());
ExpressionMappingVisitor emv = new ExpressionMappingVisitor(expressionMapping.asMap(), true);
Criteria crit = delete.getCriteria();
if (crit != null) {
PostOrderNavigator.doVisit(crit, emv);
query.setCriteria(Criteria.combineCriteria(query.getCriteria(), crit));
}
GroupSymbol group = mapping.getGroup();
String correlationName = mapping.getCorrelatedName().getName();
return createDeleteProcedure(delete, query, group, correlationName);
}
use of org.teiid.query.sql.visitor.ExpressionMappingVisitor in project teiid by teiid.
the class QueryRewriter method rewriteInherentUpdate.
private Command rewriteInherentUpdate(Update update, UpdateInfo info) throws QueryValidatorException, QueryMetadataException, TeiidComponentException, QueryResolverException, TeiidProcessingException {
UpdateMapping mapping = info.findUpdateMapping(update.getChangeList().getClauseMap().keySet(), false);
if (mapping == null) {
throw new QueryValidatorException(QueryPlugin.Event.TEIID30376, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30376, update.getChangeList().getClauseMap().keySet()));
}
Map<ElementSymbol, ElementSymbol> symbolMap = mapping.getUpdatableViewSymbols();
if (info.isSimple()) {
Collection<ElementSymbol> elements = getAllElementsUsed(update, update.getGroup());
UpdateMapping fullMapping = info.findUpdateMapping(elements, false);
if (fullMapping != null) {
update.setGroup(mapping.getGroup().clone());
for (SetClause clause : update.getChangeList().getClauses()) {
clause.setSymbol(symbolMap.get(clause.getSymbol()));
}
// TODO: properly handle correlated references
DeepPostOrderNavigator.doVisit(update, new ExpressionMappingVisitor(symbolMap, true));
if (info.getViewDefinition().getCriteria() != null) {
update.setCriteria(Criteria.combineCriteria(update.getCriteria(), (Criteria) info.getViewDefinition().getCriteria().clone()));
}
// resolve
update.setUpdateInfo(ProcedureContainerResolver.getUpdateInfo(update.getGroup(), metadata, Command.TYPE_UPDATE, true));
return rewriteUpdate(update);
}
}
Query query = (Query) info.getViewDefinition().clone();
query.setOrderBy(null);
SymbolMap expressionMapping = SymbolMap.createSymbolMap(update.getGroup(), query.getProjectedSymbols(), metadata);
SetClauseList setClauseList = (SetClauseList) update.getChangeList().clone();
GroupSymbol varGroup = getVarGroup(update);
ArrayList<Expression> selectSymbols = mapChangeList(setClauseList, symbolMap, varGroup);
query.setSelect(new Select(selectSymbols));
ExpressionMappingVisitor emv = new ExpressionMappingVisitor(expressionMapping.asMap(), true);
PostOrderNavigator.doVisit(query.getSelect(), emv);
Criteria crit = update.getCriteria();
if (crit != null) {
PostOrderNavigator.doVisit(crit, emv);
query.setCriteria(Criteria.combineCriteria(query.getCriteria(), crit));
}
GroupSymbol group = mapping.getGroup();
String correlationName = mapping.getCorrelatedName().getName();
return createUpdateProcedure(update, query, group, correlationName, setClauseList, varGroup, null);
}
Aggregations