Search in sources :

Example 16 with Reference

use of org.teiid.query.sql.symbol.Reference in project teiid by teiid.

the class TestOptionsAndHints method testUpdateWithOption.

@Test
public void testUpdateWithOption() {
    Update update = new Update();
    // $NON-NLS-1$
    update.setGroup(new GroupSymbol("m.g"));
    update.addChange(new ElementSymbol("a"), new Reference(0));
    Option option = new Option();
    option.setNoCache(true);
    // $NON-NLS-1$
    Criteria crit = new CompareCriteria(new ElementSymbol("b"), CompareCriteria.EQ, new Reference(1));
    update.setCriteria(crit);
    update.setOption(option);
    // $NON-NLS-1$
    TestParser.helpTest(// $NON-NLS-1$
    "UPDATE m.g SET a = ? WHERE b = ? OPTION NOCACHE", // $NON-NLS-1$
    "UPDATE m.g SET a = ? WHERE b = ? OPTION NOCACHE", update);
}
Also used : ElementSymbol(org.teiid.query.sql.symbol.ElementSymbol) MultipleElementSymbol(org.teiid.query.sql.symbol.MultipleElementSymbol) Reference(org.teiid.query.sql.symbol.Reference) GroupSymbol(org.teiid.query.sql.symbol.GroupSymbol) Test(org.junit.Test)

Example 17 with Reference

use of org.teiid.query.sql.symbol.Reference in project teiid by teiid.

the class RuleMergeVirtual method doMerge.

