Search in sources :

Example 1 with CubeStatement

use of io.hetu.core.spi.cube.CubeStatement in project hetu-core by openlookeng.

the class CubeStatementGenerator method generate.

public static CubeStatement generate(String fromTable, AggregationNode aggregationNode, Map<String, Object> symbolMappings) {
    CubeStatement.Builder builder = CubeStatement.newBuilder();
    builder.from(fromTable);
    Map<Symbol, AggregationNode.Aggregation> aggregations = aggregationNode.getAggregations();
    // Extract selection and aggregation
    for (Symbol symbol : aggregationNode.getOutputSymbols()) {
        Object column = symbolMappings.get(symbol.getName());
        if (column instanceof ColumnHandle) {
            // Selection
            String columnName = ((ColumnHandle) column).getColumnName();
            builder.select(columnName);
        } else if (aggregations.containsKey(symbol)) {
            // Aggregation
            Map<Symbol, AggregationSignature> signatures = Collections.emptyMap();
            AggregationNode.Aggregation aggregation = aggregations.get(symbol);
            List<RowExpression> arguments = aggregation.getArguments();
            if (arguments.isEmpty()) {
                signatures = createSignature(aggregation, symbol, null);
            } else if (arguments.size() == 1) {
                RowExpression argument = arguments.get(0);
                if (OriginalExpressionUtils.isExpression(argument)) {
                    Expression argAsExpr = OriginalExpressionUtils.castToExpression(argument);
                    if (argAsExpr instanceof SymbolReference) {
                        signatures = createSignature(aggregation, symbol, symbolMappings.get(((SymbolReference) argAsExpr).getName()));
                    }
                } else if (argument instanceof VariableReferenceExpression) {
                    signatures = createSignature(aggregation, symbol, symbolMappings.get(((VariableReferenceExpression) argument).getName()));
                }
            }
            if (signatures.isEmpty()) {
                throw new IllegalArgumentException("Failed to generate aggregator signature");
            }
            for (Map.Entry<Symbol, AggregationSignature> aggEntry : signatures.entrySet()) {
                builder.aggregate(aggEntry.getValue());
            }
        } else {
            throw new IllegalArgumentException("Column " + column + " is not an actual column or expressions");
        }
    }
    // Extract group by
    for (Symbol symbol : aggregationNode.getGroupingKeys()) {
        Object column = symbolMappings.get(symbol.getName());
        if (column instanceof ColumnHandle) {
            builder.groupByAddString(((ColumnHandle) column).getColumnName());
        } else {
            // Don't know how to handle it
            throw new IllegalArgumentException("Column " + symbol + " is not an actual column");
        }
    }
    return builder.build();
}
Also used : ColumnHandle(io.prestosql.spi.connector.ColumnHandle) Symbol(io.prestosql.spi.plan.Symbol) SymbolReference(io.prestosql.sql.tree.SymbolReference) RowExpression(io.prestosql.spi.relation.RowExpression) CubeStatement(io.hetu.core.spi.cube.CubeStatement) VariableReferenceExpression(io.prestosql.spi.relation.VariableReferenceExpression) RowExpression(io.prestosql.spi.relation.RowExpression) Expression(io.prestosql.sql.tree.Expression) VariableReferenceExpression(io.prestosql.spi.relation.VariableReferenceExpression) List(java.util.List) Map(java.util.Map)

Example 2 with CubeStatement

use of io.hetu.core.spi.cube.CubeStatement in project hetu-core by openlookeng.

the class TestStarTreeMetadata method testMetadataNotMatchesCubeStatement.

@Test
public void testMetadataNotMatchesCubeStatement() {
    CubeStatement statement = CubeStatement.newBuilder().select("returnflag", "linestatus").aggregate(avg("unknown", false)).from("tpch.tiny.lineitem").groupByAddStringList("returnflag", "linestatus").build();
    assertFalse(metadata.matches(statement), "failed to detect an invalid cube statement");
}
Also used : CubeStatement(io.hetu.core.spi.cube.CubeStatement) Test(org.testng.annotations.Test)

Example 3 with CubeStatement

use of io.hetu.core.spi.cube.CubeStatement in project hetu-core by openlookeng.

the class TestStarTreeMetadata method testMatchEmptyGroupMetadata.

@Test
public void testMatchEmptyGroupMetadata() {
    CubeStatement statement = CubeStatement.newBuilder().select("returnflag", "linestatus").aggregate(avg("quantity", false)).from("tpch.tiny.lineitem").build();
    assertTrue(emptyGroupMetadata.matches(statement));
}
Also used : CubeStatement(io.hetu.core.spi.cube.CubeStatement) Test(org.testng.annotations.Test)

Example 4 with CubeStatement

use of io.hetu.core.spi.cube.CubeStatement in project hetu-core by openlookeng.

the class StarTreeAggregationRule method optimize.

