Search in sources :

Example 31 with AggregateSymbol

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

the class AccessNode method multiSourceModify.

private static RelationalNode multiSourceModify(AccessNode accessNode, Expression ex, QueryMetadataInterface metadata, List<String> sourceNames) throws TeiidComponentException, TeiidProcessingException {
    List<AccessNode> accessNodes = new ArrayList<AccessNode>();
    boolean hasOutParams = RelationalNodeUtil.hasOutputParams(accessNode.getCommand());
    if (!Constant.NULL_CONSTANT.equals(ex)) {
        for (String sourceName : sourceNames) {
            Command command = accessNode.getCommand();
            // Modify the command to pull the instance column and evaluate the criteria
            if (!(command instanceof Insert || command instanceof StoredProcedure)) {
                command = (Command) command.clone();
                MultiSourceElementReplacementVisitor.visit(sourceName, metadata, command);
                if (!RelationalNodeUtil.shouldExecute(command, false, true)) {
                    continue;
                }
            }
            // Create a new cloned version of the access node and set it's model name to be the bindingUUID
            AccessNode instanceNode = (AccessNode) accessNode.clone();
            instanceNode.setMultiSource(false);
            instanceNode.setCommand(command);
            accessNodes.add(instanceNode);
            if (accessNodes.size() > 1 && command instanceof Insert) {
                // $NON-NLS-1$
                throw new AssertionError("Multi-source insert must target a single source.  Should have been caught in validation");
            }
            instanceNode.setConnectorBindingId(sourceName);
        }
    }
    if (hasOutParams && accessNodes.size() != 1) {
        throw new QueryProcessingException(QueryPlugin.Event.TEIID30561, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30561, accessNode.getCommand()));
    }
    switch(accessNodes.size()) {
        case 0:
            {
                if (RelationalNodeUtil.isUpdate(accessNode.getCommand())) {
                    // should return a 0 update count
                    ProjectNode pnode = new ProjectNode(accessNode.getID());
                    pnode.setSelectSymbols(Arrays.asList(new Constant(0)));
                    return pnode;
                }
                // Replace existing access node with a NullNode
                NullNode nullNode = new NullNode(accessNode.getID());
                return nullNode;
            }
        case 1:
            {
                // Replace existing access node with new access node (simplified command)
                return accessNodes.get(0);
            }
        default:
            {
                UnionAllNode unionNode = new UnionAllNode(accessNode.getID());
                unionNode.setElements(accessNode.getElements());
                for (AccessNode newNode : accessNodes) {
                    unionNode.addChild(newNode);
                }
                RelationalNode parent = unionNode;
                // More than 1 access node - replace with a union
                if (RelationalNodeUtil.isUpdate(accessNode.getCommand())) {
                    GroupingNode groupNode = new GroupingNode(accessNode.getID());
                    AggregateSymbol sumCount = new AggregateSymbol(NonReserved.SUM, false, accessNode.getElements().get(0));
                    groupNode.setElements(Arrays.asList(sumCount));
                    groupNode.addChild(unionNode);
                    ProjectNode projectNode = new ProjectNode(accessNode.getID());
                    Expression intSum = ResolverUtil.getConversion(sumCount, DataTypeManager.getDataTypeName(sumCount.getType()), DataTypeManager.DefaultDataTypes.INTEGER, false, metadata.getFunctionLibrary());
                    List<Expression> outputElements = Arrays.asList(intSum);
                    projectNode.setElements(outputElements);
                    projectNode.setSelectSymbols(outputElements);
                    projectNode.addChild(groupNode);
                    parent = projectNode;
                }
                return parent;
            }
    }
}
Also used : AggregateSymbol(org.teiid.query.sql.symbol.AggregateSymbol) Constant(org.teiid.query.sql.symbol.Constant) Insert(org.teiid.query.sql.lang.Insert) StoredProcedure(org.teiid.query.sql.lang.StoredProcedure) QueryCommand(org.teiid.query.sql.lang.QueryCommand) Command(org.teiid.query.sql.lang.Command) WithQueryCommand(org.teiid.query.sql.lang.WithQueryCommand) Expression(org.teiid.query.sql.symbol.Expression) QueryProcessingException(org.teiid.api.exception.query.QueryProcessingException)

