All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.deephaven.sql.LogicalAggregateAdapter Maven / Gradle / Ivy

//
// Copyright (c) 2016-2024 Deephaven Data Labs and Patent Pending
//
package io.deephaven.sql;

import io.deephaven.api.ColumnName;
import io.deephaven.api.Selectable;
import io.deephaven.qst.table.AggregateTable;
import io.deephaven.qst.table.SelectDistinctTable;
import io.deephaven.qst.table.TableSpec;
import io.deephaven.qst.table.ViewTable;
import org.apache.calcite.rel.core.AggregateCall;
import org.apache.calcite.rel.logical.LogicalAggregate;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

final class LogicalAggregateAdapter {

    public static TableSpec namedTable(SqlRootContext rootContext, LogicalAggregate aggregate) {
        return of(rootContext, aggregate, rootContext.namedAdapter());
    }

    public static TableSpec indexTable(SqlRootContext rootContext, LogicalAggregate aggregate, IndexRef indexRef) {
        return of(rootContext, aggregate, indexRef);
    }

    private static TableSpec of(SqlRootContext rootContext, LogicalAggregate aggregate, FieldAdapter fieldAdapter) {
        final IndexRef indexInputRef = rootContext.createIndexRef(Prefix.AGGREGATE, aggregate);
        final TableSpec parent = indexInputRef.table(aggregate.getInput());
        final int groupCount = aggregate.getGroupCount();
        final int outputFieldCount = aggregate.getRowType().getFieldCount();
        final List groupByColumns = new ArrayList<>(groupCount);
        Iterator groupInputIt = aggregate.getGroupSet().iterator();
        int groupI = 0;
        for (; groupI < groupCount && groupInputIt.hasNext(); ++groupI) {
            final int groupInputIndex = groupInputIt.next();
            groupByColumns.add(Helper.inputColumnName(aggregate, groupInputIndex, indexInputRef));
        }
        if (groupI != groupCount || groupInputIt.hasNext()) {
            throw new IllegalStateException();
        }
        final TableSpec aggTable;
        if (groupCount == outputFieldCount) {
            // this is how calcite expresses SELECT DISTINCT
            aggTable = SelectDistinctTable.builder().parent(parent).addAllColumns(groupByColumns).build();
        } else {
            AggregateTable.Builder builder =
                    AggregateTable.builder().parent(parent).addAllGroupByColumns(groupByColumns);
            for (int outFieldIndex = groupCount; outFieldIndex < outputFieldCount; ++outFieldIndex) {
                final AggregateCall aggregateCall = aggregate.getAggCallList().get(outFieldIndex - groupCount);
                final List inColumns = new ArrayList<>(aggregateCall.getArgList().size());
                for (int inputIndex : aggregateCall.getArgList()) {
                    inColumns.add(Helper.inputColumnName(aggregate, inputIndex, indexInputRef));
                }
                final ColumnName outColumn = Helper.outputColumnName(aggregate, outFieldIndex, fieldAdapter);
                builder.addAggregations(AggregateCallAdapterImpl.aggregation(aggregateCall, outColumn, inColumns));
            }
            aggTable = builder.build();
        }
        if (groupCount == 0) {
            return aggTable;
        }
        // If group columns are present, we need to rename them.
        final ViewTable.Builder viewBuilder = ViewTable.builder().parent(aggTable);
        groupInputIt = aggregate.getGroupSet().iterator();
        for (groupI = 0; groupI < groupCount && groupInputIt.hasNext(); ++groupI) {
            final int groupInputIndex = groupInputIt.next();
            final ColumnName newColumn = Helper.outputColumnName(aggregate, groupI, fieldAdapter);
            final ColumnName existing = Helper.inputColumnName(aggregate, groupInputIndex, indexInputRef);
            viewBuilder.addColumns(Selectable.of(newColumn, existing));
        }
        if (groupI != groupCount || groupInputIt.hasNext()) {
            throw new IllegalStateException();
        }
        for (int i = groupCount; i < outputFieldCount; ++i) {
            viewBuilder.addColumns(Helper.outputColumnName(aggregate, i, fieldAdapter));
        }
        return viewBuilder.build();
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy