Skip to content

Commit 956b447

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

5 files changed

Lines changed: 299 additions & 254 deletions

File tree

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

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

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

0 commit comments

Comments
 (0)