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 (!isAssignable(metadata, param)) {
throw new QueryResolverException(QueryPlugin.Util.getString("UpdateProcedureResolver.only_variables", param.getExpression())); //$NON-NLS-1$
}
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 && !command.isUpdateProcedure()
&& !dynCommand.isAsClauseSet() && !command.getProjectedSymbols().isEmpty()) {
dynCommand.setAsColumns(command.getProjectedSymbols());
}
}
if(!command.isUpdateProcedure()){
//don't bother using the metadata when it doesn't matter
if (command.getResultsCommand() != null && command.getResultsCommand().getType() == Command.TYPE_DYNAMIC) {
DynamicCommand dynamicCommand = (DynamicCommand)command.getResultsCommand();
if (!dynamicCommand.isAsClauseSet()) {
dynamicCommand.setAsColumns(Collections.EMPTY_LIST);
}
}
if (subCommand.returnsResultSet()) {
//this could be the last select statement, set the projected symbol
//on the virtual procedure command
command.setResultsCommand(subCommand);
}
}
break;
case Statement.TYPE_ERROR:
case Statement.TYPE_ASSIGNMENT:
case Statement.TYPE_DECLARE:
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
if(statement.getType() == Statement.TYPE_DECLARE) {
collectDeclareVariable((DeclareStatement)statement, variables, metadata, externalGroups);
} else if (statement.getType() == 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.Util.getString("UpdateProcedureResolver.only_variables", assStmt.getVariable())); //$NON-NLS-1$
}
//don't allow variable assignments to be external
assStmt.getVariable().setIsExternalReference(false);
}
//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.Util.getString("ResolveVariablesVisitor.datatype_for_the_expression_not_resolvable")); //$NON-NLS-1$
}
String varTypeName = DataTypeManager.getDataTypeName(varType);
exprStmt.setExpression(ResolverUtil.convertExpression(exprStmt.getExpression(), varTypeName, metadata));
}
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();
if (metadata.getMetadataStore().getTempGroupID(groupName) != null) {
throw new QueryResolverException(QueryPlugin.Util.getString("ERR.015.012.0065")); //$NON-NLS-1$
}
//check - cursor name should not start with #
if(GroupSymbol.isTempGroupName(loopStmt.getCursorName())){
String errorMsg = QueryPlugin.Util.getString("ResolveVariablesVisitor.reserved_word_for_temporary_used", loopStmt.getCursorName()); //$NON-NLS-1$
throw new QueryResolverException(errorMsg);
}
Command cmd = loopStmt.getCommand();
resolveEmbeddedCommand(metadata, externalGroups, cmd);
List<SingleElementSymbol> symbols = cmd.getProjectedSymbols();
//add the loop cursor group into its own context
TempMetadataStore store = new TempMetadataStore(new HashMap(metadata.getMetadataStore().getData()));
metadata = new TempMetadataAdapter(metadata.getMetadata(), store);
externalGroups = new GroupContext(externalGroups, null);
ProcedureContainerResolver.addScalarGroup(groupName, store, externalGroups, symbols, false);