static PlanNode doMerge(PlanNode frame, PlanNode root, boolean beforeDecomposeJoin, QueryMetadataInterface metadata, CapabilitiesFinder capFinder) throws QueryPlannerException, QueryMetadataException, TeiidComponentException {
    if (frame.hasBooleanProperty(Info.NO_UNNEST)) {
        return root;
    }
    GroupSymbol virtualGroup = frame.getGroups().iterator().next();
    // check to see if frame represents a proc relational query.
    if (virtualGroup.isProcedure()) {
        return root;
    }
    List<PlanNode> sources = NodeEditor.findAllNodes(frame.getFirstChild(), NodeConstants.Types.SOURCE, NodeConstants.Types.SOURCE);
    SymbolMap references = (SymbolMap) frame.getProperty(NodeConstants.Info.CORRELATED_REFERENCES);
    if (references != null) {
        if (!sources.isEmpty()) {
            // correlated nested table commands should not be merged
            return root;
        }
        // this is ok only if all of the references go above the correlating join
        // currently this check is simplistic - just look at the parent join more nested scenarios won't work
        PlanNode parentJoin = NodeEditor.findParent(frame, NodeConstants.Types.JOIN, NodeConstants.Types.SOURCE | NodeConstants.Types.GROUP);
        if (parentJoin != null && !parentJoin.getGroups().containsAll(GroupsUsedByElementsVisitor.getGroups(references.getValues()))) {
            return root;
        }
    }
    PlanNode parentProject = NodeEditor.findParent(frame, NodeConstants.Types.PROJECT);
    // Check whether the upper frame is a SELECT INTO
    if (parentProject.getProperty(NodeConstants.Info.INTO_GROUP) != null) {
        return root;
    }
    if (!FrameUtil.canConvertAccessPatterns(frame)) {
        return root;
    }
    PlanNode projectNode = frame.getFirstChild();
    // Check if lower frame has only a stored procedure execution - this cannot be merged to parent frame
    if (FrameUtil.isProcedure(projectNode)) {
        return root;
    }
    SymbolMap symbolMap = (SymbolMap) frame.getProperty(NodeConstants.Info.SYMBOL_MAP);
    PlanNode sortNode = NodeEditor.findParent(parentProject, NodeConstants.Types.SORT, NodeConstants.Types.SOURCE);
    if (sortNode != null && sortNode.hasBooleanProperty(NodeConstants.Info.UNRELATED_SORT)) {
        OrderBy sortOrder = (OrderBy) sortNode.getProperty(NodeConstants.Info.SORT_ORDER);
        boolean unrelated = false;
        for (OrderByItem item : sortOrder.getOrderByItems()) {
            if (!item.isUnrelated()) {
                continue;
            }
            Collection<ElementSymbol> elements = ElementCollectorVisitor.getElements(item.getSymbol(), true);
            for (ElementSymbol elementSymbol : elements) {
                if (virtualGroup.equals(elementSymbol.getGroupSymbol())) {
                    unrelated = true;
                }
            }
        }
        // the lower frame cannot contain DUP_REMOVE, GROUP, UNION if unrelated
        if (unrelated && NodeEditor.findNodePreOrder(frame, NodeConstants.Types.DUP_REMOVE, NodeConstants.Types.PROJECT) != null || NodeEditor.findNodePreOrder(frame, NodeConstants.Types.SET_OP, NodeConstants.Types.SOURCE) != null || NodeEditor.findNodePreOrder(frame, NodeConstants.Types.GROUP, NodeConstants.Types.SOURCE) != null) {
            return root;
        }
    }
    PlanNode parentJoin = NodeEditor.findParent(frame, NodeConstants.Types.JOIN, NodeConstants.Types.SOURCE | NodeConstants.Types.GROUP);
    // 3. if the frame has no sources
    if (projectNode.getType() != NodeConstants.Types.PROJECT || NodeEditor.findNodePreOrder(frame.getFirstChild(), NodeConstants.Types.GROUP, NodeConstants.Types.SOURCE | NodeConstants.Types.JOIN) != null || sources.isEmpty()) {
        PlanNode parentSource = NodeEditor.findParent(parentProject, NodeConstants.Types.SOURCE);
        if (beforeDecomposeJoin && parentSource != null && parentSource.hasProperty(Info.PARTITION_INFO) && !NodeEditor.findAllNodes(frame.getFirstChild(), NodeConstants.Types.SET_OP, NodeConstants.Types.SOURCE).isEmpty()) {
            // don't bother to merge until after
            return root;
        }
        root = checkForSimpleProjection(frame, root, parentProject, metadata, capFinder);
        if (frame.getParent() == null || !sources.isEmpty() || projectNode.getType() != NodeConstants.Types.PROJECT || parentJoin == null) {
            // only consider no sources when the frame is simple and there is a parent join
            return root;
        }
        if (sources.isEmpty() && parentJoin != null) {
            JoinType jt = (JoinType) parentJoin.getProperty(Info.JOIN_TYPE);
            if (jt.isOuter()) {
                // cannot remove if the no source side is an outer side, or if it can change the meaning of the plan
                return root;
            }
            PlanNode joinToTest = parentJoin;
            while (joinToTest != null) {
                if (FrameUtil.findJoinSourceNode(joinToTest.getFirstChild()).getGroups().contains(virtualGroup)) {
                    // scan all sources under the other side as there could be a join structure
                    for (PlanNode node : NodeEditor.findAllNodes(joinToTest.getLastChild(), NodeConstants.Types.SOURCE, NodeConstants.Types.SOURCE)) {
                        SymbolMap map = (SymbolMap) node.getProperty(NodeConstants.Info.CORRELATED_REFERENCES);
                        if (map != null && GroupsUsedByElementsVisitor.getGroups(map.getValues()).contains(virtualGroup)) {
                            // TODO: we don't have the logic yet to then replace the correlated references
                            return root;
                        }
                    }
                }
                joinToTest = NodeEditor.findParent(joinToTest, NodeConstants.Types.JOIN, NodeConstants.Types.SOURCE | NodeConstants.Types.GROUP);
            }
        }
    }
    if (!checkJoinCriteria(frame.getFirstChild(), virtualGroup, parentJoin)) {
        return root;
    }
    // we don't have to check for null dependent with no source without criteria since there must be a row
    if (!checkProjectedSymbols(projectNode, virtualGroup, parentJoin, metadata, sources, !sources.isEmpty() || frame.getParent() != parentJoin, parentProject)) {
        // TODO: propagate constants if just inhibited by subquery/non-deterministic expressions
        return root;
    }
    // Otherwise merge should work
    // Convert parent frame before merge
    Set<GroupSymbol> groups = Collections.emptySet();
    if (!sources.isEmpty()) {
        groups = FrameUtil.findJoinSourceNode(projectNode).getGroups();
    } else if (references != null) {
        // convert from correlated form to regular references
        RuleMergeCriteria.ReferenceReplacementVisitor rrv = new RuleMergeCriteria.ReferenceReplacementVisitor(references);
        for (Map.Entry<ElementSymbol, Expression> entry : symbolMap.asUpdatableMap().entrySet()) {
            if (entry.getValue() instanceof Reference) {
                Expression ex = rrv.replaceExpression(entry.getValue());
                entry.setValue(ex);
            } else {
                PreOrPostOrderNavigator.doVisit(entry.getValue(), rrv, PreOrPostOrderNavigator.PRE_ORDER);
            }
        }
    }
    FrameUtil.convertFrame(frame, virtualGroup, groups, symbolMap.asMap(), metadata);
    PlanNode parentBottom = frame.getParent();
    prepareFrame(frame);
    if (sources.isEmpty() && parentJoin != null) {
        // special handling for no sources
        PlanNode parent = frame;
        List<PlanNode> criteriaNodes = new ArrayList<PlanNode>();
        while (parent.getParent() != parentJoin) {
            parent = parent.getParent();
            if (!parent.hasBooleanProperty(Info.IS_PHANTOM)) {
                criteriaNodes.add(parent);
            }
        }
        PlanNode parentNode = parentJoin.getParent();
        parentJoin.removeChild(parent);
        PlanNode other = parentJoin.getFirstChild();
        NodeEditor.removeChildNode(parentNode, parentJoin);
        JoinType jt = (JoinType) parentJoin.getProperty(Info.JOIN_TYPE);
        if (!jt.isOuter()) {
            // if we are not an outer join then the join/parent criteria is effectively
            // applied to the other side
            List<Criteria> joinCriteria = (List<Criteria>) parentJoin.getProperty(Info.JOIN_CRITERIA);
            if (joinCriteria != null) {
                for (Criteria crit : joinCriteria) {
                    PlanNode critNode = RelationalPlanner.createSelectNode(crit, false);
                    criteriaNodes.add(critNode);
                }
            }
            if (!criteriaNodes.isEmpty()) {
                for (PlanNode selectNode : criteriaNodes) {
                    selectNode.removeAllChildren();
                    selectNode.removeFromParent();
                    other.addAsParent(selectNode);
                }
            }
        }
    } else {
        // Remove top 2 nodes (SOURCE, PROJECT) of virtual group - they're no longer needed
        NodeEditor.removeChildNode(parentBottom, frame);
        NodeEditor.removeChildNode(parentBottom, projectNode);
    }
    return root;
}
Also used : OrderBy(org.teiid.query.sql.lang.OrderBy) ElementSymbol(org.teiid.query.sql.symbol.ElementSymbol) Reference(org.teiid.query.sql.symbol.Reference) ArrayList(java.util.ArrayList) JoinType(org.teiid.query.sql.lang.JoinType) SymbolMap(org.teiid.query.sql.util.SymbolMap) Criteria(org.teiid.query.sql.lang.Criteria) PlanNode(org.teiid.query.optimizer.relational.plantree.PlanNode) OrderByItem(org.teiid.query.sql.lang.OrderByItem) Expression(org.teiid.query.sql.symbol.Expression) GroupSymbol(org.teiid.query.sql.symbol.GroupSymbol) ArrayList(java.util.ArrayList) LinkedList(java.util.LinkedList) List(java.util.List)