public Result optimize(AggregationNode aggregationNode, final PlanNode filterNode, TableScanNode tableScanNode, Map<String, Object> symbolMapping, Session session, PlanSymbolAllocator symbolAllocator, PlanNodeIdAllocator idAllocator, WarningCollector warningCollector) {
    TableHandle tableHandle = tableScanNode.getTable();
    TableMetadata tableMetadata = metadata.getTableMetadata(session, tableHandle);
    String tableName = tableMetadata.getQualifiedName().toString();
    CubeStatement statement = CubeStatementGenerator.generate(tableName, aggregationNode, symbolMapping);
    // Don't use star-tree for non-aggregate queries
    if (statement.getAggregations().isEmpty()) {
        return Result.empty();
    }
    boolean hasDistinct = statement.getAggregations().stream().anyMatch(AggregationSignature::isDistinct);
    // Since cube is pre-aggregated, utilising it for such queries could return incorrect result
    if (aggregationNode.hasEmptyGroupingSet() && hasDistinct) {
        return Result.empty();
    }
    List<CubeMetadata> cubeMetadataList = CubeMetadata.filter(this.cubeMetaStore.getMetadataList(statement.getFrom()), statement);
    // Compare FilterNode predicate with Cube predicates to evaluate which cube can be used.
    List<CubeMetadata> matchedCubeMetadataList = cubeMetadataList.stream().filter(cubeMetadata -> filterPredicateMatches((FilterNode) filterNode, cubeMetadata, session, symbolAllocator.getTypes())).collect(Collectors.toList());
    // Match based on filter conditions
    if (matchedCubeMetadataList.isEmpty()) {
        return Result.empty();
    }
    LongSupplier lastModifiedTimeSupplier = metadata.getTableLastModifiedTimeSupplier(session, tableHandle);
    if (lastModifiedTimeSupplier == null) {
        warningCollector.add(new PrestoWarning(EXPIRED_CUBE, "Unable to identify last modified time of " + tableName + ". Ignoring star tree cubes."));
        return Result.empty();
    }
    // Filter out cubes that were created before the source table was updated
    long lastModifiedTime = lastModifiedTimeSupplier.getAsLong();
    // There was a problem retrieving last modified time, we should skip using star tree rather than failing the query
    if (lastModifiedTime == -1L) {
        return Result.empty();
    }
    matchedCubeMetadataList = matchedCubeMetadataList.stream().filter(cubeMetadata -> cubeMetadata.getSourceTableLastUpdatedTime() >= lastModifiedTime).collect(Collectors.toList());
    if (matchedCubeMetadataList.isEmpty()) {
        warningCollector.add(new PrestoWarning(EXPIRED_CUBE, tableName + " has been modified after creating cubes. Ignoring expired cubes."));
        return Result.empty();
    }
    // If multiple cubes are matching then lets select the recent built cube
    // so sort the cube based on the last updated time stamp
    matchedCubeMetadataList.sort(Comparator.comparingLong(CubeMetadata::getLastUpdatedTime).reversed());
    CubeMetadata matchedCubeMetadata = matchedCubeMetadataList.get(0);
    AggregationRewriteWithCube aggregationRewriteWithCube = new AggregationRewriteWithCube(metadata, session, symbolAllocator, idAllocator, symbolMapping, matchedCubeMetadata);
    return Result.ofPlanNode(aggregationRewriteWithCube.rewrite(aggregationNode, rewriteByRemovingSourceFilter(filterNode, matchedCubeMetadata)));
}
Also used : TableMetadata(io.prestosql.metadata.TableMetadata) LongSupplier(java.util.function.LongSupplier) PrestoWarning(io.prestosql.spi.PrestoWarning) Patterns.aggregation(io.prestosql.sql.planner.plan.Patterns.aggregation) SystemSessionProperties(io.prestosql.SystemSessionProperties) TypeProvider(io.prestosql.sql.planner.TypeProvider) SqlParser(io.prestosql.sql.parser.SqlParser) AggregationNode(io.prestosql.spi.plan.AggregationNode) WarningCollector(io.prestosql.execution.warnings.WarningCollector) Capture.newCapture(io.prestosql.matching.Capture.newCapture) FilterNode(io.prestosql.spi.plan.FilterNode) Pair(org.apache.commons.lang3.tuple.Pair) Map(java.util.Map) OriginalExpressionUtils.castToRowExpression(io.prestosql.sql.relational.OriginalExpressionUtils.castToRowExpression) OriginalExpressionUtils.castToExpression(io.prestosql.sql.relational.OriginalExpressionUtils.castToExpression) CubeFilter(io.hetu.core.spi.cube.CubeFilter) Identifier(io.prestosql.sql.tree.Identifier) CubeMetaStore(io.hetu.core.spi.cube.io.CubeMetaStore) SymbolsExtractor(io.prestosql.sql.planner.SymbolsExtractor) TableScanNode(io.prestosql.spi.plan.TableScanNode) Set(java.util.Set) PlanNode(io.prestosql.spi.plan.PlanNode) CubeStatement(io.hetu.core.spi.cube.CubeStatement) ProjectNode(io.prestosql.spi.plan.ProjectNode) Collectors(java.util.stream.Collectors) Metadata(io.prestosql.metadata.Metadata) PlanSymbolAllocator(io.prestosql.sql.planner.PlanSymbolAllocator) Captures(io.prestosql.matching.Captures) List(java.util.List) ExpressionUtils(io.prestosql.sql.ExpressionUtils) Capture(io.prestosql.matching.Capture) AggregationSignature(io.hetu.core.spi.cube.aggregator.AggregationSignature) Optional(java.util.Optional) STAR_TREE(io.prestosql.cube.CubeManager.STAR_TREE) Patterns.optionalSource(io.prestosql.sql.planner.plan.Patterns.optionalSource) Patterns.source(io.prestosql.sql.planner.plan.Patterns.source) TableMetadata(io.prestosql.metadata.TableMetadata) Logger(io.airlift.log.Logger) Pattern(io.prestosql.matching.Pattern) TableHandle(io.prestosql.spi.metadata.TableHandle) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) ExpressionDomainTranslator(io.prestosql.sql.planner.ExpressionDomainTranslator) BooleanLiteral(io.prestosql.sql.tree.BooleanLiteral) Objects.requireNonNull(java.util.Objects.requireNonNull) Session(io.prestosql.Session) LinkedList(java.util.LinkedList) ParsingOptions(io.prestosql.sql.parser.ParsingOptions) Symbol(io.prestosql.spi.plan.Symbol) EXPIRED_CUBE(io.prestosql.spi.connector.StandardWarningCode.EXPIRED_CUBE) Rule(io.prestosql.sql.planner.iterative.Rule) TupleDomain(io.prestosql.spi.predicate.TupleDomain) CubeStatementGenerator(io.prestosql.cube.CubeStatementGenerator) SystemSessionProperties.isEnableStarTreeIndex(io.prestosql.SystemSessionProperties.isEnableStarTreeIndex) Patterns.anyPlan(io.prestosql.sql.planner.plan.Patterns.anyPlan) ImmutablePair(org.apache.commons.lang3.tuple.ImmutablePair) CubeManager(io.prestosql.cube.CubeManager) PlanNodeIdAllocator(io.prestosql.spi.plan.PlanNodeIdAllocator) FeaturesConfig(io.prestosql.sql.analyzer.FeaturesConfig) CubeMetadata(io.hetu.core.spi.cube.CubeMetadata) Patterns.tableScan(io.prestosql.sql.planner.plan.Patterns.tableScan) Comparator(java.util.Comparator) Expression(io.prestosql.sql.tree.Expression) AggregationSignature(io.hetu.core.spi.cube.aggregator.AggregationSignature) CubeMetadata(io.hetu.core.spi.cube.CubeMetadata) CubeStatement(io.hetu.core.spi.cube.CubeStatement) PrestoWarning(io.prestosql.spi.PrestoWarning) TableHandle(io.prestosql.spi.metadata.TableHandle) LongSupplier(java.util.function.LongSupplier)

