Skip to content

Commit

Permalink
[#14005] Code generator produces wrong ordering of DataType
Browse files Browse the repository at this point in the history
properties for nullable and defaulted array types
  • Loading branch information
lukaseder committed Dec 9, 2024
1 parent f71609a commit 8696387
Showing 1 changed file with 73 additions and 13 deletions.
86 changes: 73 additions & 13 deletions jOOQ-codegen/src/main/java/org/jooq/codegen/JavaGenerator.java
Original file line number Diff line number Diff line change
Expand Up @@ -10500,24 +10500,43 @@ protected String refNumberType(JavaWriter out, DataTypeDefinition type) {
}

protected String getJavaTypeReference(Database db, DataTypeDefinition type, JavaWriter out) {
if (database.isArrayType(type.getType())) {
DataTypeDefinition t;
DataTypeDefinition base = type;

do
base = GenerationUtil.getArrayBaseType(db.getDialect(), t = base);
while (base != t);

return getJavaTypeReference0(db, base, out, arrayAppender(type));
}

else
return getJavaTypeReference0(db, type, out, arrayAppender(type));
}

// [#4388] TODO: Improve array handling
private Consumer<? super StringBuilder> arrayAppender(DataTypeDefinition type) {
if (database.isArrayType(type.getType())) {
DataTypeDefinition base = GenerationUtil.getArrayBaseType(db.getDialect(), type);
DataTypeDefinition base = GenerationUtil.getArrayBaseType(database.getDialect(), type);

// [#252] This check prevents StackOverflowError in case of e.g. PostgreSQL ANYARRAY types
if (base != type)
return getJavaTypeReference(db, base, out) + ".array()";
return sb -> arrayAppender(base).accept(sb.append(".array()"));
else
return getJavaTypeReference0(db, type, out) + ".array()";
return sb -> sb.append(".array()");
}

else
return getJavaTypeReference0(db, type, out);
return sb -> {};
}

private String getJavaTypeReference0(Database db, DataTypeDefinition type, JavaWriter out) {
return getTypeReference(
private String getJavaTypeReference0(
Database db,
DataTypeDefinition type,
JavaWriter out,
Consumer<? super StringBuilder> arrayAppender
) {
return getTypeReference0(
db,
type.getSchema(),
out,
Expand All @@ -10532,7 +10551,8 @@ private String getJavaTypeReference0(Database db, DataTypeDefinition type, JavaW
type.getGenerationOption(),
type.getGenerator(),
type.getDefaultValue(),
type.getQualifiedUserType()
type.getQualifiedUserType(),
arrayAppender
);
}

Expand Down Expand Up @@ -10861,6 +10881,7 @@ else if (kotlin && clazz == byte[].class)
return type;
}

@Deprecated
protected String getTypeReference(
Database db,
SchemaDefinition schema,
Expand All @@ -10877,6 +10898,29 @@ protected String getTypeReference(
String ge,
String d,
Name u
) {
return getTypeReference0(
db, schema, out, t, p, s, l, n, i, r, g, go, ge, d, u, x -> {}
);
}

private String getTypeReference0(
Database db,
SchemaDefinition schema,
JavaWriter out,
String t,
int p,
int s,
int l,
boolean n,
boolean i,
boolean r,
String g,
GenerationOption go,
String ge,
String d,
Name u,
Consumer<? super StringBuilder> arrayAppender
) {
StringBuilder sb = new StringBuilder();

Expand All @@ -10892,18 +10936,23 @@ else if (db.getDomain(schema, u) != null) {
final String sqlDataTypeRef = out.ref(getStrategy().getFullJavaIdentifier(db.getDomain(schema, u)), domainRefSegments()) + ".getDataType()";
sb.append(sqlDataTypeRef);

arrayAppender.accept(sb);
appendTypeReferenceNullability(db, out, sb, n);
appendTypeReferenceDefault(db, out, sb, d, sqlDataTypeRef);
appendTypeReferenceDefault(db, out, sb, d, sqlDataTypeRef, arrayAppender);
}
else if (db.getUDT(schema, u) != null) {
sb.append(out.ref(getStrategy().getFullJavaIdentifier(db.getUDT(schema, u)), 2));

appendGetDataTypeCall(sb);
arrayAppender.accept(sb);
}
// [#3942] [#7863] Dialects that support tables as UDTs
// [#5334] In MySQL, the user type is (ab)used for synthetic enum types. This can lead to accidental matches here
else if (SUPPORT_TABLE_AS_UDT.contains(db.getDialect()) && db.getTable(schema, u) != null) {
sb.append(out.ref(getStrategy().getFullJavaIdentifier(db.getTable(schema, u)), 2));

appendGetDataTypeCall(sb);
arrayAppender.accept(sb);
}
else if (db.getEnum(schema, u) != null) {
sb.append(getJavaTypeReference(db, new DefaultDataTypeDefinition(
Expand All @@ -10915,6 +10964,8 @@ else if (db.getEnum(schema, u) != null) {
sb.append(".asEnumDataType(");
sb.append(classOf(out.ref(getStrategy().getFullJavaClassName(db.getEnum(schema, u), Mode.ENUM))));
sb.append(")");

arrayAppender.accept(sb);
}
else {
DataType<?> dataType;
Expand Down Expand Up @@ -10988,6 +11039,7 @@ else if (db.getEnum(schema, u) != null) {
sb.append(sqlDataTypeRef);
}

arrayAppender.accept(sb);
appendTypeReferenceNullability(db, out, sb, n);

if (dataType.identity())
Expand Down Expand Up @@ -11018,7 +11070,7 @@ else if (db.getEnum(schema, u) != null) {
// [#5291] Some dialects report valid SQL expresions (e.g. PostgreSQL), others
// report actual values (e.g. MySQL).
if (dataType.defaulted())
appendTypeReferenceDefault(db, out, sb, d, sqlDataTypeRef);
appendTypeReferenceDefault(db, out, sb, d, sqlDataTypeRef, arrayAppender);
}

return sb.toString();
Expand All @@ -11040,7 +11092,14 @@ private final void appendTypeReferenceNullability(Database db, JavaWriter out, S

private static final Pattern P_TS_EXPRESSION = Pattern.compile("^(?i:current_(date|timestamp).*)$");

private final void appendTypeReferenceDefault(Database db, JavaWriter out, StringBuilder sb, String d, String sqlDataTypeRef) {
private final void appendTypeReferenceDefault(
Database db,
JavaWriter out,
StringBuilder sb,
String d,
String sqlDataTypeRef,
Consumer<? super StringBuilder> arrayAppender
) {
if (d != null) {
sb.append(".defaultValue(");

Expand Down Expand Up @@ -11071,8 +11130,9 @@ private final void appendTypeReferenceDefault(Database db, JavaWriter out, Strin
.append("\")");

sb.append(", ")
.append(sqlDataTypeRef)
.append(")")
.append(sqlDataTypeRef);
arrayAppender.accept(sb);
sb.append(")")
.append(kotlin && sqlDataTypeRef.contains(".OTHER") ? " as Any?" : "")
.append(")");
}
Expand Down

0 comments on commit 8696387

Please sign in to comment.