Search in sources :

Example 1 with GroupContext

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

the class ExecResolver method resolveProceduralCommand.

/**
 * @see org.teiid.query.resolver.ProcedureContainerResolver#resolveProceduralCommand(org.teiid.query.sql.lang.Command, org.teiid.query.metadata.TempMetadataAdapter)
 */
public void resolveProceduralCommand(Command command, TempMetadataAdapter metadata) throws QueryMetadataException, QueryResolverException, TeiidComponentException {
    findCommandMetadata(command, metadata.getMetadataStore(), metadata);
    // Resolve expressions on input parameters
    StoredProcedure storedProcedureCommand = (StoredProcedure) command;
    GroupContext externalGroups = storedProcedureCommand.getExternalGroupContexts();
    for (SPParameter param : storedProcedureCommand.getParameters()) {
        Expression expr = param.getExpression();
        if (expr == null) {
            continue;
        }
        for (SubqueryContainer<?> container : ValueIteratorProviderCollectorVisitor.getValueIteratorProviders(expr)) {
            QueryResolver.setChildMetadata(container.getCommand(), command);
            QueryResolver.resolveCommand(container.getCommand(), metadata.getMetadata());
        }
        try {
            ResolverVisitor.resolveLanguageObject(expr, null, externalGroups, metadata);
        } catch (QueryResolverException e) {
            if (!checkForArray(param, expr)) {
                throw e;
            }
            continue;
        }
        Class<?> paramType = param.getClassType();
        ResolverUtil.setDesiredType(expr, paramType, storedProcedureCommand);
        // Compare type of parameter expression against parameter type
        // and add implicit conversion if necessary
        Class<?> exprType = expr.getType();
        if (paramType == null || exprType == null) {
            throw new QueryResolverException(QueryPlugin.Event.TEIID30143, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30143, storedProcedureCommand.getProcedureName(), param.getName()));
        }
        String tgtType = DataTypeManager.getDataTypeName(paramType);
        String srcType = DataTypeManager.getDataTypeName(exprType);
        Expression result = null;
        if (param.getParameterType() == SPParameter.RETURN_VALUE || param.getParameterType() == SPParameter.OUT) {
            if (!ResolverUtil.canImplicitlyConvert(tgtType, srcType)) {
                throw new QueryResolverException(QueryPlugin.Event.TEIID30144, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30144, param.getParameterSymbol(), tgtType, srcType));
            }
        } else {
            try {
                result = ResolverUtil.convertExpression(expr, tgtType, metadata);
            } catch (QueryResolverException e) {
                throw new QueryResolverException(QueryPlugin.Event.TEIID30145, e, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30145, new Object[] { param.getParameterSymbol(), srcType, tgtType }));
            }
            param.setExpression(result);
        }
    }
}
Also used : StoredProcedure(org.teiid.query.sql.lang.StoredProcedure) Expression(org.teiid.query.sql.symbol.Expression) SPParameter(org.teiid.query.sql.lang.SPParameter) GroupContext(org.teiid.query.sql.lang.GroupContext) QueryResolverException(org.teiid.api.exception.query.QueryResolverException)

Example 2 with GroupContext

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

the class UpdateProcedureResolver method resolveBlock.

public void resolveBlock(CreateProcedureCommand command, Block block, GroupContext originalExternalGroups, TempMetadataAdapter original) throws QueryResolverException, QueryMetadataException, TeiidComponentException {
    // $NON-NLS-1$
    LogManager.logTrace(org.teiid.logging.LogConstants.CTX_QUERY_RESOLVER, new Object[] { "Resolving block", block });
    // create a new variable and metadata context for this block so that discovered metadata is not visible else where
    TempMetadataStore store = original.getMetadataStore().clone();
    TempMetadataAdapter metadata = new TempMetadataAdapter(original.getMetadata(), store);
    GroupContext externalGroups = new GroupContext(originalExternalGroups, null);
    // create a new variables group for this block
    GroupSymbol variables = ProcedureContainerResolver.addScalarGroup(ProcedureReservedWords.VARIABLES, store, externalGroups, new LinkedList<Expression>());
    for (Statement statement : block.getStatements()) {
        resolveStatement(command, statement, externalGroups, variables, metadata);
    }
    if (block.getExceptionGroup() != null) {
        // create a new variable and metadata context for this block so that discovered metadata is not visible else where
        store = original.getMetadataStore().clone();
        metadata = new TempMetadataAdapter(original.getMetadata(), store);
        externalGroups = new GroupContext(originalExternalGroups, null);
        // create a new variables group for this block
        variables = ProcedureContainerResolver.addScalarGroup(ProcedureReservedWords.VARIABLES, store, externalGroups, new LinkedList<Expression>());
        isValidGroup(metadata, block.getExceptionGroup());
        if (block.getExceptionStatements() != null) {
            ProcedureContainerResolver.addScalarGroup(block.getExceptionGroup(), store, externalGroups, exceptionGroup, false);
            for (Statement statement : block.getExceptionStatements()) {
                resolveStatement(command, statement, externalGroups, variables, metadata);
            }
        }
    }
}
Also used : TempMetadataAdapter(org.teiid.query.metadata.TempMetadataAdapter) Expression(org.teiid.query.sql.symbol.Expression) GroupSymbol(org.teiid.query.sql.symbol.GroupSymbol) TempMetadataStore(org.teiid.query.metadata.TempMetadataStore) GroupContext(org.teiid.query.sql.lang.GroupContext) LinkedList(java.util.LinkedList)

Example 3 with GroupContext

use of org.teiid.query.sql.lang.GroupContext 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 4 with GroupContext

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

