[jOOQ/jOOQ#7284] Replace common patterns in query object model

- Added global Settings.transformPatterns flag
- TRIM
- NOT NOT
- NEG NEG
- BITNOT BITNOT
This commit is contained in:
Lukas Eder 2022-01-10 17:30:05 +01:00
parent bb5f6d1dab
commit db42d102a4
3 changed files with 383 additions and 2 deletions

View File

@ -112,6 +112,16 @@ public class Settings
@XmlSchemaType(name = "string")
protected FetchIntermediateResult fetchIntermediateResult = FetchIntermediateResult.WHEN_RESULT_REQUESTED;
@XmlElement(defaultValue = "false")
protected Boolean transformPatterns = false;
@XmlElement(defaultValue = "true")
protected Boolean transformPatternsTrim = true;
@XmlElement(defaultValue = "true")
protected Boolean transformPatternsNotNot = true;
@XmlElement(defaultValue = "true")
protected Boolean transformPatternsNegNeg = true;
@XmlElement(defaultValue = "true")
protected Boolean transformPatternsBitNotBitNot = true;
@XmlElement(defaultValue = "false")
protected Boolean transformAnsiJoinToTableLists = false;
@XmlElement(defaultValue = "WHEN_NEEDED")
@XmlSchemaType(name = "string")
@ -1107,6 +1117,165 @@ public class Settings
this.fetchIntermediateResult = value;
}
/**
* Transform various syntax patterns to better versions, if possible.
* <p>
* This flag enables the pattern transformation feature, which consists of several sub-flags that are
* all prefixed with "transformPatterns", e.g. {@link #transformPatternsTrim}. While the sub-flags default
* to being enabled, and can be disabled on an individual basis, the global feature itself is disabled by
* default.
* <p>
* This feature is available in the commercial distribution only.
*
* @return
* possible object is
* {@link Boolean }
*
*/
public Boolean isTransformPatterns() {
return transformPatterns;
}
/**
* Sets the value of the transformPatterns property.
*
* @param value
* allowed object is
* {@link Boolean }
*
*/
public void setTransformPatterns(Boolean value) {
this.transformPatterns = value;
}
/**
* Transform <code>LTRIM(RTRIM(x))</code> or <code>RTRIM(LTRIM(x))</code> to <code>TRIM(x)</code>
* <p>
* Historically, a few dialects did not implement <code>TRIM(x)</code> or <code>TRIM(BOTH FROM x)</code>,
* so users worked around this by wrapping <code>LTRIM()</code> and <code>RTRIM()</code> with each other.
* Maintaining this is usually undesirable, so this transformation helps remove the unwanted wrapping.
* <p>
* To enable this feature, {@link #transformPatterns} must be enabled as well.
* <p>
* This feature is available in the commercial distribution only.
*
* @return
* possible object is
* {@link Boolean }
*
*/
public Boolean isTransformPatternsTrim() {
return transformPatternsTrim;
}
/**
* Sets the value of the transformPatternsTrim property.
*
* @param value
* allowed object is
* {@link Boolean }
*
*/
public void setTransformPatternsTrim(Boolean value) {
this.transformPatternsTrim = value;
}
/**
* Transform <code>NOT(NOT(x))</code> to <code>x</code>
* <p>
* For various reasons, there may be a redundant nesting of <code>NOT</code> unary operators, e.g. as a
* left over of some prior transformation, including manual ones. This transformation will simplify such
* redundant negations by removing them.
* <p>
* To enable this feature, {@link #transformPatterns} must be enabled as well.
* <p>
* This feature is available in the commercial distribution only.
*
* @return
* possible object is
* {@link Boolean }
*
*/
public Boolean isTransformPatternsNotNot() {
return transformPatternsNotNot;
}
/**
* Sets the value of the transformPatternsNotNot property.
*
* @param value
* allowed object is
* {@link Boolean }
*
*/
public void setTransformPatternsNotNot(Boolean value) {
this.transformPatternsNotNot = value;
}
/**
* Transform <code>-(-(x))</code> to <code>x</code>
* <p>
* For various reasons, there may be a redundant nesting of <code>-</code> unary operators, e.g. as a
* left over of some prior transformation, including manual ones. This transformation will simplify such
* redundant negations by removing them.
* <p>
* To enable this feature, {@link #transformPatterns} must be enabled as well.
* <p>
* This feature is available in the commercial distribution only.
*
* @return
* possible object is
* {@link Boolean }
*
*/
public Boolean isTransformPatternsNegNeg() {
return transformPatternsNegNeg;
}
/**
* Sets the value of the transformPatternsNegNeg property.
*
* @param value
* allowed object is
* {@link Boolean }
*
*/
public void setTransformPatternsNegNeg(Boolean value) {
this.transformPatternsNegNeg = value;
}
/**
* Transform <code>~(~(x))</code> to <code>x</code>
* <p>
* For various reasons, there may be a redundant nesting of <code>~</code> unary operators, e.g. as a
* left over of some prior transformation, including manual ones. This transformation will simplify such
* redundant negations by removing them.
* <p>
* To enable this feature, {@link #transformPatterns} must be enabled as well.
* <p>
* This feature is available in the commercial distribution only.
*
* @return
* possible object is
* {@link Boolean }
*
*/
public Boolean isTransformPatternsBitNotBitNot() {
return transformPatternsBitNotBitNot;
}
/**
* Sets the value of the transformPatternsBitNotBitNot property.
*
* @param value
* allowed object is
* {@link Boolean }
*
*/
public void setTransformPatternsBitNotBitNot(Boolean value) {
this.transformPatternsBitNotBitNot = value;
}
/**
* Transform ANSI join to table lists if possible.
* <p>
@ -3343,6 +3512,31 @@ public class Settings
return this;
}
public Settings withTransformPatterns(Boolean value) {
setTransformPatterns(value);
return this;
}
public Settings withTransformPatternsTrim(Boolean value) {
setTransformPatternsTrim(value);
return this;
}
public Settings withTransformPatternsNotNot(Boolean value) {
setTransformPatternsNotNot(value);
return this;
}
public Settings withTransformPatternsNegNeg(Boolean value) {
setTransformPatternsNegNeg(value);
return this;
}
public Settings withTransformPatternsBitNotBitNot(Boolean value) {
setTransformPatternsBitNotBitNot(value);
return this;
}
public Settings withTransformAnsiJoinToTableLists(Boolean value) {
setTransformAnsiJoinToTableLists(value);
return this;
@ -4166,6 +4360,11 @@ public class Settings
builder.append("bindOffsetTimeType", bindOffsetTimeType);
builder.append("fetchTriggerValuesAfterSQLServerOutput", fetchTriggerValuesAfterSQLServerOutput);
builder.append("fetchIntermediateResult", fetchIntermediateResult);
builder.append("transformPatterns", transformPatterns);
builder.append("transformPatternsTrim", transformPatternsTrim);
builder.append("transformPatternsNotNot", transformPatternsNotNot);
builder.append("transformPatternsNegNeg", transformPatternsNegNeg);
builder.append("transformPatternsBitNotBitNot", transformPatternsBitNotBitNot);
builder.append("transformAnsiJoinToTableLists", transformAnsiJoinToTableLists);
builder.append("transformInConditionSubqueryWithLimitToDerivedTable", transformInConditionSubqueryWithLimitToDerivedTable);
builder.append("transformQualify", transformQualify);
@ -4561,6 +4760,51 @@ public class Settings
return false;
}
}
if (transformPatterns == null) {
if (other.transformPatterns!= null) {
return false;
}
} else {
if (!transformPatterns.equals(other.transformPatterns)) {
return false;
}
}
if (transformPatternsTrim == null) {
if (other.transformPatternsTrim!= null) {
return false;
}
} else {
if (!transformPatternsTrim.equals(other.transformPatternsTrim)) {
return false;
}
}
if (transformPatternsNotNot == null) {
if (other.transformPatternsNotNot!= null) {
return false;
}
} else {
if (!transformPatternsNotNot.equals(other.transformPatternsNotNot)) {
return false;
}
}
if (transformPatternsNegNeg == null) {
if (other.transformPatternsNegNeg!= null) {
return false;
}
} else {
if (!transformPatternsNegNeg.equals(other.transformPatternsNegNeg)) {
return false;
}
}
if (transformPatternsBitNotBitNot == null) {
if (other.transformPatternsBitNotBitNot!= null) {
return false;
}
} else {
if (!transformPatternsBitNotBitNot.equals(other.transformPatternsBitNotBitNot)) {
return false;
}
}
if (transformAnsiJoinToTableLists == null) {
if (other.transformAnsiJoinToTableLists!= null) {
return false;
@ -5454,6 +5698,11 @@ 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)+((transformPatterns == null)? 0 :transformPatterns.hashCode()));
result = ((prime*result)+((transformPatternsTrim == null)? 0 :transformPatternsTrim.hashCode()));
result = ((prime*result)+((transformPatternsNotNot == null)? 0 :transformPatternsNotNot.hashCode()));
result = ((prime*result)+((transformPatternsNegNeg == null)? 0 :transformPatternsNegNeg.hashCode()));
result = ((prime*result)+((transformPatternsBitNotBitNot == null)? 0 :transformPatternsBitNotBitNot.hashCode()));
result = ((prime*result)+((transformAnsiJoinToTableLists == null)? 0 :transformAnsiJoinToTableLists.hashCode()));
result = ((prime*result)+((transformInConditionSubqueryWithLimitToDerivedTable == null)? 0 :transformInConditionSubqueryWithLimitToDerivedTable.hashCode()));
result = ((prime*result)+((transformQualify == null)? 0 :transformQualify.hashCode()));

View File

@ -42,6 +42,7 @@ import static java.lang.Boolean.TRUE;
import static org.jooq.SQLDialect.SQLITE;
import static org.jooq.conf.ParamType.INLINED;
import static org.jooq.conf.SettingsTools.renderLocale;
import static org.jooq.impl.DSL.trim;
import static org.jooq.impl.Identifiers.QUOTES;
import static org.jooq.impl.Identifiers.QUOTE_END_DELIMITER;
import static org.jooq.impl.Identifiers.QUOTE_END_DELIMITER_ESCAPED;
@ -64,12 +65,13 @@ import org.jooq.Configuration;
import org.jooq.Constants;
import org.jooq.Field;
import org.jooq.ForeignKey;
import org.jooq.LanguageContext;
import org.jooq.Param;
// ...
import org.jooq.Query;
import org.jooq.QueryPart;
import org.jooq.QueryPartInternal;
import org.jooq.RenderContext;
// ...
import org.jooq.SQLDialect;
import org.jooq.Select;
import org.jooq.Table;
@ -81,6 +83,11 @@ import org.jooq.conf.Settings;
import org.jooq.conf.SettingsTools;
import org.jooq.exception.ControlFlowSignal;
import org.jooq.exception.DataAccessException;
import org.jooq.impl.QOM.BitNot;
import org.jooq.impl.QOM.Ltrim;
import org.jooq.impl.QOM.Neg;
import org.jooq.impl.QOM.Not;
import org.jooq.impl.QOM.Rtrim;
import org.jooq.impl.ScopeMarker.ScopeContent;
import org.jooq.tools.JooqLogger;
import org.jooq.tools.StringUtils;
@ -703,13 +710,19 @@ class DefaultRenderContext extends AbstractContext<RenderContext> implements Ren
@Override
protected final void visit0(QueryPartInternal internal) {
if (isQuery == null)
if (isQuery == null) {
isQuery = internal instanceof Query;
}
@ -780,6 +793,66 @@ class DefaultRenderContext extends AbstractContext<RenderContext> implements Ren
}
}
private final void checkForceInline(int max) throws ForceInlineSignal {
if (bindValues.size() > max)
if (TRUE.equals(data(DATA_COUNT_BIND_VALUES)))

View File

@ -269,6 +269,65 @@ 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="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>
This flag enables the pattern transformation feature, which consists of several sub-flags that are
all prefixed with "transformPatterns", e.g. {@link #transformPatternsTrim}. While the sub-flags default
to being enabled, and can be disabled on an individual basis, the global feature itself is disabled by
default.
<p>
This feature is available in the commercial distribution only.]]></jxb:javadoc></jxb:property></appinfo></annotation>
</element>
<element name="transformPatternsTrim" type="boolean" minOccurs="0" maxOccurs="1" default="true">
<annotation><appinfo><jxb:property><jxb:javadoc><![CDATA[Transform <code>LTRIM(RTRIM(x))</code> or <code>RTRIM(LTRIM(x))</code> to <code>TRIM(x)</code>
<p>
Historically, a few dialects did not implement <code>TRIM(x)</code> or <code>TRIM(BOTH FROM x)</code>,
so users worked around this by wrapping <code>LTRIM()</code> and <code>RTRIM()</code> with each other.
Maintaining this is usually undesirable, so this transformation helps remove the unwanted wrapping.
<p>
To enable this feature, {@link #transformPatterns} must be enabled as well.
<p>
This feature is available in the commercial distribution only.]]></jxb:javadoc></jxb:property></appinfo></annotation>
</element>
<element name="transformPatternsNotNot" type="boolean" minOccurs="0" maxOccurs="1" default="true">
<annotation><appinfo><jxb:property><jxb:javadoc><![CDATA[Transform <code>NOT(NOT(x))</code> to <code>x</code>
<p>
For various reasons, there may be a redundant nesting of <code>NOT</code> unary operators, e.g. as a
left over of some prior transformation, including manual ones. This transformation will simplify such
redundant negations by removing them.
<p>
To enable this feature, {@link #transformPatterns} must be enabled as well.
<p>
This feature is available in the commercial distribution only.]]></jxb:javadoc></jxb:property></appinfo></annotation>
</element>
<element name="transformPatternsNegNeg" type="boolean" minOccurs="0" maxOccurs="1" default="true">
<annotation><appinfo><jxb:property><jxb:javadoc><![CDATA[Transform <code>-(-(x))</code> to <code>x</code>
<p>
For various reasons, there may be a redundant nesting of <code>-</code> unary operators, e.g. as a
left over of some prior transformation, including manual ones. This transformation will simplify such
redundant negations by removing them.
<p>
To enable this feature, {@link #transformPatterns} must be enabled as well.
<p>
This feature is available in the commercial distribution only.]]></jxb:javadoc></jxb:property></appinfo></annotation>
</element>
<element name="transformPatternsBitNotBitNot" type="boolean" minOccurs="0" maxOccurs="1" default="true">
<annotation><appinfo><jxb:property><jxb:javadoc><![CDATA[Transform <code>~(~(x))</code> to <code>x</code>
<p>
For various reasons, there may be a redundant nesting of <code>~</code> unary operators, e.g. as a
left over of some prior transformation, including manual ones. This transformation will simplify such
redundant negations by removing them.
<p>
To enable this feature, {@link #transformPatterns} must be enabled as well.
<p>
This feature is available in the commercial distribution only.]]></jxb:javadoc></jxb:property></appinfo></annotation>
</element>
<element name="transformAnsiJoinToTableLists" type="boolean" minOccurs="0" maxOccurs="1" default="false">
<annotation><appinfo><jxb:property><jxb:javadoc><![CDATA[Transform ANSI join to table lists if possible.
<p>