[jOOQ/jOOQ#7398] Add Settings for each individual diagnostic

This includes:

- [jOOQ/jOOQ#14136] Let DiagnosticsContext extends Scope
This commit is contained in:
Lukas Eder 2022-10-26 14:53:48 +02:00
parent ea3c4590b3
commit a167560143
8 changed files with 460 additions and 45 deletions

View File

@ -50,7 +50,7 @@ import org.jetbrains.annotations.Nullable;
*
* @author Lukas Eder
*/
public interface DiagnosticsContext {
public interface DiagnosticsContext extends Scope {
/**
* The object that was diagnosed if available, or <code>null</code>, if there was no specific {@link QueryPart} to attach the diagnostic to.

View File

@ -116,6 +116,20 @@ public class Settings
@XmlElement(defaultValue = "WHEN_RESULT_REQUESTED")
@XmlSchemaType(name = "string")
protected FetchIntermediateResult fetchIntermediateResult = FetchIntermediateResult.WHEN_RESULT_REQUESTED;
@XmlElement(defaultValue = "true")
protected Boolean diagnosticsDuplicateStatements = true;
@XmlElement(defaultValue = "true")
protected Boolean diagnosticsMissingWasNullCall = true;
@XmlElement(defaultValue = "true")
protected Boolean diagnosticsRepeatedStatements = true;
@XmlElement(defaultValue = "true")
protected Boolean diagnosticsTooManyColumnsFetched = true;
@XmlElement(defaultValue = "true")
protected Boolean diagnosticsTooManyRowsFetched = true;
@XmlElement(defaultValue = "true")
protected Boolean diagnosticsUnnecessaryWasNullCall = true;
@XmlElement(defaultValue = "true")
protected Boolean diagnosticsTrivialCondition = true;
@XmlElement(defaultValue = "false")
protected Boolean transformPatterns = false;
@XmlElement(defaultValue = "true")
@ -1230,6 +1244,197 @@ public class Settings
this.fetchIntermediateResult = value;
}
/**
* Whether to run the {@link org.jooq.DiagnosticsListener#duplicateStatements(org.jooq.DiagnosticsContext) diagnostic.
* <p>
* Diagnostics are turned off if no {@link org.jooq.Configuration#diagnosticsListenerProviders()} are configured.
* Once configured, this diagnostic is turned on by default.
*
* @return
* possible object is
* {@link Boolean }
*
*/
public Boolean isDiagnosticsDuplicateStatements() {
return diagnosticsDuplicateStatements;
}
/**
* Sets the value of the diagnosticsDuplicateStatements property.
*
* @param value
* allowed object is
* {@link Boolean }
*
*/
public void setDiagnosticsDuplicateStatements(Boolean value) {
this.diagnosticsDuplicateStatements = value;
}
/**
* Whether to run the {@link org.jooq.DiagnosticsListener#missingWasNullCall(org.jooq.DiagnosticsContext) diagnostic.
* <p>
* Diagnostics are turned off if no {@link org.jooq.Configuration#diagnosticsListenerProviders()} are configured.
* Once configured, this diagnostic is turned on by default.
*
* @return
* possible object is
* {@link Boolean }
*
*/
public Boolean isDiagnosticsMissingWasNullCall() {
return diagnosticsMissingWasNullCall;
}
/**
* Sets the value of the diagnosticsMissingWasNullCall property.
*
* @param value
* allowed object is
* {@link Boolean }
*
*/
public void setDiagnosticsMissingWasNullCall(Boolean value) {
this.diagnosticsMissingWasNullCall = value;
}
/**
* Whether to run the {@link org.jooq.DiagnosticsListener#repeatedStatements(org.jooq.DiagnosticsContext) diagnostic.
* <p>
* Diagnostics are turned off if no {@link org.jooq.Configuration#diagnosticsListenerProviders()} are configured.
* Once configured, this diagnostic is turned on by default.
*
* @return
* possible object is
* {@link Boolean }
*
*/
public Boolean isDiagnosticsRepeatedStatements() {
return diagnosticsRepeatedStatements;
}
/**
* Sets the value of the diagnosticsRepeatedStatements property.
*
* @param value
* allowed object is
* {@link Boolean }
*
*/
public void setDiagnosticsRepeatedStatements(Boolean value) {
this.diagnosticsRepeatedStatements = value;
}
/**
* Whether to run the {@link org.jooq.DiagnosticsListener#tooManyColumnsFetched(org.jooq.DiagnosticsContext) diagnostic.
* <p>
* Diagnostics are turned off if no {@link org.jooq.Configuration#diagnosticsListenerProviders()} are configured.
* Once configured, this diagnostic is turned on by default.
*
* @return
* possible object is
* {@link Boolean }
*
*/
public Boolean isDiagnosticsTooManyColumnsFetched() {
return diagnosticsTooManyColumnsFetched;
}
/**
* Sets the value of the diagnosticsTooManyColumnsFetched property.
*
* @param value
* allowed object is
* {@link Boolean }
*
*/
public void setDiagnosticsTooManyColumnsFetched(Boolean value) {
this.diagnosticsTooManyColumnsFetched = value;
}
/**
* Whether to run the {@link org.jooq.DiagnosticsListener#tooManyRowsFetched(org.jooq.DiagnosticsContext) diagnostic.
* <p>
* Diagnostics are turned off if no {@link org.jooq.Configuration#diagnosticsListenerProviders()} are configured.
* Once configured, this diagnostic is turned on by default.
*
* @return
* possible object is
* {@link Boolean }
*
*/
public Boolean isDiagnosticsTooManyRowsFetched() {
return diagnosticsTooManyRowsFetched;
}
/**
* Sets the value of the diagnosticsTooManyRowsFetched property.
*
* @param value
* allowed object is
* {@link Boolean }
*
*/
public void setDiagnosticsTooManyRowsFetched(Boolean value) {
this.diagnosticsTooManyRowsFetched = value;
}
/**
* Whether to run the {@link org.jooq.DiagnosticsListener#unnecessaryWasNullCall(org.jooq.DiagnosticsContext) diagnostic.
* <p>
* Diagnostics are turned off if no {@link org.jooq.Configuration#diagnosticsListenerProviders()} are configured.
* Once configured, this diagnostic is turned on by default.
*
* @return
* possible object is
* {@link Boolean }
*
*/
public Boolean isDiagnosticsUnnecessaryWasNullCall() {
return diagnosticsUnnecessaryWasNullCall;
}
/**
* Sets the value of the diagnosticsUnnecessaryWasNullCall property.
*
* @param value
* allowed object is
* {@link Boolean }
*
*/
public void setDiagnosticsUnnecessaryWasNullCall(Boolean value) {
this.diagnosticsUnnecessaryWasNullCall = value;
}
/**
* Whether to run the {@link org.jooq.DiagnosticsListener#trivialCondition(org.jooq.DiagnosticsContext) diagnostic.
* <p>
* Diagnostics are turned off if no {@link org.jooq.Configuration#diagnosticsListenerProviders()} are configured.
* Once configured, this diagnostic is turned on by default.
* <p>
* This feature is available in the commercial distribution only.
*
* @return
* possible object is
* {@link Boolean }
*
*/
public Boolean isDiagnosticsTrivialCondition() {
return diagnosticsTrivialCondition;
}
/**
* Sets the value of the diagnosticsTrivialCondition property.
*
* @param value
* allowed object is
* {@link Boolean }
*
*/
public void setDiagnosticsTrivialCondition(Boolean value) {
this.diagnosticsTrivialCondition = value;
}
/**
* Transform various syntax patterns to better versions, if possible.
* <p>
@ -4578,6 +4783,41 @@ public class Settings
return this;
}
public Settings withDiagnosticsDuplicateStatements(Boolean value) {
setDiagnosticsDuplicateStatements(value);
return this;
}
public Settings withDiagnosticsMissingWasNullCall(Boolean value) {
setDiagnosticsMissingWasNullCall(value);
return this;
}
public Settings withDiagnosticsRepeatedStatements(Boolean value) {
setDiagnosticsRepeatedStatements(value);
return this;
}
public Settings withDiagnosticsTooManyColumnsFetched(Boolean value) {
setDiagnosticsTooManyColumnsFetched(value);
return this;
}
public Settings withDiagnosticsTooManyRowsFetched(Boolean value) {
setDiagnosticsTooManyRowsFetched(value);
return this;
}
public Settings withDiagnosticsUnnecessaryWasNullCall(Boolean value) {
setDiagnosticsUnnecessaryWasNullCall(value);
return this;
}
public Settings withDiagnosticsTrivialCondition(Boolean value) {
setDiagnosticsTrivialCondition(value);
return this;
}
public Settings withTransformPatterns(Boolean value) {
setTransformPatterns(value);
return this;
@ -5607,6 +5847,13 @@ public class Settings
builder.append("bindOffsetTimeType", bindOffsetTimeType);
builder.append("fetchTriggerValuesAfterSQLServerOutput", fetchTriggerValuesAfterSQLServerOutput);
builder.append("fetchIntermediateResult", fetchIntermediateResult);
builder.append("diagnosticsDuplicateStatements", diagnosticsDuplicateStatements);
builder.append("diagnosticsMissingWasNullCall", diagnosticsMissingWasNullCall);
builder.append("diagnosticsRepeatedStatements", diagnosticsRepeatedStatements);
builder.append("diagnosticsTooManyColumnsFetched", diagnosticsTooManyColumnsFetched);
builder.append("diagnosticsTooManyRowsFetched", diagnosticsTooManyRowsFetched);
builder.append("diagnosticsUnnecessaryWasNullCall", diagnosticsUnnecessaryWasNullCall);
builder.append("diagnosticsTrivialCondition", diagnosticsTrivialCondition);
builder.append("transformPatterns", transformPatterns);
builder.append("transformPatternsLogging", transformPatternsLogging);
builder.append("transformPatternsTrim", transformPatternsTrim);
@ -6057,6 +6304,69 @@ public class Settings
return false;
}
}
if (diagnosticsDuplicateStatements == null) {
if (other.diagnosticsDuplicateStatements!= null) {
return false;
}
} else {
if (!diagnosticsDuplicateStatements.equals(other.diagnosticsDuplicateStatements)) {
return false;
}
}
if (diagnosticsMissingWasNullCall == null) {
if (other.diagnosticsMissingWasNullCall!= null) {
return false;
}
} else {
if (!diagnosticsMissingWasNullCall.equals(other.diagnosticsMissingWasNullCall)) {
return false;
}
}
if (diagnosticsRepeatedStatements == null) {
if (other.diagnosticsRepeatedStatements!= null) {
return false;
}
} else {
if (!diagnosticsRepeatedStatements.equals(other.diagnosticsRepeatedStatements)) {
return false;
}
}
if (diagnosticsTooManyColumnsFetched == null) {
if (other.diagnosticsTooManyColumnsFetched!= null) {
return false;
}
} else {
if (!diagnosticsTooManyColumnsFetched.equals(other.diagnosticsTooManyColumnsFetched)) {
return false;
}
}
if (diagnosticsTooManyRowsFetched == null) {
if (other.diagnosticsTooManyRowsFetched!= null) {
return false;
}
} else {
if (!diagnosticsTooManyRowsFetched.equals(other.diagnosticsTooManyRowsFetched)) {
return false;
}
}
if (diagnosticsUnnecessaryWasNullCall == null) {
if (other.diagnosticsUnnecessaryWasNullCall!= null) {
return false;
}
} else {
if (!diagnosticsUnnecessaryWasNullCall.equals(other.diagnosticsUnnecessaryWasNullCall)) {
return false;
}
}
if (diagnosticsTrivialCondition == null) {
if (other.diagnosticsTrivialCondition!= null) {
return false;
}
} else {
if (!diagnosticsTrivialCondition.equals(other.diagnosticsTrivialCondition)) {
return false;
}
}
if (transformPatterns == null) {
if (other.transformPatterns!= null) {
return false;
@ -7285,6 +7595,13 @@ public class Settings
result = ((prime*result)+((bindOffsetTimeType == null)? 0 :bindOffsetTimeType.hashCode()));
result = ((prime*result)+((fetchTriggerValuesAfterSQLServerOutput == null)? 0 :fetchTriggerValuesAfterSQLServerOutput.hashCode()));
result = ((prime*result)+((fetchIntermediateResult == null)? 0 :fetchIntermediateResult.hashCode()));
result = ((prime*result)+((diagnosticsDuplicateStatements == null)? 0 :diagnosticsDuplicateStatements.hashCode()));
result = ((prime*result)+((diagnosticsMissingWasNullCall == null)? 0 :diagnosticsMissingWasNullCall.hashCode()));
result = ((prime*result)+((diagnosticsRepeatedStatements == null)? 0 :diagnosticsRepeatedStatements.hashCode()));
result = ((prime*result)+((diagnosticsTooManyColumnsFetched == null)? 0 :diagnosticsTooManyColumnsFetched.hashCode()));
result = ((prime*result)+((diagnosticsTooManyRowsFetched == null)? 0 :diagnosticsTooManyRowsFetched.hashCode()));
result = ((prime*result)+((diagnosticsUnnecessaryWasNullCall == null)? 0 :diagnosticsUnnecessaryWasNullCall.hashCode()));
result = ((prime*result)+((diagnosticsTrivialCondition == null)? 0 :diagnosticsTrivialCondition.hashCode()));
result = ((prime*result)+((transformPatterns == null)? 0 :transformPatterns.hashCode()));
result = ((prime*result)+((transformPatternsLogging == null)? 0 :transformPatternsLogging.hashCode()));
result = ((prime*result)+((transformPatternsTrim == null)? 0 :transformPatternsTrim.hashCode()));

View File

@ -50,6 +50,7 @@ import java.util.Collections;
import java.util.List;
import java.util.Set;
import org.jooq.Configuration;
import org.jooq.DiagnosticsContext;
import org.jooq.QueryPart;
import org.jooq.tools.JooqLogger;
@ -57,7 +58,7 @@ import org.jooq.tools.JooqLogger;
/**
* @author Lukas Eder
*/
final class DefaultDiagnosticsContext implements DiagnosticsContext {
final class DefaultDiagnosticsContext extends AbstractScope implements DiagnosticsContext {
private static final JooqLogger log = JooqLogger.getLogger(DefaultDiagnosticsContext.class);
@ -79,12 +80,13 @@ final class DefaultDiagnosticsContext implements DiagnosticsContext {
int resultSetColumnIndex;
final Throwable exception;
DefaultDiagnosticsContext(String message, String actualStatement) {
this(message, actualStatement, null);
DefaultDiagnosticsContext(Configuration configuration, String message, String actualStatement) {
this(configuration, message, actualStatement, null);
}
DefaultDiagnosticsContext(String message, String actualStatement, Throwable exception) {
DefaultDiagnosticsContext(Configuration configuration, String message, String actualStatement, Throwable exception) {
this(
configuration,
message,
actualStatement,
actualStatement,
@ -96,6 +98,7 @@ final class DefaultDiagnosticsContext implements DiagnosticsContext {
}
DefaultDiagnosticsContext(
Configuration configuration,
String message,
String actualStatement,
String normalisedStatement,
@ -104,6 +107,8 @@ final class DefaultDiagnosticsContext implements DiagnosticsContext {
QueryPart part,
Throwable exception
) {
super(configuration);
this.message = message;
this.actualStatement = actualStatement;
this.normalisedStatement = normalisedStatement;

View File

@ -37,6 +37,7 @@
*/
package org.jooq.impl;
import static java.lang.Boolean.FALSE;
// ...
import static org.jooq.conf.ParamType.FORCE_INDEXED;
@ -51,6 +52,7 @@ import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.function.Predicate;
import java.util.Set;
import org.jooq.Configuration;
@ -58,6 +60,7 @@ import org.jooq.Parser;
import org.jooq.Queries;
import org.jooq.QueryPart;
import org.jooq.RenderContext;
import org.jooq.conf.Settings;
import org.jooq.impl.QOM.Eq;
import org.jooq.tools.jdbc.DefaultConnection;
@ -161,6 +164,10 @@ final class DiagnosticsConnection extends DefaultConnection {
configuration.connectionProvider().release(getDelegate());
}
final boolean check(Predicate<? super Settings> test) {
return !FALSE.equals(test.test(configuration.settings()));
}
final String parse(String sql) {
Queries queries = null;
String normalised;
@ -172,28 +179,37 @@ final class DiagnosticsConnection extends DefaultConnection {
catch (ParserException exception) {
normalised = sql;
listeners.exception(new DefaultDiagnosticsContext(
configuration,
"Query could not be parsed.", sql, exception
));
}
try {
Set<String> duplicates = null;
synchronized (DUPLICATE_SQL) {
duplicates = duplicates(DUPLICATE_SQL, sql, normalised);
if (check(Settings::isDiagnosticsDuplicateStatements)) {
Set<String> duplicates = null;
synchronized (DUPLICATE_SQL) {
duplicates = duplicates(DUPLICATE_SQL, sql, normalised);
}
if (duplicates != null)
listeners.duplicateStatements(new DefaultDiagnosticsContext(
configuration,
"Duplicate statements encountered.",
sql, normalised, duplicates, null, queries, null
));
}
if (check(Settings::isDiagnosticsRepeatedStatements)) {
List<String> repetitions = repetitions(repeatedSQL, sql, normalised);
if (repetitions != null)
listeners.repeatedStatements(new DefaultDiagnosticsContext(
configuration,
"Repeated statements encountered.",
sql, normalised, null, repetitions, queries, null
));
}
if (duplicates != null)
listeners.duplicateStatements(new DefaultDiagnosticsContext(
"Duplicate statements encountered.",
sql, normalised, duplicates, null, queries, null
));
List<String> repetitions = repetitions(repeatedSQL, sql, normalised);
if (repetitions != null)
listeners.repeatedStatements(new DefaultDiagnosticsContext(
"Repeated statements encountered.",
sql, normalised, null, repetitions, queries, null
));
@ -219,6 +235,7 @@ final class DiagnosticsConnection extends DefaultConnection {
}
catch (Throwable exception) {
listeners.exception(new DefaultDiagnosticsContext(
configuration,
"An unexpected exception has occurred. See exception for details.",
sql, normalised, null, null, queries, exception
));

View File

@ -37,12 +37,16 @@
*/
package org.jooq.impl;
import static java.lang.Boolean.FALSE;
import static org.jooq.impl.Tools.map;
import java.util.function.Predicate;
import org.jooq.Configuration;
import org.jooq.DiagnosticsContext;
import org.jooq.DiagnosticsListener;
import org.jooq.DiagnosticsListenerProvider;
import org.jooq.conf.Settings;
/**
* @author Lukas Eder
@ -59,40 +63,50 @@ final class DiagnosticsListeners implements DiagnosticsListener {
return new DiagnosticsListeners(configuration.diagnosticsListenerProviders());
}
private final boolean check(DiagnosticsContext ctx, Predicate<? super Settings> test) {
return !FALSE.equals(test.test(ctx.settings()));
}
@Override
public final void tooManyRowsFetched(DiagnosticsContext ctx) {
for (DiagnosticsListener listener : listeners)
listener.tooManyRowsFetched(ctx);
if (check(ctx, Settings::isDiagnosticsTooManyRowsFetched))
for (DiagnosticsListener listener : listeners)
listener.tooManyRowsFetched(ctx);
}
@Override
public final void tooManyColumnsFetched(DiagnosticsContext ctx) {
for (DiagnosticsListener listener : listeners)
listener.tooManyColumnsFetched(ctx);
if (check(ctx, Settings::isDiagnosticsTooManyColumnsFetched))
for (DiagnosticsListener listener : listeners)
listener.tooManyColumnsFetched(ctx);
}
@Override
public final void unnecessaryWasNullCall(DiagnosticsContext ctx) {
for (DiagnosticsListener listener : listeners)
listener.unnecessaryWasNullCall(ctx);
if (check(ctx, Settings::isDiagnosticsUnnecessaryWasNullCall))
for (DiagnosticsListener listener : listeners)
listener.unnecessaryWasNullCall(ctx);
}
@Override
public final void missingWasNullCall(DiagnosticsContext ctx) {
for (DiagnosticsListener listener : listeners)
listener.missingWasNullCall(ctx);
if (check(ctx, Settings::isDiagnosticsMissingWasNullCall))
for (DiagnosticsListener listener : listeners)
listener.missingWasNullCall(ctx);
}
@Override
public final void duplicateStatements(DiagnosticsContext ctx) {
for (DiagnosticsListener listener : listeners)
listener.duplicateStatements(ctx);
if (check(ctx, Settings::isDiagnosticsDuplicateStatements))
for (DiagnosticsListener listener : listeners)
listener.duplicateStatements(ctx);
}
@Override
public final void repeatedStatements(DiagnosticsContext ctx) {
for (DiagnosticsListener listener : listeners)
listener.repeatedStatements(ctx);
if (check(ctx, Settings::isDiagnosticsRepeatedStatements))
for (DiagnosticsListener listener : listeners)
listener.repeatedStatements(ctx);
}
@ -105,6 +119,7 @@ final class DiagnosticsListeners implements DiagnosticsListener {
@Override
public final void exception(DiagnosticsContext ctx) {
for (DiagnosticsListener listener : listeners)

View File

@ -59,7 +59,9 @@ import java.sql.Timestamp;
import java.util.BitSet;
import java.util.Calendar;
import java.util.Map;
import java.util.function.Predicate;
import org.jooq.conf.Settings;
import org.jooq.tools.jdbc.DefaultResultSet;
/**
@ -579,7 +581,7 @@ final class DiagnosticsResultSet extends DefaultResultSet {
@Override
public final boolean wasNull() throws SQLException {
if (!wasPrimitive) {
if (!wasPrimitive && check(Settings::isDiagnosticsUnnecessaryWasNullCall)) {
DefaultDiagnosticsContext ctx = ctx("ResultSet::wasNull was called unnecessarily.");
ctx.resultSetUnnecessaryWasNullCall = true;
ctx.resultSetColumnIndex = wasColumnIndex;
@ -609,7 +611,7 @@ final class DiagnosticsResultSet extends DefaultResultSet {
}
private final void checkPrimitive() throws SQLException {
if (wasPrimitive && wasNullable) {
if (wasPrimitive && wasNullable && check(Settings::isDiagnosticsMissingWasNullCall)) {
DefaultDiagnosticsContext ctx = ctx("ResultSet::wasNull was not called.");
ctx.resultSetMissingWasNullCall = true;
ctx.resultSetColumnIndex = wasColumnIndex;
@ -628,8 +630,12 @@ final class DiagnosticsResultSet extends DefaultResultSet {
read(super.findColumn(columnLabel));
}
private final boolean check(Predicate<? super Settings> test) {
return connection.check(test);
}
private final DefaultDiagnosticsContext ctx(String message) throws SQLException {
DefaultDiagnosticsContext ctx = new DefaultDiagnosticsContext(message, sql);
DefaultDiagnosticsContext ctx = new DefaultDiagnosticsContext(connection.configuration, message, sql);
ctx.resultSet = super.getDelegate();
ctx.resultSetWrapper = this;
@ -742,20 +748,24 @@ final class DiagnosticsResultSet extends DefaultResultSet {
checkPrimitive();
try {
if (current < rows)
super.absolute(current = rows);
if (check(Settings::isDiagnosticsTooManyRowsFetched)) {
if (current < rows)
super.absolute(current = rows);
DefaultDiagnosticsContext c1 = ctx("Too many rows fetched");
c1.resultSetClosing = true;
DefaultDiagnosticsContext c1 = ctx("Too many rows fetched");
c1.resultSetClosing = true;
if (super.next())
connection.listeners.tooManyRowsFetched(c1);
if (super.next())
connection.listeners.tooManyRowsFetched(c1);
}
DefaultDiagnosticsContext c2 = ctx("Too many columns fetched");
c2.resultSetClosing = true;
if (check(Settings::isDiagnosticsTooManyColumnsFetched)) {
DefaultDiagnosticsContext c2 = ctx("Too many columns fetched");
c2.resultSetClosing = true;
if (read.cardinality() != columns)
connection.listeners.tooManyColumnsFetched(c2);
if (read.cardinality() != columns)
connection.listeners.tooManyColumnsFetched(c2);
}
}
catch (SQLException ignore) {}

View File

@ -49,7 +49,7 @@ import org.jooq.tools.jdbc.DefaultCallableStatement;
*/
final class DiagnosticsStatement extends DefaultCallableStatement {
private final DiagnosticsConnection connection;
final DiagnosticsConnection connection;
DiagnosticsStatement(DiagnosticsConnection connection, Statement statement) {
super(statement);

View File

@ -279,6 +279,57 @@ Using this flag, fetching of intermediate results can be turned off even when ex
are present, or turned on even if they're absent.]]></jxb:javadoc></jxb:property></appinfo></annotation>
</element>
<element name="diagnosticsDuplicateStatements" type="boolean" minOccurs="0" maxOccurs="1" default="true">
<annotation><appinfo><jxb:property><jxb:javadoc><![CDATA[Whether to run the {@link org.jooq.DiagnosticsListener#duplicateStatements(org.jooq.DiagnosticsContext) diagnostic.
<p>
Diagnostics are turned off if no {@link org.jooq.Configuration#diagnosticsListenerProviders()} are configured.
Once configured, this diagnostic is turned on by default.]]></jxb:javadoc></jxb:property></appinfo></annotation>
</element>
<element name="diagnosticsMissingWasNullCall" type="boolean" minOccurs="0" maxOccurs="1" default="true">
<annotation><appinfo><jxb:property><jxb:javadoc><![CDATA[Whether to run the {@link org.jooq.DiagnosticsListener#missingWasNullCall(org.jooq.DiagnosticsContext) diagnostic.
<p>
Diagnostics are turned off if no {@link org.jooq.Configuration#diagnosticsListenerProviders()} are configured.
Once configured, this diagnostic is turned on by default.]]></jxb:javadoc></jxb:property></appinfo></annotation>
</element>
<element name="diagnosticsRepeatedStatements" type="boolean" minOccurs="0" maxOccurs="1" default="true">
<annotation><appinfo><jxb:property><jxb:javadoc><![CDATA[Whether to run the {@link org.jooq.DiagnosticsListener#repeatedStatements(org.jooq.DiagnosticsContext) diagnostic.
<p>
Diagnostics are turned off if no {@link org.jooq.Configuration#diagnosticsListenerProviders()} are configured.
Once configured, this diagnostic is turned on by default.]]></jxb:javadoc></jxb:property></appinfo></annotation>
</element>
<element name="diagnosticsTooManyColumnsFetched" type="boolean" minOccurs="0" maxOccurs="1" default="true">
<annotation><appinfo><jxb:property><jxb:javadoc><![CDATA[Whether to run the {@link org.jooq.DiagnosticsListener#tooManyColumnsFetched(org.jooq.DiagnosticsContext) diagnostic.
<p>
Diagnostics are turned off if no {@link org.jooq.Configuration#diagnosticsListenerProviders()} are configured.
Once configured, this diagnostic is turned on by default.]]></jxb:javadoc></jxb:property></appinfo></annotation>
</element>
<element name="diagnosticsTooManyRowsFetched" type="boolean" minOccurs="0" maxOccurs="1" default="true">
<annotation><appinfo><jxb:property><jxb:javadoc><![CDATA[Whether to run the {@link org.jooq.DiagnosticsListener#tooManyRowsFetched(org.jooq.DiagnosticsContext) diagnostic.
<p>
Diagnostics are turned off if no {@link org.jooq.Configuration#diagnosticsListenerProviders()} are configured.
Once configured, this diagnostic is turned on by default.]]></jxb:javadoc></jxb:property></appinfo></annotation>
</element>
<element name="diagnosticsUnnecessaryWasNullCall" type="boolean" minOccurs="0" maxOccurs="1" default="true">
<annotation><appinfo><jxb:property><jxb:javadoc><![CDATA[Whether to run the {@link org.jooq.DiagnosticsListener#unnecessaryWasNullCall(org.jooq.DiagnosticsContext) diagnostic.
<p>
Diagnostics are turned off if no {@link org.jooq.Configuration#diagnosticsListenerProviders()} are configured.
Once configured, this diagnostic is turned on by default.]]></jxb:javadoc></jxb:property></appinfo></annotation>
</element>
<element name="diagnosticsTrivialCondition" type="boolean" minOccurs="0" maxOccurs="1" default="true">
<annotation><appinfo><jxb:property><jxb:javadoc><![CDATA[Whether to run the {@link org.jooq.DiagnosticsListener#trivialCondition(org.jooq.DiagnosticsContext) diagnostic.
<p>
Diagnostics are turned off if no {@link org.jooq.Configuration#diagnosticsListenerProviders()} are configured.
Once configured, this diagnostic is turned on by default.
<p>
This feature is available in the commercial distribution only.]]></jxb:javadoc></jxb:property></appinfo></annotation>
</element>
<element name="transformPatterns" type="boolean" minOccurs="0" maxOccurs="1" default="false">
<annotation><appinfo><jxb:property><jxb:javadoc><![CDATA[Transform various syntax patterns to better versions, if possible.
<p>