[jOOQ/jOOQ#5713] [jOOQ/jOOQ#15286] Add static type registry warning

Historically, the static type registry could also be used to look up converted data types, which is discouraged due to how unreliable it is.

TODO: Move this to a dynamic type registry and make warning configurable
This commit is contained in:
Lukas Eder 2023-06-27 10:28:48 +02:00
parent 981c54370b
commit f455b0875e
4 changed files with 126 additions and 0 deletions

View File

@ -527,6 +527,9 @@ public class Settings
protected WriteIfReadonly readonlyUpdate = WriteIfReadonly.IGNORE;
@XmlElement(defaultValue = "true")
protected Boolean applyWorkaroundFor7962 = true;
@XmlElement(defaultValue = "LOG_WARN")
@XmlSchemaType(name = "string")
protected Warning warnOnStaticTypeRegistryAccess = Warning.LOG_WARN;
@XmlElementWrapper(name = "interpreterSearchPath")
@XmlElement(name = "schema")
protected List<InterpreterSearchSchema> interpreterSearchPath;
@ -5952,6 +5955,22 @@ public class Settings
this.applyWorkaroundFor7962 = value;
}
/**
* [#15286] The warning level when the deprecated static type registry was accessed by legacy code.
*
*/
public Warning getWarnOnStaticTypeRegistryAccess() {
return warnOnStaticTypeRegistryAccess;
}
/**
* [#15286] The warning level when the deprecated static type registry was accessed by legacy code.
*
*/
public void setWarnOnStaticTypeRegistryAccess(Warning value) {
this.warnOnStaticTypeRegistryAccess = value;
}
public List<InterpreterSearchSchema> getInterpreterSearchPath() {
if (interpreterSearchPath == null) {
interpreterSearchPath = new ArrayList<InterpreterSearchSchema>();
@ -7519,6 +7538,15 @@ public class Settings
return this;
}
/**
* [#15286] The warning level when the deprecated static type registry was accessed by legacy code.
*
*/
public Settings withWarnOnStaticTypeRegistryAccess(Warning value) {
setWarnOnStaticTypeRegistryAccess(value);
return this;
}
public Settings withInterpreterSearchPath(InterpreterSearchSchema... values) {
if (values!= null) {
for (InterpreterSearchSchema value: values) {
@ -7802,6 +7830,7 @@ public class Settings
builder.append("readonlyInsert", readonlyInsert);
builder.append("readonlyUpdate", readonlyUpdate);
builder.append("applyWorkaroundFor7962", applyWorkaroundFor7962);
builder.append("warnOnStaticTypeRegistryAccess", warnOnStaticTypeRegistryAccess);
builder.append("interpreterSearchPath", "schema", interpreterSearchPath);
builder.append("migrationSchemata", "schema", migrationSchemata);
builder.append("parseSearchPath", "schema", parseSearchPath);
@ -9788,6 +9817,15 @@ public class Settings
return false;
}
}
if (warnOnStaticTypeRegistryAccess == null) {
if (other.warnOnStaticTypeRegistryAccess!= null) {
return false;
}
} else {
if (!warnOnStaticTypeRegistryAccess.equals(other.warnOnStaticTypeRegistryAccess)) {
return false;
}
}
if (interpreterSearchPath == null) {
if (other.interpreterSearchPath!= null) {
return false;
@ -10040,6 +10078,7 @@ public class Settings
result = ((prime*result)+((readonlyInsert == null)? 0 :readonlyInsert.hashCode()));
result = ((prime*result)+((readonlyUpdate == null)? 0 :readonlyUpdate.hashCode()));
result = ((prime*result)+((applyWorkaroundFor7962 == null)? 0 :applyWorkaroundFor7962 .hashCode()));
result = ((prime*result)+((warnOnStaticTypeRegistryAccess == null)? 0 :warnOnStaticTypeRegistryAccess.hashCode()));
result = ((prime*result)+((interpreterSearchPath == null)? 0 :interpreterSearchPath.hashCode()));
result = ((prime*result)+((migrationSchemata == null)? 0 :migrationSchemata.hashCode()));
result = ((prime*result)+((parseSearchPath == null)? 0 :parseSearchPath.hashCode()));

View File

@ -0,0 +1,43 @@
package org.jooq.conf;
import jakarta.xml.bind.annotation.XmlEnum;
import jakarta.xml.bind.annotation.XmlType;
/**
* <p>Java class for Warning.
*
* <p>The following schema fragment specifies the expected content contained within this class.
* <pre>
* &lt;simpleType name="Warning"&gt;
* &lt;restriction base="{http://www.w3.org/2001/XMLSchema}string"&gt;
* &lt;enumeration value="IGNORE"/&gt;
* &lt;enumeration value="LOG_DEBUG"/&gt;
* &lt;enumeration value="LOG_INFO"/&gt;
* &lt;enumeration value="LOG_WARN"/&gt;
* &lt;enumeration value="THROW"/&gt;
* &lt;/restriction&gt;
* &lt;/simpleType&gt;
* </pre>
*
*/
@XmlType(name = "Warning")
@XmlEnum
public enum Warning {
IGNORE,
LOG_DEBUG,
LOG_INFO,
LOG_WARN,
THROW;
public String value() {
return name();
}
public static Warning fromValue(String v) {
return valueOf(v);
}
}

View File

@ -118,6 +118,7 @@ import org.jooq.exception.SQLDialectNotSupportedException;
import org.jooq.impl.DefaultBinding.InternalBinding;
import org.jooq.impl.QOM.GenerationLocation;
import org.jooq.impl.QOM.GenerationOption;
import org.jooq.tools.JooqLogger;
import org.jooq.types.UByte;
import org.jooq.types.UInteger;
import org.jooq.types.ULong;
@ -793,7 +794,26 @@ public class DefaultDataType<T> extends AbstractDataTypeX<T> {
return getDataType(dialect, type, null);
}
private static final JooqLogger getDataType = JooqLogger.getLogger(DefaultDataType.class, "getDataType", 5);
private static final class DiscouragedStaticTypeRegistryUsage extends RuntimeException {}
public static final <T> DataType<T> getDataType(SQLDialect dialect, Class<T> type, DataType<T> fallbackDataType) {
return check(getDataType0(dialect, type, fallbackDataType));
}
private static final <T> DataType<T> check(DataType<T> result) {
// [#5713] [#15286] TODO: Move this to a dynamic type registry and make warning configurable
if (result instanceof ConvertedDataType || result instanceof LegacyConvertedDataType)
getDataType.warn("Static type registry", "The deprecated static type registry was being accessed for a non-built-in data type: " + result + ". It is strongly recommended not looking up DataType<T> references from Class<T> references by relying on the internal static type registry. See https://github.com/jOOQ/jOOQ/issues/15286 for details.", new DiscouragedStaticTypeRegistryUsage());
if (result instanceof ArrayDataType<?> a)
check(a.elementType);
return result;
}
private static final <T> DataType<T> getDataType0(SQLDialect dialect, Class<T> type, DataType<T> fallbackDataType) {
// Treat primitive types the same way as their respective wrapper types
type = wrapper(type);

View File

@ -1605,6 +1605,10 @@ inside of queries (including procedural statements) are still not supported.]]><
<element name="applyWorkaroundFor7962" type="boolean" minOccurs="0" maxOccurs="1" default="true">
<annotation><appinfo><jxb:property><jxb:javadoc><![CDATA[[#7963] Apply workaround for ORA-04043 when inserting into Oracle tables with qualified, quoted identifiers, and fetching generated keys]]></jxb:javadoc></jxb:property></appinfo></annotation>
</element>
<element name="warnOnStaticTypeRegistryAccess" type="jooq-runtime:Warning" minOccurs="0" maxOccurs="1" default="LOG_WARN">
<annotation><appinfo><jxb:property><jxb:javadoc><![CDATA[[#15286] The warning level when the deprecated static type registry was accessed by legacy code.]]></jxb:javadoc></jxb:property></appinfo></annotation>
</element>
</all>
</complexType>
@ -2082,6 +2086,26 @@ Either &lt;input/&gt; or &lt;inputExpression/&gt; must be provided]]></jxb:javad
<enumeration value="THROW"/>
</restriction>
</simpleType>
<simpleType name="Warning">
<restriction base="string">
<!-- Ignore a warning -->
<enumeration value="IGNORE"/>
<!-- Log a warning at DEBUG level -->
<enumeration value="LOG_DEBUG"/>
<!-- Log a warning at INFO level -->
<enumeration value="LOG_INFO"/>
<!-- Log a warning at WARN level -->
<enumeration value="LOG_WARN"/>
<!-- Throw an exception -->
<enumeration value="THROW"/>
</restriction>
</simpleType>
<simpleType name="RenderImplicitJoinType">
<restriction base="string">