Search in sources :

Example 1 with PinotConfig

use of com.facebook.presto.pinot.PinotConfig in project presto by prestodb.

the class TestPinotQueryGenerator method helperTestMultipleAggregatesWithGroupBy.

protected void helperTestMultipleAggregatesWithGroupBy(PinotConfig givenPinotConfig) {
    Map<String, String> outputVariables = ImmutableMap.of("agg", "count(*)", "min", "min(fare)");
    PlanNode justScan = buildPlan(planBuilder -> tableScan(planBuilder, pinotTable, regionId, secondsSinceEpoch, city, fare));
    testPinotQuery(givenPinotConfig, planBuilder -> planBuilder.aggregation(aggBuilder -> aggBuilder.source(justScan).singleGroupingSet(variable("city")).addAggregation(planBuilder.variable("agg"), getRowExpression("count(*)", defaultSessionHolder)).addAggregation(planBuilder.variable("min"), getRowExpression("min(fare)", defaultSessionHolder))), String.format("SELECT %s FROM realtimeOnly GROUP BY city %s 10000", getExpectedAggOutput("__expressions__", "city"), getGroupByLimitKey()), defaultSessionHolder, outputVariables);
}
Also used : Arrays(java.util.Arrays) AggregationNode(com.facebook.presto.spi.plan.AggregationNode) VARCHAR(com.facebook.presto.common.type.VarcharType.VARCHAR) Assert.assertEquals(org.testng.Assert.assertEquals) VariableReferenceExpression(com.facebook.presto.spi.relation.VariableReferenceExpression) Test(org.testng.annotations.Test) TIMESTAMP(com.facebook.presto.common.type.TimestampType.TIMESTAMP) DistinctLimitNode(com.facebook.presto.spi.plan.DistinctLimitNode) Function(java.util.function.Function) HashSet(java.util.HashSet) LinkedHashMap(java.util.LinkedHashMap) ImmutableList(com.google.common.collect.ImmutableList) PinotTableHandle(com.facebook.presto.pinot.PinotTableHandle) Map(java.util.Map) PlanBuilder(com.facebook.presto.sql.planner.iterative.rule.test.PlanBuilder) BiConsumer(java.util.function.BiConsumer) OrderingScheme(com.facebook.presto.spi.plan.OrderingScheme) NoSuchElementException(java.util.NoSuchElementException) Assert.assertFalse(org.testng.Assert.assertFalse) BIGINT(com.facebook.presto.common.type.BigintType.BIGINT) PinotColumnHandle(com.facebook.presto.pinot.PinotColumnHandle) SortOrder(com.facebook.presto.common.block.SortOrder) ImmutableMap(com.google.common.collect.ImmutableMap) DOUBLE(com.facebook.presto.common.type.DoubleType.DOUBLE) Ordering(com.facebook.presto.spi.plan.Ordering) Set(java.util.Set) Collectors(java.util.stream.Collectors) String.format(java.lang.String.format) PlanNode(com.facebook.presto.spi.plan.PlanNode) List(java.util.List) TestPinotQueryBase(com.facebook.presto.pinot.TestPinotQueryBase) ProjectNode(com.facebook.presto.spi.plan.ProjectNode) TableScanNode(com.facebook.presto.spi.plan.TableScanNode) PinotConfig(com.facebook.presto.pinot.PinotConfig) TopNNode(com.facebook.presto.spi.plan.TopNNode) Optional(java.util.Optional) Assert.assertTrue(org.testng.Assert.assertTrue) PlanNode(com.facebook.presto.spi.plan.PlanNode)

Example 2 with PinotConfig

use of com.facebook.presto.pinot.PinotConfig in project presto by prestodb.

the class TestPinotQueryGenerator method testDistinctCountPushdownWithVariableSuffix.