Example 32 with AggregateSymbol

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

the class GroupingNode method collectionPhase.

private void collectionPhase() {
    if (this.orderBy == null) {
        // No need to sort
        this.groupTupleSource = getGroupSortTupleSource();
        this.phase = GROUP;
    } else {
        List<NullOrdering> nullOrdering = new ArrayList<NullOrdering>(orderBy.size());
        List<Boolean> sortTypes = new ArrayList<Boolean>(orderBy.size());
        int size = orderBy.size();
        if (this.removeDuplicates) {
            // sort on all inputs
            size = distinctCols;
        }
        int[] sortIndexes = new int[size];
        for (int i = 0; i < size; i++) {
            int index = i;
            if (i < this.orderBy.size()) {
                OrderByItem item = this.orderBy.get(i);
                nullOrdering.add(item.getNullOrdering());
                sortTypes.add(item.isAscending());
                index = collectedExpressions.get(SymbolMap.getExpression(item.getSymbol()));
            } else {
                nullOrdering.add(null);
                sortTypes.add(OrderBy.ASC);
            }
            sortIndexes[i] = index;
        }
        this.indexes = Arrays.copyOf(sortIndexes, orderBy.size());
        if (rollup) {
            this.indexMap = new HashMap<Integer, Integer>();
            for (int i = 0; i < indexes.length; i++) {
                this.indexMap.put(indexes[i], orderBy.size() - i);
            }
        } else if (!removeDuplicates) {
            boolean groupSort = true;
            List<AggregateFunction> aggs = new ArrayList<AggregateFunction>();
            List<Class<?>> allTypes = new ArrayList<Class<?>>();
            accumulatorStateCount = new int[this.functions.length];
            for (AggregateFunction[] afs : this.functions) {
                if (afs[0] instanceof ConstantFunction) {
                    continue;
                }
                aggs.add(afs[0]);
                List<? extends Class<?>> types = afs[0].getStateTypes();
                if (types == null) {
                    groupSort = false;
                    break;
                }
                accumulatorStateCount[aggs.size() - 1] = types.size();
                allTypes.addAll(types);
            }
            if (groupSort) {
                this.groupSortfunctions = aggs.toArray(new AggregateFunction[aggs.size()]);
                List<Expression> schema = new ArrayList<Expression>();
                for (OrderByItem item : this.orderBy) {
                    schema.add(SymbolMap.getExpression(item.getSymbol()));
                }
                List<? extends Expression> elements = getElements();
                this.projection = new int[elements.size()];
                int index = 0;
                for (int i = 0; i < elements.size(); i++) {
                    Expression symbol = elements.get(i);
                    if (this.outputMapping != null) {
                        symbol = outputMapping.getMappedExpression((ElementSymbol) symbol);
                    }
                    if (symbol instanceof AggregateSymbol) {
                        projection[i] = schema.size() + index++;
                    } else {
                        projection[i] = schema.indexOf(symbol);
                    }
                }
                // add in accumulator value types
                for (Class<?> type : allTypes) {
                    ElementSymbol es = new ElementSymbol("x");
                    es.setType(type);
                    schema.add(es);
                }
                tree = this.getBufferManager().createSTree(schema, this.getConnectionID(), orderBy.size());
                // non-default order needs to update the comparator
                tree.getComparator().setNullOrdering(nullOrdering);
                tree.getComparator().setOrderTypes(sortTypes);
                this.groupSortTupleSource = this.getGroupSortTupleSource();
                this.phase = GROUP_SORT;
                return;
            }
        }
        this.sortUtility = new SortUtility(getGroupSortTupleSource(), removeDuplicates ? Mode.DUP_REMOVE_SORT : Mode.SORT, getBufferManager(), getConnectionID(), new ArrayList<Expression>(collectedExpressions.keySet()), sortTypes, nullOrdering, sortIndexes);
        this.phase = SORT;
    }
}
Also used : ElementSymbol(org.teiid.query.sql.symbol.ElementSymbol) AggregateSymbol(org.teiid.query.sql.symbol.AggregateSymbol) ArrayList(java.util.ArrayList) OrderByItem(org.teiid.query.sql.lang.OrderByItem) Expression(org.teiid.query.sql.symbol.Expression) NullOrdering(org.teiid.language.SortSpecification.NullOrdering) ArrayList(java.util.ArrayList) List(java.util.List)

