Search in sources :

Example 1 with AggregateFunction

use of org.teiid.query.function.aggregate.AggregateFunction in project teiid by teiid.

the class WindowFunctionProjectNode method buildResults.

/**
 * Build the results by maintaining indexes that either map
 * rowid->values
 * or
 * rowid->partitionid and partitionid->values
 *
 * TODO use the size hint for tree balancing
 */
private void buildResults() throws TeiidComponentException, TeiidProcessingException, FunctionExecutionException, ExpressionEvaluationException {
    List<Map.Entry<WindowSpecification, WindowSpecificationInfo>> specs = new ArrayList<Map.Entry<WindowSpecification, WindowSpecificationInfo>>(windows.entrySet());
    for (int specIndex = 0; specIndex < specs.size(); specIndex++) {
        Map.Entry<WindowSpecification, WindowSpecificationInfo> entry = specs.get(specIndex);
        WindowSpecificationInfo info = entry.getValue();
        IndexedTupleSource specificationTs = tb.createIndexedTupleSource();
        boolean multiGroup = false;
        int[] partitionIndexes = null;
        int[] orderIndexes = null;
        // if there is partitioning or ordering, then sort
        if (!info.orderType.isEmpty()) {
            multiGroup = true;
            int[] sortKeys = new int[info.orderType.size()];
            int i = 0;
            if (!info.groupIndexes.isEmpty()) {
                for (Integer sortIndex : info.groupIndexes) {
                    sortKeys[i++] = sortIndex;
                }
                partitionIndexes = Arrays.copyOf(sortKeys, info.groupIndexes.size());
            }
            if (!info.sortIndexes.isEmpty()) {
                for (Integer sortIndex : info.sortIndexes) {
                    sortKeys[i++] = sortIndex;
                }
                orderIndexes = Arrays.copyOfRange(sortKeys, info.groupIndexes.size(), info.groupIndexes.size() + info.sortIndexes.size());
            }
            if (!info.functions.isEmpty()) {
                // $NON-NLS-1$
                ElementSymbol key = new ElementSymbol("rowId");
                key.setType(DataTypeManager.DefaultDataClasses.INTEGER);
                // $NON-NLS-1$
                ElementSymbol value = new ElementSymbol("partitionId");
                value.setType(DataTypeManager.DefaultDataClasses.INTEGER);
                List<ElementSymbol> elements = Arrays.asList(key, value);
                partitionMapping[specIndex] = this.getBufferManager().createSTree(elements, this.getConnectionID(), 1);
            }
            SortUtility su = new SortUtility(null, Mode.SORT, this.getBufferManager(), this.getConnectionID(), tb.getSchema(), info.orderType, info.nullOrderings, sortKeys);
            su.setWorkingBuffer(tb);
            su.setNonBlocking(true);
            TupleBuffer sorted = su.sort();
            specificationTs = sorted.createIndexedTupleSource(true);
        }
        List<AggregateFunction> aggs = initializeAccumulators(info.functions, specIndex, false);
        List<AggregateFunction> rowValueAggs = initializeAccumulators(info.rowValuefunctions, specIndex, true);
        int groupId = 0;
        List<?> lastRow = null;
        while (specificationTs.hasNext()) {
            List<?> tuple = specificationTs.nextTuple();
            if (multiGroup) {
                if (lastRow != null) {
                    boolean samePartition = GroupingNode.sameGroup(partitionIndexes, tuple, lastRow) == -1;
                    if (!aggs.isEmpty() && (!samePartition || GroupingNode.sameGroup(orderIndexes, tuple, lastRow) != -1)) {
                        saveValues(specIndex, aggs, groupId, samePartition, false);
                        groupId++;
                    }
                    saveValues(specIndex, rowValueAggs, lastRow.get(lastRow.size() - 1), samePartition, true);
                }
                if (!aggs.isEmpty()) {
                    List<Object> partitionTuple = Arrays.asList(tuple.get(tuple.size() - 1), groupId);
                    partitionMapping[specIndex].insert(partitionTuple, InsertMode.NEW, -1);
                }
            }
            for (AggregateFunction function : aggs) {
                function.addInput(tuple, getContext());
            }
            for (AggregateFunction function : rowValueAggs) {
                function.addInput(tuple, getContext());
            }
            lastRow = tuple;
        }
        if (lastRow != null) {
            saveValues(specIndex, aggs, groupId, true, false);
            saveValues(specIndex, rowValueAggs, lastRow.get(lastRow.size() - 1), true, true);
        }
    }
}
Also used : ElementSymbol(org.teiid.query.sql.symbol.ElementSymbol) ArrayList(java.util.ArrayList) TupleBuffer(org.teiid.common.buffer.TupleBuffer) WindowSpecification(org.teiid.query.sql.symbol.WindowSpecification) IndexedTupleSource(org.teiid.common.buffer.IndexedTupleSource) AggregateFunction(org.teiid.query.function.aggregate.AggregateFunction) LanguageObject(org.teiid.query.sql.LanguageObject) LinkedHashMap(java.util.LinkedHashMap) Map(java.util.Map) SymbolMap(org.teiid.query.sql.util.SymbolMap)