@Test
public void testDistinctCountPushdownWithVariableSuffix() {
    Map<VariableReferenceExpression, PinotColumnHandle> columnHandleMap = ImmutableMap.of(new VariableReferenceExpression(Optional.empty(), "regionid_33", regionId.getDataType()), regionId);
    PlanNode justScan = buildPlan(planBuilder -> tableScan(planBuilder, pinotTable, columnHandleMap));
    PlanNode markDistinct = buildPlan(planBuilder -> markDistinct(planBuilder, variable("regionid$distinct_62"), ImmutableList.of(variable("regionid")), justScan));
    PlanNode aggregate = buildPlan(planBuilder -> planBuilder.aggregation(aggBuilder -> aggBuilder.source(markDistinct).addAggregation(planBuilder.variable("count(regionid_33)"), getRowExpression("count(regionid_33)", defaultSessionHolder), Optional.empty(), Optional.empty(), false, Optional.of(variable("regionid$distinct_62"))).globalGrouping()));
    testPinotQuery(new PinotConfig().setAllowMultipleAggregations(true), planBuilder -> planBuilder.limit(10, aggregate), "SELECT DISTINCTCOUNT(regionId) FROM realtimeOnly");
}
Also used : Arrays(java.util.Arrays) AggregationNode(com.facebook.presto.spi.plan.AggregationNode) VARCHAR(com.facebook.presto.common.type.VarcharType.VARCHAR) Assert.assertEquals(org.testng.Assert.assertEquals) VariableReferenceExpression(com.facebook.presto.spi.relation.VariableReferenceExpression) Test(org.testng.annotations.Test) TIMESTAMP(com.facebook.presto.common.type.TimestampType.TIMESTAMP) DistinctLimitNode(com.facebook.presto.spi.plan.DistinctLimitNode) Function(java.util.function.Function) HashSet(java.util.HashSet) LinkedHashMap(java.util.LinkedHashMap) ImmutableList(com.google.common.collect.ImmutableList) PinotTableHandle(com.facebook.presto.pinot.PinotTableHandle) Map(java.util.Map) PlanBuilder(com.facebook.presto.sql.planner.iterative.rule.test.PlanBuilder) BiConsumer(java.util.function.BiConsumer) OrderingScheme(com.facebook.presto.spi.plan.OrderingScheme) NoSuchElementException(java.util.NoSuchElementException) Assert.assertFalse(org.testng.Assert.assertFalse) BIGINT(com.facebook.presto.common.type.BigintType.BIGINT) PinotColumnHandle(com.facebook.presto.pinot.PinotColumnHandle) SortOrder(com.facebook.presto.common.block.SortOrder) ImmutableMap(com.google.common.collect.ImmutableMap) DOUBLE(com.facebook.presto.common.type.DoubleType.DOUBLE) Ordering(com.facebook.presto.spi.plan.Ordering) Set(java.util.Set) Collectors(java.util.stream.Collectors) String.format(java.lang.String.format) PlanNode(com.facebook.presto.spi.plan.PlanNode) List(java.util.List) TestPinotQueryBase(com.facebook.presto.pinot.TestPinotQueryBase) ProjectNode(com.facebook.presto.spi.plan.ProjectNode) TableScanNode(com.facebook.presto.spi.plan.TableScanNode) PinotConfig(com.facebook.presto.pinot.PinotConfig) TopNNode(com.facebook.presto.spi.plan.TopNNode) Optional(java.util.Optional) Assert.assertTrue(org.testng.Assert.assertTrue) PinotColumnHandle(com.facebook.presto.pinot.PinotColumnHandle) PlanNode(com.facebook.presto.spi.plan.PlanNode) PinotConfig(com.facebook.presto.pinot.PinotConfig) VariableReferenceExpression(com.facebook.presto.spi.relation.VariableReferenceExpression) Test(org.testng.annotations.Test)

Example 3 with PinotConfig

use of com.facebook.presto.pinot.PinotConfig in project presto by prestodb.

the class TestPinotPlanOptimizer method testDistinctCountInSubQueryPushdown.

@Test
public void testDistinctCountInSubQueryPushdown() {
    for (String distinctCountFunctionName : Arrays.asList("DISTINCTCOUNT", "DISTINCTCOUNTBITMAP", "SEGMENTPARTITIONEDDISTINCTCOUNT")) {
        final PinotConfig pinotConfig = new PinotConfig().setOverrideDistinctCountFunction(distinctCountFunctionName);
        testDistinctCountInSubQueryPushdown(distinctCountFunctionName, pinotConfig);
        testDistinctCountPushdownNoOverride(pinotConfig);
    }
}
Also used : PinotConfig(com.facebook.presto.pinot.PinotConfig) Test(org.testng.annotations.Test)

