[jOOQ/jOOQ#11070] Propagate type nullability through API - WIP
This commit is contained in:
parent
8cc490166c
commit
b28b478d0f
@ -38,6 +38,7 @@
|
||||
package org.jooq.impl;
|
||||
|
||||
import static org.jooq.impl.Names.N_COALESCE;
|
||||
import static org.jooq.impl.Tools.anyNotNull;
|
||||
|
||||
import org.jooq.Context;
|
||||
import org.jooq.DataType;
|
||||
@ -54,9 +55,9 @@ final class Coalesce<T> extends AbstractField<T> {
|
||||
private static final long serialVersionUID = -4546488210418866103L;
|
||||
private final Field<T>[] fields;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
Coalesce(DataType<T> dataType, Field<?>[] fields) {
|
||||
super(N_COALESCE, dataType);
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
Coalesce(Field<?>[] fields) {
|
||||
super(N_COALESCE, (DataType) anyNotNull(fields));
|
||||
|
||||
this.fields = (Field[]) fields;
|
||||
}
|
||||
|
||||
@ -107,8 +107,10 @@ import static org.jooq.impl.RankingFunction.RankingType.CUME_DIST;
|
||||
import static org.jooq.impl.RankingFunction.RankingType.DENSE_RANK;
|
||||
import static org.jooq.impl.RankingFunction.RankingType.PERCENT_RANK;
|
||||
import static org.jooq.impl.RankingFunction.RankingType.RANK;
|
||||
import static org.jooq.impl.SQLDataType.INTEGER;
|
||||
import static org.jooq.impl.SQLDataType.JSON;
|
||||
import static org.jooq.impl.SQLDataType.JSONB;
|
||||
import static org.jooq.impl.SQLDataType.NUMERIC;
|
||||
import static org.jooq.impl.SQLDataType.TIMESTAMP;
|
||||
import static org.jooq.impl.Tools.EMPTY_FIELD;
|
||||
import static org.jooq.impl.Tools.combine;
|
||||
@ -14529,7 +14531,7 @@ public class DSL {
|
||||
// Java 8 is stricter than Java 7 with respect to generics and overload
|
||||
// resolution (http://stackoverflow.com/q/5361513/521799)
|
||||
static <T> Field<T> coalesce0(Field<T> field, Field<?>... fields) {
|
||||
return new Coalesce<>(nullSafeDataType(field), nullSafe(combine(field, fields)));
|
||||
return new Coalesce<>(nullSafe(combine(field, fields)));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -22277,7 +22279,7 @@ public class DSL {
|
||||
@NotNull
|
||||
@Support({ CUBRID, FIREBIRD, H2, MARIADB, MYSQL, POSTGRES, SQLITE })
|
||||
public static WindowOverStep<Integer> rank() {
|
||||
return new RankingFunction<>(RANK, SQLDataType.INTEGER);
|
||||
return new RankingFunction<>(RANK, INTEGER);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -22286,7 +22288,7 @@ public class DSL {
|
||||
@NotNull
|
||||
@Support({ CUBRID, FIREBIRD, H2, MARIADB, MYSQL, POSTGRES, SQLITE })
|
||||
public static WindowOverStep<Integer> denseRank() {
|
||||
return new RankingFunction<>(DENSE_RANK, SQLDataType.INTEGER);
|
||||
return new RankingFunction<>(DENSE_RANK, INTEGER);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -22295,7 +22297,7 @@ public class DSL {
|
||||
@NotNull
|
||||
@Support({ CUBRID, H2, MARIADB, MYSQL, POSTGRES, SQLITE })
|
||||
public static WindowOverStep<BigDecimal> percentRank() {
|
||||
return new RankingFunction<>(PERCENT_RANK, SQLDataType.NUMERIC);
|
||||
return new RankingFunction<>(PERCENT_RANK, NUMERIC);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -22304,7 +22306,7 @@ public class DSL {
|
||||
@NotNull
|
||||
@Support({ CUBRID, H2, MARIADB, MYSQL, POSTGRES, SQLITE })
|
||||
public static WindowOverStep<BigDecimal> cumeDist() {
|
||||
return new RankingFunction<>(CUME_DIST, SQLDataType.NUMERIC);
|
||||
return new RankingFunction<>(CUME_DIST, NUMERIC);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -55,7 +55,7 @@ final class Ntile extends AbstractWindowFunction<Integer> {
|
||||
private final Field<Integer> tiles;
|
||||
|
||||
Ntile(Field<Integer> tiles) {
|
||||
super(N_NTILE, INTEGER);
|
||||
super(N_NTILE, INTEGER.notNull());
|
||||
|
||||
this.tiles = tiles;
|
||||
}
|
||||
|
||||
@ -58,7 +58,7 @@ final class NullIf<T> extends AbstractField<T> {
|
||||
private final Field<T> arg2;
|
||||
|
||||
NullIf(Field<T> arg1, Field<T> arg2) {
|
||||
super(N_NULLIF, arg1.getDataType());
|
||||
super(N_NULLIF, arg1.getDataType().null_());
|
||||
|
||||
this.arg1 = arg1;
|
||||
this.arg2 = arg2;
|
||||
|
||||
@ -60,7 +60,7 @@ final class Nvl<T> extends AbstractField<T> {
|
||||
private final Field<T> arg2;
|
||||
|
||||
Nvl(Field<T> arg1, Field<T> arg2) {
|
||||
super(N_NVL, arg1.getDataType());
|
||||
super(N_NVL, Tools.anyNotNull(arg1, arg2));
|
||||
|
||||
this.arg1 = arg1;
|
||||
this.arg2 = arg2;
|
||||
|
||||
@ -58,7 +58,7 @@ final class Nvl2<T> extends AbstractField<T> {
|
||||
private final Field<T> arg3;
|
||||
|
||||
Nvl2(Field<?> arg1, Field<T> arg2, Field<T> arg3) {
|
||||
super(N_NVL2, arg2.getDataType());
|
||||
super(N_NVL2, !arg1.getDataType().nullable() ? arg2.getDataType() : Tools.allNotNull(arg2, arg3));
|
||||
|
||||
this.arg1 = arg1;
|
||||
this.arg2 = arg2;
|
||||
|
||||
@ -65,7 +65,7 @@ final class PositionalWindowFunction<T> extends AbstractWindowFunction<T> {
|
||||
}
|
||||
|
||||
PositionalWindowFunction(PositionalFunctionType functionType, Field<T> arg, Field<Integer> offset, Field<T> defaultValue) {
|
||||
super(functionType.name, arg.getDataType());
|
||||
super(functionType.name, arg.getDataType().null_());
|
||||
|
||||
this.functionType = functionType;
|
||||
this.arg = arg;
|
||||
|
||||
@ -79,7 +79,7 @@ final class RankingFunction<T> extends AbstractWindowFunction<T> {
|
||||
private final RankingType rankingType;
|
||||
|
||||
RankingFunction(RankingType rankingType, DataType<T> type) {
|
||||
super(rankingType.name, type);
|
||||
super(rankingType.name, type.notNull());
|
||||
|
||||
this.rankingType = rankingType;
|
||||
}
|
||||
|
||||
@ -55,7 +55,7 @@ final class RowNumber extends AbstractWindowFunction<Integer> {
|
||||
private static final long serialVersionUID = -7318928420486422195L;
|
||||
|
||||
RowNumber() {
|
||||
super(N_ROW_NUMBER, INTEGER);
|
||||
super(N_ROW_NUMBER, INTEGER.notNull());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -155,6 +155,7 @@ import static org.jooq.impl.SQLDataType.BLOB;
|
||||
import static org.jooq.impl.SQLDataType.CLOB;
|
||||
import static org.jooq.impl.SQLDataType.JSON;
|
||||
import static org.jooq.impl.SQLDataType.JSONB;
|
||||
import static org.jooq.impl.SQLDataType.OTHER;
|
||||
import static org.jooq.impl.SQLDataType.VARCHAR;
|
||||
import static org.jooq.impl.SQLDataType.XML;
|
||||
import static org.jooq.impl.Tools.DataCacheKey.DATA_REFLECTION_CACHE_GET_ANNOTATED_GETTER;
|
||||
@ -5898,4 +5899,58 @@ final class Tools {
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static final <T> DataType<T> allNotNull(Field<T> f1, Field<T> f2) {
|
||||
DataType<T> result = f1.getDataType();
|
||||
|
||||
if (result.nullable())
|
||||
return result;
|
||||
else if (f2.getDataType().nullable())
|
||||
return result.null_();
|
||||
else
|
||||
return result;
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
static final <T> DataType<T> allNotNull(Field<T>... fields) {
|
||||
if (fields == null || fields.length == 0)
|
||||
return (DataType) OTHER;
|
||||
|
||||
DataType<T> result = fields[0].getDataType();
|
||||
if (result.nullable())
|
||||
return result;
|
||||
|
||||
for (int i = 1; i < fields.length; i++)
|
||||
if (fields[i].getDataType().nullable())
|
||||
return result.null_();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static final <T> DataType<T> anyNotNull(Field<T> f1, Field<T> f2) {
|
||||
DataType<T> result = f1.getDataType();
|
||||
|
||||
if (!result.nullable())
|
||||
return result;
|
||||
else if (!f2.getDataType().nullable())
|
||||
return result.notNull();
|
||||
else
|
||||
return result;
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
static final <T> DataType<T> anyNotNull(Field<T>... fields) {
|
||||
if (fields == null || fields.length == 0)
|
||||
return (DataType) OTHER;
|
||||
|
||||
DataType<T> result = fields[0].getDataType();
|
||||
if (!result.nullable())
|
||||
return result;
|
||||
|
||||
for (int i = 1; i < fields.length; i++)
|
||||
if (!fields[i].getDataType().nullable())
|
||||
return result.notNull();
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@ -67,11 +67,15 @@ final class Val<T> extends AbstractParam<T> {
|
||||
private static final ConcurrentHashMap<Class<?>, Object> legacyWarnings = new ConcurrentHashMap<>();
|
||||
|
||||
Val(T value, DataType<T> type) {
|
||||
super(value, type);
|
||||
super(value, type(value, type));
|
||||
}
|
||||
|
||||
Val(T value, DataType<T> type, String paramName) {
|
||||
super(value, type, paramName);
|
||||
super(value, type(value, type), paramName);
|
||||
}
|
||||
|
||||
private static final <T> DataType<T> type(T value, DataType<T> type) {
|
||||
return value == null ? type.null_() : type.notNull();
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
Loading…
Reference in New Issue
Block a user