Search in sources :

Example 11 with SPParameter

use of org.teiid.query.sql.lang.SPParameter 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);
}
Also used : TempMetadataAdapter(org.teiid.query.metadata.TempMetadataAdapter) ElementSymbol(org.teiid.query.sql.symbol.ElementSymbol) TriggerAction(org.teiid.query.sql.proc.TriggerAction) CreateProcedureCommand(org.teiid.query.sql.proc.CreateProcedureCommand) SPParameter(org.teiid.query.sql.lang.SPParameter) StoredProcedureInfo(org.teiid.query.metadata.StoredProcedureInfo) GroupSymbol(org.teiid.query.sql.symbol.GroupSymbol) ArrayList(java.util.ArrayList) List(java.util.List) TempMetadataStore(org.teiid.query.metadata.TempMetadataStore) GroupContext(org.teiid.query.sql.lang.GroupContext)

Example 12 with SPParameter

use of org.teiid.query.sql.lang.SPParameter 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;
    }
}
Also used : TempMetadataAdapter(org.teiid.query.metadata.TempMetadataAdapter) SubqueryContainer(org.teiid.query.sql.lang.SubqueryContainer) SPParameter(org.teiid.query.sql.lang.SPParameter) Criteria(org.teiid.query.sql.lang.Criteria) QueryResolverException(org.teiid.api.exception.query.QueryResolverException) DynamicCommand(org.teiid.query.sql.lang.DynamicCommand) StoredProcedure(org.teiid.query.sql.lang.StoredProcedure) DynamicCommand(org.teiid.query.sql.lang.DynamicCommand) Command(org.teiid.query.sql.lang.Command) Expression(org.teiid.query.sql.symbol.Expression) TempMetadataStore(org.teiid.query.metadata.TempMetadataStore) GroupContext(org.teiid.query.sql.lang.GroupContext)

Example 13 with SPParameter

use of org.teiid.query.sql.lang.SPParameter in project teiid by teiid.

the class TestStaticSymbolMappingVisitor method testExecParamFunction.

public void testExecParamFunction() {
    StoredProcedure exec = new StoredProcedure();
    // $NON-NLS-1$
    exec.setProcedureName("pm1.proc1");
    // $NON-NLS-1$
    exec.setProcedureID("proc");
    // $NON-NLS-1$
    Function f = new Function("length", new Expression[] { exampleElement(true, 1) });
    SPParameter param1 = new SPParameter(1, f);
    exec.setParameter(param1);
    // Run symbol mapper
    StaticSymbolMappingVisitor visitor = new StaticSymbolMappingVisitor(getSymbolMap());
    DeepPreOrderNavigator.doVisit(exec, visitor);
    // Check that element got switched
    Function afterFunc = (Function) param1.getExpression();
    // $NON-NLS-1$
    assertEquals("Stored proc param did not get mapped correctly: ", exampleElement(false, 1), afterFunc.getArg(0));
}
Also used : Function(org.teiid.query.sql.symbol.Function) StoredProcedure(org.teiid.query.sql.lang.StoredProcedure) SPParameter(org.teiid.query.sql.lang.SPParameter)

Example 14 with SPParameter

use of org.teiid.query.sql.lang.SPParameter in project teiid by teiid.

the class TestStaticSymbolMappingVisitor method testExecParamNestedFunction.

public void testExecParamNestedFunction() {
    StoredProcedure exec = new StoredProcedure();
    // $NON-NLS-1$
    exec.setProcedureName("pm1.proc1");
    // $NON-NLS-1$
    exec.setProcedureID("proc");
    // $NON-NLS-1$
    Function f = new Function("length", new Expression[] { exampleElement(true, 1) });
    // $NON-NLS-1$
    Function f2 = new Function("+", new Expression[] { f, new Constant(new Integer(1)) });
    SPParameter param1 = new SPParameter(1, f2);
    exec.setParameter(param1);
    // Run symbol mapper
    StaticSymbolMappingVisitor visitor = new StaticSymbolMappingVisitor(getSymbolMap());
    DeepPreOrderNavigator.doVisit(exec, visitor);
    // Check that element got switched
    Function afterFunc = (Function) param1.getExpression();
    Function innerFunc = (Function) afterFunc.getArgs()[0];
    // $NON-NLS-1$
    assertEquals("Stored proc param did not get mapped correctly: ", exampleElement(false, 1), innerFunc.getArg(0));
}
Also used : Function(org.teiid.query.sql.symbol.Function) StoredProcedure(org.teiid.query.sql.lang.StoredProcedure) Constant(org.teiid.query.sql.symbol.Constant) SPParameter(org.teiid.query.sql.lang.SPParameter)

Aggregations

SPParameter (org.teiid.query.sql.lang.SPParameter)14 StoredProcedure (org.teiid.query.sql.lang.StoredProcedure)10 Expression (org.teiid.query.sql.symbol.Expression)5 Reference (org.teiid.query.sql.symbol.Reference)4 ArrayList (java.util.ArrayList)3 List (java.util.List)3 QueryResolverException (org.teiid.api.exception.query.QueryResolverException)3 GroupContext (org.teiid.query.sql.lang.GroupContext)3 GroupSymbol (org.teiid.query.sql.symbol.GroupSymbol)3 HashSet (java.util.HashSet)2 QueryMetadataException (org.teiid.api.exception.query.QueryMetadataException)2 Procedure (org.teiid.metadata.Procedure)2 Schema (org.teiid.metadata.Schema)2 QueryNode (org.teiid.query.mapping.relational.QueryNode)2 StoredProcedureInfo (org.teiid.query.metadata.StoredProcedureInfo)2 TempMetadataAdapter (org.teiid.query.metadata.TempMetadataAdapter)2 TempMetadataStore (org.teiid.query.metadata.TempMetadataStore)2 Command (org.teiid.query.sql.lang.Command)2 Criteria (org.teiid.query.sql.lang.Criteria)2 ElementSymbol (org.teiid.query.sql.symbol.ElementSymbol)2