- [#5960] Add diagnostic to detect duplicate IN lists of different degree - [#7095] Add Settings.inListPadBase
This commit is contained in:
parent
b2e4cadf8a
commit
af2e6acf6a
@ -102,6 +102,8 @@ public class Settings
|
||||
protected Boolean debugInfoOnStackTrace = true;
|
||||
@XmlElement(defaultValue = "false")
|
||||
protected Boolean inListPadding = false;
|
||||
@XmlElement(defaultValue = "2")
|
||||
protected Integer inListPadBase = 2;
|
||||
@XmlElement(defaultValue = ";")
|
||||
protected String delimiter = ";";
|
||||
@XmlElement(defaultValue = "LOG_DEBUG")
|
||||
@ -871,7 +873,7 @@ public class Settings
|
||||
}
|
||||
|
||||
/**
|
||||
* [#5600] Whether IN lists in IN predicates should be padded to powers of 2.
|
||||
* [#5600] Whether IN lists in IN predicates should be padded to powers of inListPadBase (default 2).
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
@ -894,6 +896,30 @@ public class Settings
|
||||
this.inListPadding = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* [#7095] The base to use to calculate the powers of when applying in list padding.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link Integer }
|
||||
*
|
||||
*/
|
||||
public Integer getInListPadBase() {
|
||||
return inListPadBase;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the inListPadBase property.
|
||||
*
|
||||
* @param value
|
||||
* allowed object is
|
||||
* {@link Integer }
|
||||
*
|
||||
*/
|
||||
public void setInListPadBase(Integer value) {
|
||||
this.inListPadBase = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* [#5826] The delimiter character to be used to delimit statements in batches.
|
||||
*
|
||||
@ -1121,6 +1147,11 @@ public class Settings
|
||||
return this;
|
||||
}
|
||||
|
||||
public Settings withInListPadBase(Integer value) {
|
||||
setInListPadBase(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Settings withDelimiter(String value) {
|
||||
setDelimiter(value);
|
||||
return this;
|
||||
|
||||
@ -66,7 +66,7 @@ final class DiagnosticsConnection extends DefaultConnection {
|
||||
|
||||
static final Map<String, Set<String>> DUPLICATE_SQL = Collections.synchronizedMap(new LRU());
|
||||
final Configuration configuration;
|
||||
final RenderContext forceIndexed;
|
||||
final RenderContext duplicates;
|
||||
final Parser parser;
|
||||
final DiagnosticsListeners listeners;
|
||||
|
||||
@ -75,7 +75,16 @@ final class DiagnosticsConnection extends DefaultConnection {
|
||||
super(configuration.connectionProvider().acquire());
|
||||
|
||||
this.configuration = configuration;
|
||||
this.forceIndexed = configuration.derive(SettingsTools.clone(configuration.settings()).withParamType(FORCE_INDEXED)).dsl().renderContext();
|
||||
this.duplicates = configuration.derive(
|
||||
SettingsTools.clone(configuration.settings())
|
||||
|
||||
// Forcing all inline parameters to be indexed helps find opportunities to use bind variables
|
||||
.withParamType(FORCE_INDEXED)
|
||||
|
||||
// Padding IN lists shows duplicates that arise from arbitrary-length dynamic IN lists
|
||||
.withInListPadding(true)
|
||||
.withInListPadBase(16)
|
||||
).dsl().renderContext();
|
||||
this.parser = configuration.dsl().parser();
|
||||
this.listeners = DiagnosticsListeners.get(configuration);
|
||||
}
|
||||
@ -145,7 +154,6 @@ final class DiagnosticsConnection extends DefaultConnection {
|
||||
configuration.connectionProvider().release(getDelegate());
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
final String parse(String sql) {
|
||||
Queries queries;
|
||||
|
||||
@ -156,7 +164,7 @@ final class DiagnosticsConnection extends DefaultConnection {
|
||||
return sql;
|
||||
}
|
||||
|
||||
String normalised = forceIndexed.render(queries);
|
||||
String normalised = duplicates.render(queries);
|
||||
List<String> duplicates = null;
|
||||
|
||||
synchronized (DUPLICATE_SQL) {
|
||||
|
||||
@ -39,6 +39,12 @@
|
||||
package org.jooq.impl;
|
||||
|
||||
import static java.lang.Boolean.TRUE;
|
||||
import static java.lang.Math.ceil;
|
||||
import static java.lang.Math.log;
|
||||
import static java.lang.Math.max;
|
||||
import static java.lang.Math.min;
|
||||
import static java.lang.Math.pow;
|
||||
import static java.lang.Math.round;
|
||||
import static org.jooq.Clause.CONDITION;
|
||||
import static org.jooq.Clause.CONDITION_IN;
|
||||
import static org.jooq.Clause.CONDITION_NOT_IN;
|
||||
@ -52,6 +58,7 @@ import static org.jooq.impl.DSL.falseCondition;
|
||||
import static org.jooq.impl.DSL.trueCondition;
|
||||
import static org.jooq.impl.Keywords.K_AND;
|
||||
import static org.jooq.impl.Keywords.K_OR;
|
||||
import static org.jooq.tools.StringUtils.defaultIfNull;
|
||||
|
||||
import java.util.AbstractList;
|
||||
import java.util.Arrays;
|
||||
@ -156,7 +163,8 @@ final class InCondition<T> extends AbstractCondition {
|
||||
return ctx.paramType() == INDEXED && TRUE.equals(ctx.settings().isInListPadding())
|
||||
? new PaddedList<Field<?>>(list, REQUIRES_IN_LIMIT.contains(ctx.family())
|
||||
? IN_LIMIT
|
||||
: Integer.MAX_VALUE)
|
||||
: Integer.MAX_VALUE,
|
||||
defaultIfNull(ctx.settings().getInListPadBase(), 2))
|
||||
: list;
|
||||
}
|
||||
|
||||
@ -196,11 +204,12 @@ final class InCondition<T> extends AbstractCondition {
|
||||
private final int realSize;
|
||||
private final int padSize;
|
||||
|
||||
PaddedList(List<T> delegate, int maxPadding) {
|
||||
PaddedList(List<T> delegate, int maxPadding, int padBase) {
|
||||
int b = max(2, padBase);
|
||||
|
||||
this.delegate = delegate;
|
||||
this.realSize = delegate.size();
|
||||
int r = Integer.highestOneBit(realSize);
|
||||
this.padSize = Math.min(maxPadding, r == realSize ? realSize : r << 1);
|
||||
this.padSize = min(maxPadding, (int) round(pow(b, ceil(log(realSize) / log(b)))));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -172,7 +172,11 @@ jOOQ queries, for which no specific fetchSize value was specified.]]></jxb:javad
|
||||
</element>
|
||||
|
||||
<element name="inListPadding" type="boolean" minOccurs="0" maxOccurs="1" default="false">
|
||||
<annotation><appinfo><jxb:property><jxb:javadoc><![CDATA[[#5600] Whether IN lists in IN predicates should be padded to powers of 2.]]></jxb:javadoc></jxb:property></appinfo></annotation>
|
||||
<annotation><appinfo><jxb:property><jxb:javadoc><![CDATA[[#5600] Whether IN lists in IN predicates should be padded to powers of inListPadBase (default 2).]]></jxb:javadoc></jxb:property></appinfo></annotation>
|
||||
</element>
|
||||
|
||||
<element name="inListPadBase" type="int" minOccurs="0" maxOccurs="1" default="2">
|
||||
<annotation><appinfo><jxb:property><jxb:javadoc><![CDATA[[#7095] The base to use to calculate the powers of when applying in list padding.]]></jxb:javadoc></jxb:property></appinfo></annotation>
|
||||
</element>
|
||||
|
||||
<element name="delimiter" type="string" minOccurs="0" maxOccurs="1" default=";">
|
||||
|
||||
Loading…
Reference in New Issue
Block a user