Example 2 with AggregateFunction

use of org.teiid.query.function.aggregate.AggregateFunction in project teiid by teiid.

the class WindowFunctionProjectNode method saveValues.

private void saveValues(int specIndex, List<AggregateFunction> aggs, Object id, boolean samePartition, boolean rowValue) throws FunctionExecutionException, ExpressionEvaluationException, TeiidComponentException, TeiidProcessingException {
    if (aggs.isEmpty()) {
        return;
    }
    List<Object> row = new ArrayList<Object>(aggs.size() + 1);
    row.add(id);
    for (AggregateFunction function : aggs) {
        row.add(function.getResult(getContext()));
        if (!samePartition) {
            function.reset();
        }
    }
    if (rowValue) {
        rowValueMapping[specIndex].insert(row, InsertMode.NEW, -1);
    } else {
        valueMapping[specIndex].insert(row, InsertMode.ORDERED, -1);
    }
}
Also used : AggregateFunction(org.teiid.query.function.aggregate.AggregateFunction) ArrayList(java.util.ArrayList) LanguageObject(org.teiid.query.sql.LanguageObject)

Example 3 with AggregateFunction

use of org.teiid.query.function.aggregate.AggregateFunction in project teiid by teiid.

the class WindowFunctionProjectNode method initializeAccumulators.

/**
 * @param functions
 * @param specIndex
 * @param rowValues
 * @return
 */
private List<AggregateFunction> initializeAccumulators(List<WindowFunctionInfo> functions, int specIndex, boolean rowValues) {
    List<AggregateFunction> aggs = new ArrayList<AggregateFunction>(functions.size());
    if (functions.isEmpty()) {
        return aggs;
    }
    List<ElementSymbol> elements = new ArrayList<ElementSymbol>(functions.size());
    // $NON-NLS-1$
    ElementSymbol key = new ElementSymbol("key");
    key.setType(DataTypeManager.DefaultDataClasses.INTEGER);
    elements.add(key);
    for (WindowFunctionInfo wfi : functions) {
        aggs.add(GroupingNode.initAccumulator(wfi.function.getFunction(), this, expressionIndexes));
        Class<?> outputType = wfi.function.getType();
        if (wfi.function.getFunction().getAggregateFunction() == Type.LEAD || wfi.function.getFunction().getAggregateFunction() == Type.LAG) {
            outputType = DataTypeManager.getArrayType(DataTypeManager.DefaultDataClasses.OBJECT);
        }
        // $NON-NLS-1$
        ElementSymbol value = new ElementSymbol("val");
        value.setType(outputType);
        elements.add(value);
    }
    if (!rowValues) {
        valueMapping[specIndex] = this.getBufferManager().createSTree(elements, this.getConnectionID(), 1);
    } else {
        rowValueMapping[specIndex] = this.getBufferManager().createSTree(elements, this.getConnectionID(), 1);
    }
    return aggs;
}
Also used : ElementSymbol(org.teiid.query.sql.symbol.ElementSymbol) AggregateFunction(org.teiid.query.function.aggregate.AggregateFunction) ArrayList(java.util.ArrayList)

Example 4 with AggregateFunction

use of org.teiid.query.function.aggregate.AggregateFunction in project teiid by teiid.

the class TestGroupingNode method test1.