Example 18 with Reference

use of org.teiid.query.sql.symbol.Reference in project teiid by teiid.

the class RulePlanProcedures method execute.

/**
 * @see org.teiid.query.optimizer.relational.OptimizerRule#execute(org.teiid.query.optimizer.relational.plantree.PlanNode, org.teiid.query.metadata.QueryMetadataInterface, org.teiid.query.optimizer.capabilities.CapabilitiesFinder, org.teiid.query.optimizer.relational.RuleStack, org.teiid.query.analysis.AnalysisRecord, org.teiid.query.util.CommandContext)
 */
public PlanNode execute(PlanNode plan, final QueryMetadataInterface metadata, CapabilitiesFinder capabilitiesFinder, RuleStack rules, AnalysisRecord analysisRecord, CommandContext context) throws QueryPlannerException, QueryMetadataException, TeiidComponentException {
    for (PlanNode node : NodeEditor.findAllNodes(plan, NodeConstants.Types.SOURCE, NodeConstants.Types.ACCESS)) {
        if (!FrameUtil.isProcedure(node.getFirstChild())) {
            continue;
        }
        StoredProcedure proc = (StoredProcedure) node.getProperty(NodeConstants.Info.NESTED_COMMAND);
        if (!proc.isProcedureRelational()) {
            continue;
        }
        HashSet<ElementSymbol> inputSymbols = new HashSet<ElementSymbol>();
        List<Reference> inputReferences = new LinkedList<Reference>();
        PlanNode critNode = node.getParent();
        List<Criteria> conjuncts = new LinkedList<Criteria>();
        HashSet<ElementSymbol> coveredParams = new HashSet<ElementSymbol>();
        for (Iterator<SPParameter> params = proc.getInputParameters().iterator(); params.hasNext(); ) {
            SPParameter param = params.next();
            ElementSymbol symbol = param.getParameterSymbol();
            Expression input = param.getExpression();
            inputReferences.add((Reference) input);
            inputSymbols.add(symbol);
        }
        findInputNodes(inputSymbols, critNode, conjuncts, coveredParams);
        List<Expression> defaults = new LinkedList<Expression>();
        for (Reference ref : inputReferences) {
            ElementSymbol symbol = ref.getExpression();
            Expression defaultValue = null;
            /*try {
                    defaultValue = ResolverUtil.getDefault(symbol, metadata);
                } catch (QueryResolverException qre) {
                    //Just ignore
                }*/
            defaults.add(defaultValue);
            if (defaultValue == null && !coveredParams.contains(symbol)) {
                throw new QueryPlannerException(QueryPlugin.Event.TEIID30270, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30270, symbol));
            }
        }
        /*if (conjuncts.isEmpty()) {
                for (int j = 0; j < inputReferences.size(); j++) {
                    Reference ref = (Reference)inputReferences.get(j);
                    ref.setValue(defaults.get(j));
                }
                continue;
            }*/
        PlanNode accessNode = NodeEditor.findNodePreOrder(node, NodeConstants.Types.ACCESS);
        Criteria crit = Criteria.combineCriteria(conjuncts);
        if (crit != null) {
            accessNode.setProperty(NodeConstants.Info.PROCEDURE_CRITERIA, crit);
            accessNode.setProperty(NodeConstants.Info.PROCEDURE_INPUTS, inputReferences);
            accessNode.setProperty(NodeConstants.Info.PROCEDURE_DEFAULTS, defaults);
            accessNode.setProperty(NodeConstants.Info.IS_DEPENDENT_SET, Boolean.TRUE);
        }
    }
    return plan;
}
Also used : ElementSymbol(org.teiid.query.sql.symbol.ElementSymbol) Reference(org.teiid.query.sql.symbol.Reference) SPParameter(org.teiid.query.sql.lang.SPParameter) DependentSetCriteria(org.teiid.query.sql.lang.DependentSetCriteria) IsNullCriteria(org.teiid.query.sql.lang.IsNullCriteria) Criteria(org.teiid.query.sql.lang.Criteria) CompareCriteria(org.teiid.query.sql.lang.CompareCriteria) SetCriteria(org.teiid.query.sql.lang.SetCriteria) LinkedList(java.util.LinkedList) PlanNode(org.teiid.query.optimizer.relational.plantree.PlanNode) StoredProcedure(org.teiid.query.sql.lang.StoredProcedure) Expression(org.teiid.query.sql.symbol.Expression) QueryPlannerException(org.teiid.api.exception.query.QueryPlannerException) HashSet(java.util.HashSet)

