From 9cbcc0e2b17336889efab495d271a67797f27d25 Mon Sep 17 00:00:00 2001 From: Victor Barua Date: Thu, 30 Apr 2026 15:49:50 -0700 Subject: [PATCH 1/3] fix(core): correct type short names for binary and fixedbinary in ToTypeString Type.Binary was emitting "binary" instead of the spec-mandated short name "vbin", and Type.FixedBinary / ParameterizedType.FixedBinary were emitting "fbinary" instead of "fbin". These mismatches caused function signature key lookup failures for any function with binary or fixedbinary arguments. Co-Authored-By: Claude Sonnet 4.6 --- core/src/main/java/io/substrait/function/ToTypeString.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/src/main/java/io/substrait/function/ToTypeString.java b/core/src/main/java/io/substrait/function/ToTypeString.java index 5c942f46a..2cb5f73c8 100644 --- a/core/src/main/java/io/substrait/function/ToTypeString.java +++ b/core/src/main/java/io/substrait/function/ToTypeString.java @@ -57,7 +57,7 @@ public String visit(final Type.Str expr) { @Override public String visit(final Type.Binary expr) { - return "binary"; + return "vbin"; } @Override @@ -112,7 +112,7 @@ public String visit(final Type.VarChar expr) { @Override public String visit(final Type.FixedBinary expr) { - return "fbinary"; + return "fbin"; } @Override @@ -172,7 +172,7 @@ public String visit(ParameterizedType.VarChar expr) throws RuntimeException { @Override public String visit(ParameterizedType.FixedBinary expr) throws RuntimeException { - return "fbinary"; + return "fbin"; } @Override From 3d386bd354d8beab2280aa69d2ecc24c7637c6e4 Mon Sep 17 00:00:00 2001 From: Victor Barua Date: Thu, 30 Apr 2026 16:03:50 -0700 Subject: [PATCH 2/3] test(core): add ToTypeStringTest covering all spec short type names Adds a parameterized test suite that explicitly asserts each type maps to its canonical short name from https://substrait.io/extensions/#type-short-names, covering both required and nullable variants plus UserDefined and any/lossless edge cases. Co-Authored-By: Claude Sonnet 4.6 --- .../substrait/function/ToTypeStringTest.java | 73 +++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 core/src/test/java/io/substrait/function/ToTypeStringTest.java diff --git a/core/src/test/java/io/substrait/function/ToTypeStringTest.java b/core/src/test/java/io/substrait/function/ToTypeStringTest.java new file mode 100644 index 000000000..02f81411a --- /dev/null +++ b/core/src/test/java/io/substrait/function/ToTypeStringTest.java @@ -0,0 +1,73 @@ +package io.substrait.function; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import io.substrait.type.Type; +import io.substrait.type.TypeCreator; +import java.util.stream.Stream; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +class ToTypeStringTest { + + static Stream types() { + return Stream.of(TypeCreator.REQUIRED, TypeCreator.NULLABLE) + .flatMap( + c -> + Stream.of( + Arguments.of(c.BOOLEAN, "bool"), + Arguments.of(c.I8, "i8"), + Arguments.of(c.I16, "i16"), + Arguments.of(c.I32, "i32"), + Arguments.of(c.I64, "i64"), + Arguments.of(c.FP32, "fp32"), + Arguments.of(c.FP64, "fp64"), + Arguments.of(c.STRING, "str"), + Arguments.of(c.BINARY, "vbin"), + Arguments.of(c.DATE, "date"), + Arguments.of(c.TIME, "time"), + Arguments.of(c.TIMESTAMP, "ts"), + Arguments.of(c.TIMESTAMP_TZ, "tstz"), + Arguments.of(c.INTERVAL_YEAR, "iyear"), + Arguments.of(c.UUID, "uuid"), + Arguments.of(c.fixedChar(1), "fchar"), + Arguments.of(c.varChar(1), "vchar"), + Arguments.of(c.fixedBinary(1), "fbin"), + Arguments.of(c.decimal(10, 2), "dec"), + Arguments.of(c.intervalDay(6), "iday"), + Arguments.of(c.intervalCompound(3), "icompound"), + Arguments.of(c.precisionTime(3), "pt"), + Arguments.of(c.precisionTimestamp(3), "pts"), + Arguments.of(c.precisionTimestampTZ(3), "ptstz"), + Arguments.of(c.struct(c.I32), "struct"), + Arguments.of(c.list(c.I32), "list"), + Arguments.of(c.map(c.I32, c.I64), "map"))); + } + + @ParameterizedTest + @MethodSource("types") + void typeToShortName(Type type, String expected) { + assertEquals(expected, ToTypeString.apply(type)); + } + + @Test + void userDefined() { + assertEquals("u!point", ToTypeString.apply(TypeCreator.REQUIRED.userDefined("urn", "point"))); + } + + @Test + void anyCollapsesNumericSuffix() { + ParameterizedType.StringLiteral any1 = + ParameterizedType.StringLiteral.builder().nullable(false).value("any1").build(); + assertEquals("any", any1.accept(ToTypeString.INSTANCE)); + } + + @Test + void losslessPreservesNumericSuffix() { + ParameterizedType.StringLiteral any1 = + ParameterizedType.StringLiteral.builder().nullable(false).value("any1").build(); + assertEquals("any1", any1.accept(ToTypeString.ToTypeLiteralStringLossless.INSTANCE)); + } +} From b63e4a333be8269da3665c20d5931afed17d6061 Mon Sep 17 00:00:00 2001 From: Victor Barua Date: Fri, 1 May 2026 07:54:47 -0700 Subject: [PATCH 3/3] docs: explicitly mention short names in ToTypeString --- core/src/main/java/io/substrait/function/ToTypeString.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/core/src/main/java/io/substrait/function/ToTypeString.java b/core/src/main/java/io/substrait/function/ToTypeString.java index 2cb5f73c8..a17f80b6b 100644 --- a/core/src/main/java/io/substrait/function/ToTypeString.java +++ b/core/src/main/java/io/substrait/function/ToTypeString.java @@ -2,6 +2,10 @@ import io.substrait.type.Type; +/** + * Converts types to their short name string representations as defined by the Substrait specification + */ public class ToTypeString extends ParameterizedTypeVisitor.ParameterizedTypeThrowsVisitor {