SqlLibraryOperatorTableFactory discovers operators by reflecting over the public fields of SqlLibraryOperators, but isthmus-cli's RegisterAtRuntime registers SqlStdOperatorTable.class and not SqlLibraryOperators.class. In the native image that field scan therefore yields nothing, SubstraitOperatorTable's LIBRARY_OPERATOR_TABLE ends up empty, and every mapping backed by a library operator is unreachable — while the JVM test suite stays green, because it never runs against the image.
Verified against a nativeCompile -Pquick-build-native build of main, with --create 'CREATE TABLE strings (c16 CHAR(16), vc32 VARCHAR(32), vc VARCHAR)':
select reverse(vc32) from strings -> Error: No match found for function signature REVERSE(<CHARACTER>)
select sinh(1.0) from strings -> Error: No match found for function signature SINH(<NUMERIC>)
select least(i, i) from t -> Error: No match found for function signature LEAST(...)
select starts_with(vc32, 'a') ... -> Error: No match found for function signature STARTS_WITH(...)
select lpad(vc32, 4) from strings -> Error: No match found for function signature LPAD(...)
select log2(d) from t -> Error: No match found for function signature LOG2(<NUMERIC>)
select upper(vc32) from strings -> "name": "upper:vchar" (SqlStdOperatorTable — works)
select initcap(vc32) from strings -> "name": "initcap:vchar" (SqlStdOperatorTable — works)
So the split is exactly "is the Calcite operator declared in SqlStdOperatorTable or in SqlLibraryOperators", and roughly a dozen SCALAR_SIGS entries fall on the wrong side of it: the hyperbolic family, least/greatest, log2, factorial, concat, starts_with/ends_with/contains, left/right, lpad/rpad, and now reverse.
Adding SqlLibraryOperators.class to the register(...) block in RegisterAtRuntime was verified sufficient — with it, reverse:vchar, reverse:fchar and sinh:fp64 all resolve in the rebuilt image.
The reason this survived is that isthmus-cli's native smoke tests only cover TPC-H and arithmetic, so no case exercises a library operator. A smoke case for one (sinh or starts_with) belongs with the fix, otherwise the same gap reopens silently.
Found while reviewing #1251, which adds the reverse mapping and is the newest entry to land on the broken side.
SqlLibraryOperatorTableFactorydiscovers operators by reflecting over the public fields ofSqlLibraryOperators, butisthmus-cli'sRegisterAtRuntimeregistersSqlStdOperatorTable.classand notSqlLibraryOperators.class. In the native image that field scan therefore yields nothing,SubstraitOperatorTable'sLIBRARY_OPERATOR_TABLEends up empty, and every mapping backed by a library operator is unreachable — while the JVM test suite stays green, because it never runs against the image.Verified against a
nativeCompile -Pquick-build-nativebuild ofmain, with--create 'CREATE TABLE strings (c16 CHAR(16), vc32 VARCHAR(32), vc VARCHAR)':So the split is exactly "is the Calcite operator declared in
SqlStdOperatorTableor inSqlLibraryOperators", and roughly a dozenSCALAR_SIGSentries fall on the wrong side of it: the hyperbolic family,least/greatest,log2,factorial,concat,starts_with/ends_with/contains,left/right,lpad/rpad, and nowreverse.Adding
SqlLibraryOperators.classto theregister(...)block inRegisterAtRuntimewas verified sufficient — with it,reverse:vchar,reverse:fcharandsinh:fp64all resolve in the rebuilt image.The reason this survived is that
isthmus-cli's native smoke tests only cover TPC-H and arithmetic, so no case exercises a library operator. A smoke case for one (sinhorstarts_with) belongs with the fix, otherwise the same gap reopens silently.Found while reviewing #1251, which adds the
reversemapping and is the newest entry to land on the broken side.