// ################################## ACTUAL TESTS ################################
@Test
public void test1() throws Exception {
    BufferManager mgr = BufferManagerFactory.getStandaloneBufferManager();
    // Set up
    GroupingNode node = new GroupingNode(1);
    List outputElements = new ArrayList();
    // $NON-NLS-1$
    ElementSymbol col1 = new ElementSymbol("col1");
    col1.setType(Integer.class);
    // $NON-NLS-1$
    ElementSymbol col2 = new ElementSymbol("col2");
    col2.setType(Integer.class);
    outputElements.add(col1);
    // $NON-NLS-1$ //$NON-NLS-2$
    outputElements.add(new AggregateSymbol("COUNT", false, null));
    // $NON-NLS-1$ //$NON-NLS-2$
    outputElements.add(new AggregateSymbol("COUNT", false, col2));
    // $NON-NLS-1$ //$NON-NLS-2$
    outputElements.add(new AggregateSymbol("COUNT", true, col2));
    // $NON-NLS-1$ //$NON-NLS-2$
    outputElements.add(new AggregateSymbol("SUM", false, col2));
    // $NON-NLS-1$ //$NON-NLS-2$
    outputElements.add(new AggregateSymbol("SUM", true, col2));
    // $NON-NLS-1$ //$NON-NLS-2$
    outputElements.add(new AggregateSymbol("AVG", false, col2));
    // $NON-NLS-1$ //$NON-NLS-2$
    outputElements.add(new AggregateSymbol("AVG", true, col2));
    // $NON-NLS-1$ //$NON-NLS-2$
    outputElements.add(new AggregateSymbol("MIN", false, col2));
    // $NON-NLS-1$ //$NON-NLS-2$
    outputElements.add(new AggregateSymbol("MIN", true, col2));
    // $NON-NLS-1$ //$NON-NLS-2$
    outputElements.add(new AggregateSymbol("MAX", false, col2));
    // $NON-NLS-1$ //$NON-NLS-2$
    outputElements.add(new AggregateSymbol("MAX", true, col2));
    node.setElements(outputElements);
    List groupingElements = new ArrayList();
    groupingElements.add(col1);
    node.setOrderBy(new OrderBy(groupingElements).getOrderByItems());
    // $NON-NLS-1$ //$NON-NLS-2$
    CommandContext context = new CommandContext("pid", "test", null, null, 1);
    List[] expected = new List[] { Arrays.asList(new Object[] { null, new Integer(2), new Integer(1), new Integer(1), new Long(3), new Long(3), new BigDecimal(3.0), new BigDecimal(3.0), new Integer(3), new Integer(3), new Integer(3), new Integer(3) }), Arrays.asList(new Object[] { new Integer(0), new Integer(1), new Integer(1), new Integer(1), new Long(4), new Long(4), new BigDecimal(4.0), new BigDecimal(4.0), new Integer(4), new Integer(4), new Integer(4), new Integer(4) }), Arrays.asList(new Object[] { new Integer(1), new Integer(1), new Integer(1), new Integer(1), new Long(2), new Long(2), new BigDecimal(2.0), new BigDecimal(2.0), new Integer(2), new Integer(2), new Integer(2), new Integer(2) }), Arrays.asList(new Object[] { new Integer(2), new Integer(4), new Integer(4), new Integer(2), new Long(5), new Long(3), new BigDecimal(1.25), new BigDecimal(1.5), new Integer(1), new Integer(1), new Integer(2), new Integer(2) }), Arrays.asList(new Object[] { new Integer(3), new Integer(1), new Integer(1), new Integer(1), new Long(0), new Long(0), new BigDecimal(0.0), new BigDecimal(0.0), new Integer(0), new Integer(0), new Integer(0), new Integer(0) }), Arrays.asList(new Object[] { new Integer(4), new Integer(3), new Integer(2), new Integer(2), new Long(5), new Long(5), new BigDecimal(2.5), new BigDecimal(2.5), new Integer(2), new Integer(2), new Integer(3), new Integer(3) }), Arrays.asList(new Object[] { new Integer(5), new Integer(1), new Integer(1), new Integer(1), new Long(3), new Long(3), new BigDecimal(3.0), new BigDecimal(3.0), new Integer(3), new Integer(3), new Integer(3), new Integer(3) }), Arrays.asList(new Object[] { new Integer(6), new Integer(2), new Integer(2), new Integer(2), new Long(7), new Long(7), new BigDecimal(3.5), new BigDecimal(3.5), new Integer(3), new Integer(3), new Integer(4), new Integer(4) }) };
    helpProcess(mgr, node, context, expected, null);
    // ensure that the distinct input type is correct
    AggregateFunction[][] functions = node.getFunctions();
    AggregateFunction countDist = functions[5][0];
    SortingFilter dup = (SortingFilter) countDist;
    assertEquals(DataTypeManager.DefaultDataClasses.INTEGER, dup.getElements().get(0).getType());
}
Also used : ElementSymbol(org.teiid.query.sql.symbol.ElementSymbol) OrderBy(org.teiid.query.sql.lang.OrderBy) AggregateSymbol(org.teiid.query.sql.symbol.AggregateSymbol) CommandContext(org.teiid.query.util.CommandContext) ArrayList(java.util.ArrayList) BufferManager(org.teiid.common.buffer.BufferManager) BigDecimal(java.math.BigDecimal) AggregateFunction(org.teiid.query.function.aggregate.AggregateFunction) ArrayList(java.util.ArrayList) List(java.util.List) Test(org.junit.Test)

Aggregations

ArrayList (java.util.ArrayList)4 AggregateFunction (org.teiid.query.function.aggregate.AggregateFunction)4 ElementSymbol (org.teiid.query.sql.symbol.ElementSymbol)3 LanguageObject (org.teiid.query.sql.LanguageObject)2 BigDecimal (java.math.BigDecimal)1 LinkedHashMap (java.util.LinkedHashMap)1 List (java.util.List)1 Map (java.util.Map)1 Test (org.junit.Test)1 BufferManager (org.teiid.common.buffer.BufferManager)1 IndexedTupleSource (org.teiid.common.buffer.IndexedTupleSource)1 TupleBuffer (org.teiid.common.buffer.TupleBuffer)1 OrderBy (org.teiid.query.sql.lang.OrderBy)1 AggregateSymbol (org.teiid.query.sql.symbol.AggregateSymbol)1 WindowSpecification (org.teiid.query.sql.symbol.WindowSpecification)1 SymbolMap (org.teiid.query.sql.util.SymbolMap)1 CommandContext (org.teiid.query.util.CommandContext)1