diff --git a/jOOQ/src/main/java/org/jooq/impl/DefaultBinding.java b/jOOQ/src/main/java/org/jooq/impl/DefaultBinding.java index 1c84a4fa1e..b6b3b8f881 100644 --- a/jOOQ/src/main/java/org/jooq/impl/DefaultBinding.java +++ b/jOOQ/src/main/java/org/jooq/impl/DefaultBinding.java @@ -155,6 +155,8 @@ import org.jooq.Converters; import org.jooq.DataType; import org.jooq.EnumType; import org.jooq.Field; +import org.jooq.JSON; +import org.jooq.JSONB; // ... import org.jooq.Record; import org.jooq.RenderContext; @@ -244,6 +246,10 @@ public class DefaultBinding implements Binding { return new DefaultFloatBinding(converter, isLob); else if (type == Integer.class || type == int.class) return new DefaultIntegerBinding(converter, isLob); + else if (type == JSON.class) + return new DefaultJSONBinding(converter, isLob); + else if (type == JSONB.class) + return new DefaultJSONBBinding(converter, isLob); else if (type == LocalDate.class) { DateToLocalDateConverter c1 = new DateToLocalDateConverter(); @@ -603,6 +609,17 @@ public class DefaultBinding implements Binding { + case POSTGRES: + return true; + } + } + + // [#7242] Other vendor specific types also need a lot of casting + if (type == JSON.class || type == JSONB.class) { + switch (ctx.family()) { + + + case POSTGRES: return true; } @@ -662,7 +679,13 @@ public class DefaultBinding implements Binding { // [#4338] ... specifically when using JSR-310 types // [#1130] TODO type can be null for ARRAY types, etc. // [#7351] UUID data types need to be cast too - else if (( POSTGRES == family) && (sqlDataType == null || (!sqlDataType.isTemporal() && sqlDataType != SQLDataType.UUID))) + // [#7242] JSON(B) data types need to be cast too + else if (( POSTGRES == family) && + (sqlDataType == null || + (!sqlDataType.isTemporal() + && sqlDataType != SQLDataType.UUID + && sqlDataType != SQLDataType.JSON + && sqlDataType != SQLDataType.JSONB))) sql(ctx, converted); // [#1727] VARCHAR types should be cast to their actual lengths in some @@ -4141,6 +4164,90 @@ public class DefaultBinding implements Binding { } } + static final class DefaultJSONBinding extends AbstractBinding { + + /** + * Generated UID + */ + private static final long serialVersionUID = 3430629127218407737L; + + DefaultJSONBinding(Converter converter, boolean isLob) { + super(converter, isLob); + } + + @Override + final void set0(BindingSetStatementContext ctx, JSON value) throws SQLException { + ctx.statement().setString(ctx.index(), value.toString()); + } + + @Override + final void set0(BindingSetSQLOutputContext ctx, JSON value) throws SQLException { + ctx.output().writeString(value.toString()); + } + + @Override + final JSON get0(BindingGetResultSetContext ctx) throws SQLException { + return JSON.valueOf(ctx.resultSet().getString(ctx.index())); + } + + @Override + final JSON get0(BindingGetStatementContext ctx) throws SQLException { + return JSON.valueOf(ctx.statement().getString(ctx.index())); + } + + @Override + final JSON get0(BindingGetSQLInputContext ctx) throws SQLException { + return JSON.valueOf(ctx.input().readString()); + } + + @Override + final int sqltype(Statement statement, Configuration configuration) { + return Types.VARCHAR; + } + } + + static final class DefaultJSONBBinding extends AbstractBinding { + + /** + * Generated UID + */ + private static final long serialVersionUID = 3430629127218407737L; + + DefaultJSONBBinding(Converter converter, boolean isLob) { + super(converter, isLob); + } + + @Override + final void set0(BindingSetStatementContext ctx, JSONB value) throws SQLException { + ctx.statement().setString(ctx.index(), value.toString()); + } + + @Override + final void set0(BindingSetSQLOutputContext ctx, JSONB value) throws SQLException { + ctx.output().writeString(value.toString()); + } + + @Override + final JSONB get0(BindingGetResultSetContext ctx) throws SQLException { + return JSONB.valueOf(ctx.resultSet().getString(ctx.index())); + } + + @Override + final JSONB get0(BindingGetStatementContext ctx) throws SQLException { + return JSONB.valueOf(ctx.statement().getString(ctx.index())); + } + + @Override + final JSONB get0(BindingGetSQLInputContext ctx) throws SQLException { + return JSONB.valueOf(ctx.input().readString()); + } + + @Override + final int sqltype(Statement statement, Configuration configuration) { + return Types.VARCHAR; + } + } + static final class DefaultYearToSecondBinding extends AbstractBinding { /** diff --git a/jOOQ/src/main/java/org/jooq/impl/SQLDataType.java b/jOOQ/src/main/java/org/jooq/impl/SQLDataType.java index 4cae403501..c1fee05fcf 100644 --- a/jOOQ/src/main/java/org/jooq/impl/SQLDataType.java +++ b/jOOQ/src/main/java/org/jooq/impl/SQLDataType.java @@ -81,6 +81,8 @@ import java.util.UUID; import org.jooq.Configuration; import org.jooq.DataType; +import org.jooq.JSON; +import org.jooq.JSONB; import org.jooq.Record; import org.jooq.Result; import org.jooq.RowId; @@ -656,6 +658,22 @@ public final class SQLDataType { */ public static final DataType UUID = new DefaultDataType<>(null, UUID.class, "uuid"); + /** + * The {@link JSON} type. + *