Example 5 with CubeStatement

use of io.hetu.core.spi.cube.CubeStatement in project hetu-core by openlookeng.

the class TestStarTreeMetadata method testMetadataMatchesCubeStatement.

@Test
public void testMetadataMatchesCubeStatement() {
    CubeStatement statement = CubeStatement.newBuilder().select("returnflag", "linestatus").aggregate(avg("quantity", false)).from("tpch.tiny.lineitem").groupByAddStringList("returnflag", "linestatus").build();
    assertTrue(metadata.matches(statement), "failed to match a valid cube statement");
}
Also used : CubeStatement(io.hetu.core.spi.cube.CubeStatement) Test(org.testng.annotations.Test)

Aggregations

CubeStatement (io.hetu.core.spi.cube.CubeStatement)8 Test (org.testng.annotations.Test)6 Symbol (io.prestosql.spi.plan.Symbol)2 Expression (io.prestosql.sql.tree.Expression)2 List (java.util.List)2 Map (java.util.Map)2 Logger (io.airlift.log.Logger)1 CubeFilter (io.hetu.core.spi.cube.CubeFilter)1 CubeMetadata (io.hetu.core.spi.cube.CubeMetadata)1 AggregationSignature (io.hetu.core.spi.cube.aggregator.AggregationSignature)1 CubeMetaStore (io.hetu.core.spi.cube.io.CubeMetaStore)1 Session (io.prestosql.Session)1 SystemSessionProperties (io.prestosql.SystemSessionProperties)1 SystemSessionProperties.isEnableStarTreeIndex (io.prestosql.SystemSessionProperties.isEnableStarTreeIndex)1 CubeManager (io.prestosql.cube.CubeManager)1 STAR_TREE (io.prestosql.cube.CubeManager.STAR_TREE)1 CubeStatementGenerator (io.prestosql.cube.CubeStatementGenerator)1 WarningCollector (io.prestosql.execution.warnings.WarningCollector)1 Capture (io.prestosql.matching.Capture)1 Capture.newCapture (io.prestosql.matching.Capture.newCapture)1