Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
9d60dc7
feat(isthmus): udf support for substrait<->calcite
ZorinAnton Jul 8, 2025
556847b
chore(isthmus): handle nullability and EnumArgument in SimplExtension…
ZorinAnton Aug 13, 2025
857fe2c
feat(isthmus): udf support for substrait<->calcite
ZorinAnton Jul 8, 2025
eeb97cd
chore(isthmus): handle nullability and EnumArgument in SimplExtension…
ZorinAnton Aug 13, 2025
f30b556
Merge branch 'main' into zor-udf
ZorinAnton Oct 13, 2025
6d9cc2a
chore: resolve pmd
ZorinAnton Oct 13, 2025
1a1bf47
chore: sync submodules with main
ZorinAnton Oct 13, 2025
834ab5e
chore: sync substrait with main
ZorinAnton Oct 13, 2025
8340cc5
chore(isthmus): resolve conflicts after submodule update
ZorinAnton Oct 14, 2025
6ba115f
chore(isthmus): fix yaml for custom udf
ZorinAnton Oct 14, 2025
e739184
Merge branch 'main' into zor-udf
ZorinAnton Nov 26, 2025
838a0a7
chore(isthmus): fix regression
ZorinAnton Nov 26, 2025
32ae275
fix: add missing serialVersionUIDs (#621)
nielspardon Nov 26, 2025
e4f656d
Merge branch 'main' into zor-udf
ZorinAnton Nov 26, 2025
8d2b4ed
chore(isthmus): fix regression
ZorinAnton Nov 26, 2025
9b0c027
feat(isthmus): enable dynamic UDFs with FeatureBoard
ZorinAnton Dec 3, 2025
a9e7c60
chore(isthmus): refactor SimpleExtensionToSqlOperatorTest
ZorinAnton Dec 3, 2025
2f6cd28
chore(isthmus): address minor PR comments
ZorinAnton Dec 3, 2025
71fcdfc
feat(isthmus): make dynamic UDF configurable for substrait to sql con…
ZorinAnton Dec 3, 2025
ca3d967
Merge branch 'main' into zor-udf
ZorinAnton Dec 3, 2025
142d372
chore(isthmus): fix format violations
ZorinAnton Dec 3, 2025
74fd2e7
chore(isthmus): minor refactoring
ZorinAnton Dec 3, 2025
ec45173
chore(isthmus): check arg types in SimpleExtensionToSqlOperatorTest
ZorinAnton Dec 4, 2025
6eedacd
chore(isthmus): minor refactoring of SimpleExtensionToSqlOperator
ZorinAnton Dec 4, 2025
b002d9b
chore(isthmus): fix opt-in for dynamic operators
ZorinAnton Dec 5, 2025
fcf24bb
Merge branch 'main' into zor-udf
ZorinAnton Dec 5, 2025
fc2d576
chore(isthmus): fix regression in test
ZorinAnton Dec 5, 2025
26c15dc
Merge branch 'main' into zor-udf
ZorinAnton Dec 8, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions isthmus/src/main/java/io/substrait/isthmus/ExtensionUtils.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package io.substrait.isthmus;

import io.substrait.extension.SimpleExtension;
import io.substrait.isthmus.expression.FunctionMappings;
import java.util.List;
import java.util.Locale;
import java.util.Set;
import java.util.stream.Collectors;

public class ExtensionUtils {

/**
* Extracts dynamic extensions from a collection of extensions.
*
* <p>A <b>dynamic extension</b> is a user-defined function (UDF) that is not part of the standard
* Substrait function catalog. These are custom functions that users define and provide at
* runtime, extending the built-in function set with domain-specific or application-specific
* operations.
*
* <p>This method filters out all functions that are already known to the Calcite operator table
* (the standard/built-in functions) and returns only the custom functions that represent new
* capabilities not available in the default function set.
*
* <p><b>Example:</b> If a user defines a custom UDF "my_hash_function" that computes a
* proprietary hash, this would be a dynamic extension since it's not part of the standard
* Substrait specification.
*
* @param extensions the complete collection of extensions (both standard and custom)
* @return a new ExtensionCollection containing only the dynamic (custom/user-defined) functions
* that are not present in the standard Substrait function catalog
*/
public static SimpleExtension.ExtensionCollection getDynamicExtensions(
SimpleExtension.ExtensionCollection extensions) {
Set<String> knownFunctionNames =
FunctionMappings.SCALAR_SIGS.stream()
.map(FunctionMappings.Sig::name)
.collect(Collectors.toSet());

List<SimpleExtension.ScalarFunctionVariant> customFunctions =
extensions.scalarFunctions().stream()
.filter(f -> !knownFunctionNames.contains(f.name().toLowerCase(Locale.ROOT)))
.collect(Collectors.toList());

return SimpleExtension.ExtensionCollection.builder()
.scalarFunctions(customFunctions)
// TODO: handle aggregates and other functions
.build();
}
}
15 changes: 15 additions & 0 deletions isthmus/src/main/java/io/substrait/isthmus/FeatureBoard.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,19 @@ public abstract class FeatureBoard {
public Casing unquotedCasing() {
return Casing.TO_UPPER;
}

/**
* Controls whether to support dynamic user-defined functions (UDFs) during SQL to Substrait plan
* conversion.
*
* <p>When enabled, custom functions defined in extension YAML files are available for use in SQL
* queries. These functions will be dynamically converted to SQL operators during plan conversion.
* This feature must be explicitly enabled by users and is disabled by default.
*
* @return true if dynamic UDFs should be supported; false otherwise (default)
*/
@Value.Default
public boolean allowDynamicUdfs() {
return false;
}
}
Loading