use of org.teiid.query.sql.proc.CreateProcedureCommand in project teiid by teiid.
the class TestProcedureResolving method testAnonBlockNoResult.
@Test
public void testAnonBlockNoResult() throws Exception {
// $NON-NLS-1$
String sql = "begin select 1 as something without return; end";
CreateProcedureCommand sp = (CreateProcedureCommand) TestResolver.helpResolve(sql, RealMetadataFactory.example1Cached());
assertEquals(0, sp.getProjectedSymbols().size());
assertFalse(sp.returnsResultSet());
}
use of org.teiid.query.sql.proc.CreateProcedureCommand in project teiid by teiid.
the class TestOptionsAndHints method testCacheProc.
@Test
public void testCacheProc() {
// $NON-NLS-1$
String sql = "/*+ cache */ CREATE VIRTUAL PROCEDURE BEGIN END";
CreateProcedureCommand command = new CreateProcedureCommand(new Block());
command.setCacheHint(new CacheHint());
// $NON-NLS-1$
TestParser.helpTest(sql, "/*+ cache */ BEGIN\nEND", command);
}
use of org.teiid.query.sql.proc.CreateProcedureCommand 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.sql.proc.CreateProcedureCommand in project teiid by teiid.
the class Request method createProcessor.
private void createProcessor() throws TeiidComponentException {
if (this.userCommand instanceof CreateProcedureCommand && this.processPlan instanceof ProcedurePlan) {
((ProcedurePlan) this.processPlan).setValidateAccess(true);
}
this.context.setTransactionContext(getTransactionContext(true));
this.processor = new QueryProcessor(processPlan, context, bufferManager, processorDataManager);
}
use of org.teiid.query.sql.proc.CreateProcedureCommand 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