Example 33 with AggregateSymbol

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

the class TempTable method createTupleSource.

public TupleSource createTupleSource(final List<? extends Expression> projectedCols, final Criteria condition, OrderBy orderBy) throws TeiidComponentException, TeiidProcessingException {
    // special handling for count(*)
    boolean agg = false;
    for (Expression singleElementSymbol : projectedCols) {
        if (singleElementSymbol instanceof ExpressionSymbol && ((ExpressionSymbol) singleElementSymbol).getExpression() instanceof AggregateSymbol) {
            agg = true;
            break;
        }
    }
    if (agg) {
        if (condition == null) {
            long count = this.getRowCount();
            return new CollectionTupleSource(Arrays.asList(Collections.nCopies(projectedCols.size(), (int) Math.min(Integer.MAX_VALUE, count))).iterator());
        }
        orderBy = null;
    }
    IndexInfo primary = new IndexInfo(this, projectedCols, condition, orderBy, true);
    IndexInfo ii = primary;
    if ((indexTables != null || (!this.updatable && allowImplicitIndexing && condition != null && this.getRowCount() > 2 * this.getTree().getPageSize(true))) && (condition != null || orderBy != null) && ii.valueSet.size() != 1) {
        // $NON-NLS-1$ //$NON-NLS-2$
        LogManager.logDetail(LogConstants.CTX_DQP, "Considering indexes on table", this, "for query", projectedCols, condition, orderBy);
        long rowCost = this.tree.getRowCount();
        long bestCost = estimateCost(orderBy, ii, rowCost);
        if (this.indexTables != null) {
            for (TempTable table : this.indexTables.values()) {
                IndexInfo secondary = new IndexInfo(table, projectedCols, condition, orderBy, false);
                long cost = estimateCost(orderBy, secondary, rowCost);
                if (cost < bestCost) {
                    ii = secondary;
                    bestCost = cost;
                }
            }
        }
        if (ii == primary && allowImplicitIndexing) {
            // TODO: detect if it should be covering
            if (createImplicitIndexIfNeeded(condition)) {
                IndexInfo secondary = new IndexInfo(this.indexTables.values().iterator().next(), projectedCols, condition, orderBy, false);
                // $NON-NLS-1$
                LogManager.logDetail(LogConstants.CTX_DQP, "Created an implicit index ", secondary.table);
                long cost = estimateCost(orderBy, secondary, rowCost);
                if (cost < bestCost) {
                    ii = secondary;
                    bestCost = cost;
                } else {
                    // $NON-NLS-1$ //$NON-NLS-2$
                    LogManager.logDetail(LogConstants.CTX_DQP, "Did not utilize the implicit index");
                }
            }
        }
        // $NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
        LogManager.logDetail(LogConstants.CTX_DQP, "Choose index", ii.table, "covering:", ii.coveredCriteria, "ordering:", ii.ordering);
        if (ii.covering) {
            return ii.table.createTupleSource(projectedCols, condition, orderBy, ii, agg);
        }
        List<ElementSymbol> pkColumns = this.columns.subList(0, this.tree.getKeyLength());
        if (ii.ordering != null) {
            // use order and join
            primary.valueTs = ii.table.createTupleSource(pkColumns, ii.coveredCriteria, orderBy, ii, agg);
            primary.ordering = null;
            return createTupleSource(projectedCols, ii.nonCoveredCriteria, null, primary, agg);
        }
        // order by pk to localize lookup costs, then join
        OrderBy pkOrderBy = new OrderBy();
        for (ElementSymbol elementSymbol : pkColumns) {
            pkOrderBy.addVariable(elementSymbol);
        }
        primary.valueTs = ii.table.createTupleSource(pkColumns, ii.coveredCriteria, pkOrderBy, ii, agg);
        return createTupleSource(projectedCols, ii.nonCoveredCriteria, orderBy, primary, agg);
    }
    return createTupleSource(projectedCols, condition, orderBy, ii, agg);
}
Also used : ElementSymbol(org.teiid.query.sql.symbol.ElementSymbol) OrderBy(org.teiid.query.sql.lang.OrderBy) AggregateSymbol(org.teiid.query.sql.symbol.AggregateSymbol) Expression(org.teiid.query.sql.symbol.Expression) CollectionTupleSource(org.teiid.query.processor.CollectionTupleSource) ExpressionSymbol(org.teiid.query.sql.symbol.ExpressionSymbol)

