[jOOQ/jOOQ#11711] Use floating point literals for inline DOUBLE, FLOAT, and REAL literals
This commit is contained in:
parent
db6f8efc22
commit
9923e22bb5
@ -38,6 +38,7 @@
|
||||
package org.jooq;
|
||||
|
||||
import java.sql.PreparedStatement;
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.jooq.RenderContext.CastMode;
|
||||
@ -481,12 +482,22 @@ public interface Context<C extends Context<C>> extends Scope {
|
||||
@NotNull
|
||||
C sql(long sql);
|
||||
|
||||
/**
|
||||
* A formatter to produce scientific notation for {@link Float} types.
|
||||
*/
|
||||
DecimalFormat floatFormat();
|
||||
|
||||
/**
|
||||
* Append some SQL to the context's contained {@link StringBuilder}.
|
||||
*/
|
||||
@NotNull
|
||||
C sql(float sql);
|
||||
|
||||
/**
|
||||
* A formatter to produce scientific notation for {@link Double} types.
|
||||
*/
|
||||
DecimalFormat doubleFormat();
|
||||
|
||||
/**
|
||||
* Append some SQL to the context's contained {@link StringBuilder}.
|
||||
*/
|
||||
|
||||
@ -50,11 +50,11 @@ import static org.jooq.conf.InvocationOrder.REVERSE;
|
||||
import static org.jooq.conf.ParamType.INDEXED;
|
||||
import static org.jooq.impl.Tools.EMPTY_CLAUSE;
|
||||
import static org.jooq.impl.Tools.EMPTY_QUERYPART;
|
||||
import static org.jooq.impl.Tools.settings;
|
||||
import static org.jooq.impl.Tools.BooleanDataKey.DATA_NESTED_SET_OPERATIONS;
|
||||
import static org.jooq.impl.Tools.BooleanDataKey.DATA_OMIT_CLAUSE_EVENT_EMISSION;
|
||||
|
||||
import java.sql.PreparedStatement;
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.Arrays;
|
||||
import java.util.BitSet;
|
||||
@ -62,10 +62,10 @@ import java.util.Deque;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
import java.util.function.BooleanSupplier;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.Set;
|
||||
|
||||
import org.jooq.BindContext;
|
||||
import org.jooq.Clause;
|
||||
@ -92,8 +92,6 @@ import org.jooq.conf.SettingsTools;
|
||||
import org.jooq.conf.StatementType;
|
||||
import org.jooq.tools.StringUtils;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* @author Lukas Eder
|
||||
*/
|
||||
@ -141,6 +139,10 @@ abstract class AbstractContext<C extends Context<C>> extends AbstractScope imple
|
||||
boolean qualifySchema = true;
|
||||
boolean qualifyCatalog = true;
|
||||
|
||||
// [#11711] Enforcing scientific notation
|
||||
private transient DecimalFormat doubleFormat;
|
||||
private transient DecimalFormat floatFormat;
|
||||
|
||||
AbstractContext(Configuration configuration, PreparedStatement stmt) {
|
||||
super(configuration);
|
||||
this.stmt = stmt;
|
||||
@ -782,6 +784,22 @@ abstract class AbstractContext<C extends Context<C>> extends AbstractScope imple
|
||||
// XXX RenderContext API
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
@Override
|
||||
public final DecimalFormat floatFormat() {
|
||||
if (floatFormat == null)
|
||||
floatFormat = new DecimalFormat("0.#######E0");
|
||||
|
||||
return floatFormat;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final DecimalFormat doubleFormat() {
|
||||
if (doubleFormat == null)
|
||||
doubleFormat = new DecimalFormat("0.################E0");
|
||||
|
||||
return doubleFormat;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final ParamType paramType() {
|
||||
return forcedParamType != null ? forcedParamType : paramType;
|
||||
|
||||
@ -84,6 +84,7 @@ import static org.jooq.impl.DSL.name;
|
||||
import static org.jooq.impl.DSL.power;
|
||||
import static org.jooq.impl.DSL.sqrt;
|
||||
import static org.jooq.impl.DSL.using;
|
||||
import static org.jooq.impl.DefaultBinding.DefaultDoubleBinding.REQUIRES_LITERAL_CAST;
|
||||
import static org.jooq.impl.DefaultBinding.DefaultDoubleBinding.infinity;
|
||||
import static org.jooq.impl.DefaultBinding.DefaultDoubleBinding.nan;
|
||||
import static org.jooq.impl.DefaultExecuteContext.localTargetConnection;
|
||||
@ -2330,7 +2331,8 @@ public class DefaultBinding<T, U> implements Binding<T, U> {
|
||||
/**
|
||||
* Generated UID
|
||||
*/
|
||||
private static final long serialVersionUID = -615723070592774059L;
|
||||
private static final long serialVersionUID = -615723070592774059L;
|
||||
static final Set<SQLDialect> REQUIRES_LITERAL_CAST = SQLDialect.supportedBy(H2);
|
||||
|
||||
DefaultDoubleBinding(DataType<Double> dataType, Converter<Double, U> converter) {
|
||||
super(dataType, converter);
|
||||
@ -2370,6 +2372,8 @@ public class DefaultBinding<T, U> implements Binding<T, U> {
|
||||
ctx.render().visit(infinity(ctx, DOUBLE, false));
|
||||
else if (value == Double.NEGATIVE_INFINITY)
|
||||
ctx.render().visit(infinity(ctx, DOUBLE, true));
|
||||
else if (REQUIRES_LITERAL_CAST.contains(ctx.dialect()))
|
||||
ctx.render().visit(field(ctx.render().doubleFormat().format(value)).cast(DOUBLE));
|
||||
else
|
||||
ctx.render().sql(value);
|
||||
}
|
||||
@ -2540,6 +2544,8 @@ public class DefaultBinding<T, U> implements Binding<T, U> {
|
||||
ctx.render().visit(infinity(ctx, REAL, false));
|
||||
else if (value == Double.NEGATIVE_INFINITY)
|
||||
ctx.render().visit(infinity(ctx, REAL, true));
|
||||
else if (REQUIRES_LITERAL_CAST.contains(ctx.dialect()))
|
||||
ctx.render().visit(field(ctx.render().floatFormat().format(value)).cast(REAL));
|
||||
else
|
||||
ctx.render().sql(value);
|
||||
}
|
||||
|
||||
@ -63,7 +63,6 @@ import org.jooq.Constants;
|
||||
import org.jooq.Field;
|
||||
import org.jooq.ForeignKey;
|
||||
import org.jooq.Param;
|
||||
// ...
|
||||
import org.jooq.QueryPart;
|
||||
import org.jooq.QueryPartInternal;
|
||||
import org.jooq.RenderContext;
|
||||
@ -459,7 +458,7 @@ class DefaultRenderContext extends AbstractContext<RenderContext> implements Ren
|
||||
@Override
|
||||
public final RenderContext sql(float f) {
|
||||
applyNewLine();
|
||||
sql.append(f);
|
||||
sql.append(floatFormat().format(f));
|
||||
resetSeparatorFlags();
|
||||
return this;
|
||||
}
|
||||
@ -467,7 +466,7 @@ class DefaultRenderContext extends AbstractContext<RenderContext> implements Ren
|
||||
@Override
|
||||
public final RenderContext sql(double d) {
|
||||
applyNewLine();
|
||||
sql.append(d);
|
||||
sql.append(doubleFormat().format(d));
|
||||
resetSeparatorFlags();
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -11903,56 +11903,48 @@ final class DefaultParseContext extends AbstractScope implements ParseContext {
|
||||
|
||||
private final Number parseUnsignedNumericLiteralIf(Sign sign) {
|
||||
int p = position();
|
||||
char c;
|
||||
boolean decimal = false;
|
||||
parseDigits();
|
||||
|
||||
for (;;) {
|
||||
c = character();
|
||||
if (c >= '0' && c <= '9') {
|
||||
positionInc();
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
if (c == '.') {
|
||||
positionInc();
|
||||
}
|
||||
else {
|
||||
if (p == position())
|
||||
return null;
|
||||
|
||||
String s = substring(p, position());
|
||||
parseWhitespaceIf();
|
||||
try {
|
||||
return sign == Sign.MINUS
|
||||
? -Long.valueOf(s)
|
||||
: Long.valueOf(s);
|
||||
}
|
||||
catch (Exception e1) {
|
||||
return sign == Sign.MINUS
|
||||
? new BigInteger(s).negate()
|
||||
: new BigInteger(s);
|
||||
}
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
c = character();
|
||||
if (c >= '0' && c <= '9') {
|
||||
positionInc();
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
if (decimal |= parseIf('.', false))
|
||||
parseDigits();
|
||||
|
||||
if (p == position())
|
||||
return null;
|
||||
|
||||
String s = substring(p, position());
|
||||
parseWhitespaceIf();
|
||||
return sign == Sign.MINUS
|
||||
? new BigDecimal(s).negate()
|
||||
: new BigDecimal(s);
|
||||
// TODO add floating point support
|
||||
if (parseIf('e', false) || parseIf('E', false)) {
|
||||
parseIf('-', false);
|
||||
parseDigits();
|
||||
|
||||
String s = substring(p, position());
|
||||
parseWhitespaceIf();
|
||||
return sign == Sign.MINUS ? -Double.parseDouble(s) : Double.parseDouble(s);
|
||||
}
|
||||
else {
|
||||
String s = substring(p, position());
|
||||
parseWhitespaceIf();
|
||||
|
||||
if (decimal)
|
||||
return sign == Sign.MINUS ? new BigDecimal(s).negate() : new BigDecimal(s);
|
||||
|
||||
try {
|
||||
return sign == Sign.MINUS ? -Long.valueOf(s) : Long.valueOf(s);
|
||||
}
|
||||
catch (Exception e1) {
|
||||
return sign == Sign.MINUS ? new BigInteger(s).negate() : new BigInteger(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void parseDigits() {
|
||||
for (;;) {
|
||||
char c = character();
|
||||
|
||||
if (c >= '0' && c <= '9')
|
||||
positionInc();
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private final Field<Integer> parseZeroOne() {
|
||||
@ -12089,15 +12081,7 @@ final class DefaultParseContext extends AbstractScope implements ParseContext {
|
||||
@Override
|
||||
public final Long parseUnsignedIntegerLiteralIf() {
|
||||
int p = position();
|
||||
|
||||
for (;;) {
|
||||
char c = character();
|
||||
|
||||
if (c >= '0' && c <= '9')
|
||||
positionInc();
|
||||
else
|
||||
break;
|
||||
}
|
||||
parseDigits();
|
||||
|
||||
if (p == position())
|
||||
return null;
|
||||
|
||||
2
pom.xml
2
pom.xml
@ -33,7 +33,7 @@
|
||||
<hsqldb.version>2.5.1</hsqldb.version>
|
||||
|
||||
<!-- JDBC drivers for jOOQ-xyz-extensions modules -->
|
||||
<postgres.version>42.2.18</postgres.version>
|
||||
<postgres.version>42.2.19</postgres.version>
|
||||
|
||||
<!-- From JDK 11 onwards, we need to depend on the JAXB API explicitly -->
|
||||
<jaxb.version>2.3.1</jaxb.version>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user