[jOOQ/jOOQ#10372] Refactor internal org.jooq.impl.Cast.Native for better reuse

This commit is contained in:
Lukas Eder 2020-07-09 14:25:37 +02:00
parent 2d0515d513
commit bde4100b8f
4 changed files with 33 additions and 29 deletions

View File

@ -40,6 +40,7 @@ package org.jooq.impl;
import static org.jooq.impl.DSL.inline;
import static org.jooq.impl.Keywords.K_AS;
import static org.jooq.impl.Keywords.K_CAST;
import static org.jooq.impl.Keywords.K_TRIM;
import static org.jooq.impl.Names.N_CAST;
import static org.jooq.impl.Names.N_TO_CLOB;
import static org.jooq.impl.Names.N_TO_DATE;
@ -58,7 +59,9 @@ import java.sql.Timestamp;
import org.jooq.Context;
import org.jooq.DataType;
import org.jooq.Field;
import org.jooq.Keyword;
// ...
import org.jooq.QueryPart;
import org.jooq.RenderContext.CastMode;
/**
@ -197,7 +200,7 @@ final class Cast<T> extends AbstractField<T> {
// [#857] Interestingly, Derby does not allow for casting numeric
// types directly to VARCHAR. An intermediary cast to CHAR is needed
if (field.getDataType().isNumeric() && type.isString() && !CHAR.equals(type))
ctx.visit(DSL.trim(new CastNative<>(new CastNative<>(field, CHAR(38)), (DataType<String>) getDataType())));
ctx.visit(K_TRIM).sql('(').visit(new CastNative<>(new CastNative<>(field, CHAR(38)), (DataType<String>) getDataType())).sql(')');
// [#888] ... neither does casting character types to FLOAT (and similar)
else if (field.getDataType().isString() && (FLOAT.equals(type) || DOUBLE.equals(type) || REAL.equals(type)))
@ -291,18 +294,26 @@ final class Cast<T> extends AbstractField<T> {
private static class CastNative<T> extends AbstractField<T> {
static class CastNative<T> extends AbstractQueryPart {
/**
* Generated UID
*/
private static final long serialVersionUID = -8497561014419483312L;
private final Field<?> field;
private final QueryPart expression;
private final DataType<T> type;
private final Keyword typeAsKeyword;
CastNative(Field<?> field, DataType<T> type) {
super(N_CAST, type);
CastNative(QueryPart expression, DataType<T> type) {
this.expression = expression;
this.type = type;
this.typeAsKeyword = null;
}
this.field = field;
CastNative(QueryPart expression, Keyword typeAsKeyword) {
this.expression = expression;
this.type = null;
this.typeAsKeyword = typeAsKeyword;
}
@Override
@ -314,11 +325,16 @@ final class Cast<T> extends AbstractField<T> {
// Default rendering, if no special case has applied yet
ctx.visit(K_CAST).sql('(')
.castMode(CastMode.NEVER)
.visit(field)
.visit(expression)
.castMode(castMode)
.sql(' ').visit(K_AS).sql(' ')
.sql(getDataType(ctx.configuration()).getCastTypeName(ctx.configuration()))
.sql(')');
.sql(' ').visit(K_AS).sql(' ');
if (typeAsKeyword != null)
ctx.visit(typeAsKeyword);
else
ctx.sql(type.getCastTypeName(ctx.configuration()));
ctx.sql(')');
}
}
}

View File

