Search in sources :

Example 11 with AliasSymbol

use of org.teiid.query.sql.symbol.AliasSymbol 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)

Example 12 with AliasSymbol

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

the class RulePlanSorts method checkForProjectOptimization.

static PlanNode checkForProjectOptimization(PlanNode node, PlanNode root, QueryMetadataInterface metadata, CapabilitiesFinder capFinder, AnalysisRecord record, CommandContext context) throws QueryMetadataException, TeiidComponentException, QueryPlannerException {
    PlanNode projectNode = node.getFirstChild();
    PlanNode parent = node.getParent();
    boolean raiseAccess = false;
    // special check for unrelated order by compensation
    if (projectNode.getType() == NodeConstants.Types.ACCESS && RuleRaiseAccess.canRaiseOverSort(projectNode, metadata, capFinder, node, record, true, context)) {
        projectNode = NodeEditor.findNodePreOrder(projectNode, NodeConstants.Types.PROJECT, NodeConstants.Types.SOURCE | NodeConstants.Types.SET_OP);
        if (projectNode == null) {
            // no interviening project
            return root;
        }
        raiseAccess = true;
    } else if (projectNode.getType() == NodeConstants.Types.PROJECT && projectNode.getFirstChild() != null) {
        raiseAccess = projectNode.getFirstChild().getType() == NodeConstants.Types.ACCESS && RuleRaiseAccess.canRaiseOverSort(projectNode.getFirstChild(), metadata, capFinder, node, record, false, context);
        // if we can't raise the access node and this doesn't have a limit, there's no point in optimizing
        if (!raiseAccess && (parent == null || parent.getType() != NodeConstants.Types.TUPLE_LIMIT)) {
            return root;
        }
    } else {
        return root;
    }
    List<Expression> childOutputCols = (List<Expression>) projectNode.getFirstChild().getProperty(Info.OUTPUT_COLS);
    OrderBy orderBy = (OrderBy) node.getProperty(Info.SORT_ORDER);
    List<Expression> orderByKeys = orderBy.getSortKeys();
    LinkedHashSet<Expression> toProject = new LinkedHashSet();
    for (Expression ss : orderByKeys) {
        Expression original = ss;
        if (ss instanceof AliasSymbol) {
            ss = ((AliasSymbol) ss).getSymbol();
        }
        if (ss instanceof ExpressionSymbol) {
            if (!raiseAccess) {
                // TODO: insert a new project node to handle this case
                return root;
            }
        }
        if (!childOutputCols.contains(ss)) {
            if (!raiseAccess) {
                return root;
            }
            toProject.add(original);
        }
    }
    PlanNode toRepair = projectNode.getParent();
    if (!toProject.isEmpty()) {
        PlanNode intermediateProject = NodeFactory.getNewNode(NodeConstants.Types.PROJECT);
        toProject.addAll(childOutputCols);
        List<Expression> projectCols = new ArrayList<Expression>(toProject);
        childOutputCols = projectCols;
        intermediateProject.setProperty(NodeConstants.Info.PROJECT_COLS, projectCols);
        intermediateProject.setProperty(NodeConstants.Info.OUTPUT_COLS, new ArrayList<Expression>(projectCols));
        toRepair.getFirstChild().addAsParent(intermediateProject);
    }
    NodeEditor.removeChildNode(projectNode.getParent(), projectNode);
    if (parent != null && parent.getType() == NodeConstants.Types.TUPLE_LIMIT && parent.getParent() != null) {
        parent.addAsParent(projectNode);
    } else {
        if (parent == null) {
            root = projectNode;
        }
        if (parent != null && parent.getType() == NodeConstants.Types.TUPLE_LIMIT) {
            if (root == parent) {
                root = projectNode;
            }
            projectNode.addFirstChild(parent);
        } else {
            projectNode.addFirstChild(node);
        }
    }
    List<Expression> orderByOutputSymbols = (List<Expression>) node.getProperty(Info.OUTPUT_COLS);
    boolean unrelated = false;
    if (node.hasBooleanProperty(Info.UNRELATED_SORT)) {
        node.setProperty(Info.UNRELATED_SORT, false);
        unrelated = true;
    }
    for (OrderByItem item : orderBy.getOrderByItems()) {
        if (unrelated || !toProject.isEmpty()) {
            // update sort order
            int index = childOutputCols.indexOf(item.getSymbol());
            item.setExpressionPosition(index);
        }
        if (toProject.isEmpty()) {
            // strip alias as project was raised
            if (item.getSymbol() instanceof AliasSymbol) {
                item.setSymbol(((AliasSymbol) item.getSymbol()).getSymbol());
            }
        }
    }
    while (toRepair != node) {
        toRepair.setProperty(Info.OUTPUT_COLS, childOutputCols);
        toRepair = toRepair.getParent();
    }
    projectNode.setProperty(Info.OUTPUT_COLS, orderByOutputSymbols);
    projectNode.setProperty(Info.PROJECT_COLS, orderByOutputSymbols);
    node.setProperty(Info.OUTPUT_COLS, childOutputCols);
    if (parent != null) {
        parent.setProperty(Info.OUTPUT_COLS, childOutputCols);
    }
    if (raiseAccess) {
        PlanNode accessNode = NodeEditor.findNodePreOrder(node, NodeConstants.Types.ACCESS);
        // instead of just calling ruleraiseaccess, we're more selective
        // we do not want to raise the access node over a project that is handling an unrelated sort
        PlanNode newRoot = RuleRaiseAccess.raiseAccessNode(root, accessNode, metadata, capFinder, true, record, context);
        if (newRoot != null) {
            accessNode.setProperty(NodeConstants.Info.OUTPUT_COLS, childOutputCols);
            root = newRoot;
            if (!toProject.isEmpty()) {
                newRoot = RuleRaiseAccess.raiseAccessNode(root, accessNode, metadata, capFinder, true, record, context);
            }
            if (newRoot != null) {
                root = newRoot;
                if (accessNode.getParent().getType() == NodeConstants.Types.TUPLE_LIMIT) {
                    newRoot = RulePushLimit.raiseAccessOverLimit(root, accessNode, metadata, capFinder, accessNode.getParent(), record);
                }
                if (newRoot != null) {
                    root = newRoot;
                }
            }
        }
    }
    return root;
}
Also used : OrderBy(org.teiid.query.sql.lang.OrderBy) LinkedHashSet(java.util.LinkedHashSet) ArrayList(java.util.ArrayList) ExpressionSymbol(org.teiid.query.sql.symbol.ExpressionSymbol) PlanNode(org.teiid.query.optimizer.relational.plantree.PlanNode) AliasSymbol(org.teiid.query.sql.symbol.AliasSymbol) OrderByItem(org.teiid.query.sql.lang.OrderByItem) Expression(org.teiid.query.sql.symbol.Expression) ArrayList(java.util.ArrayList) List(java.util.List)