+ * This is not a SQL or JDBC standard. This type handles JSON types where + * they are supported. + */ + public static final DataType JSON = new DefaultDataType<>(null, JSON.class, "json"); + + /** + * The {@link JSONB} type. + *

+ * This is not a SQL or JDBC standard. This type handles JSONB types where + * they are supported + */ + public static final DataType JSONB = new DefaultDataType<>(null, JSONB.class, "jsonb"); + // ------------------------------------------------------------------------- // Static initialisation of dialect-specific data types // ------------------------------------------------------------------------- diff --git a/jOOQ/src/main/java/org/jooq/util/postgres/PostgresDataType.java b/jOOQ/src/main/java/org/jooq/util/postgres/PostgresDataType.java index 4fe679ccf7..8675db3a17 100644 --- a/jOOQ/src/main/java/org/jooq/util/postgres/PostgresDataType.java +++ b/jOOQ/src/main/java/org/jooq/util/postgres/PostgresDataType.java @@ -49,6 +49,8 @@ import java.time.OffsetTime; import java.util.UUID; import org.jooq.DataType; +import org.jooq.JSON; +import org.jooq.JSONB; import org.jooq.Record; import org.jooq.Result; import org.jooq.SQLDialect; @@ -166,7 +168,8 @@ public class PostgresDataType { public static final DataType> REFCURSOR = new DefaultDataType<>(SQLDialect.POSTGRES, SQLDataType.RESULT, "refcursor"); public static final DataType ANY = new DefaultDataType<>(SQLDialect.POSTGRES, SQLDataType.OTHER, "any"); public static final DataType UUID = new DefaultDataType<>(SQLDialect.POSTGRES, SQLDataType.UUID, "uuid"); - public static final DataType JSON = new DefaultDataType<>(SQLDialect.POSTGRES, SQLDataType.OTHER, "json"); + public static final DataType JSON = new DefaultDataType<>(SQLDialect.POSTGRES, SQLDataType.JSON, "json"); + public static final DataType JSONB = new DefaultDataType<>(SQLDialect.POSTGRES, SQLDataType.JSONB, "jsonb"); // Meta-table types public static final DataType OID = new DefaultDataType<>(SQLDialect.POSTGRES, SQLDataType.BIGINT, "oid");