This commit is contained in:
Lukas Eder 2020-12-14 22:21:05 +01:00
parent fc343ce488
commit f36af8b52e
5 changed files with 270 additions and 205 deletions

View File

@ -57,7 +57,7 @@ import java.util.*;
* The <code>ABS</code> statement.
*/
@SuppressWarnings({ "rawtypes", "unchecked", "unused" })
final class Abs<T>
final class Abs<T extends Number>
extends
AbstractField<T>
{

View File

@ -37,30 +37,49 @@
*/
package org.jooq.impl;
import static org.jooq.impl.Names.N_CEIL;
import static org.jooq.impl.Names.N_CEILING;
import static org.jooq.impl.DSL.*;
import static org.jooq.impl.Internal.*;
import static org.jooq.impl.Keywords.*;
import static org.jooq.impl.Names.*;
import static org.jooq.impl.SQLDataType.*;
import static org.jooq.impl.Tools.*;
import static org.jooq.impl.Tools.BooleanDataKey.*;
import static org.jooq.SQLDialect.*;
import org.jooq.*;
import org.jooq.impl.*;
import org.jooq.tools.*;
import java.util.*;
import org.jooq.Context;
import org.jooq.Field;
/**
* @author Lukas Eder
* The <code>CEIL</code> statement.
*/
final class Ceil<T extends Number> extends AbstractField<T> {
@SuppressWarnings({ "rawtypes", "unchecked", "unused" })
final class Ceil<T extends Number>
extends
AbstractField<T>
{
/**
* Generated UID
*/
private static final long serialVersionUID = -7273879239726265322L;
private static final long serialVersionUID = 1L;
private final Field<T> argument;
private final Field<T> value;
Ceil(Field<T> argument) {
super(N_CEIL, argument.getDataType());
Ceil(
Field<T> value
) {
super(N_CEIL, allNotNull((DataType) dataType(INTEGER, value, false), value));
this.argument = argument;
this.value = nullSafeNotNull(value, INTEGER);
}
// -------------------------------------------------------------------------
// XXX: QueryPart API
// -------------------------------------------------------------------------
@Override
public final void accept(Context<?> ctx) {
switch (ctx.family()) {
@ -73,8 +92,8 @@ final class Ceil<T extends Number> extends AbstractField<T> {
// [#8275] Improved emulation for SQLite
case SQLITE:
Field<Long> cast = DSL.cast(argument, SQLDataType.BIGINT);
ctx.sql('(').visit(cast).sql(" + (").visit(argument).sql(" > ").visit(cast).sql("))");
Field<Long> cast = DSL.cast(value, SQLDataType.BIGINT);
ctx.sql('(').visit(cast).sql(" + (").visit(value).sql(" > ").visit(cast).sql("))");
break;
@ -83,12 +102,29 @@ final class Ceil<T extends Number> extends AbstractField<T> {
case H2:
ctx.visit(N_CEILING).sql('(').visit(argument).sql(')');
ctx.visit(N_CEILING).sql('(').visit(value).sql(')');
break;
default:
ctx.visit(N_CEIL).sql('(').visit(argument).sql(')');
ctx.visit(N_CEIL).sql('(').visit(value).sql(')');
break;
}
}
// -------------------------------------------------------------------------
// The Object API
// -------------------------------------------------------------------------
@Override
public boolean equals(Object that) {
if (that instanceof Ceil) {
return
StringUtils.equals(value, ((Ceil) that).value)
;
}
else
return super.equals(that);
}
}

View File

@ -14946,6 +14946,28 @@ public class DSL {
return new BitLength(string);
}
/**
* The <code>CEIL</code> function.
* <p>
* Get the smallest integer value equal or greater to a value.
*/
@NotNull
@Support
public static <T extends Number> Field<T> ceil(T value) {
return new Ceil(Tools.field(value));
}
/**
* The <code>CEIL</code> function.
* <p>
* Get the smallest integer value equal or greater to a value.
*/
@NotNull
@Support
public static <T extends Number> Field<T> ceil(Field<T> value) {
return new Ceil(value);
}
/**
* The <code>CHAR_LENGTH</code> function.
* <p>
@ -15066,6 +15088,28 @@ public class DSL {
return new Degrees(radians);
}
/**
* The <code>FLOOR</code> function.
* <p>
* Get the biggest integer value equal or less than a value.
*/
@NotNull
@Support
public static <T extends Number> Field<T> floor(T value) {
return new Floor(Tools.field(value));
}
/**
* The <code>FLOOR</code> function.
* <p>
* Get the biggest integer value equal or less than a value.
*/
@NotNull
@Support
public static <T extends Number> Field<T> floor(Field<T> value) {
return new Floor(value);
}
/**
* The <code>LEFT</code> function.
* <p>
@ -16800,6 +16844,62 @@ public class DSL {
return new Trim(string);
}
/**
* The <code>TRUNC</code> function.
* <p>
* Truncate a number to a given number of decimals.
*
* @param value The number to be truncated
* @param decimals The decimals to truncate to.
*/
@NotNull
@Support({ CUBRID, DERBY, FIREBIRD, H2, HSQLDB, MARIADB, MYSQL, POSTGRES })
public static <T extends Number> Field<T> trunc(T value, int decimals) {
return new Trunc(Tools.field(value), Tools.field(decimals));
}
/**
* The <code>TRUNC</code> function.
* <p>
* Truncate a number to a given number of decimals.
*
* @param value The number to be truncated
* @param decimals The decimals to truncate to.
*/
@NotNull
@Support({ CUBRID, DERBY, FIREBIRD, H2, HSQLDB, MARIADB, MYSQL, POSTGRES })
public static <T extends Number> Field<T> trunc(T value, Field<Integer> decimals) {
return new Trunc(Tools.field(value), decimals);
}
/**
* The <code>TRUNC</code> function.
* <p>
* Truncate a number to a given number of decimals.
*
* @param value The number to be truncated
* @param decimals The decimals to truncate to.
*/
@NotNull
@Support({ CUBRID, DERBY, FIREBIRD, H2, HSQLDB, MARIADB, MYSQL, POSTGRES })
public static <T extends Number> Field<T> trunc(Field<T> value, int decimals) {
return new Trunc(value, Tools.field(decimals));
}
/**
* The <code>TRUNC</code> function.
* <p>
* Truncate a number to a given number of decimals.
*
* @param value The number to be truncated
* @param decimals The decimals to truncate to.
*/
@NotNull
@Support({ CUBRID, DERBY, FIREBIRD, H2, HSQLDB, MARIADB, MYSQL, POSTGRES })
public static <T extends Number> Field<T> trunc(Field<T> value, Field<Integer> decimals) {
return new Trunc(value, decimals);
}
/**
* The <code>UPPER</code> function.
* <p>
@ -20201,57 +20301,6 @@ public class DSL {
return field.neg();
}
/**
* Get the largest integer value not greater than [this].
*
* @see #floor(Field)
*/
@NotNull
@Support
public static <T extends Number> Field<T> floor(T value) {
return floor(Tools.field(value));
}
/**
* Get the largest integer value not greater than [this].
* <p>
* This renders the floor function where available:
* <code><pre>floor([this])</pre></code>
* ... or emulates it elsewhere using round:
* <code><pre>round([this] - 0.499999999999999)</pre></code>
*/
@NotNull
@Support
public static <T extends Number> Field<T> floor(Field<T> field) {
return new Floor<>(Tools.nullSafe(field));
}
/**
* Get the smallest integer value not less than [this].
*
* @see #ceil(Field)
*/
@NotNull
@Support
public static <T extends Number> Field<T> ceil(T value) {
return ceil(Tools.field(value));
}
/**
* Get the smallest integer value not less than [field].
* <p>
* This renders the ceil or ceiling function where available:
* <code><pre>ceil([field]) or
* ceiling([field])</pre></code>
* ... or emulates it elsewhere using round:
* <code><pre>round([field] + 0.499999999999999)</pre></code>
*/
@NotNull
@Support
public static <T extends Number> Field<T> ceil(Field<T> field) {
return new Ceil<>(Tools.nullSafe(field));
}
/**
* Truncate a number to a given number of decimals.
*
@ -20263,88 +20312,6 @@ public class DSL {
return trunc(Tools.field(number), inline(0));
}
/**
* Truncate a number to a given number of decimals.
*
* @see #trunc(Field, Field)
*/
@NotNull
@Support({ CUBRID, DERBY, FIREBIRD, H2, HSQLDB, MARIADB, MYSQL, POSTGRES })
public static <T extends Number> Field<T> trunc(T number, int decimals) {
return trunc(Tools.field(number), inline(decimals));
}
/**
* Truncate a number to a given number of decimals.
*
* @see #trunc(Field, Field)
*/
@NotNull
@Support({ CUBRID, DERBY, FIREBIRD, H2, HSQLDB, MARIADB, MYSQL, POSTGRES })
public static <T extends Number> Field<T> trunc(Field<T> number, int decimals) {
return trunc(Tools.nullSafe(number), inline(decimals));
}
/**
* Truncate a number to a given number of decimals.
*
* @see #trunc(Field, Field)
*/
@NotNull
@Support({ CUBRID, DERBY, FIREBIRD, H2, HSQLDB, MARIADB, MYSQL, POSTGRES })
public static <T extends Number> Field<T> trunc(T number, Field<Integer> decimals) {
return trunc(Tools.field(number), Tools.nullSafe(decimals));
}
/**
* Truncate a number to a given number of decimals.
* <p>
* This function truncates <code>number</code> to the amount of decimals
* specified in <code>decimals</code>. Passing <code>decimals = 0</code> to
* this function is the same as using {@link #floor(Field)}. Passing
* positive values for <code>decimal</code> has a similar effect as
* {@link #round(Field, int)}. Passing negative values for
* <code>decimal</code> will truncate <code>number</code> to a given power
* of 10. Some examples
* <table border="1">
* <tr>
* <th>Function call</th>
* <th>yields...</th>
* </tr>
* <tr>
* <td>trunc(125.815)</td>
* <td>125</td>
* </tr>
* <tr>
* <td>trunc(125.815, 0)</td>
* <td>125</td>
* </tr>
* <tr>
* <td>trunc(125.815, 1)</td>
* <td>125.8</td>
* </tr>
* <tr>
* <td>trunc(125.815, 2)</td>
* <td>125.81</td>
* </tr>
* <tr>
* <td>trunc(125.815, -1)</td>
* <td>120</td>
* </tr>
* <tr>
* <td>trunc(125.815, -2)</td>
* <td>100</td>
* </tr>
* </table>
*
* @see #trunc(Field, Field)
*/
@NotNull
@Support({ CUBRID, DERBY, FIREBIRD, H2, HSQLDB, MARIADB, MYSQL, POSTGRES })
public static <T extends Number> Field<T> trunc(Field<T> number, Field<Integer> decimals) {
return new Trunc<>(Tools.nullSafe(number), Tools.nullSafe(decimals));
}
/**
* Get the sqrt(field) function.
*

View File

@ -37,29 +37,49 @@
*/
package org.jooq.impl;
import static org.jooq.impl.Names.N_FLOOR;
import static org.jooq.impl.DSL.*;
import static org.jooq.impl.Internal.*;
import static org.jooq.impl.Keywords.*;
import static org.jooq.impl.Names.*;
import static org.jooq.impl.SQLDataType.*;
import static org.jooq.impl.Tools.*;
import static org.jooq.impl.Tools.BooleanDataKey.*;
import static org.jooq.SQLDialect.*;
import org.jooq.*;
import org.jooq.impl.*;
import org.jooq.tools.*;
import java.util.*;
import org.jooq.Context;
import org.jooq.Field;
/**
* @author Lukas Eder
* The <code>FLOOR</code> statement.
*/
final class Floor<T extends Number> extends AbstractField<T> {
@SuppressWarnings({ "rawtypes", "unchecked", "unused" })
final class Floor<T extends Number>
extends
AbstractField<T>
{
/**
* Generated UID
*/
private static final long serialVersionUID = -7273879239726265322L;
private static final long serialVersionUID = 1L;
private final Field<T> argument;
private final Field<T> value;
Floor(Field<T> argument) {
super(N_FLOOR, argument.getDataType());
Floor(
Field<T> value
) {
super(N_FLOOR, allNotNull((DataType) dataType(INTEGER, value, false), value));
this.argument = argument;
this.value = nullSafeNotNull(value, INTEGER);
}
// -------------------------------------------------------------------------
// XXX: QueryPart API
// -------------------------------------------------------------------------
@Override
public final void accept(Context<?> ctx) {
switch (ctx.family()) {
@ -70,13 +90,30 @@ final class Floor<T extends Number> extends AbstractField<T> {
// [#8275] Improved emulation for SQLite
case SQLITE:
Field<Long> cast = DSL.cast(argument, SQLDataType.BIGINT);
ctx.sql('(').visit(cast).sql(" - (").visit(argument).sql(" < ").visit(cast).sql("))");
Field<Long> cast = DSL.cast(value, SQLDataType.BIGINT);
ctx.sql('(').visit(cast).sql(" - (").visit(value).sql(" < ").visit(cast).sql("))");
break;
default:
ctx.visit(N_FLOOR).sql('(').visit(argument).sql(')');
ctx.visit(N_FLOOR).sql('(').visit(value).sql(')');
break;
}
}
// -------------------------------------------------------------------------
// The Object API
// -------------------------------------------------------------------------
@Override
public boolean equals(Object that) {
if (that instanceof Floor) {
return
StringUtils.equals(value, ((Floor) that).value)
;
}
else
return super.equals(that);
}
}

View File

@ -37,45 +37,52 @@
*/
package org.jooq.impl;
import static java.math.BigDecimal.TEN;
import static org.jooq.impl.DSL.inline;
import static org.jooq.impl.DSL.zero;
import static org.jooq.impl.Internal.idiv;
import static org.jooq.impl.Internal.imul;
import static org.jooq.impl.Names.N_ROUND;
import static org.jooq.impl.Names.N_ROUND_DOWN;
import static org.jooq.impl.Names.N_TRUNC;
import static org.jooq.impl.Names.N_TRUNCATE;
import static org.jooq.impl.Names.N_TRUNCNUM;
import static org.jooq.impl.Tools.castIfNeeded;
import static org.jooq.impl.Tools.extractParamValue;
import static org.jooq.impl.DSL.*;
import static org.jooq.impl.Internal.*;
import static org.jooq.impl.Keywords.*;
import static org.jooq.impl.Names.*;
import static org.jooq.impl.SQLDataType.*;
import static org.jooq.impl.Tools.*;
import static org.jooq.impl.Tools.BooleanDataKey.*;
import static org.jooq.SQLDialect.*;
import java.math.BigDecimal;
import java.math.MathContext;
import org.jooq.*;
import org.jooq.impl.*;
import org.jooq.tools.*;
import java.util.*;
import org.jooq.Context;
import org.jooq.Field;
/**
* @author Lukas Eder
* The <code>TRUNC</code> statement.
*/
final class Trunc<T> extends AbstractField<T> {
@SuppressWarnings({ "rawtypes", "unchecked", "unused" })
final class Trunc<T extends Number>
extends
AbstractField<T>
{
/**
* Generated UID
*/
private static final long serialVersionUID = 4291348230758816484L;
private static final long serialVersionUID = 1L;
private final Field<T> field;
private final Field<T> value;
private final Field<Integer> decimals;
Trunc(Field<T> field, Field<Integer> decimals) {
super(N_TRUNC, field.getDataType());
Trunc(
Field<T> value,
Field<Integer> decimals
) {
super(N_TRUNC, allNotNull((DataType) dataType(INTEGER, value, false), value, decimals));
this.field = field;
this.decimals = decimals;
this.value = nullSafeNotNull(value, INTEGER);
this.decimals = nullSafeNotNull(decimals, INTEGER);
}
// -------------------------------------------------------------------------
// XXX: QueryPart API
// -------------------------------------------------------------------------
@Override
public final void accept(Context<?> ctx) {
switch (ctx.family()) {
@ -84,19 +91,19 @@ final class Trunc<T> extends AbstractField<T> {
case DERBY: {
Field<BigDecimal> power;
Field<?> power;
// [#1334] if possible, calculate the power in Java to prevent
// inaccurate arithmetics in the Derby database
Integer decimalsVal = extractParamValue(decimals);
if (decimalsVal != null)
power = inline(TEN.pow(decimalsVal, MathContext.DECIMAL128));
power = inline(java.math.BigDecimal.TEN.pow(decimalsVal, java.math.MathContext.DECIMAL128));
else
power = DSL.power(inline(TEN), decimals);
power = DSL.power(inline(java.math.BigDecimal.TEN), decimals);
ctx.visit(DSL.decode()
.when(field.sign().greaterOrEqual(zero()), idiv(imul(field, power).floor(), power))
.otherwise(idiv(imul(field, power).ceil(), power)));
.when(value.sign().greaterOrEqual(zero()), idiv(imul(value, power).floor(), power))
.otherwise(idiv(imul(value, power).ceil(), power)));
break;
}
@ -107,7 +114,7 @@ final class Trunc<T> extends AbstractField<T> {
case H2:
case MARIADB:
case MYSQL:
ctx.visit(N_TRUNCATE).sql('(').visit(field).sql(", ").visit(decimals).sql(')');
ctx.visit(N_TRUNCATE).sql('(').visit(value).sql(", ").visit(decimals).sql(')');
break;
// Postgres TRUNC() only takes NUMERIC arguments, no
@ -118,11 +125,11 @@ final class Trunc<T> extends AbstractField<T> {
case POSTGRES:
ctx.visit(castIfNeeded(
DSL.function("trunc", SQLDataType.NUMERIC,
castIfNeeded(field, BigDecimal.class),
DSL.function("trunc", NUMERIC,
castIfNeeded(value, NUMERIC),
decimals
),
field.getDataType()
value.getDataType()
));
break;
@ -150,8 +157,26 @@ final class Trunc<T> extends AbstractField<T> {
case CUBRID:
case HSQLDB:
default:
ctx.visit(N_TRUNC).sql('(').visit(field).sql(", ").visit(decimals).sql(')');
ctx.visit(N_TRUNC).sql('(').visit(value).sql(", ").visit(decimals).sql(')');
break;
}
}
// -------------------------------------------------------------------------
// The Object API
// -------------------------------------------------------------------------
@Override
public boolean equals(Object that) {
if (that instanceof Trunc) {
return
StringUtils.equals(value, ((Trunc) that).value) &&
StringUtils.equals(decimals, ((Trunc) that).decimals)
;
}
else
return super.equals(that);
}
}