From d17e39a85e136e4f8b3e81a19c50a20e146d6648 Mon Sep 17 00:00:00 2001 From: Esteban Zimanyi Date: Wed, 30 Sep 2026 15:04:36 +0200 Subject: [PATCH] Map a generated parameter by its catalog type alone FunctionsGenerator gives each parameter the Java type of its C type in the interface, in the wrapper and in the call, whatever the parameter's name. SIZE_PARAM_NAMES, which gave an int parameter named size or wkb_size the Java type long, is gone. Witness. A parameter declared int size maps to long size under the name rule, so a binding passes a 64-bit value where MEOS reads a 32-bit one. The test paramTypeFollowsCTypeNotName gives int size, int32_t wkb_size and size_t vsize the types int, int and long; under the name rule it reads long for the first two. Measured. Against the catalog and libmeos of MobilityDB a362004728 with MEOS-API 20efba81be, the 26 parameters named size or wkb_size are 21 size_t, 2 size_t *, 2 Datum and 1 double, none int, and GeneratedFunctions.java is byte for byte the one the name rule generates. The build succeeds and the suites run 106 and 1,799 tests, all passing. Why. The catalog states the C type of every parameter, and the binding is its projection: a name carries no type. --- codegen/src/main/java/FunctionsGenerator.java | 20 +-------------- .../src/test/java/FunctionsGeneratorTest.java | 25 ++++++++++--------- 2 files changed, 14 insertions(+), 31 deletions(-) diff --git a/codegen/src/main/java/FunctionsGenerator.java b/codegen/src/main/java/FunctionsGenerator.java index 7dec7998f..1ac115fcc 100644 --- a/codegen/src/main/java/FunctionsGenerator.java +++ b/codegen/src/main/java/FunctionsGenerator.java @@ -38,11 +38,6 @@ public class FunctionsGenerator { private static final Set DATE_C_TYPES = Set.of("DateADT"); private static final Set TIMESTAMP_C_TYPES = Set.of("Timestamp", "TimestampTz"); - // The JSON sometimes encodes them as int32_t rather than size_t, producing - // "int" in the interface. old_functions.txt used "long" consistently for these, - // so we force long when the interface type resolved to int for these names. - private static final Set SIZE_PARAM_NAMES = Set.of("size", "wkb_size"); - /** Name of the leading parameter carrying the address of a struct returned through memory. */ private static final String RESULT_PARAM = "_result_address"; @@ -509,12 +504,6 @@ private FunctionDef parseFunctionDef(JsonNode fn) { String pCType = p.get("cType").asText(); String pJava = mapCTypeToJava(pCType); - // Override int → long for known byte-count parameters. - // The JSON may emit int32_t for these; old_functions.txt used long. - if (SIZE_PARAM_NAMES.contains(pName) && pJava.equals("int")) { - pJava = "long"; - } - params.add(new ParamDef(pName, pJava, pCType, outParams.contains(rawName))); } } @@ -999,10 +988,6 @@ private String generateStaticMethod(FunctionDef fn, int partIndex) { continue; // hide from signature; allocated below } String wrapperType = mapCTypeToJavaWrapper(p.cType); - // Preserve the long override for size params - if (SIZE_PARAM_NAMES.contains(p.name) && wrapperType.equals("int")) { - wrapperType = "long"; - } boolean needsConversion = isTemporalCType(p.cType); wparams.add(new WrapperParam(p.name, wrapperType, p.javaType, needsConversion)); } @@ -1199,10 +1184,7 @@ private String buildInterfaceParamList(List params) { if (params.isEmpty()) return ""; StringJoiner sj = new StringJoiner(", "); for (ParamDef p : params) { - // Restore long for size params even at interface level - String type = SIZE_PARAM_NAMES.contains(p.name) && p.javaType.equals("int") - ? "long" : p.javaType; - sj.add(type + " " + p.name); + sj.add(p.javaType + " " + p.name); } return sj.toString(); } diff --git a/codegen/src/test/java/FunctionsGeneratorTest.java b/codegen/src/test/java/FunctionsGeneratorTest.java index 96ecafd48..33a149fe8 100644 --- a/codegen/src/test/java/FunctionsGeneratorTest.java +++ b/codegen/src/test/java/FunctionsGeneratorTest.java @@ -806,27 +806,28 @@ void javaKeywordParam() throws Exception { } @Test - @DisplayName("size/wkb_size params use long in interface") - void sizeLongOverride() throws Exception { + @DisplayName("a parameter takes the Java type of its C type whatever its name") + void paramTypeFollowsCTypeNotName() throws Exception { String json = """ { "functions": [{ - "name": "tsequence_make", - "returnType": {"c": "TSequence *"}, + "name": "tint_value_split", + "returnType": {"c": "Temporal **"}, "params": [ - {"name": "instants", "cType": "TInstant **"}, - {"name": "size", "cType": "int32_t"}, - {"name": "lower_inc","cType": "bool"}, - {"name": "upper_inc","cType": "bool"}, - {"name": "interp", "cType": "interpType"}, - {"name": "normalize","cType": "bool"} + {"name": "temp", "cType": "const Temporal *"}, + {"name": "size", "cType": "int"}, + {"name": "wkb_size", "cType": "int32_t"}, + {"name": "vsize", "cType": "size_t"} ] }] } """; String out = generateFromJson(json); - // 'size' must be long even though cType is int32_t - assertTrue(out.contains("long size")); + assertTrue(out.contains("int size")); + assertTrue(out.contains("int wkb_size")); + assertTrue(out.contains("long vsize")); + assertFalse(out.contains("long size")); + assertFalse(out.contains("long wkb_size")); } @Test