diff --git a/codegen/src/main/java/ObjectLayerGenerator.java b/codegen/src/main/java/ObjectLayerGenerator.java index fbbe3f129..62788badf 100644 --- a/codegen/src/main/java/ObjectLayerGenerator.java +++ b/codegen/src/main/java/ObjectLayerGenerator.java @@ -502,13 +502,28 @@ && cleanType(fn.path("returnType").path("c").asText()).equals("Temporal *")) { String returnKind; String returnSubtype = temporalReturn(retC); if (resultOut != null) { - if (!paramCType(params, resultOut).equals("TimestampTz *")) { - defer(ooName, "bool+result of " + paramCType(params, resultOut) + " needs a converter"); + String outT = paramCType(params, resultOut); + // A boxed return type carries the null the boolean-false case folds to; the reader pulls the + // value out of the single-element buffer. + returnType = switch (outT) { + case "TimestampTz *" -> "java.time.OffsetDateTime"; + case "int *", "int32 *", "int32_t *" -> "Integer"; + case "double *", "float8 *" -> "Double"; + case "int64 *", "int64_t *" -> "Long"; + default -> null; + }; + returnSubtype = switch (outT) { + case "TimestampTz *" -> "utils.TimestampTzConverter.toOffsetDateTime(_r.getLong(0))"; + case "int *", "int32 *", "int32_t *" -> "_r.getInt(0)"; + case "double *", "float8 *" -> "_r.getDouble(0)"; + case "int64 *", "int64_t *" -> "_r.getLong(0)"; + default -> null; + }; + if (returnType == null) { + defer(ooName, "bool+result of " + outT + " needs a converter"); return null; } - returnType = "java.time.OffsetDateTime"; returnKind = "boolResult"; - returnSubtype = "utils.TimestampTzConverter.toOffsetDateTime(_r.getLong(0))"; } else if (returnSubtype != null) { returnType = "Temporal"; returnKind = "temporal"; diff --git a/jmeos-core/src/test/java/types/temporal/generated/GeneratedConcreteNumberParityTest.java b/jmeos-core/src/test/java/types/temporal/generated/GeneratedConcreteNumberParityTest.java index 2f87dfd71..b2ca37d3a 100644 --- a/jmeos-core/src/test/java/types/temporal/generated/GeneratedConcreteNumberParityTest.java +++ b/jmeos-core/src/test/java/types/temporal/generated/GeneratedConcreteNumberParityTest.java @@ -95,6 +95,22 @@ void floatSurfaceMatchesTheLibrary() { assertEquals(GeneratedFunctions.tfloat_out(p, 6), g.out(6)); } + @Test + void intValueAccessorsMatchTheLibrary() { + TIntSeq a = new TIntSeq("[1@2019-09-01, 3@2019-09-02, 2@2019-09-03]"); + Pointer p = a.getInner(); + GeneratedTInt g = genInt(a); + + // valueN folds the bool+result to the base value; zero-based n reaches the one-based accessor. + Pointer r = GeneratedFunctions.tint_value_n(p, 2); + assertEquals(r == null ? null : Integer.valueOf(r.getInt(0)), g.valueN(1)); + + // valueAtTimestamptz folds the bool+result to the base value at a time. + OffsetDateTime t = OffsetDateTime.parse("2019-09-02T00:00:00Z"); + Pointer r2 = GeneratedFunctions.tint_value_at_timestamptz(p, t, true); + assertEquals(r2 == null ? null : Integer.valueOf(r2.getInt(0)), g.valueAtTimestamptz(t, true)); + } + @Test void intValueSplitMatchesTheLibrary() { TIntSeq a = new TIntSeq("[1@2019-09-01, 3@2019-09-02, 5@2019-09-03]");