Example 34 with AggregateSymbol

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

the class TestCapabilitiesUtil method testSupportsAggregate6.

// Test where capabilities support only COUNT
@Test
public void testSupportsAggregate6() throws Exception {
    BasicSourceCapabilities caps = new BasicSourceCapabilities();
    caps.setCapabilitySupport(Capability.QUERY_AGGREGATES, true);
    caps.setCapabilitySupport(Capability.QUERY_AGGREGATES_COUNT, true);
    caps.setCapabilitySupport(Capability.QUERY_AGGREGATES_COUNT_STAR, false);
    // $NON-NLS-1$ //$NON-NLS-2$
    AggregateSymbol aggregate = new AggregateSymbol(NonReserved.COUNT, false, new ElementSymbol("x"));
    helpTestSupportsAggregateFunction(caps, aggregate, true);
}
Also used : ElementSymbol(org.teiid.query.sql.symbol.ElementSymbol) AggregateSymbol(org.teiid.query.sql.symbol.AggregateSymbol) BasicSourceCapabilities(org.teiid.query.optimizer.capabilities.BasicSourceCapabilities) Test(org.junit.Test)

Example 35 with AggregateSymbol

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

the class TestCapabilitiesUtil method testSupportsAggregate2.

// Test where capabilities don't support COUNT
@Test
public void testSupportsAggregate2() throws Exception {
    BasicSourceCapabilities caps = new BasicSourceCapabilities();
    caps.setCapabilitySupport(Capability.QUERY_AGGREGATES, true);
    caps.setCapabilitySupport(Capability.QUERY_AGGREGATES_COUNT, false);
    caps.setCapabilitySupport(Capability.QUERY_AGGREGATES_COUNT_STAR, false);
    // $NON-NLS-1$
    AggregateSymbol aggregate = new AggregateSymbol(NonReserved.COUNT, false, null);
    helpTestSupportsAggregateFunction(caps, aggregate, false);
}
Also used : AggregateSymbol(org.teiid.query.sql.symbol.AggregateSymbol) BasicSourceCapabilities(org.teiid.query.optimizer.capabilities.BasicSourceCapabilities) Test(org.junit.Test)

Aggregations

AggregateSymbol (org.teiid.query.sql.symbol.AggregateSymbol)53 ElementSymbol (org.teiid.query.sql.symbol.ElementSymbol)27 Test (org.junit.Test)21 BasicSourceCapabilities (org.teiid.query.optimizer.capabilities.BasicSourceCapabilities)16 ArrayList (java.util.ArrayList)12 List (java.util.List)11 Expression (org.teiid.query.sql.symbol.Expression)9 OrderBy (org.teiid.query.sql.lang.OrderBy)8 CommandContext (org.teiid.query.util.CommandContext)6 BufferManager (org.teiid.common.buffer.BufferManager)5 SymbolMap (org.teiid.query.sql.util.SymbolMap)5 BigDecimal (java.math.BigDecimal)4 FakeTupleSource (org.teiid.query.processor.FakeTupleSource)4 Constant (org.teiid.query.sql.symbol.Constant)4 TeiidRuntimeException (org.teiid.core.TeiidRuntimeException)3 PlanNode (org.teiid.query.optimizer.relational.plantree.PlanNode)3 AliasSymbol (org.teiid.query.sql.symbol.AliasSymbol)3 ExpressionSymbol (org.teiid.query.sql.symbol.ExpressionSymbol)3 Map (java.util.Map)2 AggregateFunction (org.teiid.query.function.aggregate.AggregateFunction)2