use of org.teiid.query.optimizer.TriggerActionPlanner in project teiid by teiid.
the class RelationalPlanner method addNestedProcedure.
private boolean addNestedProcedure(PlanNode sourceNode, ProcedureContainer container, Object metadataId) throws TeiidComponentException, QueryMetadataException, TeiidProcessingException {
if (container instanceof StoredProcedure) {
StoredProcedure sp = (StoredProcedure) container;
if (sp.getProcedureID() instanceof Procedure) {
context.accessedPlanningObject(sp.getProcedureID());
}
}
for (SubqueryContainer<?> subqueryContainer : ValueIteratorProviderCollectorVisitor.getValueIteratorProviders(container)) {
if (subqueryContainer.getCommand().getCorrelatedReferences() != null) {
continue;
}
List<Reference> correlatedReferences = new ArrayList<Reference>();
CorrelatedReferenceCollectorVisitor.collectReferences(subqueryContainer.getCommand(), Arrays.asList(container.getGroup()), correlatedReferences, metadata);
setCorrelatedReferences(subqueryContainer, correlatedReferences);
}
// $NON-NLS-1$
String cacheString = "transformation/" + container.getClass().getSimpleName().toUpperCase();
Command c = (Command) metadata.getFromMetadataCache(metadataId, cacheString);
if (c == null) {
c = QueryResolver.expandCommand(container, metadata, analysisRecord);
if (c != null) {
if (c instanceof CreateProcedureCommand) {
// TODO: find a better way to do this
((CreateProcedureCommand) c).setProjectedSymbols(container.getProjectedSymbols());
}
Request.validateWithVisitor(new ValidationVisitor(), metadata, c);
metadata.addToMetadataCache(metadataId, cacheString, c.clone());
}
} else {
c = (Command) c.clone();
if (c instanceof CreateProcedureCommand) {
// TODO: find a better way to do this
((CreateProcedureCommand) c).setProjectedSymbols(container.getProjectedSymbols());
}
}
boolean checkRowBasedSecurity = true;
if (!container.getGroup().isProcedure() && !metadata.isVirtualGroup(metadataId)) {
Set<PlanningStackEntry> entries = planningStack.get();
if (entries.contains(new PlanningStackEntry(container, container.getGroup()))) {
checkRowBasedSecurity = false;
}
}
if (checkRowBasedSecurity) {
c = RowBasedSecurityHelper.checkUpdateRowBasedFilters(container, c, this);
}
if (c != null) {
if (c instanceof TriggerAction) {
TriggerAction ta = (TriggerAction) c;
ProcessorPlan plan = new TriggerActionPlanner().optimize((ProcedureContainer) container.clone(), ta, idGenerator, metadata, capFinder, analysisRecord, context);
sourceNode.setProperty(NodeConstants.Info.PROCESSOR_PLAN, plan);
return true;
}
if (c.getCacheHint() != null) {
if (container instanceof StoredProcedure) {
StoredProcedure sp = (StoredProcedure) container;
boolean noCache = isNoCacheGroup(metadata, sp.getProcedureID(), option);
if (!noCache) {
if (!context.isResultSetCacheEnabled()) {
// $NON-NLS-1$ //$NON-NLS-2$
recordAnnotation(analysisRecord, Annotation.CACHED_PROCEDURE, Priority.MEDIUM, "SimpleQueryResolver.procedure_cache_not_usable", container.getGroup(), "result set cache disabled");
} else if (!container.areResultsCachable()) {
// $NON-NLS-1$ //$NON-NLS-2$
recordAnnotation(analysisRecord, Annotation.CACHED_PROCEDURE, Priority.MEDIUM, "SimpleQueryResolver.procedure_cache_not_usable", container.getGroup(), "procedure performs updates");
} else if (LobManager.getLobIndexes(new ArrayList<ElementSymbol>(sp.getProcedureParameters().keySet())) != null) {
// $NON-NLS-1$ //$NON-NLS-2$
recordAnnotation(analysisRecord, Annotation.CACHED_PROCEDURE, Priority.MEDIUM, "SimpleQueryResolver.procedure_cache_not_usable", container.getGroup(), "lob parameters");
}
container.getGroup().setGlobalTable(true);
container.setCacheHint(c.getCacheHint());
// $NON-NLS-1$*/
recordAnnotation(analysisRecord, Annotation.CACHED_PROCEDURE, Priority.LOW, "SimpleQueryResolver.procedure_cache_used", container.getGroup());
return false;
}
// $NON-NLS-1$
recordAnnotation(analysisRecord, Annotation.CACHED_PROCEDURE, Priority.LOW, "SimpleQueryResolver.procedure_cache_not_used", container.getGroup());
}
}
// skip the rewrite here, we'll do that in the optimizer
// so that we know what the determinism level is.
addNestedCommand(sourceNode, container.getGroup(), container, c, false, true);
}
List<SubqueryContainer<?>> subqueries = ValueIteratorProviderCollectorVisitor.getValueIteratorProviders(container);
if (c == null && container instanceof FilteredCommand) {
// we force the evaluation of procedure params - TODO: inserts are fine except for nonpushdown functions on columns
// for non-temp source queries, we must pre-plan subqueries to know if they can be pushed down
boolean compensate = false;
boolean isTemp = container.getGroup().isTempTable() && metadata.getModelID(container.getGroup().getMetadataID()) == TempMetadataAdapter.TEMP_MODEL;
try {
planSubqueries(container, c, subqueries, true);
} catch (QueryPlannerException e) {
if (!isTemp) {
throw e;
}
compensate = true;
}
if (!isTemp && !CriteriaCapabilityValidatorVisitor.canPushLanguageObject(container, metadata.getModelID(container.getGroup().getMetadataID()), metadata, capFinder, analysisRecord)) {
compensate = true;
}
if (compensate) {
// do a workaround of row-by-row processing for update/delete
validateRowProcessing(container);
// treat this as an update procedure
if (container instanceof Update) {
c = QueryRewriter.createUpdateProcedure((Update) container, metadata, context);
} else {
c = QueryRewriter.createDeleteProcedure((Delete) container, metadata, context);
}
addNestedCommand(sourceNode, container.getGroup(), container, c, false, true);
return false;
}
}
// plan any subqueries in criteria/parameters/values
planSubqueries(container, c, subqueries, false);
return false;
}
Aggregations