Make last_by, first_by with time can push-down in TableModel

This commit is contained in:
Weihao Li 2024-09-25 14:38:13 +08:00 committed by GitHub
parent 1447d41ccf
commit d0c0fd7647
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 42 additions and 9 deletions

View File

@ -185,7 +185,8 @@ public interface Metadata {
final String database, final List<DataPartitionQueryParam> sgNameToQueryParamsMap);
/**
* @param withTime some function with time can also use Statistics, like first_by, last_by
* @return if the Aggregation can use statistics to optimize
*/
boolean canUseStatistics(final String name);
boolean canUseStatistics(final String name, boolean withTime);
}

View File

@ -76,7 +76,7 @@ public enum TableBuiltinAggregationFunction {
/**
* @return if the Aggregation can use statistics to optimize
*/
public static boolean canUseStatistics(String name) {
public static boolean canUseStatistics(String name, boolean withTime) {
final String functionName = name.toLowerCase();
switch (functionName) {
case "sum":
@ -90,6 +90,7 @@ public enum TableBuiltinAggregationFunction {
return true;
case "first_by":
case "last_by":
return withTime;
case "mode":
case "max_by":
case "min_by":

View File

@ -705,8 +705,8 @@ public class TableMetadataImpl implements Metadata {
}
@Override
public boolean canUseStatistics(String functionName) {
return TableBuiltinAggregationFunction.canUseStatistics(functionName);
public boolean canUseStatistics(String functionName, boolean withTime) {
return TableBuiltinAggregationFunction.canUseStatistics(functionName, withTime);
}
public static boolean isTwoNumericType(List<? extends Type> argumentTypes) {

View File

@ -139,7 +139,13 @@ public class PushAggregationIntoTableScan implements PlanOptimizer {
for (AggregationNode.Aggregation aggregation : values) {
// if the function cannot make use of Statistics, we don't push down
if (!metadata.canUseStatistics(
aggregation.getResolvedFunction().getSignature().getName())) {
aggregation.getResolvedFunction().getSignature().getName(),
aggregation.getArguments().stream()
.anyMatch(
v ->
((SymbolReference) v)
.getName()
.equalsIgnoreCase(TimestampOperand.TIMESTAMP_EXPRESSION_STRING)))) {
return PushDownLevel.NOOP;
}

View File

@ -657,4 +657,29 @@ public class AggregationTest {
ImmutableList.of("time", "s1", "s2"),
ImmutableSet.of("s1", "s2", "time"))))));
}
@Test
public void withTimePushDownLevelTest() {
PlanTester planTester = new PlanTester();
// first, last, first_by with time, last_by with time should be push-down
LogicalQueryPlan logicalQueryPlan =
planTester.createPlan(
"SELECT first(s1), last(s1), first_by(time,s1), last_by(time,s1) FROM table1 group by tag1, tag2, tag3");
// Output - Project - AggregationTableScan
assertPlan(
logicalQueryPlan,
output(
project(
aggregationTableScan(
singleGroupingSet("tag1", "tag2", "tag3"),
ImmutableList.of("tag1", "tag2", "tag3"), // Streamable
Optional.empty(),
SINGLE,
"testdb.table1",
ImmutableList.of(
"tag1", "tag2", "tag3", "first", "last", "first_by", "last_by"),
ImmutableSet.of("tag1", "tag2", "tag3", "s1", "time")))));
}
}

View File

@ -365,8 +365,8 @@ public class TSBSMetadata implements Metadata {
}
@Override
public boolean canUseStatistics(String name) {
return TableBuiltinAggregationFunction.canUseStatistics(name);
public boolean canUseStatistics(String name, boolean withTime) {
return TableBuiltinAggregationFunction.canUseStatistics(name, withTime);
}
private static final DataPartition DATA_PARTITION =

View File

@ -312,8 +312,8 @@ public class TestMatadata implements Metadata {
}
@Override
public boolean canUseStatistics(String name) {
return TableBuiltinAggregationFunction.canUseStatistics(name);
public boolean canUseStatistics(String name, boolean withTime) {
return TableBuiltinAggregationFunction.canUseStatistics(name, withTime);
}
private static final DataPartition DATA_PARTITION =