Skip to content

Commit c229c67

Browse files
ThoSapclaude
andcommitted
correct the annotation positioning caveat for the six array columns
The comment in `generated/build.gradle.kts` and the section in `README.md` claimed the annotation positions are correct because the generated code uses no arrays. Six generated columns are arrays. Java applies a `TYPE_USE` annotation written before an array type to the element type, and NullAway drops array-dimension annotations in JSpecify mode. So `@Nullable String[] getNspacl()` reads as a non-null array of nullable strings, while the column is a nullable array of non-null strings. The six accessors are `getNspacl`, `getDatacl`, `getRelacl`, `getReloptions`, `getSetconfig` and `getDefaclacl`. No operator code calls them today, because the operator uses the table field constants and `Routines.aclexplode` instead. The README also claimed NullAway reads the real nullness of every generated method. The generator annotates column accessors only. `Routines.java` and the classes in the `routines` package carry no annotation, so a routine such as `shobj_description` still counts as non-null. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
1 parent 419b733 commit c229c67

2 files changed

Lines changed: 20 additions & 5 deletions

File tree

README.md

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -286,13 +286,20 @@ make generate-jooq
286286
./gradlew :generated:jooqCodegen
287287
```
288288

289-
The generator writes JSpecify nullability annotations into the generated sources, so NullAway reads the real nullness of every generated method instead of guessing.
290-
Two consequences are worth knowing:
289+
The generator writes JSpecify nullability annotations into the generated sources, so NullAway reads the real nullness of every generated column accessor instead of guessing.
290+
Routine return values stay unannotated, so `Routines.shobjDescription` still counts as non-null even though PostgreSQL returns `NULL` for an object without a comment.
291+
Three consequences are worth knowing:
291292

292293
- jOOQ does not officially support the `TYPE_USE` positioning that JSpecify requires yet ([jOOQ/jOOQ#10759](https://github.com/jOOQ/jOOQ/issues/10759)).
293-
The positioning is correct here only because the generated code uses no generics, collections, maps, arrays or forced types with inner
294+
The positioning is correct for every scalar column, because the generated code uses no generics, collections, maps or forced types with inner
294295
classes.
295296
Keep the `includes` list free of such objects, or review the annotation positions after a regeneration.
297+
- The positioning is wrong for the six array columns.
298+
Java applies a `TYPE_USE` annotation written before an array type to the element type, and NullAway drops array-dimension annotations in `JSpecifyMode`.
299+
So `@Nullable String[] getNspacl()` reads as a non-null array of nullable strings, while the column is a nullable array of non-null strings.
300+
The six accessors are `getNspacl`, `getDatacl`, `getRelacl`, `getReloptions`, `getSetconfig` and `getDefaclacl`.
301+
No operator code calls them today, because the operator uses the table field constants and `Routines.aclexplode` instead.
302+
A declaration annotation for `nullableAnnotationType` would fix the positioning, because such an annotation always applies to the method. That is a design change.
296303
- Every generated class carries `@SuppressWarnings({"all", ...})`, which Error Prone honours.
297304
That suppression, and nothing else, is why the generated sources are exempt from the checks in `errorprone.args`, including `RequireExplicitNullMarking`.
298305
Do not add `NullAway:TreatGeneratedAsUnannotated`: it would make NullAway discard the nullability annotations that this generator now writes.

generated/build.gradle.kts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,16 @@ jooq {
5454
nullableAnnotation = true
5555
// We use JSpecify annotations already even though jOOQ does not officially support JSpecify's TYPE_USE positioning yet.
5656
// See https://github.com/jOOQ/jOOQ/issues/10759
57-
// This only works as our generated code is not using any generics, collections, maps, arrays
58-
// or forced types with inner classes, and therefore the positioning of the annotations is accidentally correct.
57+
// The positioning is correct for every scalar column, as our generated code is not using any generics,
58+
// collections, maps or forced types with inner classes.
59+
// The positioning is wrong for the six array columns. Java applies a TYPE_USE annotation written before
60+
// an array type to the element type, and NullAway drops array-dimension annotations in JSpecifyMode.
61+
// So "@Nullable String[] getNspacl()" reads as a non-null array of nullable strings, while the column is
62+
// a nullable array of non-null strings.
63+
// The six accessors are getNspacl, getDatacl, getRelacl, getReloptions, getSetconfig and getDefaclacl.
64+
// No operator code calls them today, as the operator uses the table field constants and Routines.aclexplode.
65+
// A declaration annotation for nullableAnnotationType would fix the positioning, as such an annotation
66+
// always applies to the method. That is a design change, not a comment fix.
5967
nonnullAnnotationType = "org.jspecify.annotations.NonNull"
6068
nullableAnnotationType = "org.jspecify.annotations.Nullable"
6169
}

0 commit comments

Comments
 (0)