From 78f7c67f674adf352a16c59e70e5a7e89943e062 Mon Sep 17 00:00:00 2001 From: Lukas Eder Date: Fri, 26 Jun 2020 13:38:14 +0200 Subject: [PATCH] [jOOQ/jOOQ#9061] Wrong data types in meta lookups for expressions When unqualified column names are part of expressions (e.g. ID + 1) then the data type information is lost on both the column reference and the whole expression. --- .../java/org/jooq/impl/AbstractDataType.java | 711 +++++++ .../org/jooq/impl/AbstractTypedNamed.java | 8 +- .../java/org/jooq/impl/ConvertedDataType.java | 2 +- .../java/org/jooq/impl/DefaultDataType.java | 604 +----- .../main/java/org/jooq/impl/FieldProxy.java | 1856 ++--------------- .../main/java/org/jooq/impl/ParserImpl.java | 12 +- 6 files changed, 869 insertions(+), 2324 deletions(-) create mode 100644 jOOQ/src/main/java/org/jooq/impl/AbstractDataType.java diff --git a/jOOQ/src/main/java/org/jooq/impl/AbstractDataType.java b/jOOQ/src/main/java/org/jooq/impl/AbstractDataType.java new file mode 100644 index 0000000000..acaba7b17d --- /dev/null +++ b/jOOQ/src/main/java/org/jooq/impl/AbstractDataType.java @@ -0,0 +1,711 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Other licenses: + * ----------------------------------------------------------------------------- + * Commercial licenses for this work are available. These replace the above + * ASL 2.0 and offer limited warranties, support, maintenance, and commercial + * database integrations. + * + * For more information, please visit: http://www.jooq.org/licenses + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + */ +package org.jooq.impl; + +import static org.jooq.Nullability.NOT_NULL; +import static org.jooq.impl.DSL.unquotedName; +import static org.jooq.impl.SQLDataType.BLOB; +import static org.jooq.impl.SQLDataType.CLOB; +import static org.jooq.impl.SQLDataType.NCLOB; + +import java.lang.reflect.Array; +import java.math.BigDecimal; +import java.math.BigInteger; +import java.sql.Blob; +import java.sql.Clob; +import java.sql.Time; +import java.sql.Timestamp; +import java.sql.Types; +import java.time.Instant; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.OffsetDateTime; +import java.time.OffsetTime; +import java.util.Collection; +import java.util.List; + +// ... +import org.jooq.Binding; +import org.jooq.CharacterSet; +import org.jooq.Collation; +import org.jooq.Comment; +import org.jooq.Configuration; +import org.jooq.Context; +import org.jooq.Converter; +import org.jooq.DataType; +import org.jooq.Domain; +import org.jooq.EnumType; +import org.jooq.Field; +import org.jooq.JSON; +import org.jooq.JSONB; +import org.jooq.Name; +import org.jooq.Nullability; +// ... +import org.jooq.Result; +import org.jooq.UDTRecord; +import org.jooq.XML; +import org.jooq.tools.Convert; +import org.jooq.types.Interval; +import org.jooq.types.UNumber; + +/** + * @author Lukas Eder + */ +@SuppressWarnings({ "rawtypes", "unchecked", "deprecation" }) +abstract class AbstractDataType extends AbstractNamed implements DataType { + + /** + * Generated UID + */ + private static final long serialVersionUID = 4155588654449505119L; + + AbstractDataType(Name name, Comment comment) { + super(name, comment); + } + + /** + * [#7811] Allow for subtypes to override the constructor + */ + abstract AbstractDataType construct( + Integer newPrecision, + Integer newScale, + Integer newLength, + Nullability newNullability, + Collation newCollation, + CharacterSet newCharacterSet, + boolean newIdentity, + Field newDefaultValue + ); + + @Override + public final DataType nullability(Nullability n) { + return construct(precision0(), scale0(), length0(), n, collation(), characterSet(), n.nullable() ? false : identity(), defaultValue()); + } + + @Override + public final DataType nullable(boolean n) { + return nullability(Nullability.of(n)); + } + + @Override + public final boolean nullable() { + return nullability().nullable(); + } + + @Override + public final DataType collation(Collation c) { + return construct(precision0(), scale0(), length0(), nullability(), c, characterSet(), identity(), defaultValue()); + } + + @Override + public final DataType characterSet(CharacterSet c) { + return construct(precision0(), scale0(), length0(), nullability(), collation(), c, identity(), defaultValue()); + } + + @Override + public final DataType identity(boolean i) { + return construct(precision0(), scale0(), length0(), i ? NOT_NULL : nullability(), collation(), characterSet(), i, i ? null : defaultValue()); + } + + @Override + public final DataType defaultValue(T d) { + return default_(d); + } + + @Override + public final DataType defaultValue(Field d) { + return default_(d); + } + + @Override + public final Field defaultValue() { + return default_(); + } + + @Override + public final DataType default_(T d) { + return default_(Tools.field(d, this)); + } + + @Override + public final DataType default_(Field d) { + return construct(precision0(), scale0(), length0(), nullability(), collation(), characterSet(), d != null ? false : identity(), d); + } + + @Override + @Deprecated + public final DataType defaulted(boolean d) { + return defaultValue(d ? Tools.field(null, this) : null); + } + + @Override + public final boolean defaulted() { + return defaultValue() != null; + } + + @Override + public final int precision() { + Integer precision = precision0(); + return precision == null ? 0 : precision; + } + + @Override + public final DataType precision(int p) { + return precision0(p, scale()); + } + + @Override + public final DataType precision(int p, int s) { + return precision0(p, s); + } + + final AbstractDataType precision0(Integer p, Integer s) { + if (eq(precision(), p) && eq(scale(), s)) + return this; + + // [#4120] LOB types are not allowed to have precision + else if (isLob()) + return this; + else + return construct(p, s, length0(), nullability(), collation(), characterSet(), identity(), defaultValue()); + } + + @Override + public final boolean hasPrecision() { + Class tType = tType0(); + + return tType == BigInteger.class + || tType == BigDecimal.class + || tType == Timestamp.class + || tType == Time.class + + || tType == LocalDateTime.class + || tType == LocalTime.class + || tType == OffsetDateTime.class + || tType == OffsetTime.class + || tType == Instant.class + + ; + } + + @Override + public final boolean precisionDefined() { + return precision0() != null && hasPrecision(); + } + + @Override + public final int scale() { + Integer scale = scale0(); + return scale == null ? 0 : scale; + } + + @Override + public final DataType scale(int s) { + return scale0(s); + } + + final AbstractDataType scale0(Integer s) { + if (eq(scale(), s)) + return this; + + // [#4120] LOB types are not allowed to have scale + if (isLob()) + return this; + else + return construct(precision0(), s, length0(), nullability(), collation(), characterSet(), identity(), defaultValue()); + } + + @Override + public final boolean hasScale() { + return tType0() == BigDecimal.class; + } + + @Override + public final boolean scaleDefined() { + return scale0() != null && hasScale(); + } + + @Override + public final DataType length(int l) { + return length0(l); + } + + final AbstractDataType length0(Integer l) { + if (eq(length0(), l)) + return this; + + // [#4120] LOB types are not allowed to have length + if (isLob()) + return this; + else + return construct(precision0(), scale0(), l, nullability(), collation(), characterSet(), identity(), defaultValue()); + } + + @Override + public final int length() { + Integer length = length0(); + return length == null ? 0 : length; + } + + @Override + public final boolean hasLength() { + Class tType = tType0(); + return (tType == byte[].class || tType == String.class) && !isLob(); + } + + @Override + public final boolean lengthDefined() { + return length0() != null && hasLength(); + } + + @Override + public /* final */ int getSQLType() { + return getSQLType(DSL.using(getDialect()).configuration()); + } + + @Override + public final int getSQLType(Configuration configuration) { + // TODO [#1227] There is some confusion with these types, especially + // when it comes to byte[] which can be mapped to BLOB, BINARY, VARBINARY + Class tType = tType0(); + + if (tType == Blob.class) + return Types.BLOB; + else if (tType == Boolean.class) + return Types.BOOLEAN; + else if (tType == BigInteger.class) + return Types.BIGINT; + else if (tType == BigDecimal.class) + return Types.DECIMAL; + else if (tType == Byte.class) + return Types.TINYINT; + else if (tType == byte[].class) + return Types.BLOB; + else if (tType == Clob.class) + return Types.CLOB; + else if (Tools.isDate(tType)) { + switch (configuration.family()) { + + + + + + + default: + return Types.DATE; + } + } + else if (tType == Double.class) + return Types.DOUBLE; + else if (tType == Float.class) + return Types.FLOAT; + else if (tType == Integer.class) + return Types.INTEGER; + else if (tType == Long.class) + return Types.BIGINT; + else if (tType == Short.class) + return Types.SMALLINT; + else if (tType == String.class) + return Types.VARCHAR; + else if (Tools.isTime(tType)) + return Types.TIME; + else if (Tools.isTimestamp(tType)) + return Types.TIMESTAMP; + + + // [#5779] Few JDBC drivers support the JDBC 4.2 TIME[STAMP]_WITH_TIMEZONE types. + else if (tType == OffsetTime.class) + return Types.VARCHAR; + else if (tType == OffsetDateTime.class) + return Types.VARCHAR; + else if (tType == Instant.class) + return Types.VARCHAR; + + + // The type byte[] is handled earlier. + else if (tType.isArray()) + return Types.ARRAY; + + + + + + + + + + + + + + + else if (EnumType.class.isAssignableFrom(tType)) + return Types.VARCHAR; + else if (UDTRecord.class.isAssignableFrom(tType)) + return Types.STRUCT; + else if (Result.class.isAssignableFrom(tType)) { + switch (configuration.family()) { + + + + case H2: + return -10; // OracleTypes.CURSOR; + + + + + + + case POSTGRES: + default: + return Types.OTHER; + } + } + else + return Types.OTHER; + } + + @Override + public /* non-final */ Domain getDomain() { + return null; + } + + @Override + public final Converter getConverter() { + return getBinding().converter(); + } + + @Override + public final String getTypeName() { + return typeName0(); + } + + @Override + public final String getCastTypeName() { + + // [#9958] We should be able to avoid checking for x > 0, but there may + // be a lot of data types constructed with a 0 value instead of + // a null value, historically, so removing this check would + // introduce a lot of regressions! + if (lengthDefined() && length() > 0) + return castTypeBase0() + "(" + length() + ")"; + else if (precisionDefined() && precision() > 0) + if (scaleDefined() && scale() > 0) + return castTypeBase0() + "(" + precision() + ", " + scale() + ")"; + else + return castTypeBase0() + "(" + precision() + ")"; + else + return castTypeName0(); + } + + @Override + public /* non-final */ String getTypeName(Configuration configuration) { + return getDataType(configuration).getTypeName(); + } + + @Override + public /* non-final */ String getCastTypeName(Configuration configuration) { + return getDataType(configuration).getCastTypeName(); + } + + @SuppressWarnings("unchecked") + @Override + public final Class getArrayType() { + return (Class) Array.newInstance(getType(), 0).getClass(); + } + + @Override + public final DataType getArrayDataType() { + return new ArrayDataType<>(this); + } + + @Override + public /* non-final */ Class getArrayComponentType() { + return null; + } + + @Override + public /* non-final */ DataType getArrayComponentDataType() { + return null; + } + + + + + + + + + + @Override + public final DataType asEnumDataType(Class enumDataType) { + // TODO: Make EnumTypes implement Named + String enumTypeName = Tools.enums(enumDataType)[0].getName(); + return new DefaultDataType<>(getDialect(), (DataType) null, enumDataType, unquotedName(enumTypeName), enumTypeName, enumTypeName, precision0(), scale0(), length0(), nullability(), (Field) defaultValue()); + } + + @Override + public /* non-final */ DataType asConvertedDataType(Converter converter) { + return asConvertedDataType(DefaultBinding.newBinding(converter, this, null)); + } + + @Override + public /* non-final */ DataType asConvertedDataType(Binding newBinding) { + if (getBinding() == newBinding) + return (DataType) this; + + if (newBinding == null) + newBinding = (Binding) DefaultBinding.binding(getType(), isLob()); + + return new ConvertedDataType<>(this, newBinding); + } + + @Override + public /* final */ T convert(Object object) { + + // [#1441] Avoid unneeded type conversions to improve performance + if (object == null) + return null; + else if (object.getClass() == getType()) + return (T) object; + else + return Convert.convert(object, getType()); + } + + @Override + public final T[] convert(Object... objects) { + return (T[]) Convert.convertArray(objects, getType()); + } + + @Override + public final List convert(Collection objects) { + return Convert.convert(objects, getType()); + } + + @Override + public final boolean isNumeric() { + return Number.class.isAssignableFrom(tType0()) && !isInterval(); + } + + @Override + public final boolean isInteger() { + Class tType = tType0(); + return UNumber.class.isAssignableFrom(tType) + || Byte.class == tType + || Short.class == tType + || Integer.class == tType + || Long.class == tType + ; + } + + @Override + public final boolean isString() { + return tType0() == String.class; + } + + @Override + public final boolean isDateTime() { + Class tType = tType0(); + return java.util.Date.class.isAssignableFrom(tType) + + || java.time.temporal.Temporal.class.isAssignableFrom(tType) + + ; + } + + @Override + public final boolean isDate() { + Class tType = tType0(); + return java.sql.Date.class.isAssignableFrom(tType) + + || java.time.LocalDate.class.isAssignableFrom(tType) + + ; + } + + @Override + public final boolean isTimestamp() { + Class tType = tType0(); + return java.sql.Timestamp.class.isAssignableFrom(tType) + + || java.time.LocalDateTime.class.isAssignableFrom(tType) + + ; + } + + @Override + public final boolean isTime() { + Class tType = tType0(); + return java.sql.Time.class.isAssignableFrom(tType) + + || java.time.LocalTime.class.isAssignableFrom(tType) + + ; + } + + @Override + public final boolean isTemporal() { + return isDateTime() || isInterval(); + } + + @Override + public final boolean isInterval() { + return Interval.class.isAssignableFrom(tType0()); + } + + @Override + public final boolean isLob() { + DataType t = getSQLDataType(); + + if (t == this) + return getTypeName().endsWith("lob"); + else + return (t == BLOB || t == CLOB || t == NCLOB); + } + + @Override + public final boolean isBinary() { + return tType0() == byte[].class; + } + + @Override + public final boolean isArray() { + Class tType = tType0(); + return + (!isBinary() && tType.isArray()); + } + + @Override + public final boolean isUDT() { + return UDTRecord.class.isAssignableFrom(tType0()); + } + + @Override + public final boolean isEnum() { + return EnumType.class.isAssignableFrom(tType0()); + } + + @Override + public final boolean isJSON() { + Class tType = tType0(); + return tType == JSON.class || tType == JSONB.class; + } + + @Override + public final boolean isXML() { + return tType0() == XML.class; + } + + @Override + public final void accept(Context ctx) { + ctx.visit(getQualifiedName()); + } + + private static final boolean eq(Integer i1, Integer i2) { + return (i1 == i2) || (i1 != null && i2 != null && i1.intValue() == i2.intValue()); + } + + abstract String typeName0(); + abstract String castTypeBase0(); + abstract String castTypeName0(); + abstract Class tType0(); + abstract Integer precision0(); + abstract Integer scale0(); + abstract Integer length0(); + + // ------------------------------------------------------------------------ + // The Object API + // ------------------------------------------------------------------------ + + @Override + public String toString() { + return getCastTypeName() + " (" + getType().getName() + ")"; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((getDialect() == null) ? 0 : getDialect().hashCode()); + result = prime * result + length(); + result = prime * result + precision(); + result = prime * result + scale(); + result = prime * result + ((getType() == null) ? 0 : getType().hashCode()); + result = prime * result + ((tType0() == null) ? 0 : tType0().hashCode()); + result = prime * result + ((typeName0() == null) ? 0 : typeName0().hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (!(obj instanceof AbstractDataType)) + return false; + AbstractDataType other = (AbstractDataType) obj; + if (getDialect() != other.getDialect()) + return false; + if (!eq(length0(), other.length0())) + return false; + if (!eq(precision0(), other.precision0())) + return false; + if (!eq(scale0(), other.scale0())) + return false; + if (getType() == null) { + if (other.getType() != null) + return false; + } + else if (!getType().equals(other.getType())) + return false; + if (tType0() == null) { + if (other.tType0() != null) + return false; + } + else if (!tType0().equals(other.tType0())) + return false; + if (typeName0() == null) { + if (other.typeName0() != null) + return false; + } + else if (!typeName0().equals(other.typeName0())) + return false; + return true; + } +} diff --git a/jOOQ/src/main/java/org/jooq/impl/AbstractTypedNamed.java b/jOOQ/src/main/java/org/jooq/impl/AbstractTypedNamed.java index 84fe3b89df..b54aa381fe 100644 --- a/jOOQ/src/main/java/org/jooq/impl/AbstractTypedNamed.java +++ b/jOOQ/src/main/java/org/jooq/impl/AbstractTypedNamed.java @@ -66,17 +66,17 @@ abstract class AbstractTypedNamed extends AbstractNamed implements Typed { @Override public final Converter getConverter() { - return type.getConverter(); + return getDataType().getConverter(); } @Override public final Binding getBinding() { - return type.getBinding(); + return getDataType().getBinding(); } @Override public final Class getType() { - return type.getType(); + return getDataType().getType(); } @Override @@ -86,6 +86,6 @@ abstract class AbstractTypedNamed extends AbstractNamed implements Typed { @Override public final DataType getDataType(Configuration configuration) { - return type.getDataType(configuration); + return getDataType().getDataType(configuration); } } diff --git a/jOOQ/src/main/java/org/jooq/impl/ConvertedDataType.java b/jOOQ/src/main/java/org/jooq/impl/ConvertedDataType.java index a9d8212871..9681d53fd9 100644 --- a/jOOQ/src/main/java/org/jooq/impl/ConvertedDataType.java +++ b/jOOQ/src/main/java/org/jooq/impl/ConvertedDataType.java @@ -71,7 +71,7 @@ final class ConvertedDataType extends DefaultDataType { private final DataType delegate; @SuppressWarnings("unchecked") - ConvertedDataType(DefaultDataType delegate, Binding binding) { + ConvertedDataType(AbstractDataType delegate, Binding binding) { super( null, binding.converter().toType(), diff --git a/jOOQ/src/main/java/org/jooq/impl/DefaultDataType.java b/jOOQ/src/main/java/org/jooq/impl/DefaultDataType.java index 38d5f732e3..07da842030 100644 --- a/jOOQ/src/main/java/org/jooq/impl/DefaultDataType.java +++ b/jOOQ/src/main/java/org/jooq/impl/DefaultDataType.java @@ -38,34 +38,18 @@ package org.jooq.impl; import static java.util.Collections.unmodifiableCollection; -import static org.jooq.Nullability.NOT_NULL; // ... import static org.jooq.SQLDialect.HSQLDB; import static org.jooq.SQLDialect.POSTGRES; import static org.jooq.impl.CommentImpl.NO_COMMENT; import static org.jooq.impl.DSL.unquotedName; import static org.jooq.impl.DefaultBinding.binding; -import static org.jooq.impl.SQLDataType.BLOB; -import static org.jooq.impl.SQLDataType.CLOB; -import static org.jooq.impl.SQLDataType.NCLOB; import static org.jooq.tools.reflect.Reflect.wrapper; -import java.lang.reflect.Array; import java.math.BigDecimal; import java.math.BigInteger; -import java.sql.Blob; -import java.sql.Clob; -import java.sql.Time; -import java.sql.Timestamp; -import java.sql.Types; -import java.time.Instant; -import java.time.LocalDateTime; -import java.time.LocalTime; -import java.time.OffsetDateTime; -import java.time.OffsetTime; import java.util.Collection; import java.util.LinkedHashMap; -import java.util.List; import java.util.Map; import java.util.regex.Pattern; @@ -74,30 +58,19 @@ import org.jooq.Binding; import org.jooq.CharacterSet; import org.jooq.Collation; import org.jooq.Configuration; -import org.jooq.Context; -import org.jooq.Converter; import org.jooq.DataType; -import org.jooq.Domain; import org.jooq.EnumType; import org.jooq.Field; -import org.jooq.JSON; -import org.jooq.JSONB; import org.jooq.Name; import org.jooq.Nullability; -// ... -import org.jooq.Result; import org.jooq.SQLDialect; import org.jooq.TableRecord; import org.jooq.UDTRecord; -import org.jooq.XML; import org.jooq.exception.MappingException; import org.jooq.exception.SQLDialectNotSupportedException; -import org.jooq.tools.Convert; -import org.jooq.types.Interval; import org.jooq.types.UByte; import org.jooq.types.UInteger; import org.jooq.types.ULong; -import org.jooq.types.UNumber; import org.jooq.types.UShort; /** @@ -111,7 +84,7 @@ import org.jooq.types.UShort; */ @SuppressWarnings({"unchecked"}) @org.jooq.Internal -public class DefaultDataType extends AbstractNamed implements DataType { +public class DefaultDataType extends AbstractDataType { /** * Generated UID @@ -212,11 +185,6 @@ public class DefaultDataType extends AbstractNamed implements DataType { */ private final Binding binding; - /** - * The Java class corresponding to arrays of this data type. - */ - private final Class arrayType; - /** * The type name used for casting to this type. */ @@ -322,7 +290,6 @@ public class DefaultDataType extends AbstractNamed implements DataType { this.typeName = typeName; this.castTypeName = castTypeName; this.castTypeBase = TYPE_NAME_PATTERN.matcher(castTypeName).replaceAll("").trim(); - this.arrayType = (Class) Array.newInstance(type, 0).getClass(); this.nullability = nullability; this.collation = collation; @@ -365,6 +332,7 @@ public class DefaultDataType extends AbstractNamed implements DataType { /** * [#7811] Allow for subtypes to override the constructor */ + @Override DefaultDataType construct( Integer newPrecision, Integer newScale, @@ -401,7 +369,6 @@ public class DefaultDataType extends AbstractNamed implements DataType { this.typeName = t.typeName; this.castTypeName = t.castTypeName; this.castTypeBase = t.castTypeBase; - this.arrayType = t.arrayType; this.nullability = nullability; this.collation = collation; @@ -429,204 +396,44 @@ public class DefaultDataType extends AbstractNamed implements DataType { return precision; } - @Override - public final DataType nullability(Nullability n) { - return construct(precision, scale, length, n, collation, characterSet, n.nullable() ? false : identity, defaultValue); - } - @Override public final Nullability nullability() { return nullability; } - @Override - public final DataType nullable(boolean n) { - return nullability(Nullability.of(n)); - } - - @Override - public final boolean nullable() { - return nullability.nullable(); - } - - @Override - public final DataType collation(Collation c) { - return construct(precision, scale, length, nullability, c, characterSet, identity, defaultValue); - } - @Override public final Collation collation() { return collation; } - @Override - public final DataType characterSet(CharacterSet c) { - return construct(precision, scale, length, nullability, collation, c, identity, defaultValue); - } - @Override public final CharacterSet characterSet() { return characterSet; } - @Override - public final DataType identity(boolean i) { - return construct(precision, scale, length, i ? NOT_NULL : nullability, collation, characterSet, i, i ? null : defaultValue); - } - @Override public final boolean identity() { return identity; } - @Override - public final DataType defaultValue(T d) { - return default_(d); - } - - @Override - public final DataType defaultValue(Field d) { - return default_(d); - } - - @Override - public final Field defaultValue() { - return default_(); - } - - @Override - public final DataType default_(T d) { - return default_(Tools.field(d, this)); - } - - @Override - public final DataType default_(Field d) { - return construct(precision, scale, length, nullability, collation, characterSet, d != null ? false : identity, d); - } - @Override public final Field default_() { return defaultValue; } @Override - @Deprecated - public final DataType defaulted(boolean d) { - return defaultValue(d ? Tools.field(null, this) : null); + final Integer precision0() { + return precision; } @Override - public final boolean defaulted() { - return defaultValue != null; + final Integer scale0() { + return scale; } @Override - public final DataType precision(int p) { - return precision0(p, scale); - } - - @Override - public final DataType precision(int p, int s) { - return precision0(p, s); - } - - private final DefaultDataType precision0(Integer p, Integer s) { - if (eq(precision, p) && eq(scale, s)) - return this; - - // [#4120] LOB types are not allowed to have precision - else if (isLob()) - return this; - else - return construct(p, s, length, nullability, collation, characterSet, identity, defaultValue); - } - - @Override - public final int precision() { - return precision == null ? 0 : precision; - } - - @Override - public final boolean hasPrecision() { - return tType == BigInteger.class - || tType == BigDecimal.class - || tType == Timestamp.class - || tType == Time.class - - || tType == LocalDateTime.class - || tType == LocalTime.class - || tType == OffsetDateTime.class - || tType == OffsetTime.class - || tType == Instant.class - - ; - } - - @Override - public final boolean precisionDefined() { - return precision != null && hasPrecision(); - } - - @Override - public final DataType scale(int s) { - return scale0(s); - } - - private final DefaultDataType scale0(Integer s) { - if (eq(scale, s)) - return this; - - // [#4120] LOB types are not allowed to have scale - if (isLob()) - return this; - else - return construct(precision, s, length, nullability, collation, characterSet, identity, defaultValue); - } - - @Override - public final int scale() { - return scale == null ? 0 : scale; - } - - @Override - public final boolean hasScale() { - return tType == BigDecimal.class; - } - - @Override - public final boolean scaleDefined() { - return scale != null && hasScale(); - } - - @Override - public final DataType length(int l) { - return length0(l); - } - - private final DefaultDataType length0(Integer l) { - if (eq(length, l)) - return this; - - // [#4120] LOB types are not allowed to have length - if (isLob()) - return this; - else - return construct(precision, scale, l, nullability, collation, characterSet, identity, defaultValue); - } - - @Override - public final int length() { - return length == null ? 0 : length; - } - - @Override - public final boolean hasLength() { - return (tType == byte[].class || tType == String.class) && !isLob(); - } - - @Override - public final boolean lengthDefined() { - return length != null && hasLength(); + final Integer length0() { + return length; } @Override @@ -671,216 +478,34 @@ public class DefaultDataType extends AbstractNamed implements DataType { return this; } - @Override - public /* final */ int getSQLType() { - return getSQLType(DSL.using(dialect).configuration()); - } - - @Override - public final int getSQLType(Configuration configuration) { - // TODO [#1227] There is some confusion with these types, especially - // when it comes to byte[] which can be mapped to BLOB, BINARY, VARBINARY - - if (tType == Blob.class) - return Types.BLOB; - else if (tType == Boolean.class) - return Types.BOOLEAN; - else if (tType == BigInteger.class) - return Types.BIGINT; - else if (tType == BigDecimal.class) - return Types.DECIMAL; - else if (tType == Byte.class) - return Types.TINYINT; - else if (tType == byte[].class) - return Types.BLOB; - else if (tType == Clob.class) - return Types.CLOB; - else if (Tools.isDate(tType)) { - switch (configuration.family()) { - - - - - - - default: - return Types.DATE; - } - } - else if (tType == Double.class) - return Types.DOUBLE; - else if (tType == Float.class) - return Types.FLOAT; - else if (tType == Integer.class) - return Types.INTEGER; - else if (tType == Long.class) - return Types.BIGINT; - else if (tType == Short.class) - return Types.SMALLINT; - else if (tType == String.class) - return Types.VARCHAR; - else if (Tools.isTime(tType)) - return Types.TIME; - else if (Tools.isTimestamp(tType)) - return Types.TIMESTAMP; - - - // [#5779] Few JDBC drivers support the JDBC 4.2 TIME[STAMP]_WITH_TIMEZONE types. - else if (tType == OffsetTime.class) - return Types.VARCHAR; - else if (tType == OffsetDateTime.class) - return Types.VARCHAR; - else if (tType == Instant.class) - return Types.VARCHAR; - - - // The type byte[] is handled earlier. - else if (tType.isArray()) - return Types.ARRAY; - - - - - - - - - - - - - - - else if (EnumType.class.isAssignableFrom(tType)) - return Types.VARCHAR; - else if (UDTRecord.class.isAssignableFrom(tType)) - return Types.STRUCT; - else if (Result.class.isAssignableFrom(tType)) { - switch (configuration.family()) { - - - - case H2: - return -10; // OracleTypes.CURSOR; - - - - - - - case POSTGRES: - default: - return Types.OTHER; - } - } - else - return Types.OTHER; - } - @Override public final Class getType() { return uType; } - @Override - public /* non-final */ Domain getDomain() { - return null; - } - @Override public final Binding getBinding() { return binding; } @Override - public final Converter getConverter() { - return binding.converter(); - } - - @Override - public final String getTypeName() { + final String typeName0() { return typeName; } @Override - public /* non-final */ String getTypeName(Configuration configuration) { - return getDataType(configuration).getTypeName(); + final String castTypeBase0() { + return castTypeBase; } @Override - public final String getCastTypeName() { - - // [#9958] We should be able to avoid checking for x > 0, but there may - // be a lot of data types constructed with a 0 value instead of - // a null value, historically, so removing this check would - // introduce a lot of regressions! - if (lengthDefined() && length() > 0) - return castTypeBase + "(" + length + ")"; - else if (precisionDefined() && precision() > 0) - if (scaleDefined() && scale() > 0) - return castTypeBase + "(" + precision + ", " + scale + ")"; - else - return castTypeBase + "(" + precision + ")"; - else - return castTypeName; + final String castTypeName0() { + return castTypeName; } @Override - public /* non-final */ String getCastTypeName(Configuration configuration) { - return getDataType(configuration).getCastTypeName(); - } - - @Override - public final Class getArrayType() { - return arrayType; - } - - @Override - public final DataType getArrayDataType() { - return new ArrayDataType<>(this); - } - - @Override - public /* non-final */ Class getArrayComponentType() { - return null; - } - - @Override - public /* non-final */ DataType getArrayComponentDataType() { - return null; - } - - - - - - - - - - @SuppressWarnings("rawtypes") - @Override - public final DataType asEnumDataType(Class enumDataType) { - // TODO: Make EnumTypes implement Named - String enumTypeName = Tools.enums(enumDataType)[0].getName(); - return new DefaultDataType<>(dialect, (DataType) null, enumDataType, unquotedName(enumTypeName), enumTypeName, enumTypeName, precision, scale, length, nullability, (Field) defaultValue); - } - - @Override - public /* non-final */ DataType asConvertedDataType(Converter converter) { - return asConvertedDataType(DefaultBinding.newBinding(converter, this, null)); - } - - @SuppressWarnings("deprecation") - @Override - public /* non-final */ DataType asConvertedDataType(Binding newBinding) { - if (binding == newBinding) - return (DataType) this; - - if (newBinding == null) - newBinding = (Binding) DefaultBinding.binding(getType(), isLob()); - - return new ConvertedDataType<>(this, newBinding); + final Class tType0() { + return tType; } @Override @@ -888,28 +513,6 @@ public class DefaultDataType extends AbstractNamed implements DataType { return dialect; } - @Override - public /* final */ T convert(Object object) { - - // [#1441] Avoid unneeded type conversions to improve performance - if (object == null) - return null; - else if (object.getClass() == uType) - return (T) object; - else - return Convert.convert(object, uType); - } - - @Override - public final T[] convert(Object... objects) { - return (T[]) Convert.convertArray(objects, uType); - } - - @Override - public final List convert(Collection objects) { - return Convert.convert(objects, uType); - } - public static final DataType getDefaultDataType(String typeName) { return new DefaultDataType<>(SQLDialect.DEFAULT, Object.class, typeName, typeName); } @@ -1029,174 +632,6 @@ public class DefaultDataType extends AbstractNamed implements DataType { } } - @Override - public final boolean isNumeric() { - return Number.class.isAssignableFrom(tType) && !isInterval(); - } - - @Override - public final boolean isInteger() { - return UNumber.class.isAssignableFrom(tType) - || Byte.class == tType - || Short.class == tType - || Integer.class == tType - || Long.class == tType - ; - } - - @Override - public final boolean isString() { - return tType == String.class; - } - - @Override - public final boolean isDateTime() { - return java.util.Date.class.isAssignableFrom(tType) - - || java.time.temporal.Temporal.class.isAssignableFrom(tType) - - ; - } - - @Override - public final boolean isDate() { - return java.sql.Date.class.isAssignableFrom(tType) - - || java.time.LocalDate.class.isAssignableFrom(tType) - - ; - } - - @Override - public final boolean isTimestamp() { - return java.sql.Timestamp.class.isAssignableFrom(tType) - - || java.time.LocalDateTime.class.isAssignableFrom(tType) - - ; - } - - @Override - public final boolean isTime() { - return java.sql.Time.class.isAssignableFrom(tType) - - || java.time.LocalTime.class.isAssignableFrom(tType) - - ; - } - - @Override - public final boolean isTemporal() { - return isDateTime() || isInterval(); - } - - @Override - public final boolean isInterval() { - return Interval.class.isAssignableFrom(tType); - } - - @Override - public final boolean isLob() { - DataType t = getSQLDataType(); - - if (t == this) - return getTypeName().endsWith("lob"); - else - return (t == BLOB || t == CLOB || t == NCLOB); - } - - @Override - public final boolean isBinary() { - return tType == byte[].class; - } - - @Override - public final boolean isArray() { - return - (!isBinary() && tType.isArray()); - } - - @Override - public final boolean isUDT() { - return UDTRecord.class.isAssignableFrom(tType); - } - - @Override - public final boolean isEnum() { - return EnumType.class.isAssignableFrom(tType); - } - - @Override - public final boolean isJSON() { - return tType == JSON.class || tType == JSONB.class; - } - - @Override - public final boolean isXML() { - return tType == XML.class; - } - - // ------------------------------------------------------------------------ - // The Object API - // ------------------------------------------------------------------------ - - @Override - public String toString() { - return getCastTypeName() + " (" + uType.getName() + ")"; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((dialect == null) ? 0 : dialect.hashCode()); - result = prime * result + length(); - result = prime * result + precision(); - result = prime * result + scale(); - result = prime * result + ((uType == null) ? 0 : uType.hashCode()); - result = prime * result + ((tType == null) ? 0 : tType.hashCode()); - result = prime * result + ((typeName == null) ? 0 : typeName.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - DefaultDataType other = (DefaultDataType) obj; - if (dialect != other.dialect) - return false; - if (!eq(length, other.length)) - return false; - if (!eq(precision, other.precision)) - return false; - if (!eq(scale, other.scale)) - return false; - if (uType == null) { - if (other.uType != null) - return false; - } - else if (!uType.equals(other.uType)) - return false; - if (tType == null) { - if (other.tType != null) - return false; - } - else if (!tType.equals(other.tType)) - return false; - if (typeName == null) { - if (other.typeName != null) - return false; - } - else if (!typeName.equals(other.typeName)) - return false; - return true; - } - /** * @return The type name without all special characters and white spaces */ @@ -1268,13 +703,4 @@ public class DefaultDataType extends AbstractNamed implements DataType { return d; } - - private static final boolean eq(Integer i1, Integer i2) { - return (i1 == i2) || (i1 != null && i2 != null && i1.intValue() == i2.intValue()); - } - - @Override - public final void accept(Context ctx) { - ctx.visit(getQualifiedName()); - } } diff --git a/jOOQ/src/main/java/org/jooq/impl/FieldProxy.java b/jOOQ/src/main/java/org/jooq/impl/FieldProxy.java index 167c4d8833..484a017f02 100644 --- a/jOOQ/src/main/java/org/jooq/impl/FieldProxy.java +++ b/jOOQ/src/main/java/org/jooq/impl/FieldProxy.java @@ -37,42 +37,20 @@ */ package org.jooq.impl; -import java.math.BigDecimal; -import java.util.Collection; -import java.util.Map; -import java.util.function.Function; - -import org.jooq.BetweenAndStep; -import org.jooq.BindContext; import org.jooq.Binding; +import org.jooq.CharacterSet; import org.jooq.Clause; import org.jooq.Collation; -import org.jooq.Comment; -import org.jooq.Comparator; -import org.jooq.Condition; import org.jooq.Configuration; import org.jooq.Context; -import org.jooq.Converter; import org.jooq.DataType; -import org.jooq.DatePart; import org.jooq.Field; -import org.jooq.LikeEscapeStep; import org.jooq.Name; -// ... -import org.jooq.QuantifiedSelect; -import org.jooq.QueryPartInternal; +import org.jooq.Nullability; import org.jooq.Record; -import org.jooq.Record1; -import org.jooq.RenderContext; -import org.jooq.Result; -import org.jooq.Select; -import org.jooq.SortField; -import org.jooq.SortOrder; +import org.jooq.SQLDialect; import org.jooq.Table; import org.jooq.TableField; -import org.jooq.WindowIgnoreNullsStep; -import org.jooq.WindowPartitionByStep; -import org.jooq.exception.DataAccessException; /** * A {@link Field} that acts as another field, allowing for the proxied field to @@ -81,36 +59,36 @@ import org.jooq.exception.DataAccessException; * @author Lukas Eder */ @SuppressWarnings("unchecked") -final class FieldProxy implements TableField, QueryPartInternal { +final class FieldProxy extends AbstractField implements TableField { /** * Generated UID */ private static final long serialVersionUID = 8311876498583467760L; - AbstractField delegate; - char[] sql; - int position; + private AbstractField delegate; + private int position; + + FieldProxy(AbstractField delegate, int position) { + super( + delegate.getQualifiedName(), + new DataTypeProxy<>((AbstractDataType) delegate.getDataType()), + delegate.getCommentPart(), + delegate.getBinding() + ); - FieldProxy(AbstractField delegate, char[] sql, int position) { this.delegate = delegate; - this.sql = sql; this.position = position; } - @Override - public final Converter getConverter() { - return delegate.getConverter(); + int position() { + return position; } - @Override - public final String getName() { - return delegate.getName(); - } + void delegate(AbstractField newDelegate) { + this.delegate = newDelegate; - @Override - public final Binding getBinding() { - return delegate.getBinding(); + ((DataTypeProxy) getDataType()).type = (AbstractDataType) newDelegate.getDataType(); } @Override @@ -118,51 +96,11 @@ final class FieldProxy implements TableField, QueryPartInternal { return delegate.getQualifiedName(); } - @Override - public final void toSQL(RenderContext context) { - delegate.toSQL(context); - } - - @Override - public final Class getType() { - return delegate.getType(); - } - - @Override - public final DataType getDataType() { - return delegate.getDataType(); - } - - @Override - public final Name getUnqualifiedName() { - return delegate.getUnqualifiedName(); - } - - @Override - public final DataType getDataType(Configuration configuration) { - return delegate.getDataType(configuration); - } - - @Override - public final String getComment() { - return delegate.getComment(); - } - - @Override - public final Comment getCommentPart() { - return delegate.getCommentPart(); - } - @Override public final int hashCode() { return delegate.hashCode(); } - @Override - public final void bind(BindContext context) throws DataAccessException { - delegate.bind(context); - } - @Override public final boolean equals(Object that) { return delegate.equals(that); @@ -208,1655 +146,127 @@ final class FieldProxy implements TableField, QueryPartInternal { return delegate.clauses(ctx); } - @Override - public final Field field(Record record) { - return delegate.field(record); - } - @Override public final String toString() { return delegate.toString(); } - @Override - public final T get(Record record) { - return delegate.get(record); - } - - @Override - public final T getValue(Record record) { - return delegate.getValue(record); - } - - @Override - public final T original(Record record) { - return delegate.original(record); - } - - @Override - public final boolean changed(Record record) { - return delegate.changed(record); - } - - @Override - public final void reset(Record record) { - delegate.reset(record); - } - - @Override - public final Record1 from(Record record) { - return delegate.from(record); - } - - @Override - public final Field as(String alias) { - return delegate.as(alias); - } - - @Override - public final Field as(Name alias) { - return delegate.as(alias); - } - - @Override - public final Field as(Field otherField) { - return delegate.as(otherField); - } - - - @Override - public final Field as(Function, ? extends String> aliasFunction) { - return delegate.as(aliasFunction); - } - - - @Override - public final Field cast(Field field) { - return delegate.cast(field); - } - - @Override - public final Field cast(DataType type) { - return delegate.cast(type); - } - - @Override - public final Field cast(Class type) { - return delegate.cast(type); - } - - @Override - public final Field coerce(Field field) { - return delegate.coerce(field); - } - - @Override - public final Field coerce(DataType type) { - return delegate.coerce(type); - } - - @Override - public final Field coerce(Class type) { - return delegate.coerce(type); - } - - @Override - public final SortField asc() { - return delegate.asc(); - } - - @Override - public final SortField desc() { - return delegate.desc(); - } - - @Override - public final SortField sortDefault() { - return delegate.sortDefault(); - } - - @Override - public final SortField sort(SortOrder order) { - return delegate.sort(order); - } - - @Override - public final SortField sortAsc(Collection sortList) { - return delegate.sortAsc(sortList); - } - - @Override - public final SortField sortAsc(T... sortList) { - return delegate.sortAsc(sortList); - } - - @Override - public final SortField sortDesc(Collection sortList) { - return delegate.sortDesc(sortList); - } - - @Override - public final SortField sortDesc(T... sortList) { - return delegate.sortDesc(sortList); - } - - @Override - public final SortField sort(Map sortMap) { - return delegate.sort(sortMap); - } - - @Override - public final Field neg() { - return delegate.neg(); - } - - @Override - public final Field unaryMinus() { - return delegate.unaryMinus(); - } - - @Override - public final Field unaryPlus() { - return delegate.unaryPlus(); - } - - @Override - public final Field add(Number value) { - return delegate.add(value); - } - - @Override - public final Field add(Field value) { - return delegate.add(value); - } - - @Override - public final Field sub(Number value) { - return delegate.sub(value); - } - - @Override - public final Field sub(Field value) { - return delegate.sub(value); - } - - @Override - public final Field mul(Number value) { - return delegate.mul(value); - } - - @Override - public final Field mul(Field value) { - return delegate.mul(value); - } - - @Override - public final Field div(Number value) { - return delegate.div(value); - } - - @Override - public final Field div(Field value) { - return delegate.div(value); - } - - @Override - public final Field mod(Number value) { - return delegate.mod(value); - } - - @Override - public final Field mod(Field value) { - return delegate.mod(value); - } - - @Override - public final Field plus(Number value) { - return delegate.plus(value); - } - - @Override - public final Field plus(Field value) { - return delegate.plus(value); - } - - @Override - public final Field subtract(Number value) { - return delegate.subtract(value); - } - - @Override - public final Field subtract(Field value) { - return delegate.subtract(value); - } - - @Override - public final Field minus(Number value) { - return delegate.minus(value); - } - - @Override - public final Field minus(Field value) { - return delegate.minus(value); - } - - @Override - public final Field multiply(Number value) { - return delegate.multiply(value); - } - - @Override - public final Field multiply(Field value) { - return delegate.multiply(value); - } - - @Override - public final Field times(Number value) { - return delegate.times(value); - } - - @Override - public final Field times(Field value) { - return delegate.times(value); - } - - @Override - public final Field divide(Number value) { - return delegate.divide(value); - } - - @Override - public final Field divide(Field value) { - return delegate.divide(value); - } - - @Override - public final Field modulo(Number value) { - return delegate.modulo(value); - } - - @Override - public final Field modulo(Field value) { - return delegate.modulo(value); - } - - @Override - public final Field rem(Number value) { - return delegate.rem(value); - } - - @Override - public final Field rem(Field value) { - return delegate.rem(value); - } - - @Override - public final Field bitNot() { - return delegate.bitNot(); - } - - @Override - public final Field bitAnd(T value) { - return delegate.bitAnd(value); - } - - @Override - public final Field bitAnd(Field value) { - return delegate.bitAnd(value); - } - - @Override - public final Field bitNand(T value) { - return delegate.bitNand(value); - } - - @Override - public final Field bitNand(Field value) { - return delegate.bitNand(value); - } - - @Override - public final Field bitOr(T value) { - return delegate.bitOr(value); - } - - @Override - public final Field bitOr(Field value) { - return delegate.bitOr(value); - } - - @Override - public final Field bitNor(T value) { - return delegate.bitNor(value); - } - - @Override - public final Field bitNor(Field value) { - return delegate.bitNor(value); - } - - @Override - public final Field bitXor(T value) { - return delegate.bitXor(value); - } - - @Override - public final Field bitXor(Field value) { - return delegate.bitXor(value); - } - - @Override - public final Field bitXNor(T value) { - return delegate.bitXNor(value); - } - - @Override - public final Field bitXNor(Field value) { - return delegate.bitXNor(value); - } - - @Override - public final Field shl(Number value) { - return delegate.shl(value); - } - - @Override - public final Field shl(Field value) { - return delegate.shl(value); - } - - @Override - public final Field shr(Number value) { - return delegate.shr(value); - } - - @Override - public final Field shr(Field value) { - return delegate.shr(value); - } - - @Override - public final Condition isDocument() { - return delegate.isDocument(); - } - - @Override - public final Condition isNotDocument() { - return delegate.isNotDocument(); - } - - @Override - public final Condition isJson() { - return delegate.isJson(); - } - - @Override - public final Condition isNotJson() { - return delegate.isNotJson(); - } - - @Override - public final Condition isNull() { - return delegate.isNull(); - } - - @Override - public final Condition isNotNull() { - return delegate.isNotNull(); - } - - @Override - public final Condition isDistinctFrom(T value) { - return delegate.isDistinctFrom(value); - } - - @Override - public final Condition isDistinctFrom(Field field) { - return delegate.isDistinctFrom(field); - } - - @Override - public final Condition isDistinctFrom(Select> select) { - return delegate.isDistinctFrom(select); - } - - @Override - public final Condition isNotDistinctFrom(T value) { - return delegate.isNotDistinctFrom(value); - } - - @Override - public final Condition isNotDistinctFrom(Field field) { - return delegate.isNotDistinctFrom(field); - } - - @Override - public final Condition isNotDistinctFrom(Select> select) { - return delegate.isNotDistinctFrom(select); - } - - @Override - public final Condition isTrue() { - return delegate.isTrue(); - } - - @Override - public final Condition isFalse() { - return delegate.isFalse(); - } - - @Override - public final LikeEscapeStep similarTo(String value) { - return delegate.similarTo(value); - } - - @Override - public final Condition similarTo(String value, char escape) { - return delegate.similarTo(value, escape); - } - - @Override - public final LikeEscapeStep similarTo(Field field) { - return delegate.similarTo(field); - } - - @Override - public final Condition similarTo(Field field, char escape) { - return delegate.similarTo(field, escape); - } - - @Override - public final LikeEscapeStep notSimilarTo(String value) { - return delegate.notSimilarTo(value); - } - - @Override - public final Condition notSimilarTo(String value, char escape) { - return delegate.notSimilarTo(value, escape); - } - - @Override - public final LikeEscapeStep notSimilarTo(Field field) { - return delegate.notSimilarTo(field); - } - - @Override - public final Condition notSimilarTo(Field field, char escape) { - return delegate.notSimilarTo(field, escape); - } - - @Override - public final LikeEscapeStep like(String value) { - return delegate.like(value); - } - - @Override - public final Condition like(String value, char escape) { - return delegate.like(value, escape); - } - - @Override - public final LikeEscapeStep like(Field field) { - return delegate.like(field); - } - - @Override - public final Condition like(Field field, char escape) { - return delegate.like(field, escape); - } - - @Override - public final LikeEscapeStep like(QuantifiedSelect> query) { - return delegate.like(query); - } - - @Override - public final LikeEscapeStep likeIgnoreCase(String value) { - return delegate.likeIgnoreCase(value); - } - - @Override - public final Condition likeIgnoreCase(String value, char escape) { - return delegate.likeIgnoreCase(value, escape); - } - - @Override - public final LikeEscapeStep likeIgnoreCase(Field field) { - return delegate.likeIgnoreCase(field); - } - - @Override - public final Condition likeIgnoreCase(Field field, char escape) { - return delegate.likeIgnoreCase(field, escape); - } - - @Override - public final Condition likeRegex(String pattern) { - return delegate.likeRegex(pattern); - } - - @Override - public final Condition likeRegex(Field pattern) { - return delegate.likeRegex(pattern); - } - - @Override - public final LikeEscapeStep notLike(String value) { - return delegate.notLike(value); - } - - @Override - public final Condition notLike(String value, char escape) { - return delegate.notLike(value, escape); - } - - @Override - public final LikeEscapeStep notLike(Field field) { - return delegate.notLike(field); - } - - @Override - public final Condition notLike(Field field, char escape) { - return delegate.notLike(field, escape); - } - - @Override - public final LikeEscapeStep notLike(QuantifiedSelect> query) { - return delegate.notLike(query); - } - - @Override - public final LikeEscapeStep notLikeIgnoreCase(String value) { - return delegate.notLikeIgnoreCase(value); - } - - @Override - public final Condition notLikeIgnoreCase(String value, char escape) { - return delegate.notLikeIgnoreCase(value, escape); - } - - @Override - public final LikeEscapeStep notLikeIgnoreCase(Field field) { - return delegate.notLikeIgnoreCase(field); - } - - @Override - public final Condition notLikeIgnoreCase(Field field, char escape) { - return delegate.notLikeIgnoreCase(field, escape); - } - - @Override - public final Condition notLikeRegex(String pattern) { - return delegate.notLikeRegex(pattern); - } - - @Override - public final Condition notLikeRegex(Field pattern) { - return delegate.notLikeRegex(pattern); - } - - @Override - public final Condition contains(T value) { - return delegate.contains(value); - } - - @Override - public final Condition contains(Field value) { - return delegate.contains(value); - } - - @Override - public final Condition notContains(T value) { - return delegate.notContains(value); - } - - @Override - public final Condition notContains(Field value) { - return delegate.notContains(value); - } - - @Override - public final Condition containsIgnoreCase(T value) { - return delegate.containsIgnoreCase(value); - } - - @Override - public final Condition containsIgnoreCase(Field value) { - return delegate.containsIgnoreCase(value); - } - - @Override - public final Condition notContainsIgnoreCase(T value) { - return delegate.notContainsIgnoreCase(value); - } - - @Override - public final Condition notContainsIgnoreCase(Field value) { - return delegate.notContainsIgnoreCase(value); - } - - @Override - public final Condition startsWith(T value) { - return delegate.startsWith(value); - } - - @Override - public final Condition startsWith(Field value) { - return delegate.startsWith(value); - } - - @Override - public final Condition startsWithIgnoreCase(T value) { - return delegate.startsWithIgnoreCase(value); - } - - @Override - public final Condition startsWithIgnoreCase(Field value) { - return delegate.startsWithIgnoreCase(value); - } - - @Override - public final Condition endsWith(T value) { - return delegate.endsWith(value); - } - - @Override - public final Condition endsWith(Field value) { - return delegate.endsWith(value); - } - - @Override - public final Condition endsWithIgnoreCase(T value) { - return delegate.endsWithIgnoreCase(value); - } - - @Override - public final Condition endsWithIgnoreCase(Field value) { - return delegate.endsWithIgnoreCase(value); - } - - @Override - public final Condition in(T... values) { - return delegate.in(values); - } - - @Override - public final Condition in(Field... values) { - return delegate.in(values); - } - - @Override - public final Condition in(Collection values) { - return delegate.in(values); - } - - @Override - public final Condition in(Result> result) { - return delegate.in(result); - } - - @Override - public final Condition in(Select> query) { - return delegate.in(query); - } - - @Override - public final Condition notIn(T... values) { - return delegate.notIn(values); - } - - @Override - public final Condition notIn(Field... values) { - return delegate.notIn(values); - } - - @Override - public final Condition notIn(Collection values) { - return delegate.notIn(values); - } - - @Override - public final Condition notIn(Result> result) { - return delegate.notIn(result); - } - - @Override - public final Condition notIn(Select> query) { - return delegate.notIn(query); - } - - @Override - public final Condition between(T minValue, T maxValue) { - return delegate.between(minValue, maxValue); - } - - @Override - public final Condition between(Field minValue, Field maxValue) { - return delegate.between(minValue, maxValue); - } - - @Override - public final Condition betweenSymmetric(T minValue, T maxValue) { - return delegate.betweenSymmetric(minValue, maxValue); - } - - @Override - public final Condition betweenSymmetric(Field minValue, Field maxValue) { - return delegate.betweenSymmetric(minValue, maxValue); - } - - @Override - public final Condition notBetween(T minValue, T maxValue) { - return delegate.notBetween(minValue, maxValue); - } - - @Override - public final Condition notBetween(Field minValue, Field maxValue) { - return delegate.notBetween(minValue, maxValue); - } - - @Override - public final Condition notBetweenSymmetric(T minValue, T maxValue) { - return delegate.notBetweenSymmetric(minValue, maxValue); - } - - @Override - public final Condition notBetweenSymmetric(Field minValue, Field maxValue) { - return delegate.notBetweenSymmetric(minValue, maxValue); - } - - @Override - public final BetweenAndStep between(T minValue) { - return delegate.between(minValue); - } - - @Override - public final BetweenAndStep between(Field minValue) { - return delegate.between(minValue); - } - - @Override - public final BetweenAndStep betweenSymmetric(T minValue) { - return delegate.betweenSymmetric(minValue); - } - - @Override - public final BetweenAndStep betweenSymmetric(Field minValue) { - return delegate.betweenSymmetric(minValue); - } - - @Override - public final BetweenAndStep notBetween(T minValue) { - return delegate.notBetween(minValue); - } - - @Override - public final BetweenAndStep notBetween(Field minValue) { - return delegate.notBetween(minValue); - } - - @Override - public final BetweenAndStep notBetweenSymmetric(T minValue) { - return delegate.notBetweenSymmetric(minValue); - } - - @Override - public final BetweenAndStep notBetweenSymmetric(Field minValue) { - return delegate.notBetweenSymmetric(minValue); - } - - @Override - public final Condition eq(T value) { - return delegate.eq(value); - } - - @Override - public final Condition eq(Field field) { - return delegate.eq(field); - } - - @Override - public final Condition eq(Select> query) { - return delegate.eq(query); - } - - @Override - public final Condition eq(QuantifiedSelect> query) { - return delegate.eq(query); - } - - @Override - public final Condition ne(T value) { - return delegate.ne(value); - } - - @Override - public final Condition ne(Field field) { - return delegate.ne(field); - } - - @Override - public final Condition ne(Select> query) { - return delegate.ne(query); - } - - @Override - public final Condition ne(QuantifiedSelect> query) { - return delegate.ne(query); - } - - @Override - public final Condition lt(T value) { - return delegate.lt(value); - } - - @Override - public final Condition lt(Field field) { - return delegate.lt(field); - } - - @Override - public final Condition lt(Select> query) { - return delegate.lt(query); - } - - @Override - public final Condition lt(QuantifiedSelect> query) { - return delegate.lt(query); - } - - @Override - public final Condition le(T value) { - return delegate.le(value); - } - - @Override - public final Condition le(Field field) { - return delegate.le(field); - } - - @Override - public final Condition le(Select> query) { - return delegate.le(query); - } - - @Override - public final Condition le(QuantifiedSelect> query) { - return delegate.le(query); - } - - @Override - public final Condition gt(T value) { - return delegate.gt(value); - } - - @Override - public final Condition gt(Field field) { - return delegate.gt(field); - } - - @Override - public final Condition gt(Select> query) { - return delegate.gt(query); - } - - @Override - public final Condition gt(QuantifiedSelect> query) { - return delegate.gt(query); - } - - @Override - public final Condition ge(T value) { - return delegate.ge(value); - } - - @Override - public final Condition ge(Field field) { - return delegate.ge(field); - } - - @Override - public final Condition ge(Select> query) { - return delegate.ge(query); - } - - @Override - public final Condition ge(QuantifiedSelect> query) { - return delegate.ge(query); - } - - @Override - public final Condition equal(T value) { - return delegate.equal(value); - } - - @Override - public final Condition equal(Field field) { - return delegate.equal(field); - } - - @Override - public final Condition equalIgnoreCase(String value) { - return delegate.equalIgnoreCase(value); - } - - @Override - public final Condition equalIgnoreCase(Field value) { - return delegate.equalIgnoreCase(value); - } - - @Override - public final Condition equal(Select> query) { - return delegate.equal(query); - } - - @Override - public final Condition equal(QuantifiedSelect> query) { - return delegate.equal(query); - } - - @Override - public final Condition notEqual(T value) { - return delegate.notEqual(value); - } - - @Override - public final Condition notEqual(Field field) { - return delegate.notEqual(field); - } - - @Override - public final Condition notEqualIgnoreCase(String value) { - return delegate.notEqualIgnoreCase(value); - } - - @Override - public final Condition notEqualIgnoreCase(Field value) { - return delegate.notEqualIgnoreCase(value); - } - - @Override - public final Condition notEqual(Select> query) { - return delegate.notEqual(query); - } - - @Override - public final Condition notEqual(QuantifiedSelect> query) { - return delegate.notEqual(query); - } - - @Override - public final Condition lessThan(T value) { - return delegate.lessThan(value); - } - - @Override - public final Condition lessThan(Field field) { - return delegate.lessThan(field); - } - - @Override - public final Condition lessThan(Select> query) { - return delegate.lessThan(query); - } - - @Override - public final Condition lessThan(QuantifiedSelect> query) { - return delegate.lessThan(query); - } - - @Override - public final Condition lessOrEqual(T value) { - return delegate.lessOrEqual(value); - } - - @Override - public final Condition lessOrEqual(Field field) { - return delegate.lessOrEqual(field); - } - - @Override - public final Condition lessOrEqual(Select> query) { - return delegate.lessOrEqual(query); - } - - @Override - public final Condition lessOrEqual(QuantifiedSelect> query) { - return delegate.lessOrEqual(query); - } - - @Override - public final Condition greaterThan(T value) { - return delegate.greaterThan(value); - } - - @Override - public final Condition greaterThan(Field field) { - return delegate.greaterThan(field); - } - - @Override - public final Condition greaterThan(Select> query) { - return delegate.greaterThan(query); - } - - @Override - public final Condition greaterThan(QuantifiedSelect> query) { - return delegate.greaterThan(query); - } - - @Override - public final Condition greaterOrEqual(T value) { - return delegate.greaterOrEqual(value); - } - - @Override - public final Condition greaterOrEqual(Field field) { - return delegate.greaterOrEqual(field); - } - - @Override - public final Condition greaterOrEqual(Select> query) { - return delegate.greaterOrEqual(query); - } - - @Override - public final Condition greaterOrEqual(QuantifiedSelect> query) { - return delegate.greaterOrEqual(query); - } - - @Override - public final Condition compare(Comparator comparator, T value) { - return delegate.compare(comparator, value); - } - - @Override - public final Condition compare(Comparator comparator, Field field) { - return delegate.compare(comparator, field); - } - - @Override - public final Condition compare(Comparator comparator, Select> query) { - return delegate.compare(comparator, query); - } - - @Override - public final Condition compare(Comparator comparator, QuantifiedSelect> query) { - return delegate.compare(comparator, query); - } - - - - - - - - - - - - @Override - public final Field sign() { - return delegate.sign(); - } - - @Override - public final Field abs() { - return delegate.abs(); - } - - @Override - public final Field round() { - return delegate.round(); - } - - @Override - public final Field round(int decimals) { - return delegate.round(decimals); - } - - @Override - public final Field floor() { - return delegate.floor(); - } - - @Override - public final Field ceil() { - return delegate.ceil(); - } - - @Override - public final Field sqrt() { - return delegate.sqrt(); - } - - @Override - public final Field exp() { - return delegate.exp(); - } - - @Override - public final Field ln() { - return delegate.ln(); - } - - @Override - public final Field log(int base) { - return delegate.log(base); - } - - @Override - public final Field pow(Number exponent) { - return delegate.pow(exponent); - } - - @Override - public final Field power(Number exponent) { - return delegate.power(exponent); - } - - @Override - public final Field pow(Field exponent) { - return delegate.pow(exponent); - } - - @Override - public final Field power(Field exponent) { - return delegate.power(exponent); - } - - @Override - public final Field acos() { - return delegate.acos(); - } - - @Override - public final Field asin() { - return delegate.asin(); - } - - @Override - public final Field atan() { - return delegate.atan(); - } - - @Override - public final Field atan2(Number y) { - return delegate.atan2(y); - } - - @Override - public final Field atan2(Field y) { - return delegate.atan2(y); - } - - @Override - public final Field cos() { - return delegate.cos(); - } - - @Override - public final Field sin() { - return delegate.sin(); - } - - @Override - public final Field tan() { - return delegate.tan(); - } - - @Override - public final Field cot() { - return delegate.cot(); - } - - @Override - public final Field sinh() { - return delegate.sinh(); - } - - @Override - public final Field cosh() { - return delegate.cosh(); - } - - @Override - public final Field tanh() { - return delegate.tanh(); - } - - @Override - public final Field coth() { - return delegate.coth(); - } - - @Override - public final Field deg() { - return delegate.deg(); - } - - @Override - public final Field rad() { - return delegate.rad(); - } - - @Override - public final Field count() { - return delegate.count(); - } - - @Override - public final Field countDistinct() { - return delegate.countDistinct(); - } - - @Override - public final Field max() { - return delegate.max(); - } - - @Override - public final Field min() { - return delegate.min(); - } - - @Override - public final Field sum() { - return delegate.sum(); - } - - @Override - public final Field avg() { - return delegate.avg(); - } - - @Override - public final Field median() { - return delegate.median(); - } - - @Override - public final Field stddevPop() { - return delegate.stddevPop(); - } - - @Override - public final Field stddevSamp() { - return delegate.stddevSamp(); - } - - @Override - public final Field varPop() { - return delegate.varPop(); - } - - @Override - public final Field varSamp() { - return delegate.varSamp(); - } - - @Override - public final WindowPartitionByStep countOver() { - return delegate.countOver(); - } - - @Override - public final WindowPartitionByStep maxOver() { - return delegate.maxOver(); - } - - @Override - public final WindowPartitionByStep minOver() { - return delegate.minOver(); - } - - @Override - public final WindowPartitionByStep sumOver() { - return delegate.sumOver(); - } - - @Override - public final WindowPartitionByStep avgOver() { - return delegate.avgOver(); - } - - @Override - public final WindowIgnoreNullsStep firstValue() { - return delegate.firstValue(); - } - - @Override - public final WindowIgnoreNullsStep lastValue() { - return delegate.lastValue(); - } - - @Override - public final WindowIgnoreNullsStep lead() { - return delegate.lead(); - } - - @Override - public final WindowIgnoreNullsStep lead(int offset) { - return delegate.lead(offset); - } - - @Override - public final WindowIgnoreNullsStep lead(int offset, T defaultValue) { - return delegate.lead(offset, defaultValue); - } - - @Override - public final WindowIgnoreNullsStep lead(int offset, Field defaultValue) { - return delegate.lead(offset, defaultValue); - } - - @Override - public final WindowIgnoreNullsStep lag() { - return delegate.lag(); - } - - @Override - public final WindowIgnoreNullsStep lag(int offset) { - return delegate.lag(offset); - } - - @Override - public final WindowIgnoreNullsStep lag(int offset, T defaultValue) { - return delegate.lag(offset, defaultValue); - } - - @Override - public final WindowIgnoreNullsStep lag(int offset, Field defaultValue) { - return delegate.lag(offset, defaultValue); - } - - @Override - public final WindowPartitionByStep stddevPopOver() { - return delegate.stddevPopOver(); - } - - @Override - public final WindowPartitionByStep stddevSampOver() { - return delegate.stddevSampOver(); - } - - @Override - public final WindowPartitionByStep varPopOver() { - return delegate.varPopOver(); - } - - @Override - public final WindowPartitionByStep varSampOver() { - return delegate.varSampOver(); - } - - @Override - public final Field upper() { - return delegate.upper(); - } - - @Override - public final Field lower() { - return delegate.lower(); - } - - @Override - public final Field trim() { - return delegate.trim(); - } - - @Override - public final Field rtrim() { - return delegate.rtrim(); - } - - @Override - public final Field ltrim() { - return delegate.ltrim(); - } - - @Override - public final Field rpad(Field length) { - return delegate.rpad(length); - } - - @Override - public final Field rpad(int length) { - return delegate.rpad(length); - } - - @Override - public final Field rpad(Field length, Field character) { - return delegate.rpad(length, character); - } - - @Override - public final Field rpad(int length, char character) { - return delegate.rpad(length, character); - } - - @Override - public final Field lpad(Field length) { - return delegate.lpad(length); - } - - @Override - public final Field lpad(int length) { - return delegate.lpad(length); - } - - @Override - public final Field lpad(Field length, Field character) { - return delegate.lpad(length, character); - } - - @Override - public final Field lpad(int length, char character) { - return delegate.lpad(length, character); - } - - @Override - public final Field repeat(Number count) { - return delegate.repeat(count); - } - - @Override - public final Field repeat(Field count) { - return delegate.repeat(count); - } - - @Override - public final Field replace(Field search) { - return delegate.replace(search); - } - - @Override - public final Field replace(String search) { - return delegate.replace(search); - } - - @Override - public final Field replace(Field search, Field replace) { - return delegate.replace(search, replace); - } - - @Override - public final Field replace(String search, String replace) { - return delegate.replace(search, replace); - } - - @Override - public final Field position(String search) { - return delegate.position(search); - } - - @Override - public final Field position(Field search) { - return delegate.position(search); - } - - @Override - public final Field ascii() { - return delegate.ascii(); - } - - @Override - public final Field collate(String collation) { - return delegate.collate(collation); - } - - @Override - public final Field collate(Name collation) { - return delegate.collate(collation); - } - - @Override - public final Field collate(Collation collation) { - return delegate.collate(collation); - } - - @Override - public final Field concat(Field... fields) { - return delegate.concat(fields); - } - - @Override - public final Field concat(String... values) { - return delegate.concat(values); - } - - @Override - public final Field concat(char... values) { - return delegate.concat(values); - } - - @Override - public final Field substring(int startingPosition) { - return delegate.substring(startingPosition); - } - - @Override - public final Field substring(Field startingPosition) { - return delegate.substring(startingPosition); - } - - @Override - public final Field substring(int startingPosition, int length) { - return delegate.substring(startingPosition, length); - } - - @Override - public final Field substring(Field startingPosition, Field length) { - return delegate.substring(startingPosition, length); - } - - @Override - public final Field length() { - return delegate.length(); - } - - @Override - public final Field charLength() { - return delegate.charLength(); - } - - @Override - public final Field bitLength() { - return delegate.bitLength(); - } - - @Override - public final Field octetLength() { - return delegate.octetLength(); - } - - @Override - public final Field extract(DatePart datePart) { - return delegate.extract(datePart); - } - - @Override - public final Field greatest(T... others) { - return delegate.greatest(others); - } - - @Override - public final Field greatest(Field... others) { - return delegate.greatest(others); - } - - @Override - public final Field least(T... others) { - return delegate.least(others); - } - - @Override - public final Field least(Field... others) { - return delegate.least(others); - } - - @Override - public final Field nvl(T defaultValue) { - return delegate.nvl(defaultValue); - } - - @Override - public final Field nvl(Field defaultValue) { - return delegate.nvl(defaultValue); - } - - @Override - public final Field nvl2(Z valueIfNotNull, Z valueIfNull) { - return delegate.nvl2(valueIfNotNull, valueIfNull); - } - - @Override - public final Field nvl2(Field valueIfNotNull, Field valueIfNull) { - return delegate.nvl2(valueIfNotNull, valueIfNull); - } - - @Override - public final Field nullif(T other) { - return delegate.nullif(other); - } - - @Override - public final Field nullif(Field other) { - return delegate.nullif(other); - } - - @Override - public final Field decode(T search, Z result) { - return delegate.decode(search, result); - } - - @Override - public final Field decode(T search, Z result, Object... more) { - return delegate.decode(search, result, more); - } - - @Override - public final Field decode(Field search, Field result) { - return delegate.decode(search, result); - } - - @Override - public final Field decode(Field search, Field result, Field... more) { - return delegate.decode(search, result, more); - } - - @Override - public final Field coalesce(T option, T... options) { - return delegate.coalesce(option, options); - } - - @Override - public final Field coalesce(Field option, Field... options) { - return delegate.coalesce(option, options); - } - @Override public final Table getTable() { return delegate instanceof TableField ? ((TableField) delegate).getTable() : null; } + + private static class DataTypeProxy extends AbstractDataType { + + /** + * Generated UID + */ + private static final long serialVersionUID = -5283787691586689803L; + AbstractDataType type; + + DataTypeProxy(AbstractDataType type) { + super(type.getQualifiedName(), type.getCommentPart()); + + this.type = type; + } + + @Override + public final DataType getSQLDataType() { + return type.getSQLDataType(); + } + + @Override + public final DataType getDataType(Configuration configuration) { + return type.getDataType(configuration); + } + + @Override + public final Binding getBinding() { + return type.getBinding(); + } + + @Override + public final Class getType() { + return type.getType(); + } + + @Override + public final SQLDialect getDialect() { + return type.getDialect(); + } + + @Override + public final Nullability nullability() { + return type.nullability(); + } + + @Override + public final Collation collation() { + return type.collation(); + } + + @Override + public final CharacterSet characterSet() { + return type.characterSet(); + } + + @Override + public final boolean identity() { + return type.identity(); + } + + @Override + public final Field default_() { + return type.default_(); + } + + @Override + final AbstractDataType construct( + Integer newPrecision, + Integer newScale, + Integer newLength, + Nullability newNullability, + Collation newCollation, + CharacterSet newCharacterSet, + boolean newIdentity, + Field newDefaultValue + ) { + return type.construct(newPrecision, newScale, newLength, newNullability, newCollation, newCharacterSet, newIdentity, newDefaultValue); + } + + @Override + final String typeName0() { + return type.typeName0(); + } + + @Override + final String castTypeBase0() { + return type.castTypeBase0(); + } + + @Override + final String castTypeName0() { + return type.castTypeName0(); + } + + @Override + final Class tType0() { + return type.tType0(); + } + + @Override + final Integer precision0() { + return type.precision0(); + } + + @Override + final Integer scale0() { + return type.scale0(); + } + + @Override + final Integer length0() { + return type.length0(); + } + } } \ No newline at end of file diff --git a/jOOQ/src/main/java/org/jooq/impl/ParserImpl.java b/jOOQ/src/main/java/org/jooq/impl/ParserImpl.java index dca6e8eba1..f51bc4524f 100644 --- a/jOOQ/src/main/java/org/jooq/impl/ParserImpl.java +++ b/jOOQ/src/main/java/org/jooq/impl/ParserImpl.java @@ -12251,7 +12251,7 @@ final class ParserContext { Field f2; if ((f2 = t.field(f.getName())) != null) { if (f1 != null) { - position(f.position); + position(f.position()); throw exception("Ambiguous field identifier"); } @@ -12259,10 +12259,8 @@ final class ParserContext { } } - if (f1 != null) { - f.delegate = (AbstractField) f1; - f.sql = null; - } + if (f1 != null) + f.delegate((AbstractField) f1); else retain.add(f); } @@ -12289,7 +12287,7 @@ final class ParserContext { void unknownField(FieldProxy field) { if (!scopeClear && !metaLookupsForceIgnore && metaLookups == THROW_ON_FAILURE) { - position(field.position); + position(field.position()); throw exception("Unknown field identifier"); } } @@ -12335,7 +12333,7 @@ final class ParserContext { FieldProxy field = lookupFields.get(name.last()); if (field == null) - lookupFields.set(name.last(), field = new FieldProxy<>((AbstractField) field(name), sql, position)); + lookupFields.set(name.last(), field = new FieldProxy<>((AbstractField) field(name), position)); return field; }