Example 4 with PinotConfig

use of com.facebook.presto.pinot.PinotConfig in project presto by prestodb.

the class PinotQueryGeneratorContext method toSqlQuery.

/**
 * Convert the current context to a Pinot SQL
 */
public PinotQueryGenerator.GeneratedPinotQuery toSqlQuery(PinotConfig pinotConfig, ConnectorSession session) {
    int nonAggregateShortQueryLimit = PinotSessionProperties.getNonAggregateLimitForBrokerQueries(session);
    boolean isQueryShort = (hasAggregation() || hasGroupBy()) || limit.orElse(Integer.MAX_VALUE) < nonAggregateShortQueryLimit;
    boolean forBroker = !PinotSessionProperties.isForbidBrokerQueries(session) && isQueryShort;
    String groupByExpressions = groupByColumns.stream().map(x -> selections.get(x).getDefinition()).collect(Collectors.joining(", "));
    String selectExpressions = outputs.stream().filter(o -> !groupByColumns.contains(o)).map(o -> updateSelection(selections.get(o).getDefinition(), session)).collect(Collectors.joining(", "));
    String expressions = (groupByExpressions.isEmpty()) ? selectExpressions : (selectExpressions.isEmpty()) ? groupByExpressions : groupByExpressions + ", " + selectExpressions;
    String tableName = from.orElseThrow(() -> new PinotException(PINOT_QUERY_GENERATOR_FAILURE, Optional.empty(), "Table name not encountered yet"));
    // Rules for limit:
    // - If its a selection query:
    // + given limit or configured limit
    // - Else if has group by:
    // + default limit or configured top limit
    // - Aggregation only query limit is ignored.
    // - Fail if limit is invalid
    int queryLimit = -1;
    if (!hasAggregation() && !hasGroupBy()) {
        if (!limit.isPresent() && forBroker) {
            throw new PinotException(PINOT_QUERY_GENERATOR_FAILURE, Optional.empty(), "Broker non aggregate queries have to have a limit");
        } else {
            queryLimit = limit.orElse(PinotSessionProperties.getLimitLargerForSegment(session));
        }
    } else if (hasGroupBy()) {
        if (limit.isPresent()) {
            queryLimit = limit.getAsInt();
        } else {
            queryLimit = PinotSessionProperties.getTopNLarge(session);
        }
    }
    String limitClause = "";
    if (queryLimit > 0) {
        limitClause = " LIMIT " + queryLimit;
    }
    String query = generatePinotQueryHelper(forBroker, expressions, tableName, limitClause);
    LinkedHashMap<VariableReferenceExpression, PinotColumnHandle> assignments = getAssignments(true);
    List<Integer> indices = getIndicesMappingFromPinotSchemaToPrestoSchema(query, assignments);
    return new PinotQueryGenerator.GeneratedPinotQuery(tableName, query, PinotQueryGenerator.PinotQueryFormat.SQL, indices, groupByColumns.size(), filter.isPresent(), isQueryShort);
}
Also used : PinotPushdownUtils.checkSupported(com.facebook.presto.pinot.PinotPushdownUtils.checkSupported) PinotException(com.facebook.presto.pinot.PinotException) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) VariableReferenceExpression(com.facebook.presto.spi.relation.VariableReferenceExpression) HashMap(java.util.HashMap) PINOT_DISTINCT_COUNT_FUNCTION_NAME(com.facebook.presto.pinot.PinotPushdownUtils.PINOT_DISTINCT_COUNT_FUNCTION_NAME) OptionalInt(java.util.OptionalInt) HashSet(java.util.HashSet) LinkedHashMap(java.util.LinkedHashMap) ImmutableList(com.google.common.collect.ImmutableList) Locale(java.util.Locale) Map(java.util.Map) Objects.requireNonNull(java.util.Objects.requireNonNull) StrictMath.toIntExact(java.lang.StrictMath.toIntExact) LinkedHashSet(java.util.LinkedHashSet) PinotColumnHandle(com.facebook.presto.pinot.PinotColumnHandle) ImmutableSet(com.google.common.collect.ImmutableSet) Iterator(java.util.Iterator) SortOrder(com.facebook.presto.common.block.SortOrder) Set(java.util.Set) Collectors(java.util.stream.Collectors) PinotSessionProperties(com.facebook.presto.pinot.PinotSessionProperties) String.format(java.lang.String.format) ConnectorSession(com.facebook.presto.spi.ConnectorSession) List(java.util.List) PinotConfig(com.facebook.presto.pinot.PinotConfig) PINOT_QUERY_GENERATOR_FAILURE(com.facebook.presto.pinot.PinotErrorCode.PINOT_QUERY_GENERATOR_FAILURE) PINOT_UNSUPPORTED_EXPRESSION(com.facebook.presto.pinot.PinotErrorCode.PINOT_UNSUPPORTED_EXPRESSION) Optional(java.util.Optional) Joiner(com.google.common.base.Joiner) MoreObjects.toStringHelper(com.google.common.base.MoreObjects.toStringHelper) PinotException(com.facebook.presto.pinot.PinotException) PinotColumnHandle(com.facebook.presto.pinot.PinotColumnHandle) VariableReferenceExpression(com.facebook.presto.spi.relation.VariableReferenceExpression)

