[jOOQ/jOOQ#2500] Add support for the MySQL YEAR data type

- Added SQLDataType.YEAR
- Added parser support
- Added DDL support
- Added DefaultYearBinding
- Added CAST support
- Update Val::getJavaValueString
- Update DefaultRecordBinding
- Implement Convert logic (DefaultConverterProvider)
- Support MULTISET and ROW usage
This commit is contained in:
Lukas Eder 2023-01-19 14:10:11 +01:00
parent 8d6687bbac
commit 1bd9b56c32
16 changed files with 126 additions and 11 deletions

View File

@ -75,6 +75,7 @@ import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.OffsetDateTime;
import java.time.OffsetTime;
import java.time.Year;
import java.time.format.DateTimeParseException;
import java.time.temporal.Temporal;
import java.util.ArrayList;
@ -779,6 +780,9 @@ final class Convert {
if (wrapperFrom == Boolean.class)
return (U) (((Boolean) from) ? Long.valueOf(1L) : Long.valueOf(0L));
if (wrapperFrom == Year.class)
return (U) (Long) (long) ((Year) from).getValue();
if (java.util.Date.class.isAssignableFrom(fromClass))
return (U) Long.valueOf(((java.util.Date) from).getTime());
@ -916,6 +920,17 @@ final class Convert {
return null;
}
}
else if (toClass == Year.class) {
if (Number.class.isAssignableFrom(wrapperFrom))
return (U) Year.of((((Number) from).intValue()));
try {
return (U) Year.parse(from.toString().trim());
}
catch (DateTimeParseException e) {
return null;
}
}
else if (wrapperTo == Boolean.class) {
String s = from.toString().toLowerCase().trim();

View File

@ -201,6 +201,7 @@ import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.OffsetDateTime;
import java.time.OffsetTime;
import java.time.Year;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
@ -473,6 +474,8 @@ public class DefaultBinding<T, U> implements Binding<T, U> {
return new DefaultYearToSecondBinding(dataType, converter);
else if (type == YearToMonth.class)
return new DefaultYearToMonthBinding(dataType, converter);
else if (type == Year.class)
return new DefaultYearBinding(dataType, converter);
// Subtypes of array types etc.
// The type byte[] is handled earlier. byte[][] can be handled here
@ -3991,6 +3994,8 @@ public class DefaultBinding<T, U> implements Binding<T, U> {
return converter.from((T) UUID.fromString(string), ctx.converterContext());
else if (type == XML.class)
return converter.from((T) XML.xml(string), ctx.converterContext());
else if (type == Year.class)
return converter.from((T) Year.parse(string), ctx.converterContext());
else if (type.isArray())
return converter.from((T) pgNewArray(ctx, field, type, string), ctx.converterContext());
@ -5735,6 +5740,48 @@ public class DefaultBinding<T, U> implements Binding<T, U> {
}
}
static final class DefaultYearBinding<U> extends InternalBinding<Year, U> {
DefaultYearBinding(DataType<Year> dataType, Converter<Year, U> converter) {
super(dataType, converter);
}
@Override
final void sqlInline0(BindingSQLContext<U> ctx, Year value) {
ctx.render().sql(value.getValue());
}
@Override
final void set0(BindingSetStatementContext<U> ctx, Year value) throws SQLException {
ctx.statement().setInt(ctx.index(), value.getValue());
}
@Override
final void set0(BindingSetSQLOutputContext<U> ctx, Year value) throws SQLException {
ctx.output().writeInt(value.getValue());
}
@Override
final Year get0(BindingGetResultSetContext<U> ctx) throws SQLException {
return wasNull(ctx.resultSet(), Year.of(ctx.resultSet().getInt(ctx.index())));
}
@Override
final Year get0(BindingGetStatementContext<U> ctx) throws SQLException {
return wasNull(ctx.statement(), Year.of(ctx.statement().getInt(ctx.index())));
}
@Override
final Year get0(BindingGetSQLInputContext<U> ctx) throws SQLException {
return wasNull(ctx.input(), Year.of(ctx.input().readInt()));
}
@Override
final int sqltype(Statement statement, Configuration configuration) {
return Types.SMALLINT;
}
}
static final class DefaultYearToMonthBinding<U> extends InternalBinding<YearToMonth, U> {
private static final Set<SQLDialect> REQUIRE_PG_INTERVAL = SQLDialect.supportedBy(POSTGRES, YUGABYTEDB);
private static final Set<SQLDialect> REQUIRE_STANDARD_INTERVAL = SQLDialect.supportedBy(H2);

View File

@ -458,6 +458,7 @@ import static org.jooq.impl.SQLDataType.TINYINT;
import static org.jooq.impl.SQLDataType.VARBINARY;
import static org.jooq.impl.SQLDataType.VARCHAR;
import static org.jooq.impl.SQLDataType.XML;
import static org.jooq.impl.SQLDataType.YEAR;
import static org.jooq.impl.SelectQueryImpl.EMULATE_SELECT_INTO_AS_CTAS;
import static org.jooq.impl.SelectQueryImpl.NO_SUPPORT_FOR_UPDATE_OF_FIELDS;
import static org.jooq.impl.Tools.CONFIG;
@ -8420,7 +8421,7 @@ final class DefaultParseContext extends AbstractScope implements ParseContext {
return field;
else if (parseFunctionNameIf("ADD_YEARS"))
return parseFieldAddDatePart(YEAR);
return parseFieldAddDatePart(DatePart.YEAR);
else if (parseFunctionNameIf("ADD_MONTHS"))
return parseFieldAddDatePart(MONTH);
else if (parseFunctionNameIf("ADD_DAYS"))
@ -12673,6 +12674,12 @@ final class DefaultParseContext extends AbstractScope implements ParseContext {
return SQLDataType.XML;
break;
case 'Y':
if (parseKeywordOrIdentifierIf("YEAR"))
return parseDataTypeLength(SQLDataType.YEAR);
break;
}
Name name;

View File

@ -82,6 +82,7 @@ import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.OffsetDateTime;
import java.time.OffsetTime;
import java.time.Year;
import java.time.ZonedDateTime;
import java.util.UUID;
@ -96,6 +97,7 @@ import org.jooq.Record;
import org.jooq.Result;
import org.jooq.RowId;
import org.jooq.SQLDialect;
import org.jooq.SQLDialectCategory;
import org.jooq.XML;
import org.jooq.types.DayToSecond;
import org.jooq.types.UByte;
@ -610,6 +612,14 @@ public final class SQLDataType {
return INSTANT.precision(precision);
}
/**
* A {@link Types#SMALLINT} type that represents a year.
* <p>
* While JDBC does not support this type, some dialects do, specifically
* those of the {@link SQLDialectCategory#MYSQL} category.
*/
public static final DataType<Year> YEAR = new BuiltInDataType<>(Year.class, "year");
// -------------------------------------------------------------------------
// Binary types
// -------------------------------------------------------------------------

View File

@ -62,6 +62,7 @@ import java.sql.Timestamp;
import java.time.Instant;
import java.time.OffsetDateTime;
import java.time.OffsetTime;
import java.time.Year;
import java.util.Arrays;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
@ -321,6 +322,8 @@ final class Val<T> extends AbstractParam<T> implements UEmpty {

View File

@ -72,6 +72,7 @@ import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.OffsetDateTime;
import java.time.OffsetTime;
import java.time.Year;
import java.time.format.DateTimeParseException;
import java.time.temporal.Temporal;
import java.util.ArrayList;
@ -724,6 +725,9 @@ public final class Convert {
if (wrapperFrom == Boolean.class)
return (U) (((Boolean) from) ? Long.valueOf(1L) : Long.valueOf(0L));
if (wrapperFrom == Year.class)
return (U) (Long) (long) ((Year) from).getValue();
if (java.util.Date.class.isAssignableFrom(fromClass))
return (U) Long.valueOf(((java.util.Date) from).getTime());
@ -861,6 +865,17 @@ public final class Convert {
return null;
}
}
else if (toClass == Year.class) {
if (Number.class.isAssignableFrom(wrapperFrom))
return (U) Year.of((((Number) from).intValue()));
try {
return (U) Year.parse(from.toString().trim());
}
catch (DateTimeParseException e) {
return null;
}
}
else if (wrapperTo == Boolean.class) {
String s = from.toString().toLowerCase().trim();

View File

@ -43,6 +43,7 @@ import java.math.BigInteger;
import java.sql.Date;
import java.sql.Time;
import java.sql.Timestamp;
import java.time.Year;
import java.util.UUID;
import org.jooq.DataType;
@ -126,6 +127,7 @@ public class CUBRIDDataType {
protected static final DataType<UShort> __SMALLINTUNSIGNED = new BuiltInDataType<>(FAMILY, SQLDataType.SMALLINTUNSIGNED, "int");
protected static final DataType<UInteger> __INTEGERUNSIGNED = new BuiltInDataType<>(FAMILY, SQLDataType.INTEGERUNSIGNED, "bigint");
protected static final DataType<ULong> __BIGINTUNSIGNED = new BuiltInDataType<>(FAMILY, SQLDataType.BIGINTUNSIGNED, "decimal");
protected static final DataType<Year> __YEAR = new BuiltInDataType<>(FAMILY, SQLDataType.YEAR, "smallint");
// -------------------------------------------------------------------------
// Compatibility types for supported Java types

View File

@ -43,6 +43,7 @@ import java.math.BigInteger;
import java.sql.Date;
import java.sql.Time;
import java.sql.Timestamp;
import java.time.Year;
import java.util.UUID;
import org.jooq.DataType;
@ -124,6 +125,7 @@ public class DerbyDataType {
protected static final DataType<ULong> __BIGINTUNSIGNED = new BuiltInDataType<>(FAMILY, SQLDataType.BIGINTUNSIGNED, "decimal", "decimal(20)");
protected static final DataType<JSON> __JSON = new BuiltInDataType<>(FAMILY, SQLDataType.JSON, "clob");
protected static final DataType<JSONB> __JSONB = new BuiltInDataType<>(FAMILY, SQLDataType.JSONB, "blob");
protected static final DataType<Year> __YEAR = new BuiltInDataType<>(FAMILY, SQLDataType.YEAR, "smallint");
// -------------------------------------------------------------------------
// Compatibility types for supported Java types

View File

@ -43,6 +43,7 @@ import java.math.BigInteger;
import java.sql.Date;
import java.sql.Time;
import java.sql.Timestamp;
import java.time.Year;
import java.util.UUID;
import org.jooq.DataType;
@ -131,6 +132,7 @@ public class FirebirdDataType {
protected static final DataType<ULong> __BIGINTUNSIGNED = new BuiltInDataType<>(FAMILY, SQLDataType.BIGINTUNSIGNED, "decimal", "varchar(20)"); // There are no large numbers in firebird...?
protected static final DataType<JSON> __JSON = new BuiltInDataType<>(FAMILY, SQLDataType.JSON, "blob sub_type text");
protected static final DataType<JSONB> __JSONB = new BuiltInDataType<>(FAMILY, SQLDataType.JSONB, "blob");
protected static final DataType<Year> __YEAR = new BuiltInDataType<>(FAMILY, SQLDataType.YEAR, "smallint");
// -------------------------------------------------------------------------
// Compatibility types for supported Java types

View File

@ -46,6 +46,7 @@ import java.sql.Timestamp;
import java.time.Instant;
import java.time.OffsetDateTime;
import java.time.OffsetTime;
import java.time.Year;
import java.util.UUID;
import org.jooq.DataType;
@ -142,6 +143,7 @@ public class HSQLDBDataType {
protected static final DataType<ULong> __BIGINTUNSIGNED = new BuiltInDataType<>(FAMILY, SQLDataType.BIGINTUNSIGNED, "decimal(p, s)");
protected static final DataType<JSON> __JSON = new BuiltInDataType<>(FAMILY, SQLDataType.JSON, "clob");
protected static final DataType<JSONB> __JSONB = new BuiltInDataType<>(FAMILY, SQLDataType.JSONB, "blob");
protected static final DataType<Year> __YEAR = new BuiltInDataType<>(FAMILY, SQLDataType.YEAR, "smallint");
// -------------------------------------------------------------------------
// Compatibility types for supported Java types

View File

@ -42,6 +42,7 @@ import java.math.BigInteger;
import java.sql.Date;
import java.sql.Time;
import java.sql.Timestamp;
import java.time.Year;
import java.util.UUID;
import org.jooq.DataType;
@ -89,14 +90,14 @@ public class IgniteDataType {
public static final DataType<Time> TIME = new BuiltInDataType<>(FAMILY, SQLDataType.TIME, "time(p)");
public static final DataType<Date> DATE = new BuiltInDataType<>(FAMILY, SQLDataType.DATE, "date");
public static final DataType<Timestamp> TIMESTAMP = new BuiltInDataType<>(FAMILY, SQLDataType.TIMESTAMP, "timestamp(p)");
public static final DataType<byte[]> BINARY = new BuiltInDataType<>(FAMILY, SQLDataType.BINARY, "binary(l)");
public static final DataType<byte[]> VARBINARY = new BuiltInDataType<>(FAMILY, SQLDataType.VARBINARY, "binary(l)");
public static final DataType<byte[]> LONGVARBINARY = new BuiltInDataType<>(FAMILY, SQLDataType.LONGVARBINARY, "binary(l)");
public static final DataType<byte[]> BLOB = new BuiltInDataType<>(FAMILY, SQLDataType.BLOB, "binary");
public static final DataType<Object> OTHER = new BuiltInDataType<>(FAMILY, SQLDataType.OTHER, "other");
public static final DataType<String> VARCHAR = new BuiltInDataType<>(FAMILY, SQLDataType.VARCHAR, "varchar(l)");
public static final DataType<String> CHAR = new BuiltInDataType<>(FAMILY, SQLDataType.CHAR, "char(l)");
public static final DataType<String> CLOB = new BuiltInDataType<>(FAMILY, SQLDataType.CLOB, "varchar");
public static final DataType<byte[]> BINARY = new BuiltInDataType<>(FAMILY, SQLDataType.BINARY, "binary(l)");
public static final DataType<byte[]> VARBINARY = new BuiltInDataType<>(FAMILY, SQLDataType.VARBINARY, "binary(l)");
public static final DataType<byte[]> LONGVARBINARY = new BuiltInDataType<>(FAMILY, SQLDataType.LONGVARBINARY, "binary(l)");
public static final DataType<byte[]> BLOB = new BuiltInDataType<>(FAMILY, SQLDataType.BLOB, "binary");
public static final DataType<Object> OTHER = new BuiltInDataType<>(FAMILY, SQLDataType.OTHER, "other");
public static final DataType<String> VARCHAR = new BuiltInDataType<>(FAMILY, SQLDataType.VARCHAR, "varchar(l)");
public static final DataType<String> CHAR = new BuiltInDataType<>(FAMILY, SQLDataType.CHAR, "char(l)");
public static final DataType<String> CLOB = new BuiltInDataType<>(FAMILY, SQLDataType.CLOB, "varchar");
// -------------------------------------------------------------------------
// Compatibility types for supported Java types
@ -107,6 +108,7 @@ public class IgniteDataType {
protected static final DataType<UShort> __SMALLINTUNSIGNED = new BuiltInDataType<>(FAMILY, SQLDataType.SMALLINTUNSIGNED, "int");
protected static final DataType<UInteger> __INTEGERUNSIGNED = new BuiltInDataType<>(FAMILY, SQLDataType.INTEGERUNSIGNED, "bigint");
protected static final DataType<ULong> __BIGINTUNSIGNED = new BuiltInDataType<>(FAMILY, SQLDataType.BIGINTUNSIGNED, "number(p, s)");
protected static final DataType<Year> __YEAR = new BuiltInDataType<>(FAMILY, SQLDataType.YEAR, "smallint");
// -------------------------------------------------------------------------
// Dialect-specific data types and synonyms thereof

View File

@ -43,6 +43,7 @@ import java.math.BigInteger;
import java.sql.Date;
import java.sql.Time;
import java.sql.Timestamp;
import java.time.Year;
import java.util.UUID;
import org.jooq.DataType;
@ -144,5 +145,5 @@ public class MariaDBDataType {
public static final DataType<byte[]> TINYBLOB = new BuiltInDataType<>(FAMILY, SQLDataType.BLOB, "tinyblob", "binary");
public static final DataType<byte[]> MEDIUMBLOB = new BuiltInDataType<>(FAMILY, SQLDataType.BLOB, "mediumblob", "binary");
public static final DataType<byte[]> LONGBLOB = new BuiltInDataType<>(FAMILY, SQLDataType.BLOB, "longblob", "binary");
public static final DataType<Date> YEAR = new BuiltInDataType<>(FAMILY, SQLDataType.DATE, "year", "date");
public static final DataType<Year> YEAR = new BuiltInDataType<>(FAMILY, SQLDataType.YEAR, "year", "year");
}

View File

@ -43,6 +43,7 @@ import java.math.BigInteger;
import java.sql.Date;
import java.sql.Time;
import java.sql.Timestamp;
import java.time.Year;
import java.util.UUID;
import org.jooq.DataType;
@ -135,7 +136,7 @@ public class MySQLDataType {
public static final DataType<byte[]> TINYBLOB = new BuiltInDataType<>(FAMILY, SQLDataType.BLOB, "tinyblob", "binary");
public static final DataType<byte[]> MEDIUMBLOB = new BuiltInDataType<>(FAMILY, SQLDataType.BLOB, "mediumblob", "binary");
public static final DataType<byte[]> LONGBLOB = new BuiltInDataType<>(FAMILY, SQLDataType.BLOB, "longblob", "binary");
public static final DataType<Date> YEAR = new BuiltInDataType<>(FAMILY, SQLDataType.DATE, "year", "date");
public static final DataType<Year> YEAR = new BuiltInDataType<>(FAMILY, SQLDataType.YEAR, "year", "year");
public static final DataType<JSON> JSON = new BuiltInDataType<>(FAMILY, SQLDataType.JSON, "json");
// -------------------------------------------------------------------------

View File

@ -46,6 +46,7 @@ import java.sql.Timestamp;
import java.time.Instant;
import java.time.OffsetDateTime;
import java.time.OffsetTime;
import java.time.Year;
import java.util.UUID;
import org.jooq.DataType;
@ -140,6 +141,7 @@ public class PostgresDataType {
protected static final DataType<UShort> __SMALLINTUNSIGNED = new BuiltInDataType<>(FAMILY, SQLDataType.SMALLINTUNSIGNED, "int");
protected static final DataType<UInteger> __INTEGERUNSIGNED = new BuiltInDataType<>(FAMILY, SQLDataType.INTEGERUNSIGNED, "bigint");
protected static final DataType<ULong> __BIGINTUNSIGNED = new BuiltInDataType<>(FAMILY, SQLDataType.BIGINTUNSIGNED, "decimal(p, s)");
protected static final DataType<Year> __YEAR = new BuiltInDataType<>(FAMILY, SQLDataType.YEAR, "smallint");
// -------------------------------------------------------------------------
// Compatibility types for supported Java types

View File

@ -42,6 +42,7 @@ import java.math.BigInteger;
import java.sql.Date;
import java.sql.Time;
import java.sql.Timestamp;
import java.time.Year;
import java.util.UUID;
import org.jooq.DataType;
@ -126,6 +127,7 @@ public class SQLiteDataType {
protected static final DataType<ULong> __BIGINTUNSIGNED = new BuiltInDataType<>(FAMILY, SQLDataType.BIGINTUNSIGNED, "numeric");
protected static final DataType<JSON> __JSON = new BuiltInDataType<>(FAMILY, SQLDataType.JSON, "clob");
protected static final DataType<JSONB> __JSONB = new BuiltInDataType<>(FAMILY, SQLDataType.JSONB, "blob");
protected static final DataType<Year> __YEAR = new BuiltInDataType<>(FAMILY, SQLDataType.YEAR, "smallint");
// -------------------------------------------------------------------------
// Compatibility types for supported Java types

View File

@ -46,6 +46,7 @@ import java.sql.Timestamp;
import java.time.Instant;
import java.time.OffsetDateTime;
import java.time.OffsetTime;
import java.time.Year;
import java.util.UUID;
import org.jooq.DataType;
@ -140,6 +141,7 @@ public class YugabyteDBDataType {
protected static final DataType<UShort> __SMALLINTUNSIGNED = new BuiltInDataType<>(FAMILY, SQLDataType.SMALLINTUNSIGNED, "int");
protected static final DataType<UInteger> __INTEGERUNSIGNED = new BuiltInDataType<>(FAMILY, SQLDataType.INTEGERUNSIGNED, "bigint");
protected static final DataType<ULong> __BIGINTUNSIGNED = new BuiltInDataType<>(FAMILY, SQLDataType.BIGINTUNSIGNED, "decimal(p, s)");
protected static final DataType<Year> __YEAR = new BuiltInDataType<>(FAMILY, SQLDataType.YEAR, "smallint");
// -------------------------------------------------------------------------
// Compatibility types for supported Java types