Example 19 with Reference

use of org.teiid.query.sql.symbol.Reference in project teiid by teiid.

the class PlanToProcessConverter method aliasCommand.

private Command aliasCommand(AccessNode aNode, Command command, Object modelID) throws TeiidComponentException, QueryPlannerException {
    try {
        command = (Command) command.clone();
        boolean aliasGroups = modelID != null && (CapabilitiesUtil.supportsGroupAliases(modelID, metadata, capFinder) || CapabilitiesUtil.supports(Capability.QUERY_FROM_INLINE_VIEWS, modelID, metadata, capFinder));
        boolean aliasColumns = modelID != null && (CapabilitiesUtil.supports(Capability.QUERY_SELECT_EXPRESSION, modelID, metadata, capFinder) || CapabilitiesUtil.supports(Capability.QUERY_FROM_INLINE_VIEWS, modelID, metadata, capFinder));
        AliasGenerator visitor = new AliasGenerator(aliasGroups, !aliasColumns);
        SourceHint sh = command.getSourceHint();
        if (sh != null && aliasGroups) {
            VDBMetaData vdb = context.getDQPWorkContext().getVDB();
            ModelMetaData model = vdb.getModel(aNode.getModelName());
            List<String> sourceNames = model.getSourceNames();
            SpecificHint sp = null;
            if (sourceNames.size() == 1) {
                sp = sh.getSpecificHint(sourceNames.get(0));
            }
            if (sh.isUseAliases() || (sp != null && sp.isUseAliases())) {
                visitor.setAliasMapping(context.getAliasMapping());
            }
        }
        List<Reference> references = ReferenceCollectorVisitor.getReferences(command);
        if (!references.isEmpty()) {
            Set<String> correleatedGroups = new TreeSet<String>(String.CASE_INSENSITIVE_ORDER);
            for (Reference ref : references) {
                if (ref.isCorrelated() && ref.getExpression().getGroupSymbol() != null) {
                    correleatedGroups.add(ref.getExpression().getGroupSymbol().getName());
                }
            }
            visitor.setCorrelationGroups(correleatedGroups);
        }
        command.acceptVisitor(visitor);
    } catch (QueryMetadataException err) {
        throw new TeiidComponentException(QueryPlugin.Event.TEIID30249, err);
    } catch (TeiidRuntimeException e) {
        if (e.getCause() instanceof QueryPlannerException) {
            throw (QueryPlannerException) e.getCause();
        }
        throw e;
    }
    return command;
}
Also used : Reference(org.teiid.query.sql.symbol.Reference) SpecificHint(org.teiid.query.sql.lang.SourceHint.SpecificHint) TeiidRuntimeException(org.teiid.core.TeiidRuntimeException) QueryMetadataException(org.teiid.api.exception.query.QueryMetadataException) ModelMetaData(org.teiid.adminapi.impl.ModelMetaData) VDBMetaData(org.teiid.adminapi.impl.VDBMetaData) TeiidComponentException(org.teiid.core.TeiidComponentException) QueryPlannerException(org.teiid.api.exception.query.QueryPlannerException)

