From bfb1f8533cbac382c756e04c2b7d57d699d35bfa Mon Sep 17 00:00:00 2001 From: Lukas Eder Date: Thu, 27 Oct 2022 14:16:54 +0200 Subject: [PATCH] [jOOQ/jOOQ#7527] Add Settings.transformPatternsUnnecessaryDistinct --- jOOQ/src/main/java/org/jooq/Select.java | 14 ++++++ .../src/main/java/org/jooq/conf/Settings.java | 49 +++++++++++++++++++ .../src/main/java/org/jooq/impl/Patterns.java | 16 ++++++ .../main/java/org/jooq/impl/SelectImpl.java | 10 ++++ .../java/org/jooq/impl/SelectQueryImpl.java | 24 ++++++--- .../org/jooq/xsd/jooq-runtime-3.18.0.xsd | 11 +++++ 6 files changed, 117 insertions(+), 7 deletions(-) diff --git a/jOOQ/src/main/java/org/jooq/Select.java b/jOOQ/src/main/java/org/jooq/Select.java index 38e77803d8..ef4f806d1f 100644 --- a/jOOQ/src/main/java/org/jooq/Select.java +++ b/jOOQ/src/main/java/org/jooq/Select.java @@ -228,6 +228,20 @@ extends @Experimental @NotNull Select $distinct(boolean newDistinct); + /** + * Experimental query object model accessor method, see also {@link QOM}. + * Subject to change in future jOOQ versions, use at your own risk. + */ + @Experimental + UnmodifiableList $distinctOn(); + + /** + * Experimental query object model accessor method, see also {@link QOM}. + * Subject to change in future jOOQ versions, use at your own risk. + */ + @Experimental + @NotNull Select $distinctOn(Collection newDistinctOn); + /** * Experimental query object model accessor method, see also {@link QOM}. * Subject to change in future jOOQ versions, use at your own risk. diff --git a/jOOQ/src/main/java/org/jooq/conf/Settings.java b/jOOQ/src/main/java/org/jooq/conf/Settings.java index 62a2fee6ac..19ef75e689 100644 --- a/jOOQ/src/main/java/org/jooq/conf/Settings.java +++ b/jOOQ/src/main/java/org/jooq/conf/Settings.java @@ -143,6 +143,8 @@ public class Settings @XmlElement(defaultValue = "true") protected Boolean transformPatternsLogging = true; @XmlElement(defaultValue = "true") + protected Boolean transformPatternsUnnecessaryDistinct = true; + @XmlElement(defaultValue = "true") protected Boolean transformPatternsCountConstant = true; @XmlElement(defaultValue = "true") protected Boolean transformPatternsTrim = true; @@ -1624,6 +1626,37 @@ public class Settings this.transformPatternsLogging = value; } + /** + * Transform SELECT DISTINCT a, b FROM t GROUP BY a, b to SELECT a, b FROM t GROUP BY a, b. + *

+ * The GROUP BY clause already removes duplicates, so if the DISTINCT clause + * contains at least all the columns from GROUP BY then it can be removed. + *

+ * To enable this feature, {@link #transformPatterns} must be enabled as well. + *

+ * This feature is available in the commercial distribution only. + * + * @return + * possible object is + * {@link Boolean } + * + */ + public Boolean isTransformPatternsUnnecessaryDistinct() { + return transformPatternsUnnecessaryDistinct; + } + + /** + * Sets the value of the transformPatternsUnnecessaryDistinct property. + * + * @param value + * allowed object is + * {@link Boolean } + * + */ + public void setTransformPatternsUnnecessaryDistinct(Boolean value) { + this.transformPatternsUnnecessaryDistinct = value; + } + /** * Transform COUNT(1) or any other COUNT(const) to COUNT(*). *

@@ -5013,6 +5046,11 @@ public class Settings return this; } + public Settings withTransformPatternsUnnecessaryDistinct(Boolean value) { + setTransformPatternsUnnecessaryDistinct(value); + return this; + } + public Settings withTransformPatternsCountConstant(Boolean value) { setTransformPatternsCountConstant(value); return this; @@ -6050,6 +6088,7 @@ public class Settings builder.append("diagnosticsNullCondition", diagnosticsNullCondition); builder.append("transformPatterns", transformPatterns); builder.append("transformPatternsLogging", transformPatternsLogging); + builder.append("transformPatternsUnnecessaryDistinct", transformPatternsUnnecessaryDistinct); builder.append("transformPatternsCountConstant", transformPatternsCountConstant); builder.append("transformPatternsTrim", transformPatternsTrim); builder.append("transformPatternsNotNot", transformPatternsNotNot); @@ -6616,6 +6655,15 @@ public class Settings return false; } } + if (transformPatternsUnnecessaryDistinct == null) { + if (other.transformPatternsUnnecessaryDistinct!= null) { + return false; + } + } else { + if (!transformPatternsUnnecessaryDistinct.equals(other.transformPatternsUnnecessaryDistinct)) { + return false; + } + } if (transformPatternsCountConstant == null) { if (other.transformPatternsCountConstant!= null) { return false; @@ -7848,6 +7896,7 @@ public class Settings result = ((prime*result)+((diagnosticsNullCondition == null)? 0 :diagnosticsNullCondition.hashCode())); result = ((prime*result)+((transformPatterns == null)? 0 :transformPatterns.hashCode())); result = ((prime*result)+((transformPatternsLogging == null)? 0 :transformPatternsLogging.hashCode())); + result = ((prime*result)+((transformPatternsUnnecessaryDistinct == null)? 0 :transformPatternsUnnecessaryDistinct.hashCode())); result = ((prime*result)+((transformPatternsCountConstant == null)? 0 :transformPatternsCountConstant.hashCode())); result = ((prime*result)+((transformPatternsTrim == null)? 0 :transformPatternsTrim.hashCode())); result = ((prime*result)+((transformPatternsNotNot == null)? 0 :transformPatternsNotNot.hashCode())); diff --git a/jOOQ/src/main/java/org/jooq/impl/Patterns.java b/jOOQ/src/main/java/org/jooq/impl/Patterns.java index aef9a31dd9..46ad5da423 100644 --- a/jOOQ/src/main/java/org/jooq/impl/Patterns.java +++ b/jOOQ/src/main/java/org/jooq/impl/Patterns.java @@ -1684,6 +1684,22 @@ package org.jooq.impl; + + + + + + + + + + + + + + + + diff --git a/jOOQ/src/main/java/org/jooq/impl/SelectImpl.java b/jOOQ/src/main/java/org/jooq/impl/SelectImpl.java index d74cfdf7b0..9913b85d37 100644 --- a/jOOQ/src/main/java/org/jooq/impl/SelectImpl.java +++ b/jOOQ/src/main/java/org/jooq/impl/SelectImpl.java @@ -3423,6 +3423,16 @@ implements return getDelegate().$distinct(newDistinct); } + @Override + public final UnmodifiableList $distinctOn() { + return getDelegate().$distinctOn(); + } + + @Override + public final Select $distinctOn(Collection newDistinctOn) { + return getDelegate().$distinctOn(newDistinctOn); + } + @Override public final UnmodifiableList> $from() { return getDelegate().$from(); diff --git a/jOOQ/src/main/java/org/jooq/impl/SelectQueryImpl.java b/jOOQ/src/main/java/org/jooq/impl/SelectQueryImpl.java index cf796f8fa0..fcdf13e01a 100644 --- a/jOOQ/src/main/java/org/jooq/impl/SelectQueryImpl.java +++ b/jOOQ/src/main/java/org/jooq/impl/SelectQueryImpl.java @@ -360,7 +360,7 @@ final class SelectQueryImpl extends AbstractResultQuery imp private String hint; private String option; private boolean distinct; - private QueryPartList distinctOn; + private final QueryPartList distinctOn; private ForLock forLock; @@ -424,6 +424,7 @@ final class SelectQueryImpl extends AbstractResultQuery imp this.with = with; this.distinct = distinct; + this.distinctOn = new SelectFieldList<>(); this.select = new SelectFieldList<>(); this.from = new TableList(); this.condition = new ConditionProviderImpl(); @@ -556,7 +557,7 @@ final class SelectQueryImpl extends AbstractResultQuery imp result.hint = hint; result.distinct = distinct; - result.distinctOn = distinctOn; + result.distinctOn.addAll(distinctOn); result.orderBy.addAll(orderBy); @@ -1262,7 +1263,6 @@ final class SelectQueryImpl extends AbstractResultQuery imp - @SuppressWarnings({ "rawtypes", "unchecked" }) private final Select distinctOnEmulation() { // [#3564] TODO: Extract and merge this with getSelectResolveSomeAsterisks0() @@ -1275,7 +1275,7 @@ final class SelectQueryImpl extends AbstractResultQuery imp Field rn = rowNumber().over(partitionBy(partitionBy).orderBy(orderBy)).as("rn"); SelectQueryImpl copy = copy(x -> {}); - copy.distinctOn = null; + copy.distinctOn.clear(); copy.select.add(rn); copy.orderBy.clear(); copy.limit.clear(); @@ -3336,9 +3336,6 @@ final class SelectQueryImpl extends AbstractResultQuery imp @Override public final void addDistinctOn(Collection fields) { - if (distinctOn == null) - distinctOn = new QueryPartList<>(); - distinctOn.addAll(fields); } @@ -4579,6 +4576,19 @@ final class SelectQueryImpl extends AbstractResultQuery imp return copy(s -> s.distinct = newDistinct); } + @Override + public final UnmodifiableList $distinctOn() { + return QOM.unmodifiable(distinctOn); + } + + @Override + public final Select $distinctOn(Collection newDistinctOn) { + return copy(s -> { + s.distinctOn.clear(); + s.distinctOn.addAll(newDistinctOn); + }); + } + @Override public final UnmodifiableList> $from() { return QOM.unmodifiable(from); diff --git a/jOOQ/src/main/resources/org/jooq/xsd/jooq-runtime-3.18.0.xsd b/jOOQ/src/main/resources/org/jooq/xsd/jooq-runtime-3.18.0.xsd index f1bb807d4a..13cbf22291 100644 --- a/jOOQ/src/main/resources/org/jooq/xsd/jooq-runtime-3.18.0.xsd +++ b/jOOQ/src/main/resources/org/jooq/xsd/jooq-runtime-3.18.0.xsd @@ -389,6 +389,17 @@ This feature is available in the commercial distribution only.]]>< + + SELECT DISTINCT a, b FROM t GROUP BY a, b to SELECT a, b FROM t GROUP BY a, b. +

+The GROUP BY clause already removes duplicates, so if the DISTINCT clause +contains at least all the columns from GROUP BY then it can be removed. +

+To enable this feature, {@link #transformPatterns} must be enabled as well. +

+This feature is available in the commercial distribution only.]]> + + COUNT(1) or any other COUNT(const) to COUNT(*).