13
13
*/
14
14
package com .facebook .presto .iceberg .optimizer ;
15
15
16
- import com .facebook .presto .common .CatalogSchemaName ;
17
- import com .facebook .presto .common .QualifiedObjectName ;
18
16
import com .facebook .presto .common .predicate .NullableValue ;
19
17
import com .facebook .presto .common .predicate .TupleDomain ;
20
18
import com .facebook .presto .common .predicate .TupleDomain .ColumnDomain ;
58
56
import com .facebook .presto .spi .relation .VariableReferenceExpression ;
59
57
import com .google .common .collect .ImmutableList ;
60
58
import com .google .common .collect .ImmutableMap ;
61
- import com .google .common .collect .ImmutableSet ;
62
59
import com .google .common .collect .Iterables ;
63
60
import com .google .common .collect .Lists ;
64
61
67
64
import java .util .List ;
68
65
import java .util .Map ;
69
66
import java .util .Optional ;
70
- import java .util .Set ;
67
+ import java .util .function . Predicate ;
71
68
72
69
import static com .facebook .presto .expressions .LogicalRowExpressions .TRUE_CONSTANT ;
73
70
import static com .facebook .presto .iceberg .IcebergSessionProperties .getRowsForMetadataOptimizationThreshold ;
81
78
public class IcebergMetadataOptimizer
82
79
implements ConnectorPlanOptimizer
83
80
{
84
- public static final CatalogSchemaName DEFAULT_NAMESPACE = new CatalogSchemaName ("presto" , "default" );
85
- private static final Set <QualifiedObjectName > ALLOWED_FUNCTIONS = ImmutableSet .of (
86
- QualifiedObjectName .valueOf (DEFAULT_NAMESPACE , "max" ),
87
- QualifiedObjectName .valueOf (DEFAULT_NAMESPACE , "min" ),
88
- QualifiedObjectName .valueOf (DEFAULT_NAMESPACE , "approx_distinct" ));
89
-
90
81
// Min/Max could be folded into LEAST/GREATEST
91
- private static final Map <QualifiedObjectName , QualifiedObjectName > AGGREGATION_SCALAR_MAPPING = ImmutableMap .of (
92
- QualifiedObjectName . valueOf ( DEFAULT_NAMESPACE , "max" ), QualifiedObjectName . valueOf ( DEFAULT_NAMESPACE , "greatest" ) ,
93
- QualifiedObjectName . valueOf ( DEFAULT_NAMESPACE , "min" ), QualifiedObjectName . valueOf ( DEFAULT_NAMESPACE , "least" ) );
82
+ private static final Map <String , String > AGGREGATION_SCALAR_MAPPING = ImmutableMap .of (
83
+ "max" , "greatest" ,
84
+ "min" , "least" );
94
85
95
86
private final FunctionMetadataManager functionMetadataManager ;
96
87
private final TypeManager typeManager ;
@@ -137,6 +128,7 @@ private static class Optimizer
137
128
private final RowExpressionService rowExpressionService ;
138
129
private final StandardFunctionResolution functionResolution ;
139
130
private final int rowsForMetadataOptimizationThreshold ;
131
+ private final List <Predicate <FunctionHandle >> allowedFunctionsPredicates ;
140
132
141
133
private Optimizer (ConnectorSession connectorSession ,
142
134
PlanNodeIdAllocator idAllocator ,
@@ -156,15 +148,19 @@ private Optimizer(ConnectorSession connectorSession,
156
148
this .functionResolution = functionResolution ;
157
149
this .typeManager = typeManager ;
158
150
this .rowsForMetadataOptimizationThreshold = rowsForMetadataOptimizationThreshold ;
151
+ this .allowedFunctionsPredicates = ImmutableList .of (
152
+ functionResolution ::isMaxFunction ,
153
+ functionResolution ::isMinFunction ,
154
+ functionResolution ::isApproximateCountDistinctFunction );
159
155
}
160
156
161
157
@ Override
162
158
public PlanNode visitAggregation (AggregationNode node , RewriteContext <Void > context )
163
159
{
164
160
// supported functions are only MIN/MAX/APPROX_DISTINCT or distinct aggregates
165
161
for (Aggregation aggregation : node .getAggregations ().values ()) {
166
- QualifiedObjectName functionName = functionMetadataManager . getFunctionMetadata ( aggregation . getFunctionHandle ()). getName ();
167
- if (! ALLOWED_FUNCTIONS . contains ( functionName ) && !aggregation .isDistinct ()) {
162
+ if ( allowedFunctionsPredicates . stream (). noneMatch (
163
+ pred -> pred . test ( aggregation . getFunctionHandle ()) ) && !aggregation .isDistinct ()) {
168
164
return context .defaultRewrite (node );
169
165
}
170
166
}
@@ -270,7 +266,7 @@ private boolean isReducible(AggregationNode node, List<VariableReferenceExpressi
270
266
}
271
267
for (Aggregation aggregation : node .getAggregations ().values ()) {
272
268
FunctionMetadata functionMetadata = functionMetadataManager .getFunctionMetadata (aggregation .getFunctionHandle ());
273
- if (!AGGREGATION_SCALAR_MAPPING .containsKey (functionMetadata .getName ()) ||
269
+ if (!AGGREGATION_SCALAR_MAPPING .containsKey (functionMetadata .getName (). getObjectName () ) ||
274
270
functionMetadata .getArgumentTypes ().size () > 1 ||
275
271
!inputs .containsAll (aggregation .getCall ().getArguments ())) {
276
272
return false ;
@@ -340,7 +336,7 @@ private RowExpression evaluateMinMax(FunctionMetadata aggregationFunctionMetadat
340
336
return new ConstantExpression (Optional .empty (), null , returnType );
341
337
}
342
338
343
- String scalarFunctionName = AGGREGATION_SCALAR_MAPPING .get (aggregationFunctionMetadata .getName ()) .getObjectName ();
339
+ String scalarFunctionName = AGGREGATION_SCALAR_MAPPING .get (aggregationFunctionMetadata .getName ().getObjectName () );
344
340
while (arguments .size () > 1 ) {
345
341
List <RowExpression > reducedArguments = new ArrayList <>();
346
342
// We fold for every 100 values because GREATEST/LEAST has argument count limit
0 commit comments