Example 20 with Reference

use of org.teiid.query.sql.symbol.Reference in project teiid by teiid.

the class TempMetadataStore method createElementSymbol.

private TempMetadataID createElementSymbol(String tempName, Expression symbol, boolean isTempTable) {
    // Create new element name
    String elementName = tempName + Symbol.SEPARATOR + Symbol.getShortName(symbol);
    Object metadataID = null;
    if (symbol instanceof AliasSymbol) {
        AliasSymbol as = (AliasSymbol) symbol;
        symbol = as.getSymbol();
    }
    // the following allows for original metadata ids to be determined for proc inputs
    if (symbol instanceof ExpressionSymbol) {
        Expression expr = ((ExpressionSymbol) symbol).getExpression();
        if (expr instanceof Reference) {
            expr = ((Reference) expr).getExpression();
        }
        if (expr instanceof ElementSymbol) {
            symbol = expr;
        }
    }
    if (symbol instanceof ElementSymbol) {
        metadataID = ((ElementSymbol) symbol).getMetadataID();
    }
    while (metadataID != null && metadataID instanceof TempMetadataID) {
        metadataID = ((TempMetadataID) metadataID).getOriginalMetadataID();
    }
    TempMetadataID elementID = new TempMetadataID(elementName, symbol.getType(), metadataID);
    elementID.setTempTable(isTempTable);
    return elementID;
}
Also used : ElementSymbol(org.teiid.query.sql.symbol.ElementSymbol) AliasSymbol(org.teiid.query.sql.symbol.AliasSymbol) Expression(org.teiid.query.sql.symbol.Expression) Reference(org.teiid.query.sql.symbol.Reference) ExpressionSymbol(org.teiid.query.sql.symbol.ExpressionSymbol)

Aggregations

Reference (org.teiid.query.sql.symbol.Reference)42 Test (org.junit.Test)15 Constant (org.teiid.query.sql.symbol.Constant)14 GroupSymbol (org.teiid.query.sql.symbol.GroupSymbol)14 ElementSymbol (org.teiid.query.sql.symbol.ElementSymbol)12 Expression (org.teiid.query.sql.symbol.Expression)11 Limit (org.teiid.query.sql.lang.Limit)7 Query (org.teiid.query.sql.lang.Query)7 MultipleElementSymbol (org.teiid.query.sql.symbol.MultipleElementSymbol)7 ArrayList (java.util.ArrayList)6 Criteria (org.teiid.query.sql.lang.Criteria)6 LinkedList (java.util.LinkedList)5 From (org.teiid.query.sql.lang.From)5 Select (org.teiid.query.sql.lang.Select)5 SetQuery (org.teiid.query.sql.lang.SetQuery)5 StoredProcedure (org.teiid.query.sql.lang.StoredProcedure)5 UnaryFromClause (org.teiid.query.sql.lang.UnaryFromClause)5 Column (org.teiid.metadata.Column)4 Command (org.teiid.query.sql.lang.Command)4 SPParameter (org.teiid.query.sql.lang.SPParameter)4