diff --git a/jOOQ-meta/src/main/java/org/jooq/util/AbstractTypedElementDefinition.java b/jOOQ-meta/src/main/java/org/jooq/util/AbstractTypedElementDefinition.java index 7dcabdc7b1..feeb546998 100644 --- a/jOOQ-meta/src/main/java/org/jooq/util/AbstractTypedElementDefinition.java +++ b/jOOQ-meta/src/main/java/org/jooq/util/AbstractTypedElementDefinition.java @@ -41,9 +41,14 @@ package org.jooq.util; +import static org.jooq.tools.Convert.convert; +import static org.jooq.tools.StringUtils.isEmpty; + import java.sql.Types; import java.util.ArrayList; import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import org.jooq.DataType; import org.jooq.exception.SQLDialectNotSupportedException; @@ -58,7 +63,8 @@ abstract class AbstractTypedElementDefinition extends AbstractDefinition implements TypedElementDefinition { - private static final JooqLogger log = JooqLogger.getLogger(AbstractTypedElementDefinition.class); + private static final JooqLogger log = JooqLogger.getLogger(AbstractTypedElementDefinition.class); + private static final Pattern LENGTH_PRECISION_SCALE_PATTERN = Pattern.compile("[\\w\\s]+(?:\\(\\s*?(\\d+)\\s*?\\)|\\(\\s*?(\\d+)\\s*?,\\s*?(\\d+)\\s*?\\))"); private final T container; private final DataTypeDefinition definedType; @@ -146,13 +152,25 @@ abstract class AbstractTypedElementDefinition log.info("Forcing type", child + " into " + type + (converter != null ? " using converter " + converter : "")); DataType forcedDataType = null; - String t = result.getType(); - int l = result.getLength(); - int p = result.getPrecision(); - int s = result.getScale(); boolean n = result.isNullable(); boolean d = result.isDefaulted(); + int l = 0; + int p = 0; + int s = 0; + + // [#2486] Allow users to override length, precision, and scale + Matcher matcher = LENGTH_PRECISION_SCALE_PATTERN.matcher(type); + if (matcher.find()) { + if (!isEmpty(matcher.group(1))) { + l = p = convert(matcher.group(1), int.class); + } + else { + p = convert(matcher.group(2), int.class); + s = convert(matcher.group(3), int.class); + } + } + try { forcedDataType = DefaultDataType.getDataType(db.getDialect(), type, p, s); } catch (SQLDialectNotSupportedException ignore) {} @@ -164,6 +182,10 @@ abstract class AbstractTypedElementDefinition // Other forced types are UDT's, enums, etc. else { + l = result.getLength(); + p = result.getPrecision(); + s = result.getScale(); + String t = result.getType(); result = new DefaultDataTypeDefinition(db, child.getSchema(), t, l, p, s, n, d, type, converter); } } diff --git a/jOOQ-test/pom.xml b/jOOQ-test/pom.xml index fff42428ab..17cf73ce40 100644 --- a/jOOQ-test/pom.xml +++ b/jOOQ-test/pom.xml @@ -46,6 +46,7 @@ + + DECIMAL + (?i:.*?\.t_2486\.(val1|val3|val5)) + + + + + DECIMAL(21, 4) + (?i:.*?\.t_2486\.(val2|val4|val6)) + + + + + DECIMAL(20) + (?i:.*?\.t_2486\.(val7|val8)) + + BOOLEAN (?i:(.*?.)?T_BOOLEANS.(VC|C|N)_BOOLEAN) @@ -3849,6 +3876,222 @@ xxxxxxxxxx + xxxxxxxxx + xxxxxxxxxxxxxxxxxxxxxxxxx + xxxxxxx + xxxxxxxxx + xxxxxxxx + xxxxxxxxxxxxxxxxxxxxxxxxxxx + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + + xxxxxxxxxxxx + xxxxxxxxxxx + xxxxxxxxxxxxxxxxxxxxxxxxxx + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + xxxxxxx + xxxxxxxxxxxxxxxxxxxxx + xxxxxxxx + + xxxxxxxxxxxxxxx + xxxxxx + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + xxxxxxxxxxxxxxxxxxxxxxxxxxxxx + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + xxxxxxx + xxxxxxxxxxx + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + xxxxxxxxxx + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + + xxxxxxxxxxxxx + xxxxxxxxxxxx + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + xxxxxxxxxxxxx + xxxxxxxxxxxx + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + xxxxxxxxxxxxx + xxxxxxxxxxxx + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + xxxxxxxxxxxxx + xxxxxxxxxxxx + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + xxxxxxxxxxxxx + xxxxxxxxxxxx + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + xxxxxxxxxxxxx + xxxxxxxxxxxx + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + xxxxxxxxxxxxx + xxxxxxxxxxxx + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + xxxxxxxxxxxxx + xxxxxxxxxxxxxx + + xxxxxxxxxxxxx + xxxxxxxxxxxx + xxxxxxxxxxxxxxxxxxxx + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + xxxxxxxxxxxxx + xxxxxxxxxxxx + xxxxxxxxxxxxxxxxx + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + xxxxxxxxxxxxx + + xxxx xxxxxxx xxxxx xx xxxxxxxx xxxxx xxxx xxxxxxxxx xxx + xxxxxxxxxxxx + xxxxxxxxxxxxxxxxxxxxxxxxxxxx + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + xxxxxxxxxxxxx + xxxxxxxxxxxx + xxxxxxxxxxxxxxxxxxxxxxxxxxxxx + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + xxxxxxxxxxxxx + xxxxxxxxxxxx + xxxxxxxxxxxxxxxxxxxxxxxxxxxx + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + xxxxxxxxxxxxx + xxxxxxxxxxxx + xxxxxxxxxxxxxxxxxxxxxxxxxxx + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + xxxxxxxxxxxxx + + xxxxxxxxxxxx + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + xxxxxxxxxxxxx + xxxxxxxxxxxx + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + xxxxxxxxxxxxx + xxxxxxxxxxxx + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + xxxxxxxxxxxxx + xxxxxxxxxxxx + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + xxxxxxxxxxxxx + xxxxxxxxxxxx + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + xxxxxxxxxxxxx + xxxxxxxxxxxx + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + xxxxxxxxxxxxx + xxxxxxxxxxxx + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + xxxxxxxxxxxxx + xxxxxxxxxxxxxx + xxxxxxxxxxx + xxxxxxxxxx + xxxxxxxxxxxxxxxxxxxxxxxxxxx + xxxxxxxxxxxxxxxxxxxxxxxxxxxxx + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + xxxxxxxxxxxxxxxxxxxxxxx + xxxxxxxxxxxxxxxxxxxx + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + xxxxxxxxxxx + xxxxxxxx + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + xxxxxxxxx + xxxxxxxxxxxx + xxxxxxxxxxxxxxxx + xxxxxxxxxxxx + xxxxxxxxxxxxx + xxxxxxxxxxxxxx + xxxxxxxxxxxx + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + xxxxxxxxxxxxxxxxxxxxx + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + xxxxxxxxxxxxx + xxxxxxxxxxxxxxx + xxxxxxxxx + xxxxxxxxxx + xxxxxxxx + xxxxxxxxxx + + + + + xxxxxxxxx + xxxxxxxxxxxxxxxxxxxxxxxxxxxxx + xxxxxxx + xxxxxxxxx + xxxxxxxx + xxxxxxxxxxxxxxxxxxxxxxxxxxx + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + + xxxxxxxxxxxx + xxxxxxxxxxx + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + xxxxxxx + xxxxxxxxxxxxxxxxxxxxx + xxxxxxxx + + xxxxxxxxxxxxxxx + xxxxxx + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + xxxxxxxxxxxxxxxxxxxxxxxxxxxxx + xxxxxxxxxxxxxxxxxxxxxxxxx + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + xxxxxxx + xxxxxxxxxxx + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + xxxxxxxxxx + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + xxxxxxxxxxx + xxxxxxxxxx + xxxxxxxxxxxxxxxxxxxxxxxxxxxx + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + xxxxxxxxxxxxxxxxxxxxxxxx + xxxxxxxxxxx + xxxxxxxx + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + xxxxxxxxx + xxxxxxxxxxxx + xxxxxxxxxxxxxxxx + xxxxxxxxxxxx + xxxxxxxxxxxxx + xxxxxxxxxxxxxx + xxxxxxxxxxxx + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + xxxxxxxxxxxxxxxxxxxxx + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + xxxxxxxxxxxxx + xxxxxxxxxxxxxxx + xxxxxxxxx + xxxxxxxxxx + xxxxxxxx + xxxxxxxxxx + + xxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxx xxxxxxx diff --git a/jOOQ-test/src/main/resources/org/jooq/test/h2/create.sql b/jOOQ-test/src/main/resources/org/jooq/test/h2/create.sql index c72db1d782..b3d29a5d81 100644 --- a/jOOQ-test/src/main/resources/org/jooq/test/h2/create.sql +++ b/jOOQ-test/src/main/resources/org/jooq/test/h2/create.sql @@ -46,6 +46,7 @@ DROP TABLE IF EXISTS t_658_32/ DROP TABLE IF EXISTS t_725_lob_test/ DROP TABLE IF EXISTS t_785/ DROP TABLE IF EXISTS t_877/ +DROP TABLE IF EXISTS t_2486/ DROP TABLE IF EXISTS t_2698/ DROP TABLE IF EXISTS t_2718/ DROP TABLE IF EXISTS t_unsigned/ @@ -166,6 +167,18 @@ CREATE TABLE t_877 ( ) / +CREATE TABLE t_2486 ( + VAL1 DECIMAL(20), + VAL2 DECIMAL(20), + VAL3 DECIMAL(20, 5), + VAL4 DECIMAL(20, 5), + VAL5 VARCHAR(20), + VAL6 VARCHAR(20), + VAL7 DECIMAL(20, 5), + VAL8 DECIMAL +) +/ + CREATE TABLE t_2698 ( ID INT, XX INT DEFAULT -1 NOT NULL, diff --git a/jOOQ-test/src/test/java/org/jooq/test/H2Test.java b/jOOQ-test/src/test/java/org/jooq/test/H2Test.java index 546ca2a415..68f70c09c2 100644 --- a/jOOQ-test/src/test/java/org/jooq/test/H2Test.java +++ b/jOOQ-test/src/test/java/org/jooq/test/H2Test.java @@ -46,6 +46,7 @@ import static org.jooq.impl.DSL.count; import static org.jooq.impl.DSL.defaultValue; import static org.jooq.impl.DSL.select; import static org.jooq.impl.DSL.table; +import static org.jooq.test.h2.generatedclasses.Tables.T_2486; import static org.jooq.test.h2.generatedclasses.Tables.T_2698; import static org.jooq.test.h2.generatedclasses.Tables.T_639_NUMBERS_TABLE; import static org.jooq.test.h2.generatedclasses.Tables.T_725_LOB_TEST; @@ -124,6 +125,7 @@ import org.jooq.test.h2.generatedclasses.tables.records.TIdentityPkRecord; import org.jooq.test.h2.generatedclasses.tables.records.TIdentityRecord; import org.jooq.test.h2.generatedclasses.tables.records.TTriggersRecord; import org.jooq.test.h2.generatedclasses.tables.records.TUnsignedRecord; +import org.jooq.test.h2.generatedclasses.tables.records.T_2486Record; import org.jooq.test.h2.generatedclasses.tables.records.T_2698Record; import org.jooq.test.h2.generatedclasses.tables.records.T_639NumbersTableRecord; import org.jooq.test.h2.generatedclasses.tables.records.T_725LobTestRecord; @@ -1015,4 +1017,47 @@ public class H2Test extends jOOQAbstractTest< dao.deleteById(key2); assertNull(dao.findById(key2)); } + + @Test + @SuppressWarnings("unused") + public void testH2ForcedTypes2486() { + + // This should compile + TableField val1 = T_2486.VAL1; + TableField val2 = T_2486.VAL2; + TableField val3 = T_2486.VAL3; + TableField val4 = T_2486.VAL4; + TableField val5 = T_2486.VAL5; + TableField val6 = T_2486.VAL6; + TableField val7 = T_2486.VAL7; + TableField val8 = T_2486.VAL8; + + assertEquals(BigDecimal.class, T_2486.VAL1.getType()); + assertEquals(BigDecimal.class, T_2486.VAL2.getType()); + assertEquals(BigDecimal.class, T_2486.VAL3.getType()); + assertEquals(BigDecimal.class, T_2486.VAL4.getType()); + assertEquals(BigDecimal.class, T_2486.VAL5.getType()); + assertEquals(BigDecimal.class, T_2486.VAL6.getType()); + assertEquals(BigInteger.class, T_2486.VAL7.getType()); + assertEquals(BigInteger.class, T_2486.VAL8.getType()); + + assertEquals(0, T_2486.VAL1.getDataType().precision()); + assertEquals(21, T_2486.VAL2.getDataType().precision()); + assertEquals(0, T_2486.VAL3.getDataType().precision()); + assertEquals(21, T_2486.VAL4.getDataType().precision()); + assertEquals(0, T_2486.VAL5.getDataType().precision()); + assertEquals(21, T_2486.VAL6.getDataType().precision()); + assertEquals(20, T_2486.VAL7.getDataType().precision()); + assertEquals(20, T_2486.VAL8.getDataType().precision()); + + assertEquals(0, T_2486.VAL1.getDataType().scale()); + assertEquals(4, T_2486.VAL2.getDataType().scale()); + assertEquals(0, T_2486.VAL3.getDataType().scale()); + assertEquals(4, T_2486.VAL4.getDataType().scale()); + assertEquals(0, T_2486.VAL5.getDataType().scale()); + assertEquals(4, T_2486.VAL6.getDataType().scale()); + assertEquals(0, T_2486.VAL7.getDataType().scale()); + assertEquals(0, T_2486.VAL8.getDataType().scale()); + } + } diff --git a/jOOQ/src/main/java/org/jooq/impl/DefaultDataType.java b/jOOQ/src/main/java/org/jooq/impl/DefaultDataType.java index 080ce380db..f40ab53228 100644 --- a/jOOQ/src/main/java/org/jooq/impl/DefaultDataType.java +++ b/jOOQ/src/main/java/org/jooq/impl/DefaultDataType.java @@ -97,7 +97,7 @@ public class DefaultDataType implements DataType { /** * A pattern for data type name normalisation. */ - private static final Pattern NORMALISE_PATTERN = Pattern.compile("\"|\\.|\\s|\\(\\w+(,\\w+)*\\)|(NOT\\s*NULL)?"); + private static final Pattern NORMALISE_PATTERN = Pattern.compile("\"|\\.|\\s|\\(\\w+(\\s*,\\s*\\w+)*\\)|(NOT\\s*NULL)?"); /** * A pattern to be used to replace all precision, scale, and length