Example 5 with PinotConfig

use of com.facebook.presto.pinot.PinotConfig in project presto by prestodb.

the class PinotQueryGeneratorContext method toPqlQuery.

/**
 * Convert the current context to a PQL
 */
public PinotQueryGenerator.GeneratedPinotQuery toPqlQuery(PinotConfig pinotConfig, ConnectorSession session) {
    int nonAggregateShortQueryLimit = PinotSessionProperties.getNonAggregateLimitForBrokerQueries(session);
    boolean isQueryShort = hasAggregation() || limit.orElse(Integer.MAX_VALUE) < nonAggregateShortQueryLimit;
    boolean forBroker = !PinotSessionProperties.isForbidBrokerQueries(session) && isQueryShort;
    if (!pinotConfig.isAllowMultipleAggregations() && aggregations > 1 && hasGroupBy()) {
        throw new PinotException(PINOT_QUERY_GENERATOR_FAILURE, Optional.empty(), "Multiple aggregates in the presence of group by is forbidden");
    }
    if (hasLimit() && aggregations > 1 && hasGroupBy()) {
        throw new PinotException(PINOT_QUERY_GENERATOR_FAILURE, Optional.empty(), "Multiple aggregates in the presence of group by and limit is forbidden");
    }
    String expressions = outputs.stream().filter(// remove the group by columns from the query as Pinot barfs if the group by column is an expression
    o -> !groupByColumns.contains(o)).map(o -> updateSelection(selections.get(o).getDefinition(), session)).collect(Collectors.joining(", "));
    if (expressions.isEmpty()) {
        throw new PinotException(PINOT_QUERY_GENERATOR_FAILURE, Optional.empty(), "Empty PQL expressions: " + toString());
    }
    String tableName = from.orElseThrow(() -> new PinotException(PINOT_QUERY_GENERATOR_FAILURE, Optional.empty(), "Table name not encountered yet"));
    // Rules for limit:
    // - If its a selection query:
    // + given limit or configured limit
    // - Else if has group by:
    // + ensure that only one aggregation
    // + default limit or configured top limit
    // - Fail if limit is invalid
    String limitKeyWord = "";
    int queryLimit = -1;
    if (!hasAggregation()) {
        if (!limit.isPresent() && forBroker) {
            throw new PinotException(PINOT_QUERY_GENERATOR_FAILURE, Optional.empty(), "Broker non aggregate queries have to have a limit");
        } else {
            queryLimit = limit.orElse(PinotSessionProperties.getLimitLargerForSegment(session));
        }
        limitKeyWord = "LIMIT";
    } else if (hasGroupBy()) {
        limitKeyWord = "TOP";
        if (limit.isPresent()) {
            if (aggregations > 1) {
                throw new PinotException(PINOT_QUERY_GENERATOR_FAILURE, Optional.of(generatePinotQueryHelper(forBroker, expressions, tableName, "")), "Pinot has weird semantics with group by and multiple aggregation functions and limits");
            } else {
                queryLimit = limit.getAsInt();
            }
        } else {
            queryLimit = PinotSessionProperties.getTopNLarge(session);
        }
    }
    String limitClause = "";
    if (!limitKeyWord.isEmpty()) {
        limitClause = " " + limitKeyWord + " " + queryLimit;
    }
    String query = generatePinotQueryHelper(forBroker, expressions, tableName, limitClause);
    LinkedHashMap<VariableReferenceExpression, PinotColumnHandle> assignments = getAssignments(false);
    List<Integer> indices = getIndicesMappingFromPinotSchemaToPrestoSchema(query, assignments);
    return new PinotQueryGenerator.GeneratedPinotQuery(tableName, query, PinotQueryGenerator.PinotQueryFormat.PQL, indices, groupByColumns.size(), filter.isPresent(), isQueryShort);
}
Also used : PinotPushdownUtils.checkSupported(com.facebook.presto.pinot.PinotPushdownUtils.checkSupported) PinotException(com.facebook.presto.pinot.PinotException) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) VariableReferenceExpression(com.facebook.presto.spi.relation.VariableReferenceExpression) HashMap(java.util.HashMap) PINOT_DISTINCT_COUNT_FUNCTION_NAME(com.facebook.presto.pinot.PinotPushdownUtils.PINOT_DISTINCT_COUNT_FUNCTION_NAME) OptionalInt(java.util.OptionalInt) HashSet(java.util.HashSet) LinkedHashMap(java.util.LinkedHashMap) ImmutableList(com.google.common.collect.ImmutableList) Locale(java.util.Locale) Map(java.util.Map) Objects.requireNonNull(java.util.Objects.requireNonNull) StrictMath.toIntExact(java.lang.StrictMath.toIntExact) LinkedHashSet(java.util.LinkedHashSet) PinotColumnHandle(com.facebook.presto.pinot.PinotColumnHandle) ImmutableSet(com.google.common.collect.ImmutableSet) Iterator(java.util.Iterator) SortOrder(com.facebook.presto.common.block.SortOrder) Set(java.util.Set) Collectors(java.util.stream.Collectors) PinotSessionProperties(com.facebook.presto.pinot.PinotSessionProperties) String.format(java.lang.String.format) ConnectorSession(com.facebook.presto.spi.ConnectorSession) List(java.util.List) PinotConfig(com.facebook.presto.pinot.PinotConfig) PINOT_QUERY_GENERATOR_FAILURE(com.facebook.presto.pinot.PinotErrorCode.PINOT_QUERY_GENERATOR_FAILURE) PINOT_UNSUPPORTED_EXPRESSION(com.facebook.presto.pinot.PinotErrorCode.PINOT_UNSUPPORTED_EXPRESSION) Optional(java.util.Optional) Joiner(com.google.common.base.Joiner) MoreObjects.toStringHelper(com.google.common.base.MoreObjects.toStringHelper) PinotException(com.facebook.presto.pinot.PinotException) PinotColumnHandle(com.facebook.presto.pinot.PinotColumnHandle) VariableReferenceExpression(com.facebook.presto.spi.relation.VariableReferenceExpression)

Aggregations

PinotConfig (com.facebook.presto.pinot.PinotConfig)8 SortOrder (com.facebook.presto.common.block.SortOrder)7 PinotColumnHandle (com.facebook.presto.pinot.PinotColumnHandle)7 VariableReferenceExpression (com.facebook.presto.spi.relation.VariableReferenceExpression)7 ImmutableList (com.google.common.collect.ImmutableList)7 String.format (java.lang.String.format)7 HashSet (java.util.HashSet)7 LinkedHashMap (java.util.LinkedHashMap)7 List (java.util.List)7 Map (java.util.Map)7 Optional (java.util.Optional)7 Set (java.util.Set)7 Collectors (java.util.stream.Collectors)7 Test (org.testng.annotations.Test)6 BIGINT (com.facebook.presto.common.type.BigintType.BIGINT)5 DOUBLE (com.facebook.presto.common.type.DoubleType.DOUBLE)5 TIMESTAMP (com.facebook.presto.common.type.TimestampType.TIMESTAMP)5 VARCHAR (com.facebook.presto.common.type.VarcharType.VARCHAR)5 PinotTableHandle (com.facebook.presto.pinot.PinotTableHandle)5 TestPinotQueryBase (com.facebook.presto.pinot.TestPinotQueryBase)5