[jOOQ/jOOQ#10937] Add Settings.renderDefaultNullability

This commit is contained in:
Lukas Eder 2020-11-13 13:45:21 +01:00
parent c06bbc4008
commit 53904a378d
3 changed files with 109 additions and 6 deletions

View File

@ -82,6 +82,9 @@ public class Settings
@XmlElement(defaultValue = "DEFAULT")
@XmlSchemaType(name = "string")
protected RenderImplicitJoinType renderImplicitJoinType = RenderImplicitJoinType.DEFAULT;
@XmlElement(defaultValue = "IMPLICIT_NULL")
@XmlSchemaType(name = "string")
protected RenderDefaultNullability renderDefaultNullability = RenderDefaultNullability.IMPLICIT_NULL;
@XmlElement(defaultValue = "true")
protected Boolean renderOrderByRownumberForEmulatedPagination = true;
@XmlElement(defaultValue = "true")
@ -669,6 +672,22 @@ public class Settings
this.renderImplicitJoinType = value;
}
/**
* Whether the {@link org.jooq.Nullability#DEFAULT} nullablity should be rendered in generated DDL, and how it should be rendered.
*
*/
public RenderDefaultNullability getRenderDefaultNullability() {
return renderDefaultNullability;
}
/**
* Whether the {@link org.jooq.Nullability#DEFAULT} nullablity should be rendered in generated DDL, and how it should be rendered.
*
*/
public void setRenderDefaultNullability(RenderDefaultNullability value) {
this.renderDefaultNullability = value;
}
/**
* Whether an additional <code>ORDER BY rn</code> clause should be rendered on emulated paginated queries.
* <p>
@ -2661,6 +2680,15 @@ public class Settings
return this;
}
/**
* Whether the {@link org.jooq.Nullability#DEFAULT} nullablity should be rendered in generated DDL, and how it should be rendered.
*
*/
public Settings withRenderDefaultNullability(RenderDefaultNullability value) {
setRenderDefaultNullability(value);
return this;
}
public Settings withRenderOrderByRownumberForEmulatedPagination(Boolean value) {
setRenderOrderByRownumberForEmulatedPagination(value);
return this;
@ -3341,6 +3369,7 @@ public class Settings
builder.append("renderOptionalOuterKeyword", renderOptionalOuterKeyword);
builder.append("renderScalarSubqueriesForStoredFunctions", renderScalarSubqueriesForStoredFunctions);
builder.append("renderImplicitJoinType", renderImplicitJoinType);
builder.append("renderDefaultNullability", renderDefaultNullability);
builder.append("renderOrderByRownumberForEmulatedPagination", renderOrderByRownumberForEmulatedPagination);
builder.append("renderOutputForSQLServerReturningClause", renderOutputForSQLServerReturningClause);
builder.append("renderParenthesisAroundSetOperationQueries", renderParenthesisAroundSetOperationQueries);
@ -3609,6 +3638,15 @@ public class Settings
return false;
}
}
if (renderDefaultNullability == null) {
if (other.renderDefaultNullability!= null) {
return false;
}
} else {
if (!renderDefaultNullability.equals(other.renderDefaultNullability)) {
return false;
}
}
if (renderOrderByRownumberForEmulatedPagination == null) {
if (other.renderOrderByRownumberForEmulatedPagination!= null) {
return false;
@ -4399,6 +4437,7 @@ public class Settings
result = ((prime*result)+((renderOptionalOuterKeyword == null)? 0 :renderOptionalOuterKeyword.hashCode()));
result = ((prime*result)+((renderScalarSubqueriesForStoredFunctions == null)? 0 :renderScalarSubqueriesForStoredFunctions.hashCode()));
result = ((prime*result)+((renderImplicitJoinType == null)? 0 :renderImplicitJoinType.hashCode()));
result = ((prime*result)+((renderDefaultNullability == null)? 0 :renderDefaultNullability.hashCode()));
result = ((prime*result)+((renderOrderByRownumberForEmulatedPagination == null)? 0 :renderOrderByRownumberForEmulatedPagination.hashCode()));
result = ((prime*result)+((renderOutputForSQLServerReturningClause == null)? 0 :renderOutputForSQLServerReturningClause.hashCode()));
result = ((prime*result)+((renderParenthesisAroundSetOperationQueries == null)? 0 :renderParenthesisAroundSetOperationQueries.hashCode()));

View File

@ -62,11 +62,13 @@ import static org.jooq.SQLDialect.POSTGRES;
import static org.jooq.SQLDialect.SQLITE;
// ...
// ...
// ...
import static org.jooq.conf.BackslashEscaping.DEFAULT;
import static org.jooq.conf.BackslashEscaping.ON;
import static org.jooq.conf.ParamType.INLINED;
import static org.jooq.conf.ParamType.NAMED;
import static org.jooq.conf.ParamType.NAMED_OR_INLINED;
import static org.jooq.conf.RenderDefaultNullability.IMPLICIT_NULL;
import static org.jooq.conf.SettingsTools.getBackslashEscaping;
import static org.jooq.conf.SettingsTools.reflectionCaching;
import static org.jooq.conf.SettingsTools.updatablePrimaryKeys;
@ -275,6 +277,7 @@ import org.jooq.UpdatableRecord;
import org.jooq.XML;
import org.jooq.conf.BackslashEscaping;
import org.jooq.conf.ParseNameCase;
import org.jooq.conf.RenderDefaultNullability;
import org.jooq.conf.Settings;
import org.jooq.conf.SettingsTools;
import org.jooq.conf.ThrowExceptions;
@ -834,6 +837,10 @@ final class Tools {
private static final Set<SQLDialect> SUPPORT_MYSQL_SYNTAX = SQLDialect.supportedBy(MARIADB, MYSQL);
static final Set<SQLDialect> NO_SUPPORT_TIMESTAMP_PRECISION = SQLDialect.supportedBy(DERBY);
// ------------------------------------------------------------------------
// XXX: Record constructors and related methods
// ------------------------------------------------------------------------
@ -4924,13 +4931,48 @@ final class Tools {
if (DEFAULT_BEFORE_NULL.contains(ctx.dialect()))
toSQLDDLTypeDeclarationDefault(ctx, type);
if (!type.nullable())
ctx.sql(' ').visit(K_NOT_NULL);
switch (type.nullability()) {
case NOT_NULL:
ctx.sql(' ').visit(K_NOT_NULL);
break;
// Some databases default to NOT NULL, so explicitly setting columns to NULL is mostly required here
// [#3400] [#4321] [#7392] ... but not in Derby, Firebird, HSQLDB
else if (!NO_SUPPORT_NULL.contains(ctx.dialect()))
ctx.sql(' ').visit(K_NULL);
case NULL:
// [#3400] [#4321] [#7392] E.g. Derby, Firebird, HSQLDB do not support explicit nullability.
if (!NO_SUPPORT_NULL.contains(ctx.dialect()))
ctx.sql(' ').visit(K_NULL);
break;
// [#10937] The behaviour has been re-defined via Settings.renderDefaultNullability
case DEFAULT:
RenderDefaultNullability nullability = StringUtils.defaultIfNull(ctx.settings().getRenderDefaultNullability(), IMPLICIT_NULL);
switch (nullability) {
case EXPLICIT_NULL:
if (!NO_SUPPORT_NULL.contains(ctx.dialect()))
ctx.sql(' ').visit(K_NULL);
break;
case IMPLICIT_DEFAULT:
break;
case IMPLICIT_NULL:
break;
default:
throw new UnsupportedOperationException("Nullability not supported: " + nullability);
}
break;
default:
throw new UnsupportedOperationException("Nullability not supported: " + type.nullability());
}
if (!DEFAULT_BEFORE_NULL.contains(ctx.dialect()))
toSQLDDLTypeDeclarationDefault(ctx, type);

View File

@ -136,6 +136,10 @@ set to true, users can automatically profit from this feature in all SQL stateme
<element name="renderImplicitJoinType" type="jooq-runtime:RenderImplicitJoinType" minOccurs="0" maxOccurs="1" default="DEFAULT">
<annotation><appinfo><jxb:property><jxb:javadoc><![CDATA[The join type to be generated by implicit joins.]]></jxb:javadoc></jxb:property></appinfo></annotation>
</element>
<element name="renderDefaultNullability" type="jooq-runtime:RenderDefaultNullability" minOccurs="0" maxOccurs="1" default="IMPLICIT_NULL">
<annotation><appinfo><jxb:property><jxb:javadoc><![CDATA[Whether the {@link org.jooq.Nullability#DEFAULT} nullablity should be rendered in generated DDL, and how it should be rendered.]]></jxb:javadoc></jxb:property></appinfo></annotation>
</element>
<element name="renderOrderByRownumberForEmulatedPagination" type="boolean" minOccurs="0" maxOccurs="1" default="true">
<annotation><appinfo><jxb:property><jxb:javadoc><![CDATA[Whether an additional <code>ORDER BY rn</code> clause should be rendered on emulated paginated queries.
@ -1057,6 +1061,24 @@ Either &lt;input/&gt; or &lt;inputExpression/&gt; must be provided]]></jxb:javad
</restriction>
</simpleType>
<simpleType name="RenderDefaultNullability">
<restriction base="string">
<!-- Do not produce any nullability clause for Nullability.DEFAULT, and thus produce the dialect specific default behaviors -->
<enumeration value="IMPLICIT_DEFAULT"/>
<!-- Produce the dialect specific default behaviour, but generate it explicitly
<enumeration value="EXPLICIT_DEFAULT"/>
-->
<!-- Produce implicit nullability for Nullability.DEFAULT if NULL is the default for a given dialect, or explicit nullability otherwise (e.g. in both Sybase) -->
<enumeration value="IMPLICIT_NULL"/>
<!-- Produce explicit nullability for Nullability.DEFAULT, irrespective of the context (e.g. if the column is a primary key) -->
<enumeration value="EXPLICIT_NULL"/>
</restriction>
</simpleType>
<simpleType name="RenderOptionalKeyword">
<restriction base="string">