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);
}
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");
}
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);
}
}
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);
}
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);
}
Aggregations