Example 13 with AliasSymbol

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

the class AliasGenerator method visit.

public void visit(OrderBy obj) {
    // add/correct aliases if necessary
    for (int i = 0; i < obj.getVariableCount(); i++) {
        OrderByItem item = obj.getOrderByItems().get(i);
        Expression element = item.getSymbol();
        visitNode(element);
        Expression expr = SymbolMap.getExpression(element);
        if (item.isUnrelated()) {
            item.setSymbol(expr);
            continue;
        }
        String name = null;
        if (visitor.namingContext.currentSymbols != null) {
            name = visitor.namingContext.currentSymbols.get(element);
        }
        if (name == null) {
            // this is a bit messy, because we have cloned to do the aliasing, there
            // is a chance that a subquery is throwing off the above get
            int pos = item.getExpressionPosition();
            if (pos < visitor.namingContext.currentSymbols.size()) {
                ArrayList<Map.Entry<Expression, String>> list = new ArrayList<Map.Entry<Expression, String>>(visitor.namingContext.currentSymbols.entrySet());
                name = list.get(pos).getValue();
                expr = SymbolMap.getExpression(list.get(pos).getKey());
            } else {
                name = Symbol.getShortName(element);
            }
        }
        boolean needsAlias = visitor.namingContext.aliasColumns;
        if (name == null) {
            continue;
        }
        if (expr instanceof ElementSymbol) {
            needsAlias &= needsAlias(name, (ElementSymbol) expr);
        }
        if (needsAlias) {
            element = new AliasSymbol(Symbol.getShortName(element), expr);
        } else {
            element = expr;
            if (expr instanceof ElementSymbol && visitor.namingContext.aliasColumns) {
                ((ElementSymbol) expr).setDisplayMode(DisplayMode.SHORT_OUTPUT_NAME);
            }
        }
        item.setSymbol(element);
        if (element instanceof Symbol) {
            ((Symbol) element).setShortName(name);
        }
    }
}
Also used : ElementSymbol(org.teiid.query.sql.symbol.ElementSymbol) Entry(java.util.Map.Entry) AliasSymbol(org.teiid.query.sql.symbol.AliasSymbol) Expression(org.teiid.query.sql.symbol.Expression) AliasSymbol(org.teiid.query.sql.symbol.AliasSymbol) Symbol(org.teiid.query.sql.symbol.Symbol) ElementSymbol(org.teiid.query.sql.symbol.ElementSymbol) GroupSymbol(org.teiid.query.sql.symbol.GroupSymbol) ArrayList(java.util.ArrayList) HashMap(java.util.HashMap) SymbolMap(org.teiid.query.sql.util.SymbolMap) LinkedHashMap(java.util.LinkedHashMap) Map(java.util.Map)

