Skip to content

Commit 9314af1

Browse files
committed
chore(isthmus): adjust automatic dynamic function mapping to new way of conversion config
1 parent dd545a1 commit 9314af1

5 files changed

Lines changed: 297 additions & 254 deletions

File tree

Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
package io.substrait.isthmus;
2+
3+
import io.substrait.extension.DefaultExtensionCatalog;
4+
import io.substrait.extension.SimpleExtension;
5+
import io.substrait.isthmus.expression.AggregateFunctionConverter;
6+
import io.substrait.isthmus.expression.FunctionMappings;
7+
import io.substrait.isthmus.expression.ScalarFunctionConverter;
8+
import io.substrait.isthmus.expression.WindowFunctionConverter;
9+
import java.util.ArrayList;
10+
import java.util.List;
11+
import java.util.stream.Collectors;
12+
import org.apache.calcite.rel.type.RelDataTypeFactory;
13+
import org.apache.calcite.sql.SqlOperator;
14+
import org.apache.calcite.sql.SqlOperatorTable;
15+
import org.apache.calcite.sql.util.SqlOperatorTables;
16+
import org.slf4j.Logger;
17+
import org.slf4j.LoggerFactory;
18+
19+
public class AutomaticDynamicFunctionMappingConverterProvider extends ConverterProvider {
20+
21+
private static final Logger LOGGER =
22+
LoggerFactory.getLogger(AutomaticDynamicFunctionMappingConverterProvider.class);
23+
24+
public AutomaticDynamicFunctionMappingConverterProvider() {
25+
this(DefaultExtensionCatalog.DEFAULT_COLLECTION, SubstraitTypeSystem.TYPE_FACTORY);
26+
}
27+
28+
public AutomaticDynamicFunctionMappingConverterProvider(SimpleExtension.ExtensionCollection extensions) {
29+
this(extensions, SubstraitTypeSystem.TYPE_FACTORY);
30+
}
31+
32+
public AutomaticDynamicFunctionMappingConverterProvider(
33+
SimpleExtension.ExtensionCollection extensions, RelDataTypeFactory typeFactory) {
34+
super(extensions, typeFactory);
35+
this.scalarFunctionConverter = createScalarFunctionConverter();
36+
this.aggregateFunctionConverter = createAggregateFunctionConverter();
37+
this.windowFunctionConverter = createWindowFunctionConverter();
38+
}
39+
40+
@Override
41+
public SqlOperatorTable getSqlOperatorTable() {
42+
SqlOperatorTable baseOperatorTable = super.getSqlOperatorTable();
43+
List<SqlOperator> dynamicOperators = new ArrayList<>();
44+
45+
List<SimpleExtension.ScalarFunctionVariant> unmappedScalars =
46+
io.substrait.isthmus.expression.FunctionConverter.getUnmappedFunctions(
47+
extensions.scalarFunctions(),
48+
io.substrait.isthmus.expression.FunctionMappings.SCALAR_SIGS);
49+
List<SimpleExtension.AggregateFunctionVariant> unmappedAggregates =
50+
io.substrait.isthmus.expression.FunctionConverter.getUnmappedFunctions(
51+
extensions.aggregateFunctions(),
52+
io.substrait.isthmus.expression.FunctionMappings.AGGREGATE_SIGS);
53+
List<SimpleExtension.WindowFunctionVariant> unmappedWindows =
54+
io.substrait.isthmus.expression.FunctionConverter.getUnmappedFunctions(
55+
extensions.windowFunctions(),
56+
io.substrait.isthmus.expression.FunctionMappings.WINDOW_SIGS);
57+
58+
if (!unmappedScalars.isEmpty()) {
59+
dynamicOperators.addAll(SimpleExtensionToSqlOperator.from(unmappedScalars, typeFactory));
60+
}
61+
if (!unmappedAggregates.isEmpty()) {
62+
dynamicOperators.addAll(SimpleExtensionToSqlOperator.from(unmappedAggregates, typeFactory));
63+
}
64+
if (!unmappedWindows.isEmpty()) {
65+
dynamicOperators.addAll(SimpleExtensionToSqlOperator.from(unmappedWindows, typeFactory));
66+
}
67+
68+
if (!dynamicOperators.isEmpty()) {
69+
return SqlOperatorTables.chain(baseOperatorTable, SqlOperatorTables.of(dynamicOperators));
70+
} else {
71+
return baseOperatorTable;
72+
}
73+
}
74+
75+
protected ScalarFunctionConverter createScalarFunctionConverter() {
76+
List<SimpleExtension.ScalarFunctionVariant> unmappedFunctions =
77+
io.substrait.isthmus.expression.FunctionConverter.getUnmappedFunctions(
78+
extensions.scalarFunctions(), FunctionMappings.SCALAR_SIGS);
79+
80+
List<FunctionMappings.Sig> additionalSignatures = new ArrayList<>();
81+
82+
if (!unmappedFunctions.isEmpty()) {
83+
LOGGER.info(
84+
"Dynamically mapping {} unmapped scalar functions: {}",
85+
unmappedFunctions.size(),
86+
unmappedFunctions.stream().map(f -> f.name()).collect(Collectors.toList()));
87+
88+
List<SqlOperator> dynamicOperators =
89+
SimpleExtensionToSqlOperator.from(unmappedFunctions, typeFactory);
90+
91+
java.util.Map<String, SqlOperator> operatorsByName = new java.util.LinkedHashMap<>();
92+
for (SqlOperator op : dynamicOperators) {
93+
operatorsByName.put(op.getName().toLowerCase(), op);
94+
}
95+
96+
additionalSignatures.addAll(
97+
operatorsByName.values().stream()
98+
.map(op -> FunctionMappings.s(op, op.getName().toLowerCase()))
99+
.collect(Collectors.toList()));
100+
}
101+
102+
return new ScalarFunctionConverter(
103+
extensions.scalarFunctions(), additionalSignatures, typeFactory, typeConverter);
104+
}
105+
106+
protected AggregateFunctionConverter createAggregateFunctionConverter() {
107+
List<FunctionMappings.Sig> additionalSignatures = new ArrayList<>();
108+
109+
List<SimpleExtension.AggregateFunctionVariant> unmappedFunctions =
110+
io.substrait.isthmus.expression.FunctionConverter.getUnmappedFunctions(
111+
extensions.aggregateFunctions(), FunctionMappings.AGGREGATE_SIGS);
112+
113+
if (!unmappedFunctions.isEmpty()) {
114+
List<SqlOperator> dynamicOperators =
115+
SimpleExtensionToSqlOperator.from(unmappedFunctions, typeFactory);
116+
117+
java.util.Map<String, SqlOperator> operatorsByName = new java.util.LinkedHashMap<>();
118+
for (SqlOperator op : dynamicOperators) {
119+
operatorsByName.put(op.getName().toLowerCase(), op);
120+
}
121+
122+
additionalSignatures.addAll(
123+
operatorsByName.values().stream()
124+
.map(op -> FunctionMappings.s(op, op.getName().toLowerCase()))
125+
.collect(Collectors.toList()));
126+
}
127+
128+
return new AggregateFunctionConverter(
129+
extensions.aggregateFunctions(), additionalSignatures, typeFactory, typeConverter);
130+
}
131+
132+
protected WindowFunctionConverter createWindowFunctionConverter() {
133+
List<FunctionMappings.Sig> additionalSignatures = new ArrayList<>();
134+
135+
List<SimpleExtension.WindowFunctionVariant> unmappedFunctions =
136+
io.substrait.isthmus.expression.FunctionConverter.getUnmappedFunctions(
137+
extensions.windowFunctions(), FunctionMappings.WINDOW_SIGS);
138+
139+
if (!unmappedFunctions.isEmpty()) {
140+
List<SqlOperator> dynamicOperators =
141+
SimpleExtensionToSqlOperator.from(unmappedFunctions, typeFactory);
142+
143+
java.util.Map<String, SqlOperator> operatorsByName = new java.util.LinkedHashMap<>();
144+
for (SqlOperator op : dynamicOperators) {
145+
operatorsByName.put(op.getName().toLowerCase(), op);
146+
}
147+
148+
additionalSignatures.addAll(
149+
operatorsByName.values().stream()
150+
.map(op -> FunctionMappings.s(op, op.getName().toLowerCase()))
151+
.collect(Collectors.toList()));
152+
}
153+
154+
return new WindowFunctionConverter(
155+
extensions.windowFunctions(), additionalSignatures, typeFactory, typeConverter);
156+
}
157+
}

isthmus/src/main/java/io/substrait/isthmus/FeatureBoard.java

Lines changed: 0 additions & 53 deletions
This file was deleted.

0 commit comments

Comments
 (0)