Version 3.14.0 - October 19, 2020
================================================================================
In this release, we've sorted our github issues according to user feedback and
finally implemented some of the most wanted features, which include better
Kotlin support, embeddable types, and domain type support.
In addition to this, we believe that our newly added XML and JSON operation
support will be a leading game changer in how ORMs interact with SQL databases
in the future.
XML and JSON
------------
Standard SQL has long supported SQL/XML, and since recently, most RDBMS also
support standard SQL/JSON or vendor specific variants thereof. While ORDBMS
extensions have never seen the adoption they deserve, XML and JSON do. It makes
sense to occasionally denormalise data and store documents in the database
directly. However, this is not what we're most excited about.
We're excited about our support for all the fancy operators like:
- JSON_TABLE to turn JSON values into SQL tables
- JSON_ARRAY, JSON_OBJECT, JSON_VALUE to construct JSON data from values
- JSON_ARRAYAGG, JSON_OBJECTAGG to aggregate data into nested JSON documents
- JSON_EXISTS to query documents with JSON path
Similar functions are available for XML, like XMLTABLE, XMLELEMENT, XMLAGG, etc.
All editions of jOOQ 3.14 support standard SQL XML and JSON operators, and
emulate them where non-standard support is available (e.g. PostgreSQL and SQL
Server).
The commercial editions also support SQL Server's very convenient FOR XML and
FOR JSON APIs, emulating that syntax using standard operators elsewhere. See:
But that's not all of it! If you have Gson, Jackson, or JAXB on the classpath,
we can use that to map org.jooq.XML, org.jooq.JSON, org.jooq.JSONB types from
your query results to your nested data structures, automatically. See:
These approaches are extremely powerful. In many cases, you might just skip
most of your middleware layer and bind a REST or similar endpoint directly to a
jOOQ / SQL query, producing JSON for your frontend:
Kotlin support
--------------
We've long supported some Scala extensions and a ScalaGenerator. Kotlin is an
additional very promising JVM language where a new jOOQ-kotlin module as well as
a KotlinGenerator will add a lot of value for your jOOQ/Kotlin integration.
The KotlinGenerator offers, among other things:
- Data class support for generated POJOs
- Property support for generated POJOs, interfaces and records
- Better nullability support
The jOOQ-kotlin module offers some useful extension functions to further improve
the experience of the jOOQ/Kotlin integration.
In addition to the above, we've annotated the entire jOOQ API with nullability
annotations from JetBrains:
- org.jetbrains.annotations.Nullable
- org.jetbrains.annotations.NotNull
This will remove many of the annoying T! types in your Kotlin/jOOQ code,
turning them into T or T? types instead, giving you more confidence.
With these improvements, we've also critically reviewed our existing
ScalaGenerator, fixing a lot of bugs.
Embeddable types
----------------
One of the biggest new features in jOOQ 3.14 is inspired by JPA, which ships
with embeddable types. An embeddable type is an emulation of a database user-
defined type (UDT), which are supported natively only in Oracle and PostgreSQL.
The biggest gain of such types is to create more semantic, composite data types
in your database schema, and profit from the additional type safety.
Our interpretation of the feature is mostly in the source code generator, whose
output now becomes even more valuable. All jOOQ editions support the basic
infrastructure to pattern-match column sets and turn them into synthetic
embeddable types.
In addition to the above, our commercial editions offer some auto configuration
of embeddable types in cases where they really shine:
- For primary/unique constraints and their matching foreign keys
- For DOMAIN types (see below)
- Handling overlapping embeddable types
- Allowing for embeddable types to replace their underlying columns
We took the concept a step further than JPA. In jOOQ, embeddable types can act
as views on the underlying columns, without replacing them, or as a replacement
like in JPA. jOOQ respects all levels of relational modelling, including
overlapping constraints and thus allowing for two embeddable types to overlap.
For more information, please refer to:
DOMAIN types
------------
Speaking of types, some database dialects support standard SQL DOMAIN types,
which are a simpler form of UDTs. Instead of working with low level technical
types like VARCHAR(10), why not give your single-column types a name, and add
a few re-usable CHECK constraints to them?
That's what a DOMAIN type is:
- A named type
- Aliasing a technical type, like VARCHAR(10)
- Possibly adding a DEFAULT expression
- Possibly adding a NOT NULL constraint
- Possibly adding a set of CHECK constraints
All of the above is reusable across your schema and if you're commercially
licensed, you can even have the code generator auto-generate embeddable types
for all of your domains to profit from the additional type safety in Java.
For more information, please refer to:
Synthetic constraints
---------------------
Related to the above improved code generator output are synthetic objects,
such as the previously supported synthetic primary keys, and now also synthetic
unique and foreign keys.
If you invest heavily in security and re-usable components within your database,
you will make heavy use of SQL views. Unfortunately, views do not have any meta
data like foreign key constraints - despite the meta data being "obvious" to you
the database designer. With synthetic constraints, you can tell jOOQ about your
knowledge of underlying constraints.
The main benefits of meta data being available to jOOQ being:
- You can now use implicit joins on views as well
- You can now use the JOIN .. ON KEY syntax on views as well
- You can use embeddable key types from before on views just like on tables
For more information, please refer to:
Better MERGE support
--------------------
We've finally tackled support for more advanced MERGE statement clauses and now
support:
- Multiple WHEN MATCHED AND condition THEN UPDATE clauses
- Multiple WHEN MATCHED AND condition THEN DELETE clauses
- UpdatableRecord.merge() and all the related goodies to simplify record merging
Transformations
---------------
invest more and more in new use-cases for putting jOOQ to use other than as an
embeddable DSL in Java.
Our translation capabilities have already been strong, and with a new set of SQL
transformations, they become even stronger helping customers migrate off RDBMS A
towards RDBMS B (and back, if they made a mistake).
While our website translator is free of charge, the jOOQ library can always be
used programmatically, or as a command line utility:
To make this use-case even more useful, new transformation features have been
added, including:
- ROWNUM to LIMIT or to ROW_NUMBER()
- Table lists to ANSI JOIN (including Oracle (+) support)
- Unnecessary arithmetic expressions
This is an exciting area that we'll be exploring for our commercially licensed
customers in the future, while even the jOOQ Open Source Edition profits from
these improvements. For example, the infrastructure created for transformations
finally enabled emulating PostgreSQL's DISTINCT ON clause, elsewhere.
For more information, please refer to:
Better manual
-------------
We've taken a step back and reviewed a few important parts of our documentation.
We're now offering:
- Sticky tabs for code generator techniques (XML, Programmatic, Gradle): If
you're using Gradle with jOOQ's code generator, you don't want to look at the
XML configuration again, in the manual. These tabs finally hide unneeded
information.
- Subsections for each function: We've started documenting each SQL function
individually, explaining how it works in SQL, and providing some examples and
example results.
- Generate example vendor specific rendering of SQL: We're using jOOQ when
generating the manual, translating some jOOQ API usage to all of our supported
dialects, and displaying how the function renders in each dialect.
- Show imports button and display context sensitive imports: All the examples in
the manual can be overwhelming. We're assuming a lot of (static) imports,
which we're finally documenting in an expandable "show imports" section of
each code fragment.
- We've rewritten some sections to be much more complete with examples, such as
the data import section.
- A new API diff page displays what has changed between each minor release in
Features and Improvements
-------------------------
#229 - Enhance API to provide access to ARRAY elements
#681 - Add support for type DOMAINs
#1571 - Add support for REGEXP_REPLACE()
#1962 - Improve formatting of SQL rendered by window functions
#2230 - Add support for INTERVAL data types in code generator
#2530 - Add support for "fetch groups" or "embedded record types", where a group of fields is defined as a reusable RowN type across various tables
#2961 - Add UpdatableRecord.merge()
#3419 - Add support for intercepting PreparedStatements, collecting individual bind value sets into larger batch sets
#3505 - Emulate quantified comparison predicates for row value expressions, if not natively supported
#3564 - Emulate PostgreSQL's DISTINCT ON clause
#3713 - Add <pojosAsScalaCaseClasses/> to the code generator to generate case classes
#3774 - Move Configuration thread safety content to new section
#3896 - Add Configuration.converterProvider() to allow for implementing default converters between <T> and <U> types
#4528 - Add manual section about DSLContext.connection()
#4941 - Add LoaderListenerStep.onRowStart() for preprocessing input data
#5216 - Add UpdatableRecord<R>.children(ForeignKey<O, R>): Table<O>
#5218 - Add support for FOR SHARE OF in Postgres dialect
#6124 - Add code generator option to generate an embeddable record per primary / unique key
#6183 - Add GeneratorStrategy.getGlobalReferencesFile(Class.class) and getGlobalReferencesJavaClassName(Class.class) etc. to allow for overriding the files that contain global references
#6187 - Add Schema.getTable(Name), getSequence(Name), getUDT(Name), getDomain(Name)
#6188 - Add Catalog.getSchema(Name)
#6248 - Implement KotlinGenerator
#6256 - Add Kotlin infix and extension functions to a new jOOQ-kotlin extensions module
#6345 - Generate Kotlin data classes
#6456 - Generate comments also on POJOs
#6501 - Can we profit from Kotlin's named and defaulted parameters for procedure calls, record constructors etc?
#6598 - Support mapping into nested immutable POJOs
#6736 - Add support for PostgreSQL ON CONFLICT .. WHERE <index_predicate>
#7067 - Specify jOOQ's lack of Serializable backwards compatibility in the manual
#7155 - Add support for synthetic foreign keys
#7168 - Maven, Gradle, programmatic configuration code should be toggled using tabs
#7253 - Add support for Loader.batchAll() with onDuplicateKeyIgnore()
#7262 - Improve formatting of dual emulations
#7291 - Add support for multiple MERGE .. WHEN MATCHED AND { condition }
#7312 - Add Setting to transform table lists to ansi join
#7507 - Implicit Joins should produce inner joins when possible
#7553 - Add more and better DDL examples to the manual
#7681 - Add programmatic and Gradle examples on how to configure generator strategies in the manual
#7711 - Support recent features for Sybase ASE
#7860 - Add support for synthetic unique keys
#7997 - Emulate DISTINCT predicate using DECODE in Db2, H2, Oracle
#8054 - Support `NO WAIT` with FOR SHARE on MySQL/Postgres
#8254 - Publish an API version diff in the manual
#8353 - Fix known limitations of embeddable types
#8381 - Pull up OracleDSL.toChar() to DSL
#8384 - Emulate support for INSERT INTO t [ AS alias ]
#8450 - Improve procedural language abstraction API
#8492 - DSL.row(Collection<?>) should also accept Select in argument collection
#8519 - Add native support for H2 JOIN .. USING syntax
#8548 - Add support for SQLite window function extensions from version 3.28
#8553 - Add support for foreign keys referencing unique key columns in different order than in the unique key definition
#8575 - Implement native support for H2 RATIO_TO_REPORT()
#8592 - Emulate PERCENT_RANK and CUME_DIST where not natively supported
#8719 - Use native support for H2 <rve> IS [ NOT ] NULL predicate
#8732 - Add native support for H2's new UNIQUE predicate
#8805 - Support OVERLAY() function
#8841 - Redshift: Support ILIKE
#8844 - Emulate FOR UPDATE SKIP LOCKED using READPAST table hint
#8949 - Add CharsetProvider SPI
#8950 - Add support for standard JSON functions - continued
#9017 - Add Settings.transformRownum
#9044 - Add support for parsing single parameter numeric TRUNC() function
#9054 - Manual headers should offer a link to the "latest" version
#9061 - Improve Settings.parseWithMetaLookups
#9131 - Support parsing MySQL BIT(1) value literals
#9212 - Add support for MariaDB INSERT and DELETE RETURNING
#9351 - Let DataType extend QueryPart
#9404 - AbstractKey and subtypes should accept Name instead of string in constructors
#9492 - Deprecate static data type registry lookups for user defined data types
#9496 - Improve formatting of CREATE TABLE and derived column lists
#9639 - Apply Database::getOrderProvider to Keys.java content as well
#9744 - Add <locale/> to code generator <target/> specification
#9764 - Rework formatting of SQL
#9775 - Various parser bugs / missing features
#9798 - Make the names in org.jooq.impl.Names unquoted
#9825 - Document new jOOQ-refaster module
#9833 - Add missing @Support annotation to DSLContext#fetch*() methods
#9839 - Remove manual version 3.2, unsupport 3.7
#9841 - Update documentation to refer to org.jooq.trial-java-8 Maven groupId
#9851 - Rewrite ResultQuery Javadoc
#9861 - Add covariant overrides Record[N].with(Field, T) for fluent setting of values on a Record
#9866 - Liquibase imports should use ClassLoaderResourceAccessor
#9868 - SQL Server: Support STRING_AGG() function
#9872 - LiquibaseDatabase should use configured changeLogParameters.contexts when updating
#9874 - [#9872] LiquibaseDatabase should use provided contexts on update
#9881 - DB2: Support ALTER TABLE ... DROP PRIMARY KEY
#9882 - Deprecate SQLDialect#supports(Collection<SQLDialect>) method
#9885 - Add support for DSL.execute() in Oracle
#9888 - Support parsing some PostgreSQL specific matching operators
#9889 - Add support for native ILIKE in H2
#9891 - Change Pro annotation retention to class
#9894 - DB2: New aggregate functions in version 11
#9898 - Implement native support for LIKE ANY et al in PostgreSQL
#9899 - Programmatic code generator configuration documentation should fully qualify org.jooq.meta.jaxb.Configuration
#9900 - Add TransactionalRunnable.of(TransactionalRunnable...) to compose nested transactions
#9902 - Add Settings to apply native JSR 310 data type binding
#9911 - Deprecate Comparator.supportsQuantifier() and supportsSubselect()
#9921 - Offer additional settings as dropdowns in /translate
#9923 - Add support for FOR XML and FOR JSON
#9924 - Emulate SQL Server FOR XML (single table) in other dialects
#9925 - Add support for standard XML functions
#9926 - Emulate SQL Server FOR JSON (single table) in other dialects
#9927 - Add support for JSON_ARRAYAGG
#9928 - Add support for JSON_OBJECT <JSON constructor null clause>
#9930 - Add internal DefaultAggregateFunction and DefaultWindowFunction
#9932 - Add DSL.jsonEntry(String, Field) and jsonObject(String, Field)
#9936 - Add support for JSON_OBJECTAGG
#9938 - Emulate SQL Server FOR JSON PATH and FOR XML PATH with dot / slash notation in other dialects
#9939 - Emulate SQL Server FOR JSON AUTO nested collections from to-many joins
#9950 - Improve support for EXECUTE for use in procedural blocks
#9952 - Implement procedural language support for Firebird
#9958 - Add DataType.precisionDefined(), scaleDefined(), lengthDefined()
#9959 - Code generator should produce TIMESTAMP(precision) calls instead of TIMESTAMP.precision(precision)
#9967 - Add support for HSQLDB temporal tables
#9971 - Support parsing BETWEEN ASYMMETRIC where the SQL standard supports it
#9973 - Remove internal AbstractFunction
#9976 - Deprecate also CUBRIDDSL
#9977 - Add more thread safety documentation around DSLContext and Configuration
#9979 - Add DSL.val(), value(), and inline() overloads for JSON, JSONB, and XML types
#9985 - Refactor some rendering logic to make better reuse of QueryPartList
#9986 - Add an internal QueryPartListView class
#9990 - Add some convenience API to SQLDialect, delegating to JDBCUtils
#9991 - Offer an org.jooq.impl.AbstractBinding base implementation for the common case
#9994 - Add missing with(Collection<? extends CommonTableExpression<?>>) overloads
#9995 - Add SQLDialect.POSTGRES_12
#10000 - Add DSL.tau() to support τ, which is a better π
#10008 - Add a configuration flag to DDLDatabase to specify whether queries should be logged
#10010 - Rename Loader { CSV | JSON | Rows } Step.fieldsFromSource() to fieldsCorresponding()
#10013 - Add <constructorPropertiesAnnotation/> to generate @ConstructorProperties on pojos and records
#10015 - Replace internal usages of QueryPartList by QueryPartListView
#10016 - Improve H2's derived column list support
#10023 - Add Table.with(SQL) to allow for plain SQL templating in T-SQL style table hints
#10024 - Upgrade dependencies
#10025 - Move Keywords.F_XYZ to Names.N_XYZ and make them unquotedName
#10032 - Add a /doc/dev URL mapping to the manual
#10038 - Add SQLDialect.ORACLE20C
#10040 - Add support for Oracle 20c EXCEPT ALL and INTERSECT ALL
#10041 - Add support for Oracle 20c window function GROUPS and EXCLUDE clauses
#10042 - Add RecordListener.mergeStart() and RecordListener.mergeEnd() lifecycle events
#10043 - Add Support annotations to TableRecord.insert(), UpdatableRecord.store(), DAO.update(), etc.
#10045 - Deprecate the H2 style MERGE statement
#10046 - Add DSLContext.batchMerge()
#10049 - Add DAO.merge()
#10050 - Add support for optimistic locking with UpdatableRecord.merge()
#10052 - Add support for standard SQL MERGE .. WHEN MATCHED [ AND .. ] THEN DELETE
#10053 - Improve tutorial "jOOQ as a SQL builder" explaining the resulting bind parameter markers
#10060 - Emulate JSON_ARRAYAGG() in older MariaDB versions
#10061 - Add native support for DISTINCT predicate in Db2
#10064 - trueCondition(), noCondition() and falseCondition() should generate TRUE and FALSE, where BOOLEAN types are supported
#10068 - Add native support for the DB2 11.1 OVERLAPS predicate
#10070 - jOOQ should allow empty JOIN .. USING clauses
#10071 - DefaultRecordMapper should apply ConverterProvider for Record1.into(...) calls
#10072 - Out of the box support mapping between XML/JSON and POJOs using JAXB or Jackson/Gson
#10074 - Provide default implementation of AbstractTable.as(Name)
#10075 - Support unqualified column lookups in parser
#10078 - Create manual subsections for each function
#10079 - Create subsections in the manual for aggregate function features
#10082 - Add JSON.json(), JSONB.jsonb(), XML.xml() methods
#10085 - Add DataType.isJSON() and isXML()
#10089 - Emulate JSON_OBJECTAGG where unavailable
#10090 - Add a <generatedAnnotationDate/> flag to allow for turning off generating @Generated.date()
#10094 - Emulate FOR XML AUTO with joins in other dialects
#10097 - Add support for DB2 CREATE INDEX .. EXCLUDE NULL KEYS clause
#10099 - Emulate XMLTABLE in SQL Server with NODES() and VALUE()
#10100 - Emulate JSON_TABLE in SQL Server with OPENJSON
#10104 - Add synthetic FOR JSONB syntax that produces JSONB instead of JSON
#10105 - Support parsing ALTER { SEQUENCE | TABLE | TYPE | VIEW } .. OWNER TO ..
#10111 - FOR JSON WITHOUT_ARRAY_WRAPPER emulation should use REGEXP_REPLACE, not SUBSTRING
#10112 - Add QueryPartInternal.rendersContent(Context<?>)
#10127 - Generate dialect specific rendering information in manual
#10128 - Add support for Postgres 12 materialized CTEs
#10131 - Emulate NVL2 using IIF in SQL Server
#10133 - Add Javadoc and manual documentation for WIDTH_BUCKET
#10137 - RPAD() and LPAD() should no longer need to cast
#10152 - Add support for SAP HANA's BOOLEAN data type
#10153 - Get HANA dialect support up to date
#10156 - Deprecate createView(X, Function), Table.as(X, Function), and DSLContext.with(X, Function)
#10160 - Add support for MySQL's IF() function
#10162 - Add parser support for named NOT NULL constraints in DDL
#10164 - Support parsing statement batches without delimiter
#10165 - Add support for MySQL's INSERT() function via OVERLAY()
#10171 - Parse a few known syntaxes and throw an exception about them not being supported
#10178 - Add Field.is[Not]DistinctFrom(Select) and RowN.is[Not]DistinctFrom(Select)
#10179 - Boolean field emulation should be NOT NULL aware
#10180 - Add native support for DECODE where it is supported
#10184 - Add missing TableLike.asTable(Name) and asTable(Table) overloads
#10188 - Add Tools.visitSubquery(Context<?>, Select)
#10193 - Support precision on LOCALTIME and LOCALDATETIME data types
#10196 - GeneratorWriter should auto-indent generated code
#10204 - Add a way to filter out objects from org.jooq.Meta instances
#10210 - Add support for CREATE, ALTER, and DROP DATABASE statements
#10215 - Stop emulating GROUP BY () in PostgreSQL 9.5+
#10216 - Add code generation support for HANA ARRAY type parameters
#10220 - Support parsing CHECK constraints without parentheses
#10230 - Let DataType extend Named
#10235 - jOOQ-kotlin-example should use new KotlinGenerator
#10246 - Add missing <includeXYZ/> flag documentation to manual
#10250 - Add Db2 11.1 support for more EXTRACT DateParts
#10258 - Improve PostgreSQL dateAdd() implementation
#10264 - Support \s in the code generation config's indentation configuration
#10278 - Add Named.getCommentPart()
#10280 - Add Meta.snapshot() to create an in-memory copy of a Meta implementation
#10284 - Add UDT.getPackage() in the OSS edition API
#10288 - Add <pojosAsKotlinDataClasses/> to the code generator to generate data classes
#10291 - Add support for CITEXT and VARCHAR_IGNORECASE types in parser
#10292 - Add org.jooq.Qualified
#10294 - Remove unnecessary covariant overrides from RenderContext and BindContext
#10299 - Improve ParserImpl code reuse for single arg functions
#10300 - Add DataType.getArrayComponentType() and getArrayComponentDataType()
#10309 - Add code generation support for arrays of domain types
#10317 - Deprecate Context.formatIndentLockStart() and formatIndentLockEnd()
#10321 - Add support for JSON / JSONB types in H2
#10322 - Add parser support for JSON, JSONB, and XML types
#10353 - Add a new internal InlineDerivedTable implementation
#10354 - Retrofit Table.where() implementation to use new InlineDerivedTable
#10360 - Support parsing NOT DEFERRABLE INITIALLY IMMEDIATE on foreign key constraints
#10361 - Add JSONFormat.quoteNested() and XMLFormat.quoteNested() flags
#10362 - Refactor DefaultBinding to reference DataType<T>, not Class<T>
#10368 - Add DataType.isNString()
#10372 - Refactor internal org.jooq.impl.Cast.Native for better reuse
#10377 - Inline internal AbstractContext.visit0() to reduce stack trace size
#10382 - Add support for CockroachDB 20.1 features
#10383 - Add support for CockroachDB WITH RECURSIVE
#10384 - Add support for CockroachDB TEMPORARY tables
#10388 - Add parser support for Oracle's INTERVAL YEAR TO MONTH and INTERVAL DAY TO SECOND types
#10389 - Support INFORMATION_SCHEMA.COLUMNS.INTERVAL_TYPE in H2
#10391 - Implement TableOptions equals() and hashCode()
#10397 - Default implementation of AbstractTable.getIdentity() should check Table.fields() for any Field with DataType.identity()
#10400 - Use DataType.identity() information in the absence of Table.getIdentity() in INSERT .. RETURNING emulation
#10402 - Add when(Field<Boolean>) overloads to CASE expression API
#10404 - Add SQLDialect.ASE_12_5, ASE_15_5, ASE_15_7, ASE_16_0 dialects
#10406 - Get ASE dialect support up to date
#10420 - Add Context.methodIf(Arg, boolean) for an "internal if" implementation
#10422 - Let User and Role extend Named to give access to quoted / unquoted and qualified / unqualified names
#10428 - Improve manual section "importing"
#10429 - Make LoaderRowListener a FunctionalInterface
#10432 - Add Settings.cachePreparedStatementsInLoader to keeping open PreparedStatements in Loader API
#10438 - Support lazy DataType lookups in DSL.val() and DSL.inline()
#10447 - Refactor some internal duplicate logic
#10451 - Use H2, HSQLDB native interval arithmetic instead of DATEADD emulation
#10453 - Support parsing additional standard interval literals
#10456 - Add static YearToMonth and DayToSecond.<intervalType>(String) constructor methods
#10460 - Use MERGE to emulate INSERT .. ON DUPLICATE KEY IGNORE in H2
#10472 - Add LazySchema and LazyCatalog to allow for lazy referencing a schema or catalog in generated code
#10478 - Add Matchers for catalogs
#10481 - Add <replacesFields/> to embeddable configuration
#10483 - Add Database.getUniqueKeys(), getForeignKeys() to look up constraints without a specific schema
#10489 - Add parser support for qualified data types in DDL and casts
#10491 - Add conditional-expressions subsection about Field<Boolean>
#10493 - Add TemplatingException for errors that occur with plain SQL templating
#10495 - Add a "show imports" button to all manual code sections
#10497 - Add parser support for the PostgreSQL CREATE INDEX .. ON .. USING syntax
#10499 - Support overlapping embeddables
#10511 - Add <embeddableDomains/> to allow for wrapping all DOMAIN types in embeddables
#10518 - /learn should clearly distinguish between unreleased and released versions in the docs
#10524 - Add DataType.isEmbeddable()
#10532 - Add new <lambdaConverter/> configuration in <forcedType/> to further simplify programmatic converters
#10535 - Generated code should import org.jooq.impl.SQLDataType if possible
#10540 - Implement new internal syntax to create derived column lists only if necessary
#10542 - Add Comparator.inverse()
#10543 - Manual should discourage using jOOQ without the code generator
#10550 - Remove the Derby SelectQueryImpl.UNION_PARENTHESIS_IN_DERIVED_TABLES emulation
#10554 - Avoid workaround for too large initialisers when unnecessary
#10568 - ParserCLI should offer configuration of RenderQuotedNames
#10569 - ParserCLI should display individual flags when not providing a new value in interactive mode
#10575 - Add some empty protected methods to generate custom class footers in reference classes
#10578 - Add PackageDefinition.getUDTs()
#10583 - Loader API should pad input rows if more target fields are provided than source fields
#10588 - Add new <syntheticObjects/> configuration, and deprecate / replace existing functionality
#10592 - Add DDLExportConfiguration.includeConstraintsOnViews to prevent Meta::ddl from exporting synthetic constraints on views
#10600 - Gradle example in the manual should not use MarkupBuilder to avoid issues with name
#10613 - Add Key.nullable() to indicate that a key is (partially) nullable
#10616 - Add Settings.implicitJoinType to govern whether an INNER or LEFT JOIN is generated
#10625 - Static import all SQLDataType types in the manual
#10631 - Display context sensitive imports in manual
#10632 - Log all column and parameter types in DEBUG level in JavaGenerator
#10633 - Add DataTypeDefinition.getMatchNames()
#10636 - Link to SEEK clause from OFFSET clause in the manual
#10638 - Add parser support for arbitrary CONNECT BY .. START WITH .. GROUP BY .. HAVING ordering
#10640 - Remove unneeded private DSL constructors
#10641 - Support and emulate Oracle's TO_CHAR() function
#10646 - Document that import-on-demand cannot be used with org.jooq.Record
#10648 - Log info when code generation run doesn't produce any difference
#10651 - Manual section about like should document example of concatenating "%" to a bind value
#10653 - Make the JavaGenerator::INITIALISER_SIZE configurable through <maxMembersPerInitialiser/>
#10654 - Make the generation of the serialVersionUID configurable
#10658 - Add Sequence.nextvals(int):Select<Record1<T>> and DSLContext.nextvals(Sequence<T>, int):List<T> to fetch a number of sequence values in one go
#10659 - Add Informix emulation for GENERATE_SERIES
#10660 - Add WITH RECURSIVE emulations for GENERATE_SERIES, where available
#10665 - Change org.jooq.impl.Expression implementation to be binary only
#10682 - Add Collection overload for CatalogMetaProvider, SchemaMetaProvider, TableMetaProvider constructors
#10688 - Add Converter.forArrays() to turn a Converter<T, U> into a Converter<T[], U[]>
#10689 - Deprecate zero-args and one-arg Converters.of() methods
#10692 - Address known issues of BatchedConnection
#10693 - Add Settings.batchSize to transparently specify a maximum batch size for BatchedConnection
#10694 - Add DataType.asConvertedDataType(Class<U>, Function<-T, +U>, Function<-U, +T>)
#10705 - MockResultSet::toString should visually display current row
#10707 - Add Routine.getInValue(Parameter) to allow for retrieving IN parameter values
#10711 - Emulate using WITH in UNION subqueries by wrapping the subquery in a derived table in dialects where this isn't supported
#10713 - Upgrade SQLite JDBC dependency from 3.30 to 3.32
#10728 - Add DSL.jsonEntry(Field) and DSL.jsonObject(Field...) overloads that derive key value(s) from field name(s)
#10731 - Bump junit from 4.13 to 4.13.1 in /jOOQ-examples/jOOQ-spark-example
#10732 - Bump junit from 4.13 to 4.13.1 in /jOOQ-examples/jOOQ-academy
#10733 - Bump junit from 4.13 to 4.13.1 in /jOOQ-examples/jOOQ-javafx-example
#10735 - Bump junit from 4.13 to 4.13.1
#10750 - Deprecate some internal field(String) and field(Name) implementations
#10753 - Add support for ALTER TABLE .. SET NOT NULL in Oracle
Breaking changes
----------------
#3285 - Add support for HSQLDB table-valued functions
#4695 - Create separate Row[N] and Record[N] implementations for each N
#4703 - The underscore "_" is a reserved token in Java 9. The jOOQ code generator should avoid generating it
#6612 - Modularise jOOQ
#7328 - Replace cursor-based FOR UPDATE emulation in SQL Server by table hints
#7342 - Field.as(Field) and Table.as(Table) should inherit alias-defining Named's quoted flag
#8576 - Regenerate jOOQ-meta code with <instanceFields>true</instanceFields>
#8829 - Loader should decode binary data as base64, not with new String(byte[])
#8945 - Add org.jooq.XML
#9754 - Unstable routine name suffix generation with overloaded names
#9840 - Remove DSL.groupingId() from jOOQ Open Source Edition, as no OSS dialect supports it
#9933 - Optimistic locking does not work when recordTimestamp column has precision less than TIMESTAMP(3)
#10081 - Make accidentally public classes package private again
#10129 - SQLite's SIGN() emulation does not produce the correct value on NULL
#10146 - Let SQLDataType.TIMESTAMP map to DATETIME2 instead of DATETIME in SQL Server
#10187 - Remove CONNECT BY support from OSS Edition
#10276 - DSLContext.ddl() should not produce foreign keys that point outside of the argument schema
#10283 - Stop generating singleton Identity declarations and move logic into TableImpl
#10331 - Split jOOQ-meta-extensions into jOOQ-meta-extensions-hibernate and jOOQ-meta-extensions-liquibase
#10338 - XMLGenerator should produce 1-based <ordinal_position/> in <key_column_usage/>
#10343 - Make JSON::data, JSONB::data, and XML::data NotNull
#10355 - Change JavaGenerator.printClassAnnotations() to (JavaWriter, Definition, Mode)
#10418 - GrantOnStep.on(String) and RevokeOnStep.on(String) should wrap String argument in Name
#10435 - DSLContext.connection() and similar methods should not wrap RuntimeException in DataAccessException
#10512 - Add a CloseableDSLContext and stop subtyping AutoCloseable from DSLContext directly
#10534 - <enumConverter/> and <lambdaConverter/> don't work in ScalaGenerator and KotlinGenerator
#10566 - Wrong DDL generated in Oracle when translating integer types
#10576 - Compilation error when 2 Oracle packages both contain the same record type name
#10686 - ConnectionRunnable and ConnectionCallable should accept throwing Throwable
Bug Fixes
---------
#3379 - Table-valued function aliasing is confusing as the order of .call() and .as() is relevant
#3479 - Awkward formatting of "short" functions
#4691 - Add an unused forced type hint about Pattern.COMMENTS being turned on to help debug regexes with whitespace
#5200 - Loader API onDuplicateKeyIgnore() doesn't work when primary key is an identity
#5422 - ScalaGenerator should follow Scala Style Guide in generated code
#5488 - Excess newline in formatted SELECT without FROM clause
#6004 - DSL.values(Row[N]...) and DSL.table(Record) should emulate simpler SQL
#6186 - Log warning if standalone <outputSchema/> element is not paired with <inputSchema/>
#6266 - JoinTable.join(...).onKey() does not work
#6278 - Wrong DDL generated when using SQLDataType.TINYINT on SQL Server
#6356 - H2 row expression IN predicate with subquery doesn't work when subquery columns are aliased
#6385 - Derby emulation of all(T...) is incorrect
#6793 - Avoid allocating (and iterating) the MutablePOJOMapper's nestedFields HashMap
#6819 - PostgreSQL UDT not working when used as stored procedure return type
#6935 - insert queries having auto-generated ids are not executed
#7070 - Add code generation support for PostgreSQL types referencing domains
#7334 - DataAccessException.sqlStateClass() always returns OTHER for SQLite
#7411 - `returning` statement does not work in MySQL even with primary key and auto increment
#7489 - Datetime arithmetic generates bind values when input uses inline values
#7626 - join(...).onKey(TableField) doesn't work with aliased tables
#7667 - Generated SQL is missing aliasing for Stored Procedure
#7673 - Cannot call SQL Server stored procedure on HSQLDB
#7679 - Cannot use Meta.getSchema() for DROP SCHEMA statement
#7682 - KeepNamesGeneratorStrategy doesn't work with ScalaGenerator
#7867 - DSLContext.fetchCount(Select) should rename the select statement's column names to prevent ambiguities
#7917 - Use H2 1.4.198 domain qualification for enums stored as domains
#8029 - Cast expressions on TIMESTAMP data types should use explicit precision
#8045 - EnumConverter doesn't work when fromType is Kotlin Int
#8089 - Compilation error in generated Scala code for single letter schema names
#8139 - scala.UninitializedFieldError in runtime using generated data objects
#8220 - Row[N] predicates should wrap T argument values in Tools.field() to allow for raw type scalar subqueries
#8278 - Code generation for SQLite doesn't pick up view column types correctly
#8589 - Unstable code generation in PostgreSQL regexp_split_to_table function
#8869 - jOOQ-scala modules no longer compile under JDK 13
#8965 - Wrong DDL generated when using precision on TIMESTAMPTZ type
#9103 - Remove EPUB manual from website
#9164 - Consistently show SQL code to the left and Java code to the right in manual
#9188 - Cannot use DayToSecond intervals in Oracle, for intervals bigger than 99 days
#9246 - ALTER TABLE .. ADD UNIQUE INDEX syntax cannot be parsed
#9337 - DDLDatabase does not support JSON or JSONB columns
#9396 - Too many tables produced from DSLContext.meta(Tables).getSchemas()
#9540 - SQL Server NVARCHAR literal is not rendered correctly
#9554 - not(unique(c)) / notUnique(c) and not(exists(c)) / notExists(c) should generate the same SQL
#9590 - JDBC DatabaseMetaData backed Meta implementation should read DECIMAL_DIGITS for timestamp precision, not COLUMN_SIZE
#9647 - Dead links to javax.validation
#9832 - jOOQ Open Source Edition code generation fails on MySQL 5.7 and MariaDB 10.3
#9834 - jOOQ-meta Database implementations should dynamically detect server version and use appropriate dialect version
#9835 - NPE when using AbstractDatabase instance without explicit configuredCustomTypes
#9842 - Update error messages to refer to org.jooq.trial-java-8 Maven groupId
#9849 - Compilation error in generated code for check constraints containing bad escape sequences
#9856 - Parser cannot handle double quotes in string literals
#9865 - Fix a few REDSHIFT support annotations and DDL statements
#9870 - OracleDatabase produces wrong query when tableValuedFunctions is active
#9873 - LiquibaseDatabase should use actual changeLog database table names
#9875 - [#9873] LiquibaseDatabase should use actual changeLog table names
#9896 - DB2: Wrong rendering of DSL#stddevSamp() and DSL#varSamp()
#9897 - CockroachDB does not yet implement STDDEV_SAMP() and VAR_SAMP()
#9903 - Changing getJavaClassName() for Mode.ENUM in DefaultGeneratorStrategy generates invalid code
#9907 - NullPointerException in ByteArrayClassLoader, when it is asked to load an external class
#9914 - PostgreSQL UNION requires parentheses if subquery has WITH clause
#9916 - NullPointerException in XMLDatabase when new <enforced> element is missing
#9922 - INSERT .. RETURNING with aliased target table generates wrong SQL in Oracle
#9934 - Fix Sakila install scripts for Oracle Database
#9935 - Oracle Database 11g: Column SEARCH_CONDITION_VC does not exist in table SYS.ALL_CONSTRAINTS
#9940 - AS keyword is mandatory when aliasing DML target tables in SQLite
#9946 - INSERT .. RETURNING emulation produces wrong follow up SELECT query when target table is aliased
#9954 - Incorrect SQL generated in DB2's INSERT INTO t .. RETURNING t.* emulation
#9961 - Wrong SQL generated when using implicit joins in union subquery
#9968 - Error when reading or writing timestamps of year 10000+ in HSQLDB
#9975 - Fix generated imports in RowN types
#9980 - Wrong Javadoc link in DSL.value() methods
#9992 - Firebird batch statements can produce java.sql.DataTruncation
#9996 - INSERT ... RETURNING documentation in chapter 4.3.4.6 is lacking further explanation about returningResult
#9998 - DSL.and(noCondition()) and DSL.or(noCondition()) generates a "1 = 1" or "1 = 0" predicate
#9999 - Work around CockroachDB's wrong implementation of <row> IS NULL predicate
#10007 - "constant string too long" in generated code when view source code exceeds 64KB
#10029 - Manual documentation about RenderQuotedNames is not up to date
#10033 - Stop casting bind values in INSERT .. VALUES()
#10034 - Stop casting bind values in UPDATE .. SET
#10056 - Again ORA-38104 on newer versions of Oracle
#10066 - The FOR LOOP is supported only by MariaDB 10.3
#10093 - Sqlserver datetime2 precision not respected in batch insert
#10098 - Support parsing SQL Server multi-column ADD syntax
#10121 - Compiler regression on CI
#10130 - Remove reference to ADBA from docs
#10134 - Bad formatting of nullif()
#10135 - Improve SPACE(n) emulation where possible
#10136 - DSL.repeat().getName() is "rpad"
#10139 - Unknown columns in code generator queries for Firebird 2.5
#10143 - java.nio.file.InvalidPathException: Illegal char <*> when using FilePattern on module path
#10144 - Runtime compilation error when compiling enum types on module path
#10145 - NoClassDefFoundError when trying to load JAXB from a modularised jOOQ
#10158 - The default ParseNameCase for MariaDB should be AS_IS
#10169 - Improve parser error message for 2 expected tokens
#10172 - Wrong Javadoc: There are also DSLContext.fetchSingle() methods that return null
#10183 - Bad record type returned for selectFrom(T) when T contains LEFT SEMI JOIN or LEFT ANTI JOIN
#10189 - Bad formatting when selecting NULL
#10191 - Fix several ScalaGenerator issues
#10192 - Optimistic locking does not work when recordTimestamp column has precision less than LOCALDATETIME(3)
#10194 - DefaultRecordMapper incorrectly maps immutable Kotlin classes with defaulted properties
#10195 - GenerationTool should execute SHUTDOWN on HSQLDB connections
#10197 - Implicit join constructor shouldn't be generated on table valued functions
#10203 - Bad Javadoc generated for Tables.java in the default schema
#10205 - NullPointerException when calling Meta.apply() on an H2 database with views
#10207 - DataDefinitionException: Table can only have one identity when using Meta.apply() on PostgreSQL
#10211 - Syntax errors in manual's SQL snippets
#10223 - AUTO_INCREMENT columns fail to parse if they are preceded by a column with DEFAULT
#10226 - DSLContext.fetchValue(field(name("t", "i"))) should select "i" from "t"
#10227 - Global UDT, Index, Identity, references are generated as static, not static final
#10248 - Wrong emulation of EXTRACT() with DECADE, CENTURY, MILLENIUM date parts
#10252 - Add empty comment after stmt in trigger in Db2 Sakila scripts
#10254 - Derby date time arithmetic uses unsupported sql_tsi_milli_second
#10256 - HSQLDB cannot handle negative DAY intervals when using expression syntax
#10262 - Newline configuration doesn't work
#10267 - ImmutablePOJOMapperWithParameterNames throws InaccessibleObjectException on module path
#10268 - Unrelated Liquibase error when using jooq-meta-extensions with Spring Boot
#10269 - Settings.renderQuotedNames does not work with Routine
#10271 - Cannot create or drop catalog-qualified schema in SQL Server
#10272 - NPE in Interpreter when foreign key references table from other schema that does not exist
#10279 - Missing implementations in DetachedMeta
#10281 - AbstractKey.equals doesn't work for MetaPrimaryKey
#10282 - Creating a Record, setting no fields explicitly, doing .insert(), PK is not set into Record object
#10289 - Tutorial documentation - Incorrectly suggests installing XAMPP to get MySQL
#10295 - Configuration.transactionProvider() is null after deserialisation
#10296 - Reflect branch renaming from master to main in CONTRIBUTING.md
#10301 - Columns are aliased by default to their own name, when using SQL Server parse dialect
#10305 - Excluded schema is still included in code generation of foreign keys in PostgreSQL
#10311 - Javadoc of SQLDataType.INTERVAL is incorrect
#10312 - Converted datatype not using type from dialect after calling nullable
#10313 - SQLDialect.supportedBy() sets should be used with contains(dialect()), not contains(family())
#10315 - Bad formatting of single WHEN simple CASE expression
#10318 - Long source code workaround allocates substrings twice
#10326 - Derby binary literals don't work with BLOB types
#10334 - MySQLRoutineDefinition uses HSQLDB's INFORMATION_SCHEMA.PARAMETERS table, not MySQL's
#10335 - NullPointerException when Database.setOnError(null) is called
#10336 - jooq-meta.xsd shouldn't require table_type
#10339 - orderProvider is not applied to AbstractDatabase.getSchemata0()
#10345 - NON_BIND_VARIABLE_SUFFIXES should only be used in PostgreSQL dialect
#10350 - Document Kotlin meta data usage by the DefaultRecordMapper in Javadoc
#10364 - Mistake in the "FOR clause" documentation
#10365 - DSL.currentTimestamp() should generate GETDATE() instead of CURRENT_BIGDATETIME() in Sybase ASE 12.5
#10370 - General exception error has occurred in the optimizer in Informix code generation, when generating only one schema and <includeSystemIndexes/> is turned on
#10373 - Db2 and Derby CHAR casts erroneously casts to VARCHAR
#10374 - YearToSecond interval not correctly supported in Oracle
#10381 - CockroachDB FOR UPDATE must now specify unqualified names
#10387 - XMLGenerator should quote source code from views, check constraints, and default expressions in generated output
#10390 - <sources/> and <sourcesOnViews/> are not implemented in XMLGenerator
#10394 - <comments/> and related flags implemented incorrectly in JavaGenerator
#10398 - <syntheticIdentities/> doesn't set DataType.identity(true) in generated code
#10399 - DataType.defaultValue() and DataType.identity() shouldn't be mutually exclusive
#10408 - Error in Sybase ASE INSERT .. DEFAULT VALUES emulation when used with identity column
#10410 - Excess derived table generated when putting unions in derived tables in Sybase ASE
#10413 - maven-deploy.sh and maven-install.sh should use #!/bin/bash
#10415 - Wrong Support annotations on INTERSECT and EXCEPT for MySQL
#10417 - Sybase ASE cannot cast from numbers to TEXT directly
#10421 - Sybase ASE TEXT columns get generated as LONGVARCHAR rather than CLOB
#10425 - ImmutablePOJOMapperWithParameterNames no longer injects default values for unmapped primitive arguments
#10426 - Use standard SQL for identity columns in H2 DDL
#10442 - Wrong Javadoc on Settings.renderKeywordStyle
#10444 - PostgreSQL code generation is incorrect when two tables share check constraint name
#10445 - Manual redirects don't produce anchors in manual-single-page
#10448 - Firebird arithmetic exception, numeric overflow, or string truncation; numeric value is out of range, when using Field.add(DayToSecond) with large millisecond numbers
#10459 - Empty GROUP BY emulation stops working in HSQLDB 2.5.1
#10461 - INSERT .. ON DUPLICATE KEY IGNORE emulation using MERGE should support multi value inserts
#10463 - Configuration log level is ignored by GenerationTool for first log statements
#10466 - Code generator fails with ArrayIndexOutOfBoundsException for Index..Include statements
#10467 - PostgresUtils.toPGArray does not handle escaped quotes
#10474 - Manual refers to wrong <nonnnullannotation/> code generation configuration element
#10479 - Manual section about custom code section doesn't document the possibility of overriding catalog related methods
#10480 - Avoid generating empty header comments in Keys.java
#10494 - Avoid querying ALL_JSON_COLUMNS on Oracle 12.1.0.1.0
#10498 - Compilation error in generated code when there is a table called OVERRIDE
#10508 - DSLContext.meta(Table) may contain sequences
#10538 - Improve emulation of (a, b) >= (x, y)
#10548 - Unnecessary stack elements when SelectQueryImpl doesn't have both semi join and where clause predicates
#10558 - Mention mapping into Record types in DefaultRecordMapper Javadoc
#10561 - Various compilation errors when schema, table, key names conflict
#10565 - Known issues with new FOR XML, FOR JSON features
#10567 - Translator doesn't correctly quote identifiers in FOR XML and FOR JSON emulations
#10579 - JavaWriter::beforeClose shouldn't search for package using a regex
#10586 - Some missing nullable annotations in generated code
#10587 - NullPointerException when misconfiguring code generator, lacking a <database/>
#10594 - Meta::ddl does not correctly export view contents from generated code
#10595 - Error when fully qualifying a view with catalog name in CREATE/DROP VIEW in SQL Server
#10602 - Missing NOT NULL constraint in generated DDL for some dialects
#10603 - Ambiguous match found when using complex implicit join graphs
#10605 - offset(0) is ignored
#10608 - Apply URL rewrite in /latest and /dev manuals also to internal links
#10614 - Avoid ClassCastException when comparing two column values without natural order in Record::compareTo
#10624 - Failing constraint exclusion with partitioned tables in Postgres 12.4 - 10.2
#10628 - BackslashEscaping.DEFAULT should implement ON behaviour in Redshift, not OFF
#10635 - AbstractQueryPart::equals might not work when one QueryPart has a different Configuration than the other
#10644 - Add Settings.transformUnneededArithmeticExpressions to optimise arithmetic prior to SQL generation
#10655 - Support empty INSERT .. VALUES() clause via DEFAULT VALUES
#10663 - Improve formatting of CONNECT BY emulation of GENERATE_SERIES
#10664 - DataType.getArrayDataType() should wrap custom Converter<T, U> implementations into Converter<T[], U[]> automatically
#10669 - Parser should parse DATE - DATE to dateDiff() and TIMESTAMP - TIMESTAMP to timestampDiff()
#10670 - Error when parsing Oracle (+) operator with ParseUnknownFunctions.IGNORE
#10674 - jOOQ Translator - Maria DB Version are missing
#10675 - Parser doesn't recognise Oracle ( + ) operator, if it contains whitespace
#10678 - Unsafe re-use of object in Expression math causes incorrect SQL generation
#10679 - Parser incorrectly parses IN predicate of degree > 1 with extra parentheses around SELECT subquery
#10680 - Translator should ignore unknown functions
#10704 - ClassCastException when using MockDataProvider with Oracle ArrayRecord types
#10718 - Error when mocking Oracle routines that have VARRAY or TABLE parameters
#10720 - MockConnection must not produce first ResultSet when calling stored procedures with OUT parameters
#10736 - NullPointerExceptions when calling DSLContext.informationSchema() with DSL.schema(Name) and similar meta data
#10738 - NullPointerException in Meta.migrateTo() when using DatabaseMetaData backed Meta containing views
#10741 - NullPointerException in SQLite Meta.migrateTo() when using DatabaseMetaData backed Meta containing FK referencing wrong identifier case
#10743 - Fix emulations of nested FOR JSON and FOR XML queries
#10751 - Code generator can't handle SQL Server database names with dash