Example 14 with AliasSymbol

use of org.teiid.query.sql.symbol.AliasSymbol 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 15 with AliasSymbol

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

the class ProjectNode method init.

void init() {
    List<? extends Expression> childElements = getChildren()[0].getElements();
    // Create element lookup map for evaluating project expressions
    this.elementMap = createLookupMap(childElements);
    // Check whether project needed at all - this occurs if:
    // 1. outputMap == null (see previous block)
    // 2. project elements are either elements or aggregate symbols (no processing required)
    // 3. order of input values == order of output values
    needsProject = childElements.size() != selectSymbols.size();
    for (int i = 0; i < selectSymbols.size(); i++) {
        Expression symbol = selectSymbols.get(i);
        if (symbol instanceof AliasSymbol) {
            Integer index = elementMap.get(symbol);
            if (index != null && index.intValue() == i) {
                projectionIndexes[i] = index;
                continue;
            }
            symbol = ((AliasSymbol) symbol).getSymbol();
        }
        Integer index = elementMap.get(symbol);
        if (index == null) {
            needsProject = true;
        } else {
            if (index.intValue() != i) {
                needsProject = true;
            }
            projectionIndexes[i] = index;
        }
    }
}
Also used : AliasSymbol(org.teiid.query.sql.symbol.AliasSymbol) Expression(org.teiid.query.sql.symbol.Expression)

Aggregations

AliasSymbol (org.teiid.query.sql.symbol.AliasSymbol)19 Expression (org.teiid.query.sql.symbol.Expression)12 ElementSymbol (org.teiid.query.sql.symbol.ElementSymbol)9 ArrayList (java.util.ArrayList)7 ExpressionSymbol (org.teiid.query.sql.symbol.ExpressionSymbol)5 List (java.util.List)3 Map (java.util.Map)3 OrderBy (org.teiid.query.sql.lang.OrderBy)3 AggregateSymbol (org.teiid.query.sql.symbol.AggregateSymbol)3 Constant (org.teiid.query.sql.symbol.Constant)3 GroupSymbol (org.teiid.query.sql.symbol.GroupSymbol)3 SymbolMap (org.teiid.query.sql.util.SymbolMap)3 HashMap (java.util.HashMap)2 LinkedHashMap (java.util.LinkedHashMap)2 LinkedHashSet (java.util.LinkedHashSet)2 Test (org.junit.Test)2 TeiidRuntimeException (org.teiid.core.TeiidRuntimeException)2 TempMetadataStore (org.teiid.query.metadata.TempMetadataStore)2 PlanNode (org.teiid.query.optimizer.relational.plantree.PlanNode)2 Reference (org.teiid.query.sql.symbol.Reference)2