the class QueryResolver method resolveWithBindingMetadata.

/**
 * Bindings are a poor mans input parameters.  They are represented in legacy metadata
 * by ElementSymbols and placed positionally into the command or by alias symbols
 * and matched by names.  After resolving bindings will be replaced with their
 * referenced symbols (input names will not be used) and those symbols will
 * be marked as external references.
 */
public static TempMetadataStore resolveWithBindingMetadata(Command currentCommand, QueryMetadataInterface metadata, QueryNode queryNode, boolean replaceBindings) throws TeiidComponentException, QueryResolverException {
    Map<ElementSymbol, ElementSymbol> symbolMap = null;
    if (queryNode.getBindings() != null && queryNode.getBindings().size() > 0) {
        symbolMap = new HashMap<ElementSymbol, ElementSymbol>();
        // Create ElementSymbols for each InputParameter
        final List<ElementSymbol> elements = new ArrayList<ElementSymbol>(queryNode.getBindings().size());
        boolean positional = true;
        for (Expression ses : parseBindings(queryNode)) {
            String name = Symbol.getShortName(ses);
            if (ses instanceof AliasSymbol) {
                ses = ((AliasSymbol) ses).getSymbol();
                positional = false;
            }
            ElementSymbol elementSymbol = (ElementSymbol) ses;
            ResolverVisitor.resolveLanguageObject(elementSymbol, metadata);
            elementSymbol.setIsExternalReference(true);
            if (!positional) {
                symbolMap.put(new ElementSymbol("INPUT" + Symbol.SEPARATOR + name), elementSymbol.clone());
                symbolMap.put(new ElementSymbol(BINDING_GROUP + Symbol.SEPARATOR + name), elementSymbol.clone());
                elementSymbol.setShortName(name);
            }
            elements.add(elementSymbol);
        }
        if (positional) {
            ExpressionMappingVisitor emv = new ExpressionMappingVisitor(null) {

                @Override
                public Expression replaceExpression(Expression element) {
                    if (!(element instanceof Reference)) {
                        return element;
                    }
                    Reference ref = (Reference) element;
                    if (!ref.isPositional()) {
                        return ref;
                    }
                    return elements.get(ref.getIndex()).clone();
                }
            };
            DeepPostOrderNavigator.doVisit(currentCommand, emv);
        } else {
            TempMetadataStore rootExternalStore = new TempMetadataStore();
            GroupContext externalGroups = new GroupContext();
            // $NON-NLS-1$
            ProcedureContainerResolver.addScalarGroup("INPUT", rootExternalStore, externalGroups, elements);
            ProcedureContainerResolver.addScalarGroup(BINDING_GROUP, rootExternalStore, externalGroups, elements);
            QueryResolver.setChildMetadata(currentCommand, rootExternalStore, externalGroups);
        }
    }
    TempMetadataStore result = resolveCommand(currentCommand, metadata, false);
    if (replaceBindings && symbolMap != null && !symbolMap.isEmpty()) {
        ExpressionMappingVisitor emv = new ExpressionMappingVisitor(symbolMap);
        DeepPostOrderNavigator.doVisit(currentCommand, emv);
    }
    return result;
}
Also used : ElementSymbol(org.teiid.query.sql.symbol.ElementSymbol) Reference(org.teiid.query.sql.symbol.Reference) ArrayList(java.util.ArrayList) ExpressionMappingVisitor(org.teiid.query.sql.visitor.ExpressionMappingVisitor) AliasSymbol(org.teiid.query.sql.symbol.AliasSymbol) Expression(org.teiid.query.sql.symbol.Expression) TempMetadataStore(org.teiid.query.metadata.TempMetadataStore) GroupContext(org.teiid.query.sql.lang.GroupContext)

Example 5 with GroupContext

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

the class QueryResolver method setChildMetadata.

public static void setChildMetadata(Command subCommand, Command parent) {
    TempMetadataStore childMetadata = parent.getTemporaryMetadata();
    GroupContext parentContext = parent.getExternalGroupContexts();
    setChildMetadata(subCommand, childMetadata, parentContext);
}
Also used : TempMetadataStore(org.teiid.query.metadata.TempMetadataStore) GroupContext(org.teiid.query.sql.lang.GroupContext)

Aggregations

GroupContext (org.teiid.query.sql.lang.GroupContext)7 TempMetadataStore (org.teiid.query.metadata.TempMetadataStore)5 Expression (org.teiid.query.sql.symbol.Expression)4 TempMetadataAdapter (org.teiid.query.metadata.TempMetadataAdapter)3 SPParameter (org.teiid.query.sql.lang.SPParameter)3 ElementSymbol (org.teiid.query.sql.symbol.ElementSymbol)3 ArrayList (java.util.ArrayList)2 LinkedList (java.util.LinkedList)2 QueryResolverException (org.teiid.api.exception.query.QueryResolverException)2 StoredProcedure (org.teiid.query.sql.lang.StoredProcedure)2 GroupSymbol (org.teiid.query.sql.symbol.GroupSymbol)2 List (java.util.List)1 StoredProcedureInfo (org.teiid.query.metadata.StoredProcedureInfo)1 Command (org.teiid.query.sql.lang.Command)1 Criteria (org.teiid.query.sql.lang.Criteria)1 DynamicCommand (org.teiid.query.sql.lang.DynamicCommand)1 SubqueryContainer (org.teiid.query.sql.lang.SubqueryContainer)1 CreateProcedureCommand (org.teiid.query.sql.proc.CreateProcedureCommand)1 TriggerAction (org.teiid.query.sql.proc.TriggerAction)1 AliasSymbol (org.teiid.query.sql.symbol.AliasSymbol)1