@ -39,9 +39,7 @@ package org.jooq.impl;
// ...
import static org.jooq.impl.DSL.val;
import static org.jooq.impl.Keywords.K_AS;
import static org.jooq.impl.Keywords.K_CAST;
import static org.jooq.impl.Keywords.K_DATE;
import static org.jooq.impl.SQLDataType.DATE;
import java.sql.SQLException;
import java.sql.Timestamp;
@ -58,6 +56,7 @@ import org.jooq.Converter;
import org.jooq.Converters;
import org.jooq.RenderContext;
import org.jooq.SQLDialect;
import org.jooq.impl.Cast.CastNative;
/**
* A binding that implements the date-as-timestamp semantics of the jOOQ code
@ -101,9 +100,6 @@ public class DateAsTimestampBinding implements Binding<Timestamp, Timestamp> {
delegate.sql(ctx);
}

View File

@ -76,7 +76,6 @@ import static org.jooq.SQLDialect.SQLITE;
import static org.jooq.conf.ParamType.INLINED;
import static org.jooq.impl.DSL.cast;
import static org.jooq.impl.DSL.inline;
import static org.jooq.impl.DSL.keyword;
import static org.jooq.impl.DSL.name;
import static org.jooq.impl.DSL.sqrt;
import static org.jooq.impl.DSL.using;
@ -197,6 +196,7 @@ import org.jooq.exception.ControlFlowSignal;
import org.jooq.exception.DataTypeException;
import org.jooq.exception.MappingException;
import org.jooq.exception.SQLDialectNotSupportedException;
import org.jooq.impl.Cast.CastNative;
import org.jooq.tools.Convert;
import org.jooq.tools.JooqLogger;
import org.jooq.tools.Longs;
@ -2007,7 +2007,6 @@ public class DefaultBinding<T, U> implements Binding<T, U> {
// [#1253] Derby doesn't support the standard literal
else if (ctx.family() == DERBY)
ctx.render().visit(K_DATE).sql("('").sql(escape(value, ctx.render())).sql("')");
@ -2273,7 +2272,7 @@ public class DefaultBinding<T, U> implements Binding<T, U> {
else if (ctx.family() == HSQLDB)
ctx.render().visit(sqrt(inline(-1)));
else
ctx.render().visit(K_CAST).sql('(').visit(inline("NaN")).sql(' ').visit(K_AS).sql(' ').visit(keyword(DOUBLE.getCastTypeName(ctx.configuration()))).sql(')');
ctx.render().visit(new CastNative<>(inline("NaN"), DOUBLE));
else
ctx.render().sql(value);
}
@ -2448,7 +2447,7 @@ public class DefaultBinding<T, U> implements Binding<T, U> {
else if (ctx.family() == HSQLDB)
ctx.render().visit(sqrt(inline(-1)));
else
ctx.render().visit(K_CAST).sql('(').visit(inline("NaN")).sql(' ').visit(K_AS).sql(' ').visit(keyword(DOUBLE.getCastTypeName(ctx.configuration()))).sql(')');
ctx.render().visit(new CastNative<>(inline("NaN"), DOUBLE));
else
ctx.render().sql(value);
}
@ -2804,7 +2803,6 @@ public class DefaultBinding<T, U> implements Binding<T, U> {
// Some dialects implement SQL standard time literals
default:
ctx.render().visit(K_TIMESTAMP_WITH_TIME_ZONE).sql(" '").sql(escape(format(value, family), ctx.render())).sql('\'');
@ -3901,7 +3899,6 @@ public class DefaultBinding<T, U> implements Binding<T, U> {
// Most dialects implement SQL standard time literals
else
ctx.render().visit(K_TIME).sql(" '").sql(escape(value, ctx.render())).sql('\'');
@ -3981,7 +3978,6 @@ public class DefaultBinding<T, U> implements Binding<T, U> {
// [#1253] Derby doesn't support the standard literal
else if (ctx.family() == DERBY)
ctx.render().visit(K_TIMESTAMP).sql("('").sql(escape(value, ctx.render())).sql("')");

View File

@ -44,9 +44,7 @@ package org.jooq.impl;
// ...
import static org.jooq.impl.DSL.val;
import static org.jooq.impl.Keywords.K_AS;
import static org.jooq.impl.Keywords.K_CAST;
import static org.jooq.impl.Keywords.K_DATE;
import static org.jooq.impl.SQLDataType.DATE;
import java.sql.SQLException;
import java.time.LocalDateTime;
@ -63,6 +61,7 @@ import org.jooq.Converter;
import org.jooq.Converters;
import org.jooq.RenderContext;
import org.jooq.SQLDialect;
import org.jooq.impl.Cast.CastNative;
/**
* A binding that implements the date-as-timestamp semantics of the jOOQ code
@ -106,9 +105,6 @@ public class LocalDateAsLocalDateTimeBinding implements Binding<LocalDateTime, L
delegate.sql(ctx);
}