extends Serializable {
*/
String getCastTypeName(Configuration configuration);
- /**
- * Retrieve the dialect-specific type name associated with this data type
- * used for casting
- *
- * This is useful for some dialects that have specialised type names for
- * cast expressions. Other dialects require type-length binding when
- * casting, (e.g. VARCHAR(20))
- */
- String getCastTypeName(Configuration configuration, int length);
-
- /**
- * Retrieve the dialect-specific type name associated with this data type
- * used for casting
- *
- * This is useful for some dialects that have specialised type names for
- * cast expressions. Other dialects require type-length binding when
- * casting, (e.g. DECIMAL(20,5))
- */
- String getCastTypeName(Configuration configuration, int precision, int scale);
-
/**
* Retrieve the underlying {@link SQLDialect}
*/
diff --git a/jOOQ/src/main/java/org/jooq/impl/ConvertedDataType.java b/jOOQ/src/main/java/org/jooq/impl/ConvertedDataType.java
index 9105b097f6..a75767bc3e 100644
--- a/jOOQ/src/main/java/org/jooq/impl/ConvertedDataType.java
+++ b/jOOQ/src/main/java/org/jooq/impl/ConvertedDataType.java
@@ -78,11 +78,6 @@ class ConvertedDataType extends DefaultDataType {
return delegate.getCastTypeName(configuration);
}
- @Override
- public String getCastTypeName(Configuration configuration, int precision, int scale) {
- return delegate.getCastTypeName(configuration, precision, scale);
- }
-
@SuppressWarnings("unchecked")
@Override
public U convert(Object object) {
diff --git a/jOOQ/src/main/java/org/jooq/impl/DefaultDataType.java b/jOOQ/src/main/java/org/jooq/impl/DefaultDataType.java
index b13d3e626a..e2775e5d3d 100644
--- a/jOOQ/src/main/java/org/jooq/impl/DefaultDataType.java
+++ b/jOOQ/src/main/java/org/jooq/impl/DefaultDataType.java
@@ -92,6 +92,12 @@ public class DefaultDataType implements DataType {
*/
private static final Pattern NORMALISE_PATTERN = Pattern.compile("\"|\\.|\\s|\\(\\w+(,\\w+)*\\)|(NOT\\s*NULL)?");
+ /**
+ * A pattern to be used to replace all precision, scale, and length
+ * information
+ */
+ private static final Pattern TYPE_NAME_PATTERN = Pattern.compile("\\([^\\)]*\\)");
+
// -------------------------------------------------------------------------
// Data type caches
// -------------------------------------------------------------------------
@@ -168,6 +174,10 @@ public class DefaultDataType implements DataType {
* The type name used for casting to this type
*/
private final String castTypeName;
+ /**
+ * The type name used for casting to this type
+ */
+ private final String castTypeBase;
/**
* The type name
@@ -220,6 +230,7 @@ public class DefaultDataType implements DataType {
this.type = type;
this.typeName = typeName;
this.castTypeName = castTypeName;
+ this.castTypeBase = TYPE_NAME_PATTERN.matcher(castTypeName).replaceAll("").trim();
this.arrayType = (Class) Array.newInstance(type, 0).getClass();
if (type == Long.class || type == ULong.class) {
@@ -270,11 +281,15 @@ public class DefaultDataType implements DataType {
@Override
public final DataType precision(int p) {
- if (hasPrecision()) {
+ if (precision == p) {
+ return this;
+ }
+ else if (hasPrecision()) {
return new DefaultDataType(dialect, sqlDataType, type, typeName, castTypeName, p, scale, length);
}
-
- return this;
+ else {
+ return this;
+ }
}
@Override
@@ -289,11 +304,15 @@ public class DefaultDataType implements DataType {
@Override
public final DataType scale(int s) {
- if (hasScale()) {
+ if (scale == s) {
+ return this;
+ }
+ else if (hasScale()) {
return new DefaultDataType(dialect, sqlDataType, type, typeName, castTypeName, precision, s, length);
}
-
- return this;
+ else {
+ return this;
+ }
}
@Override
@@ -308,11 +327,15 @@ public class DefaultDataType implements DataType {
@Override
public final DataType length(int l) {
- if (hasLength()) {
+ if (length == l) {
+ return this;
+ }
+ else if (hasLength()) {
return new DefaultDataType(dialect, sqlDataType, type, typeName, castTypeName, precision, scale, l);
}
-
- return this;
+ else {
+ return this;
+ }
}
@Override
@@ -322,16 +345,7 @@ public class DefaultDataType implements DataType {
@Override
public final boolean hasLength() {
- return sqlDataType == SQLDataType.BINARY
- || sqlDataType == SQLDataType.BIT
- || sqlDataType == SQLDataType.CHAR
- || sqlDataType == SQLDataType.LONGNVARCHAR
- || sqlDataType == SQLDataType.LONGVARBINARY
- || sqlDataType == SQLDataType.LONGVARCHAR
- || sqlDataType == SQLDataType.NCHAR
- || sqlDataType == SQLDataType.NVARCHAR
- || sqlDataType == SQLDataType.VARBINARY
- || sqlDataType == SQLDataType.VARCHAR;
+ return type == byte[].class || type == String.class;
}
@Override
@@ -345,7 +359,10 @@ public class DefaultDataType implements DataType {
// If this is a SQLDataType find the most suited dialect-specific
// data type
if (getDialect() == null) {
- DataType> dataType = TYPES_BY_SQL_DATATYPE[configuration.getDialect().ordinal()].get(this);
+
+ // Be sure to reset length, precision, and scale, as those values
+ // were not registered in the below cache
+ DataType> dataType = TYPES_BY_SQL_DATATYPE[configuration.getDialect().ordinal()].get(length(0).precision(0).scale(0));
if (dataType != null) {
return (DataType) dataType;
@@ -475,41 +492,20 @@ public class DefaultDataType implements DataType {
@Override
public final String getCastTypeName() {
- return castTypeName;
- }
-
- @Override
- public /* final */ String getCastTypeName(Configuration configuration, int length) {
- String result = getCastTypeName(configuration);
-
- if (length != 0) {
-
- // Remove existing length information, first
- result = result.replaceAll("\\([^\\)]*\\)", "");
- result += "(" + length + ")";
+ if (length != 0 && hasLength()) {
+ return castTypeBase + "(" + length + ")";
}
-
- return result;
- }
-
- @Override
- public /* final */ String getCastTypeName(Configuration configuration, int precision, int scale) {
- String result = getCastTypeName(configuration);
-
- if (precision != 0) {
-
- // Remove existing precision / scale information, first
- result = result.replaceAll("\\([^\\)]*\\)", "");
-
- if (scale != 0) {
- result += "(" + precision + ", " + scale + ")";
+ else if (precision != 0 && hasPrecision()) {
+ if (scale != 0 && hasScale()) {
+ return castTypeBase + "(" + precision + ", " + scale + ")";
}
else {
- result += "(" + precision + ")";
+ return castTypeBase + "(" + precision + ")";
}
}
-
- return result;
+ else {
+ return castTypeName;
+ }
}
@Override
@@ -696,6 +692,9 @@ public class DefaultDataType implements DataType {
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 + ((type == null) ? 0 : type.hashCode());
result = prime * result + ((typeName == null) ? 0 : typeName.hashCode());
return result;
@@ -712,6 +711,12 @@ public class DefaultDataType implements DataType {
DefaultDataType> other = (DefaultDataType>) obj;
if (dialect != other.dialect)
return false;
+ if (length != other.length)
+ return false;
+ if (precision != other.precision)
+ return false;
+ if (scale != other.scale)
+ return false;
if (type == null) {
if (other.type != null)
return false;
diff --git a/jOOQ/src/main/java/org/jooq/impl/Val.java b/jOOQ/src/main/java/org/jooq/impl/Val.java
index 96cba33d51..8634cce077 100644
--- a/jOOQ/src/main/java/org/jooq/impl/Val.java
+++ b/jOOQ/src/main/java/org/jooq/impl/Val.java
@@ -194,7 +194,8 @@ class Val extends AbstractField implements Param {
* Render the bind variable including a cast, if necessary
*/
private void toSQLCast(RenderContext context) {
- DataType type = getDataType(context).getSQLDataType();
+ DataType dataType = getDataType(context);
+ DataType type = dataType.getSQLDataType();
SQLDialect dialect = context.getDialect();
// [#822] Some RDBMS need precision / scale information on BigDecimals
@@ -209,7 +210,7 @@ class Val extends AbstractField implements Param {
precision = Math.min(precision, 18);
}
- toSQLCast(context, getDataType(context), precision, scale);
+ toSQLCast(context, dataType, 0, precision, scale);
}
// [#1028] Most databases don't know an OTHER type (except H2, HSQLDB).
@@ -217,7 +218,7 @@ class Val extends AbstractField implements Param {
// If the bind value is set, it can be used to derive the cast type
if (value != null) {
- toSQLCast(context, DefaultDataType.getDataType(dialect, value.getClass()), 0, 0);
+ toSQLCast(context, DefaultDataType.getDataType(dialect, value.getClass()), 0, 0, 0);
}
// [#632] [#722] Current integration tests show that Ingres and
@@ -229,7 +230,7 @@ class Val extends AbstractField implements Param {
// Derby and DB2 must have a type associated with NULL. Use VARCHAR
// as a workaround. That's probably not correct in all cases, though
else {
- toSQLCast(context, DefaultDataType.getDataType(dialect, String.class), 0, 0);
+ toSQLCast(context, DefaultDataType.getDataType(dialect, String.class), 0, 0, 0);
}
}
@@ -244,12 +245,12 @@ class Val extends AbstractField implements Param {
// [#1727] VARCHAR types should be cast to their actual lengths in some
// dialects
else if ((type == SQLDataType.VARCHAR || type == SQLDataType.CHAR) && asList(FIREBIRD).contains(dialect)) {
- toSQLCast(context, getDataType(context), getValueLength());
+ toSQLCast(context, dataType, getValueLength(), 0, 0);
}
// In all other cases, the bind variable can be cast normally
else {
- toSQLCast(context, getDataType(context), 0, 0);
+ toSQLCast(context, dataType, dataType.length(), dataType.precision(), dataType.scale());
}
}
@@ -275,19 +276,11 @@ class Val extends AbstractField implements Param {
}
}
- private void toSQLCast(RenderContext context, DataType> type, int length) {
+ private void toSQLCast(RenderContext context, DataType> type, int length, int precision, int scale) {
context.keyword("cast(");
toSQL(context, getValue(), getType());
context.keyword(" as ")
- .sql(type.getCastTypeName(context, length))
- .sql(")");
- }
-
- private void toSQLCast(RenderContext context, DataType> type, int precision, int scale) {
- context.keyword("cast(");
- toSQL(context, getValue(), getType());
- context.keyword(" as ")
- .sql(type.getCastTypeName(context, precision, scale))
+ .sql(type.length(length).precision(precision).scale(scale).getCastTypeName(context))
.sql(")");
}