use of org.teiid.query.metadata.TempMetadataAdapter in project teiid by teiid.
the class QueryRewriter method rewriteCommand.
/**
* Rewrites the command and all of its subcommands (both embedded and non-embedded)
*
* @param command
* @param removeOrderBy
* @return
* @throws QueryValidatorException
*/
private Command rewriteCommand(Command command, boolean removeOrderBy) throws TeiidComponentException, TeiidProcessingException {
boolean oldRewriteAggs = rewriteAggs;
QueryMetadataInterface oldMetadata = metadata;
TempMetadataStore tempMetadata = command.getTemporaryMetadata();
if (tempMetadata != null) {
metadata = new TempMetadataAdapter(metadata, tempMetadata);
}
switch(command.getType()) {
case Command.TYPE_QUERY:
QueryCommand queryCommand = (QueryCommand) command;
if (removeOrderBy && queryCommand.getLimit() == null) {
queryCommand.setOrderBy(null);
}
List<WithQueryCommand> withList = queryCommand.getWith();
if (withList != null) {
queryCommand.setWith(null);
List<UnaryFromClause> clauses = getUnaryFromClauses(queryCommand);
queryCommand.setWith(withList);
outer: for (int i = withList.size() - 1; i >= 0; i--) {
WithQueryCommand withQueryCommand = withList.get(i);
if (withQueryCommand.getColumns() == null) {
List<ElementSymbol> columns = ResolverUtil.resolveElementsInGroup(withQueryCommand.getGroupSymbol(), metadata);
withQueryCommand.setColumns(LanguageObject.Util.deepClone(columns, ElementSymbol.class));
}
Collection<UnaryFromClause> all = new ArrayList<UnaryFromClause>(clauses);
List<UnaryFromClause> current = getUnaryFromClauses(withQueryCommand.getCommand());
clauses.addAll(current);
rewriteSubqueryContainer(withQueryCommand, true);
// can't inline with a hint or once it's planned
if (withQueryCommand.isNoInline() || withQueryCommand.getCommand().getProcessorPlan() != null || processing) {
// pushing them down
continue;
}
boolean removeOnly = false;
// check for scalar with clauses
boolean replaceScalar = replaceScalar(withQueryCommand);
if (!replaceScalar) {
int referenceCount = 0;
for (UnaryFromClause ufc : all) {
if (ufc.getGroup().getMetadataID() != withQueryCommand.getGroupSymbol().getMetadataID()) {
continue;
}
referenceCount++;
if (referenceCount > 1) {
// referenced in more than 1 location
continue outer;
}
}
if (referenceCount == 0) {
removeOnly = true;
} else if (withQueryCommand.isRecursive()) {
// can't inline if recursive
continue;
}
}
withList.remove(i);
if (withList.isEmpty()) {
queryCommand.setWith(null);
}
if (removeOnly) {
clauses = clauses.subList(0, clauses.size() - current.size());
continue;
}
for (UnaryFromClause clause : all) {
// we match on equality as the name can be redefined
if (clause.getGroup().getMetadataID() != withQueryCommand.getGroupSymbol().getMetadataID()) {
continue;
}
if (!replaceScalar) {
// use the original since we need to keep the references
// to nested unaryfromclause instances
clause.setExpandedCommand(withQueryCommand.getCommand());
break;
}
clause.setExpandedCommand((Command) withQueryCommand.getCommand().clone());
}
}
}
if (command instanceof Query) {
command = rewriteQuery((Query) command);
} else {
command = rewriteSetQuery((SetQuery) command);
}
break;
case Command.TYPE_STORED_PROCEDURE:
command = rewriteExec((StoredProcedure) command);
break;
case Command.TYPE_INSERT:
command = rewriteInsert((Insert) command);
break;
case Command.TYPE_UPDATE:
command = rewriteUpdate((Update) command);
break;
case Command.TYPE_DELETE:
command = rewriteDelete((Delete) command);
break;
case Command.TYPE_UPDATE_PROCEDURE:
command = rewriteUpdateProcedure((CreateProcedureCommand) command);
break;
case Command.TYPE_BATCHED_UPDATE:
List subCommands = ((BatchedUpdateCommand) command).getUpdateCommands();
for (int i = 0; i < subCommands.size(); i++) {
Command subCommand = (Command) subCommands.get(i);
subCommand = rewriteCommand(subCommand, false);
subCommands.set(i, subCommand);
}
break;
case Command.TYPE_TRIGGER_ACTION:
TriggerAction ta = (TriggerAction) command;
ta.setBlock(rewriteBlock(ta.getBlock()));
break;
}
this.rewriteAggs = oldRewriteAggs;
this.metadata = oldMetadata;
return command;
}
use of org.teiid.query.metadata.TempMetadataAdapter in project teiid by teiid.
the class ProcedureContainerResolver method findChildCommandMetadata.
/**
* Set the appropriate "external" metadata for the given command
* @param inferProcedureResultSetColumns
* @throws QueryResolverException
*/
public static void findChildCommandMetadata(Command currentCommand, GroupSymbol container, int type, QueryMetadataInterface metadata, boolean inferProcedureResultSetColumns) throws QueryMetadataException, TeiidComponentException, QueryResolverException {
// find the childMetadata using a clean metadata store
TempMetadataStore childMetadata = new TempMetadataStore();
TempMetadataAdapter tma = new TempMetadataAdapter(metadata, childMetadata);
GroupContext externalGroups = new GroupContext();
if (currentCommand instanceof TriggerAction) {
TriggerAction ta = (TriggerAction) currentCommand;
ta.setView(container);
// TODO: it seems easier to just inline the handling here rather than have each of the resolvers check for trigger actions
List<ElementSymbol> viewElements = ResolverUtil.resolveElementsInGroup(ta.getView(), metadata);
if (type == Command.TYPE_UPDATE || type == Command.TYPE_INSERT) {
ProcedureContainerResolver.addChanging(tma.getMetadataStore(), externalGroups, viewElements);
ProcedureContainerResolver.addScalarGroup(SQLConstants.Reserved.NEW, tma.getMetadataStore(), externalGroups, viewElements, false);
if (type == Command.TYPE_INSERT) {
List<ElementSymbol> key = InsertResolver.getAutoIncrementKey(ta.getView().getMetadataID(), viewElements, metadata);
if (key != null) {
ProcedureContainerResolver.addScalarGroup(SQLConstants.NonReserved.KEY, tma.getMetadataStore(), externalGroups, key, true);
}
}
}
if (type == Command.TYPE_UPDATE || type == Command.TYPE_DELETE) {
ProcedureContainerResolver.addScalarGroup(SQLConstants.Reserved.OLD, tma.getMetadataStore(), externalGroups, viewElements, false);
}
} else if (currentCommand instanceof CreateProcedureCommand) {
CreateProcedureCommand cupc = (CreateProcedureCommand) currentCommand;
cupc.setVirtualGroup(container);
if (type == Command.TYPE_STORED_PROCEDURE) {
StoredProcedureInfo info = metadata.getStoredProcedureInfoForProcedure(container.getName());
// Create temporary metadata that defines a group based on either the stored proc
// name or the stored query name - this will be used later during planning
String procName = info.getProcedureCallableName();
// Look through parameters to find input elements - these become child metadata
List<ElementSymbol> tempElements = new ArrayList<ElementSymbol>(info.getParameters().size());
boolean[] updatable = new boolean[info.getParameters().size()];
int i = 0;
List<ElementSymbol> rsColumns = Collections.emptyList();
for (SPParameter param : info.getParameters()) {
if (param.getParameterType() != ParameterInfo.RESULT_SET) {
ElementSymbol symbol = param.getParameterSymbol();
tempElements.add(symbol);
updatable[i++] = param.getParameterType() != ParameterInfo.IN;
if (param.getParameterType() == ParameterInfo.RETURN_VALUE) {
cupc.setReturnVariable(symbol);
}
} else {
rsColumns = param.getResultSetColumns();
}
}
if (inferProcedureResultSetColumns) {
rsColumns = null;
}
GroupSymbol gs = ProcedureContainerResolver.addScalarGroup(procName, childMetadata, externalGroups, tempElements, updatable);
if (cupc.getReturnVariable() != null) {
ResolverVisitor.resolveLanguageObject(cupc.getReturnVariable(), Arrays.asList(gs), metadata);
}
cupc.setResultSetColumns(rsColumns);
// the relational planner will override this with the appropriate value
cupc.setProjectedSymbols(rsColumns);
} else {
cupc.setUpdateType(type);
}
}
QueryResolver.setChildMetadata(currentCommand, childMetadata, externalGroups);
}
use of org.teiid.query.metadata.TempMetadataAdapter in project teiid by teiid.
the class QueryResolver method resolveCommand.
public static TempMetadataStore resolveCommand(Command currentCommand, QueryMetadataInterface metadata, boolean resolveNullLiterals) throws QueryResolverException, TeiidComponentException {
// $NON-NLS-1$
LogManager.logTrace(org.teiid.logging.LogConstants.CTX_QUERY_RESOLVER, new Object[] { "Resolving command", currentCommand });
TempMetadataAdapter resolverMetadata = null;
try {
TempMetadataStore discoveredMetadata = currentCommand.getTemporaryMetadata();
if (discoveredMetadata == null) {
discoveredMetadata = new TempMetadataStore();
currentCommand.setTemporaryMetadata(discoveredMetadata);
}
resolverMetadata = new TempMetadataAdapter(metadata, discoveredMetadata);
// Resolve external groups for command
Collection<GroupSymbol> externalGroups = currentCommand.getAllExternalGroups();
for (GroupSymbol extGroup : externalGroups) {
Object metadataID = extGroup.getMetadataID();
// TODO: this is mainly for XML resolving since it sends external groups in unresolved
if (metadataID == null || (!(extGroup.getMetadataID() instanceof TempMetadataID) && discoveredMetadata.getTempGroupID(extGroup.getName()) != null)) {
boolean missing = metadataID == null;
metadataID = resolverMetadata.getGroupID(extGroup.getName());
if (missing) {
extGroup.setMetadataID(metadataID);
} else {
// we shouldn't modify the existing, just add a shadow group
GroupSymbol gs = extGroup.clone();
gs.setMetadataID(metadataID);
currentCommand.getExternalGroupContexts().addGroup(gs);
}
}
}
CommandResolver resolver = chooseResolver(currentCommand, resolverMetadata);
// Resolve this command
resolver.resolveCommand(currentCommand, resolverMetadata, resolveNullLiterals);
} catch (QueryMetadataException e) {
throw new QueryResolverException(e);
}
// Flag that this command has been resolved.
currentCommand.setIsResolved(true);
return resolverMetadata.getMetadataStore();
}
use of org.teiid.query.metadata.TempMetadataAdapter in project teiid by teiid.
the class UpdateProcedureResolver method resolveStatement.
private void resolveStatement(CreateProcedureCommand command, Statement statement, GroupContext externalGroups, GroupSymbol variables, TempMetadataAdapter metadata) throws QueryResolverException, QueryMetadataException, TeiidComponentException {
// $NON-NLS-1$
LogManager.logTrace(org.teiid.logging.LogConstants.CTX_QUERY_RESOLVER, new Object[] { "Resolving statement", statement });
switch(statement.getType()) {
case Statement.TYPE_IF:
IfStatement ifStmt = (IfStatement) statement;
Criteria ifCrit = ifStmt.getCondition();
for (SubqueryContainer container : ValueIteratorProviderCollectorVisitor.getValueIteratorProviders(ifCrit)) {
resolveEmbeddedCommand(metadata, externalGroups, container.getCommand());
}
ResolverVisitor.resolveLanguageObject(ifCrit, null, externalGroups, metadata);
resolveBlock(command, ifStmt.getIfBlock(), externalGroups, metadata);
if (ifStmt.hasElseBlock()) {
resolveBlock(command, ifStmt.getElseBlock(), externalGroups, metadata);
}
break;
case Statement.TYPE_COMMAND:
CommandStatement cmdStmt = (CommandStatement) statement;
Command subCommand = cmdStmt.getCommand();
TempMetadataStore discoveredMetadata = resolveEmbeddedCommand(metadata, externalGroups, subCommand);
if (subCommand instanceof StoredProcedure) {
StoredProcedure sp = (StoredProcedure) subCommand;
for (SPParameter param : sp.getParameters()) {
switch(param.getParameterType()) {
case ParameterInfo.OUT:
case ParameterInfo.RETURN_VALUE:
if (param.getExpression() != null) {
if (!isAssignable(metadata, param)) {
throw new QueryResolverException(QueryPlugin.Event.TEIID30121, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30121, param.getExpression()));
}
sp.setCallableStatement(true);
}
break;
case ParameterInfo.INOUT:
if (!isAssignable(metadata, param)) {
continue;
}
sp.setCallableStatement(true);
break;
}
}
}
if (discoveredMetadata != null) {
metadata.getMetadataStore().getData().putAll(discoveredMetadata.getData());
}
// dynamic commands need to be updated as to their implicitly expected projected symbols
if (subCommand instanceof DynamicCommand) {
DynamicCommand dynCommand = (DynamicCommand) subCommand;
if (dynCommand.getIntoGroup() == null && !dynCommand.isAsClauseSet()) {
if ((command.getResultSetColumns() != null && command.getResultSetColumns().isEmpty()) || !cmdStmt.isReturnable() || command.getResultSetColumns() == null) {
// we're not interested in the resultset
dynCommand.setAsColumns(Collections.EMPTY_LIST);
} else {
// should match the procedure
dynCommand.setAsColumns(command.getResultSetColumns());
}
}
}
if (command.getResultSetColumns() == null && cmdStmt.isReturnable() && subCommand.returnsResultSet() && subCommand.getResultSetColumns() != null && !subCommand.getResultSetColumns().isEmpty()) {
command.setResultSetColumns(subCommand.getResultSetColumns());
if (command.getProjectedSymbols().isEmpty()) {
command.setProjectedSymbols(subCommand.getResultSetColumns());
}
}
break;
case Statement.TYPE_ERROR:
case Statement.TYPE_ASSIGNMENT:
case Statement.TYPE_DECLARE:
case Statement.TYPE_RETURN:
ExpressionStatement exprStmt = (ExpressionStatement) statement;
// first resolve the value. this ensures the value cannot use the variable being defined
if (exprStmt.getExpression() != null) {
Expression expr = exprStmt.getExpression();
for (SubqueryContainer container : ValueIteratorProviderCollectorVisitor.getValueIteratorProviders(expr)) {
resolveEmbeddedCommand(metadata, externalGroups, container.getCommand());
}
ResolverVisitor.resolveLanguageObject(expr, null, externalGroups, metadata);
}
// second resolve the variable
switch(statement.getType()) {
case Statement.TYPE_DECLARE:
collectDeclareVariable((DeclareStatement) statement, variables, metadata, externalGroups);
break;
case Statement.TYPE_ASSIGNMENT:
AssignmentStatement assStmt = (AssignmentStatement) statement;
ResolverVisitor.resolveLanguageObject(assStmt.getVariable(), null, externalGroups, metadata);
if (!metadata.elementSupports(assStmt.getVariable().getMetadataID(), SupportConstants.Element.UPDATE)) {
throw new QueryResolverException(QueryPlugin.Event.TEIID30121, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30121, assStmt.getVariable()));
}
// don't allow variable assignments to be external
assStmt.getVariable().setIsExternalReference(false);
break;
case Statement.TYPE_RETURN:
ReturnStatement rs = (ReturnStatement) statement;
if (rs.getExpression() != null) {
if (command.getReturnVariable() == null) {
throw new QueryResolverException(QueryPlugin.Event.TEIID31125, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID31125, rs));
}
rs.setVariable(command.getReturnVariable().clone());
}
// else - we don't currently require the use of return for backwards compatibility
break;
}
// third ensure the type matches
if (exprStmt.getExpression() != null) {
Class<?> varType = exprStmt.getExpectedType();
Class<?> exprType = exprStmt.getExpression().getType();
if (exprType == null) {
throw new QueryResolverException(QueryPlugin.Event.TEIID30123, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30123));
}
String varTypeName = DataTypeManager.getDataTypeName(varType);
exprStmt.setExpression(ResolverUtil.convertExpression(exprStmt.getExpression(), varTypeName, metadata));
if (statement.getType() == Statement.TYPE_ERROR) {
ResolverVisitor.checkException(exprStmt.getExpression());
}
}
break;
case Statement.TYPE_WHILE:
WhileStatement whileStmt = (WhileStatement) statement;
Criteria whileCrit = whileStmt.getCondition();
for (SubqueryContainer container : ValueIteratorProviderCollectorVisitor.getValueIteratorProviders(whileCrit)) {
resolveEmbeddedCommand(metadata, externalGroups, container.getCommand());
}
ResolverVisitor.resolveLanguageObject(whileCrit, null, externalGroups, metadata);
resolveBlock(command, whileStmt.getBlock(), externalGroups, metadata);
break;
case Statement.TYPE_LOOP:
LoopStatement loopStmt = (LoopStatement) statement;
String groupName = loopStmt.getCursorName();
isValidGroup(metadata, groupName);
Command cmd = loopStmt.getCommand();
resolveEmbeddedCommand(metadata, externalGroups, cmd);
List<Expression> symbols = cmd.getProjectedSymbols();
// add the loop cursor group into its own context
TempMetadataStore store = metadata.getMetadataStore().clone();
metadata = new TempMetadataAdapter(metadata.getMetadata(), store);
externalGroups = new GroupContext(externalGroups, null);
ProcedureContainerResolver.addScalarGroup(groupName, store, externalGroups, symbols, false);
resolveBlock(command, loopStmt.getBlock(), externalGroups, metadata);
break;
case Statement.TYPE_COMPOUND:
resolveBlock(command, (Block) statement, externalGroups, metadata);
break;
}
}
use of org.teiid.query.metadata.TempMetadataAdapter in project teiid by teiid.
the class TestMultiSourceMetadataWrapper method testMultiSourcePseudoElement.
@Test
public void testMultiSourcePseudoElement() throws Exception {
HashSet<String> multiSourceModels = new HashSet<String>();
multiSourceModels.add("BQT1");
MultiSourceMetadataWrapper wrapper = new MultiSourceMetadataWrapper(RealMetadataFactory.exampleBQTCached(), multiSourceModels);
// $NON-NLS-1$
Object groupID = wrapper.getGroupID("BQT1.SmallA");
List<?> elements = wrapper.getElementIDsInGroupID(groupID);
assertEquals(18, elements.size());
Object instanceElementID = elements.get(elements.size() - 1);
String fullName = wrapper.getFullName(instanceElementID);
// $NON-NLS-1$
assertEquals("BQT1.SmallA." + MultiSourceElement.DEFAULT_MULTI_SOURCE_ELEMENT_NAME, fullName);
assertEquals(instanceElementID, wrapper.getElementID(fullName));
assertEquals(groupID, wrapper.getGroupIDForElementID(instanceElementID));
assertEquals(null, wrapper.getMaximumValue(instanceElementID));
assertEquals(null, wrapper.getMinimumValue(instanceElementID));
assertEquals(wrapper.getModelID(groupID), wrapper.getModelID(instanceElementID));
assertEquals(null, wrapper.getDefaultValue(instanceElementID));
assertEquals(255, wrapper.getElementLength(instanceElementID));
assertEquals(DataTypeManager.DefaultDataTypes.STRING, wrapper.getElementRuntimeTypeName(instanceElementID));
assertEquals(new Properties(), wrapper.getExtensionProperties(instanceElementID));
assertEquals(null, wrapper.getNameInSource(instanceElementID));
assertEquals(null, wrapper.getNativeType(instanceElementID));
assertEquals(18, wrapper.getPosition(instanceElementID));
assertEquals(0, wrapper.getPrecision(instanceElementID));
assertEquals(0, wrapper.getScale(instanceElementID));
assertEquals(0, wrapper.getRadix(instanceElementID));
assertEquals(MultiSourceElement.DEFAULT_MULTI_SOURCE_ELEMENT_NAME, Symbol.getShortName(fullName));
assertEquals(fullName, wrapper.getFullName(groupID) + Symbol.SEPARATOR + MultiSourceElement.DEFAULT_MULTI_SOURCE_ELEMENT_NAME);
TempMetadataAdapter tma = new TempMetadataAdapter(wrapper, new TempMetadataStore());
ElementSymbol elementSymbol = new ElementSymbol("y");
elementSymbol.setType(DataTypeManager.DefaultDataClasses.STRING);
TempMetadataID id = tma.getMetadataStore().addTempGroup("x", Arrays.asList(elementSymbol));
assertFalse(tma.isMultiSourceElement(id.getElements().get(0)));
assertTrue(tma.isMultiSourceElement(instanceElementID));
assertTrue(tma.isPseudo(instanceElementID));
assertEquals(17, tma.getElementIDsInGroupID(tma.getGroupID("VQT.Smalla")).size());
}
Aggregations