jOOQ Release notes
==================
- For an interactive overview, see also https://github.com/jOOQ/jOOQ/issues
- For a formatted text version, see https://www.jooq.org/notes
- For a text version, see https://www.jooq.org/inc/RELEASENOTES.txt
- For an API diff, see https://www.jooq.org/api-diff
Version 3.20.7 - September 11, 2025
================================================================================
This is a 3.20 patch release with minor improvements and bug fixes
Features and Improvements
-------------------------
#18898 - Add information about the lack of thread safety in Meta implementations to Meta Javadoc
#18947 - Add catalog support for Databricks in MetaImpl
#18952 - Add Javadoc to various SPIs about an expectation for them to be side-effect free and thus cacheable
#18979 - Improve DSLContext.meta(Catalog...) and similar Javadoc to explain that these are intended to be used with generated code
#19034 - Support ClickHouse ALTER TABLE .. ADD INDEX / DROP INDEX syntax
Bug Fixes
---------
#18859 - Meta.getSequences() only lists sequences of current catalog in SQL Server
#18863 - DuckDB code generation can't generate sequences for multiple catalogs
#18866 - DuckDB DSL.currentTime() returns NULL
#18869 - Fix throwing IntegrityConstraintViolationException in DuckDB
#18872 - DuckDB doesn't support TIME precision
#18875 - DuckDB doesn't support TIMESTAMPTZ precision
#18883 - HTML encoding issue in DataType Javadoc
#18888 - Bad routine code generated when using array types in H2 stored functions
#18896 - Invalid Require-Capability OSGi MANIFEST header in JDK 21 built artifacts
#18902 - NullPointerException in various locations when another thread cancels a blocking, JDBC backed Subscription
#18906 - Base64 error when using multiset, binary column, and custom converter in MySQL
#18911 - Parser cannot handle Long.MIN_VALUE signed integer literal in rare contexts
#18914 - KotlinGenerator produces bad code when sequences reference Long.MIN_VALUE with their flags
#18919 - Cannot use Parser::parseSignedIntegerLiteral to parse BigInteger sequence flag values
#18922 - KotlinGenerator generates invalid code for sequences with BigInteger MINVALUE or MAXVALUE flags
#18925 - PostgreSQL UDT array not deserialized correctly when embedded in multiset
#18928 - Avoid allocating StringBuilder in PostgresUtils::toPGObjectOrArray if not necessary
#18932 - Avoid DefaultDSLContext allocation in AbstractQueryPart::equals
#18936 - Revert to using classes instead of records for Cache.Key2 and Cache.Key3 objects
#18942 - Override FieldAlias::equals and hashCode to improve reflection cache performance
#18950 - Cached RecordMapper instances should cache also ConverterProvider results
#18951 - Cannot convert from user type to UnknownType error when converting nested, mapped type to itself
#18956 - Bad result in MariaDB when MULTISET contents contain binary data
#18962 - Wrong data type generated in DDL for VARBINARY converted as UUID type
#18966 - Bad DDL generated when attempting to CREATE TABLE with UUID column in Oracle and other dialects
#18969 - Wrong encoding of JSONB document contained in MULTISET using XML emulation in Db2
#18971 - ORA-01790 when projecting NULL bind value of type BLOB in UNION ALL query
#18975 - Bad rendering of unsupported OffsetTime type in Oracle
#18984 - Avoid calling Stream::collect in Result::collect and Cursor::collect
#18990 - Cache Method::getParameterTypes and Method::getGenericParameterTypes in reflection cache
#18992 - Race condition in JooqLogger leads to too many identical messages being logged, where only one is requested
#18994 - Avoid unnecessary ConverterContext allocations in jOOQ internals
#18995 - QOM generated equals() methods shouldn't use StringUtils::equals, but Objects::equals
#19005 - Make DefaultExecuteContext available to internals via ThreadLocal
#19010 - Change AbstractParseContext to be an AbstractLazyScope
#19014 - Change some AbstractLazyScope implementations to inherit their Scope::creationTime from the parent scope
#19019 - Regression: Wrong DDL exported by MetaImpl for MySQL DEFAULT CURRENT_TIMESTAMP columns
#19022 - Adding a DDL comment to aliased columns produces wrong SQL, or does not maintain comment after execution
#19027 - DDLDatabase and H2Database shouldn't generate VARCHAR(1000000000) for VARCHAR types without explicit length
#19031 - Various code generator queries fail with more recent ClickHouse server or client versions
#19036 - ALTER TABLE .. ADD FOREIGN KEY .. REFERENCES references unqualified table name when column is also added
#19040 - Correctly handle NULLS FIRST | NULLS LAST in SEEK method
Version 3.20.6 - August 12, 2025
================================================================================
This is a 3.20 patch release with minor improvements and bug fixes
Features and Improvements
-------------------------
#18733 - Add DataType::isQualifiedRecord and DataType::isUDTRecord
#18826 - Add Meta and DDL catalog support for Databricks
#18846 - Add a warning to the Query::bind Javadoc about the method not being very useful in general
Bug Fixes
---------
#18588 - Upgrade pgjdbc dependency to 42.7.7 to mitigate CVE-2025-49146
#18594 - Meta.getSchemas() produces schema multiple times across catalogs in DuckDB
#18595 - Ad-hoc compilation of code generator shouldn't require adding jooq-codegen dependency to project, explicitly
#18600 - Wrong list of supported dialects on various IF [ NOT ] EXISTS methods
#18610 - NClobBinding doesn't correctly bind NULL values
#18613 - Inlining of large SQLDataType.NCLOB values doesn't use TO_NCLOB() in Oracle, like for large CLOB values
#18619 - NClobBinding should revert to ordinary String usage when JDBC driver doesn't support NClob
#18622 - MetaImpl doesn't return Db2 GLOBAL TEMPORARY tables
#18635 - JDBC backed MetaImpl reports Oracle GLOBAL TEMPORARY tables as ordinary tables
#18644 - Slash in name results in invalid identifier being generated using KotlinGenerator
#18647 - KotlinGenerator produces bad code when table / column identifier disambiguation clashes with special character escaping
#18650 - Bad file names generated on Windows in KotlinGenerator and ScalaGenerator when using special characters
#18655 - Compilation error in Kotlin generated code when table name contains special characters and paths are generated
#18658 - org.jooq.codegen.gradle.MetaExtensions classes should adhere to JavaBeans convention to avoid deprecation warning in Gradle 8.x
#18664 - Bad types generated in Informix UDT classes for informix.boolean, informix.blob, and informix.lvarchar types
#18667 - Informix generated code contains extra "_0" attribute in generated UDTs
#18671 - Work around Informix JDBC driver java.lang.IllegalMonitorStateException bug when reading UDT out parameters
#18673 - Parser cannot parse Oracle style IN, OUT modifier in procedure declarations
#18688 - PostgresDatabase and subtypes may still produce wrong table comments in presence of stored functions
#18689 - PostgreSQL UDT not deserialized correctly when embedded in multiset
#18694 - Function parameter references aren't rendered with @ prefix in SQL Server, in function body
#18697 - Generated CREATE FUNCTION statement renders extra BEGIN .. END block in SQL Server
#18703 - MetaImpl should support DataType::generatedAlwaysAs property if JDBC DatabaseMetaData::getColumns can report it
#18708 - MetaDataFieldProvider debug logs warnings about Nullable(xyz) types not being supported for ClickHouse
#18710 - DataType.generationOption(null) shouldn't store null value, but DEFAULT value
#18719 - Bad formatting in PostgreSQL IF [ NOT ] EXISTS emulation when nested in more blocks
#18723 - Cannot place Oracle UDT in MULTISET with JSON emulation
#18729 - Settings.renderQuotedNames shouldn't affect xsi:nil attribute rending in MULTISET XML emulation
#18737 - Typo in DataType::hidden Javadoc
#18739 - Code generator does not apply DataType.GEOMETRY to PostgreSQL materialized view
#18750 - Formatting problem in generated Kotlin UDTs
#18754 - Insert::$updateSet doesn't replace the SET clause, but appends to it
#18763 - Parser fails to parse T-SQL query with TOP and quoted identifiers, when Settings.parseDialect is set to DEFAULT
#18774 - Bad rendering of UDTPathField in PL/SQL contexts
#18788 - XMLDatabase has O(N^2) complexity in column / attribute / parameter lookups
#18809 - Procedural IF a = b is emulated incorrectly in H2
#18828 - Missing VARCHAR lengths in Databricks generated code
#18830 - MetaImpl reports wrong array component length for Databricks
#18833 - Avoid unnecessary StringReader and StringWriter allocations and data transfer in MULTISET deserialisation
#18837 - deprecation notice should mention DateAsTimestampBinding alternative explicitly
#18842 - JSONParser::parseStringLiteral should omit StringBuilder copy if no escape sequence is found
Version 3.20.5 - June 11, 2025
================================================================================
This is a 3.20 patch release with minor improvements and bug fixes
Features and Improvements
-------------------------
#18432 - Add a jOOQ-bom module
Bug Fixes
---------
#18442 - Diff cannot handle name swaps of constraints and indexes
#18451 - Diff should drop PRIMARY KEY first, then NOT NULL constraint
#18457 - CockroachDB 24 identity column sequences aren't recognised as system sequences by code generator or runtime Meta
#18463 - Diff must never drop single column from table
#18466 - IN list padding generates too large lists in rare edge cases due to floating point rounding errors
#18470 - Ad-hoc converter receives non-attached records when using implicit join path table projections from within MULTISET
#18475 - Race condition in TableImpl initialisation leads to wrong INFO log message about duplicate identities in AbstractTable#getIdentity
#18482 - Diff generates CREATE VIEW statements that depend on not-yet existing tables
#18485 - Parser doesn't recognise built-in functions when quoted
#18495 - DDLExportConfiguration::createOrReplaceSynonym returns wrong flag
#18496 - Diff should export synonyms
#18505 - Diff may produce DROP TABLE before corresponding DROP SYNONYM statement
#18507 - Diff should properly sort DDL for Sequences, Schemas, Catalogs
#18517 - Meta::getDomains methods have insufficient dialect support
#18521 - Interpreter can only work with the first Settings.interpreterSearchPath
#18527 - The Settings.migrationDefaultSchema doesn't apply to Diff
#18529 - Configuration::derive and SettingsTools::clone don't deep-clone all Settings collection properties
#18535 - Wrong rendering of implicit join in DML when query is wrapped in DSL::queries
#18538 - Excess semicolon rendered when procedural block is placed inside of DSL::queries
#18544 - Parser cannot handle left-associative parenthesised nested set operations in derived table
#18549 - Parser cannot parse non-scalar subquery NULL predicate
#18553 - Parser cannot parse CAST(? AS ) expression in certain DDL contexts
#18558 - Upgrade Spring dependency to 6.2.7 to mitigate CVE-2024-38820
#18562 - Informix stored functions containing DML cannot be called from SELECT statement
#18572 - NullPointerException when working with Scala-3 generated enums (or Java enum literals with bodies)
Version 3.20.4 - May 2, 2025
================================================================================
This is a 3.20 patch release with minor improvements and bug fixes
Features and Improvements
-------------------------
#18320 - Document how to run individual Maven plugin executions from the command line
#18345 - Add native DECODE support for Redshift
Bug Fixes
---------
#18287 - Oracle JSON type cannot be mapped to DBMS_SQL.XXX_TABLE type when using INSERT .. RETURNING
#18294 - CREATE MATERIALIZED VIEW IF EXISTS isn't emulated correctly in Oracle 19c and earlier
#18302 - Compilation error in generated Keys class when non-embeddable unique keys overlap with embeddable primary keys
#18310 - Javadoc typo in Stringly class
#18316 - Compilation error in generated Kotlin or Scala code when working with audit columns
#18331 - MULTISET JSON enumeration rounds NUMERIC values as they're represented as Double values by JSON parser
#18334 - Exception when parsing large double values without decimals in MULTISET JSON emulation
#18338 - Wrong SQL generated when using inline derived table in UPDATE .. RETURNING emulation using UPSERT in MariaDB
#18343 - SQLDialect.REDSHIFT generates wrong CREATE MATERIALIZED VIEW syntax
#18354 - Remove H2 specific Javadoc from MERGE statement
#18361 - Support GROUP BY
in REDSHIFT
#18364 - Support LIMIT with subqueries in REDSHIFT
#18374 - Wrong Support annotation on InsertOnConflictDoUpdateStep::doUpdate
#18380 - Meta.migrateTo() should defer adding FOREIGN KEY constraints after CREATE TABLE
#18384 - Wrong ordering of adding PRIMARY KEY to parent table and FOREIGN KEY to child table with Meta::migrateTo
#18389 - Missing ALTER TABLE .. DROP CONSTRAINT statement generated for FOREIGN KEY when dropping both parent key and child table using Meta::migrateTo
#18404 - ORDER BY Javadoc references a non-existing DSL.literal() method
#18409 - Code generator logs forced type application multiple times
#18417 - LIMIT emulation should use <= comparison instead of BETWEEN comparison, if there's no OFFSET
Version 3.20.3 - April 2, 2025
================================================================================
This is a 3.20 patch release with minor improvements and bug fixes
Features and Improvements
-------------------------
#18139 - Add Settings.emulateNestedRecordProjectionsUsingMultisetEmulation to replace flattening emulation by MULTISET emulation for top level nested record projections
#18178 - Add some WARN logging about the Settings.namePathSeparator when people turn off quoting of identifiers and use flattened nested rows
#18230 - Add Snowflake support for Field::likeRegex and DSL::regexpReplaceAll
#18243 - SnowflakeDatabase::getTables should read table comments from INFORMATION_SCHEMA.TABLES
Bug Fixes
---------
#18134 - Log message doesn't concatenate helpful information in code generator
#18142 - MergeImpl shouldn't implement QOM.UNotYetImplemented anymore
#18145 - MULTISET emulation using XML doesn't correctly encode NULL String values when nesting tables as SelectField
#18153 - JSON MULTISET emulation of deeply nested records doesn't correctly set touched flag to false
#18158 - ORA-17004 Invalid column type when trying to read XML typed expression using R2DBC in Oracle
#18162 - YearToMonth::valueOf cannot parse P0D, which is a valid Period value
#18166 - Wrong YearToMonth interval parsed when parsing ISO interval values with negative components
#18170 - Wrong type generated in Oracle NVARCHAR CAST
#18181 - AbstractRowAsField should generate DSL.quotedName() identifiers when emulating nested records using aliased flattened fields
#18187 - MULTISET XML emulation doesn't work on SQL Server for unnamed columns: An object or column name is missing or empty
#18193 - Converter is not applied in multisets
#18199 - DefaultConverterProvider cannot convert "1970-01-01T00:00Z" string to OffsetDateTime
#18204 - DSL.excluded with UDTField creates query with syntax error
#18207 - XJC generated toString() methods produce empty list elements
#18211 - XJC generated equals() and hashCode() values are List lazy initialisation sensitive
#18215 - ROWNUM transformation prevents FOR UPDATE transformation in SQL Server
#18220 - Revert deprecation of internal, protected AbstractRecord.from(Record) method
#18223 - BatchMultiple rendering Context doesn't have a Context.executeContext() reference
#18227 - SQLite doesn't actually support a REGEXP operator
#18235 - Window specification isn't inlined in Snowflake query using WITH TIES syntax
#18239 - Excess whitespace in formatted CREATE TABLE .. COMMENT clause for Snowflake
#18248 - Wrong SET SCHEMA implementation for Snowflake
#18252 - Add SNOWFLAKE to the DerivedTable.NO_SUPPORT_CORRELATED_DERIVED_TABLE list
#18258 - KotlinGenerator doesn't produce TriggerNames file in a names subpackage
#18266 - DSLContext::nextvals and DSL::digits isn't really supported by Derby
#18270 - Derby cannot emulate CONTAINS, STARTS_WITH, ENDS_WITH using LIKE
#18277 - Query.getSQL(NAMED) produces a gap in the parameter numbering when the query contains a null UDT value, while Query::getBindValues still produces the value
#18280 - Regression: Failed UpdateableRecord::delete resets the Record::original values to null and sets the Record::touched values to true
Version 3.20.2 - March 11, 2025
================================================================================
This is a 3.20 patch release with minor improvements and bug fixes
Features and Improvements
-------------------------
#18063 - Add MySQL and MariaDB support for ALTER TABLE .. SET NOT NULL / DROP NOT NULL
#18106 - DiagnosticsListener Javadoc should link to manual
Bug Fixes
---------
#18049 - Include fields and values lengths in "The number of values must match the number of fields" error message
#18053 - Meta.migrateTo() drops column before dropping its foreign keys or indexes
#18056 - ClassCastException in ArrayConverter when working with primitive typed int.class component type
#18060 - ArrayStoreException when using Converter with empty arrays
#18079 - DiagnosticsListener::duplicateStatements event isn't triggered for DiagnosticsConnection.ON setting
#18085 - DiagnosticsConnection.ON does not retain the internally created DiagnosticsConnection's caches
#18099 - PostgreSQL nested row isn't attached to Configuration when used with ad-hoc converter
#18102 - Record::key produces unattached records
#18115 - should explicitly declare String type in KotlinGenerator, for usage with explicit API compiler flag
#18117 - should generate const val in KotlinGenerator or ScalaGenerator, for annotation usage
#18124 - Work around ORA-00929: missing period when fully qualifying JSON columns
Version 3.20.1 - February 21, 2025
================================================================================
This is a 3.20 patch release with minor improvements and bug fixes
Bug Fixes
---------
#18035 - Scala 3.5 problem when calling AbstractTable::getIdentity from generated code
#18038 - Generated POJO equals() and hashCode() implementations shouldn't exclude non-primary key columns by default
Version 3.20.0 - February 19, 2025
================================================================================
New dialects:
-------------
jOOQ 3.20 ships with 2 new experimental dialects:
- ClickHouse in all editions, including the jOOQ Open Source Edition
- Databricks in the jOOQ Enterprise Edition
ClickHouse is a fast-moving SQL dialect with a historic vendor-specific syntax
that is gradually migrated to a more standards compliant alternative, which is
why our support is still experimental. A lot of behaviours differ from what one
would expect elsewhere, including NULL handling, which is very different from
standard SQL. Future jOOQ versions will continue deepening this integration.
Databricks offers a very promising SQL dialect with a lot of functionality,
which we're going to cover in full with the next version jOOQ 3.21. An initial
version of the dialect is shipped already in 3.20 as an experimental dialect.
3.20 will continue to receive bug fixes and Databricks improvements as we work
with early adopting customers.
DuckDB improvements
-------------------
We continue supporting various DuckDB SQL features, including:
- ARRAY, ROW, and STRUCT support
- MULTISET support
- JSON support
- Date time arithmetic
- Sequences
- More DDL support
- More DML support
- Spatial support
- And much more
New modules
-----------
In order to better integrate with Reactor, probably the most popular reactive
streams API on the JVM, we've added a new jOOQ-reactor-extensions module, which
offers an implementation of the new SubscriberProvider SPI, a new
SPI in the Configuration that helps make jOOQ's R2DBC specific internals
Reactor Context aware.
The jOOQ-beans-extensions module now hosts our support for the
@ConstructorProperties annotation in the
DefaultRecordMapper, an annotation that is located in the JDK's
jdk.desktop module. This allows us to move the heavy module
dependency out of jOOQ's core library, which is useful for those applications
that want to omit shipping the complete JDK and keep low footprints.
The jOOQ-jpa-extensions module now hosts our support for the various JPA
annotations like @Column, @Table, also in the
DefaultRecordMapper, effectively removing the optional
jakarta.persistence dependency from the core library, as well as
offering alternative implementations of annotation based mapping.
Support for Oracle type hierarchies
-----------------------------------
Oracle is the most sophisticated ORDBMS implementation, with a rich set of
object-oriented PL/SQL language features. jOOQ 3.20 finally adds support for
PL/SQL OBJECT type hierarchies both in our code generator as well as in the
runtime library, making jOOQ an even strong match for your PL/SQL language usage
This is a commercial only feature.
Better spatial support
----------------------
A lot of additional spatial functions have been added to jOOQ's spatial support.
These efforts also include many improvements to the DuckDB and Oracle spatial
implementations.
For more information, refer to:
- https://www.jooq.org/doc/dev/manual/sql-building/column-expressions/spatial-functions/
- https://www.jooq.org/doc/dev/manual/sql-building/conditional-expressions/spatial-predicates/
This is a commercial only feature.
DECFLOAT support
----------------
A variety of dialects offer an additional decimal floating point data type,
DECFLOAT, in addition to the binary floating point types
REAL (32 bit), DOUBLE PRECISION (64 bit), and
FLOAT (variable sized). Our new org.jooq.Decfloat
type allows for capturing these types in our code generator and runtime.
Synonym support
---------------
A variety of dialects support the concept of a SYNONYM or
ALIAS where an alternative name can be given to any object type.
jOOQ 3.20 supports these synonyms both in the code generator as well as the DDL
API. Future jOOQ versions may continue to improve synonym support, e.g. by
generating type aliases in Kotlin or Scala.
For more information, refer to:
- https://www.jooq.org/doc/dev/manual/code-generation/codegen-synonyms/
This is a commercial only feature.
Hidden columns
--------------
Just like a few dialects support hidden or invisible columns, this is now
possible in jOOQ as well, at the client side. Hiding columns effectively removes
them from:
- Asterisk expansions
- selectFrom() and similar calls
- Generated records, POJOs, and interfaces
At the same time, the columns are still available for explicit references. This
feature can be useful for schema evolution purposes, where data of deprecated
columns is kept around for historic purposes. It works well together with the
column deprecation feature of the code generator:
- https://www.jooq.org/doc/latest/manual/code-generation/codegen-advanced/codegen-config-database/codegen-database-comments/
For more information about hidden columns, refer to:
- https://www.jooq.org/doc/dev/manual/sql-building/column-expressions/hidden-columns/
This is a commercial only feature.
Kotlin 2 and Scala 3 support
----------------------------
Starting from jOOQ 3.20, we formally support both Kotlin 2 and Scala 3 and
fully integration tests both the core libraries as well as the code generator
and extension libraries on these language versions. For Scala support, please
also consider our support matrix:
- https://www.jooq.org/download/support-matrix-scala
JDK baselines
-------------
The jOOQ Open Source Edition 3.20 increases its baseline to JDK 21. Support for
older JDKs is available int he commercial distributions, see:
- https://www.jooq.org/download/support-matrix-jdk
Record dirty tracking
---------------------
jOOQ has long supported record dirty tracking in its
UpdatableRecord allowing for a simple way of performing CRUD. With
jOOQ 3.20, it will be possible for users to override the default behaviour of
the dirty flag from a "touched" semantics to a "modified" semantics, effectively
sending only actual modifications to the database.
For more information, refer to:
- https://www.jooq.org/doc/dev/manual/sql-building/dsl-context/custom-settings/settings-dirty-tracking/
DML join improvements
---------------------
jOOQ 3.20 now supports the useful DELETE .. USING and
UPDATE .. FROM syntaxes on all RDBMS through a new set of SQL
transformations that allow for these vendor specific JOIN syntaxes to be used
in DML statements even in the absence of MERGE statement support.
At the same time, MERGE itself also received an upgrade, including:
- BY SOURCE and BY TARGET support
- Multiple WHEN NOT MATCHED AND .. clause support
For more information, refer to:
- https://www.jooq.org/doc/latest/manual/sql-building/sql-statements/update-statement/update-from/
- https://www.jooq.org/doc/latest/manual/sql-building/sql-statements/delete-statement/delete-using/
- https://www.jooq.org/doc/latest/manual/sql-building/sql-statements/merge-statement/
Code generation improvements
----------------------------
A lot of problems related to the generation of interfaces, immutablePojos, UDTs,
etc. have been addressed in this release, making generated code more sound for
various configuration edge cases where these features are combined.
Manual search
-------------
We have (at last!) added in-page search functionality to our user manual, so
users can better find information on our website.
For a complete list other, minor improvements, see the below change notes.
Features and Improvements
-------------------------
#644 - Add support for Oracle TYPE .. UNDER type hierarchies
#2309 - Add search to manual pages
#4819 - Document the fact that org.jooq.Binding does not necessarily have to implement a complete org.jooq.Converter
#5394 - Add Settings.recordDirtyTracking to prefer Record.modified() over Record.touched() for dirty tracking operations
#5844 - IndexOutOfBoundsException when calling PostgreSQL table valued function returning empty result, with turned off
#7104 - Add DSL.stringAgg() and stringAggDistinct()
#7406 - Add code generation support for SETOF UDT returning functions in PostgreSQL
#7531 - Support UNION .. LIMIT in Teradata
#7539 - Add support for Clickhouse
#8705 - Add code generation configuration to generate primary key based equals() and hashCode() on POJOs
#9557 - Add support for ALTER TABLE .. DROP CONSTRAINT IF EXISTS
#9574 - Add org.jooq.Synonym
#9736 - Add runtime model for foreign key ON DELETE and ON UPDATE actions
#10059 - Add support for SQL Server MERGE .. WHEN NOT MATCHED BY { SOURCE | TARGET }
#10574 - Add PascalCaseGeneratorStrategy to improve user experience for T-SQL schemas implemented in PascalCase
#10715 - Add support for multiple MERGE .. WHEN NOT MATCHED AND { condition }
#10776 - Add GeneratorStrategy::getJavaMemberOverride, getJavaSetterOverride, getJavaGetterOverride, getJavaMethodOverride
#11158 - Emulate UPDATE .. JOIN with UPDATE .. FROM where not supported natively
#11371 - Generate UDT.getSupertype() and UDT.getSubtypes()
#11375 - Should produce a file containing enum literals for each enum type
#11886 - Avoid parentheses when rendering associative concatenation chains
#12073 - Emulate combination of JSON_ARRAYAGG() FILTER clause and NULL ON NULL clause
#12180 - Add support for Scala 3
#12361 - Emulate simple cases of the data change delta table in Firebird, MariaDB, SQL Server
#12462 - Overload DSL.function() to accept arguments also as Collection extends Field>>
#12494 - Add additional Record.modified() and Record.touched() methods, deprecate Record.changed()
#12605 - Add support for Firebird 4 TIME[STAMP] WITH TIME ZONE data types
#12736 - Continue support for spatial extensions
#13304 - Every manual section that makes use of classpath resources should briefly explain how to use classpath resources in the code generator
#13411 - Add , a flag that removes columns from projections by default
#13412 - Emulate UPDATE .. FROM with multiple tables or joins
#14398 - Avoid rendering parentheses on left associative operations
#14402 - Add experimental support for Databricks SQL
#14490 - Add a jOOQ-reactor-extensions module offering reactor specific extensions
#14552 - Add more "Don't Do This" content to the manual
#14610 - Get HANA dialect support up to date
#14676 - Document Fields::field behaviour in the manual
#14775 - Add Settings to turn off client side computed column including audit columns
#14806 - Upgrade checkerframework to 3.19.0 to better support JDK 17
#14827 - Add support for the JSON_KEY_EXISTS() function
#14894 - Remove examples in favour of our demo
#15012 - Get BigQuery dialect up to date
#15177 - Make JDK 21 the baseline for the jOOQ Open Source Edition
#15222 - Improve exception message when SEEK field list size doesn't match ORDER BY field list size
#15251 - Add support for synthetic DEFAULT expressions
#15346 - Add a Settings.fetchTrimmedCharValues flag to auto-trim CHAR results from certain RDBMS
#15528 - Add a section to the manual about experimental and internal API
#15637 - Emulate DELETE .. USING with MERGE, where available
#15723 - Generate comments also on other PostgreSQL object types
#15732 - Improve on DuckDB support
#15830 - Add support for the Oracle 23ai multi row INSERT .. VALUES statement
#15906 - Continue work on public query object model API
#15968 - Add section in Maven code generation manual page about multiple executions
#15970 - Manual page about implicit join type settings should document Settings.renderImplicitJoinToManyType
#15979 - Visually separate active / eol / snapshot versions on website
#15987 - pom.xml files should use https links instead of http links
#15989 - AbstractJoin.toString() should render SQL with tables declared, not referenced
#15999 - Add a section to the manual showing usage of EXCLUDED with INSERT .. ON DUPLICATE KEY UPDATE
#16002 - Add new code generation flag to omit @NotNull / @Nullable annotations on write-only nullable types
#16009 - Document on codegen-database-include-object-types
#16012 - Add Javadoc to discourage using any Fields.field(x, Class) method if there's an Fields.field(x, DataType) overload, as well as inline(T), value(T), and val(T)
#16031 - SQLPerformanceWarning should log hint about gathering dictionary statistics in OracleDatabase
#16044 - org.jooq.tools.Convert should delegate to org.jooq.impl.Convert, instead of duplicating implementations
#16071 - Add MAX_BY() and MIN_BY() aggregate functions
#16087 - Improve manual section about jOOQ-codegen-gradle
#16093 - Add matcher strategies for method overrides
#16101 - Support binary versions of supported string functions
#16110 - Add documentation sections for BIT_LENGTH and OCTET_LENGTH functions
#16112 - Mark tags as releases in GitHub repo
#16117 - Upgrade dependencies
#16121 - Add Context.scopeParts(Class): Iterable to allow for iterating over the values that are currently in scope
#16135 - Add a code generation flag that applies the forcedType for RDBMS hidden fields
#16136 - Meta::ddl should include hidden columns in DDL exports
#16138 - Let AbstractRecord, AbstractRow implement FieldsTrait
#16139 - Upgrade Spring dependency from jOOQ-meta-extensions-hibernate to 6.1.3 due to CVE-2024-22233
#16178 - Implement in more dialects
#16216 - Add parser support for SQLite's undocumented inline AUTOINCREMENT syntax
#16227 - Add JSON_ARRAY_LENGTH() function support
#16274 - Document ARRAY_APPEND and ARRAY_PREPEND functions
#16287 - Upgrade DuckDB dialect to DuckDB 0.10.2
#16289 - Support COMMENT ON in DuckDB 0.10.0
#16307 - Add parser support for MySQL YEAR_MONTH style interval literals
#16308 - Support parsing ORDER BY clause of STRING_AGG function
#16318 - Allow for specifying inputs to the gradle CodegenTask in order to participate in incremental builds
#16363 - Upgrade pgjdbc to 42.7.3
#16416 - Split CREATE SEQUENCE section of the manual to document flags individually
#16418 - Add flag to a few code generation elements, for better reuse
#16432 - Add support for the CBRT() and ROOT() functions
#16436 - Document DSL.jsonGetElement() index being 0 based
#16442 - Support parsing function alternatives to operators
#16448 - Add auto converter support between primitive and non-primitive arrays
#16483 - Add Settings.renderNullifEmptyStringForBindValues to emulate Oracle behaviour on other RDBMS
#16484 - Document Settings.renderCoalesceToEmptyStringInConcat
#16486 - Add native support for SEMI JOIN / ANTI JOIN in DuckDB
#16492 - Add code generation support for FOREIGN KEYs in DuckDB
#16498 - Render standard SQL DATE literal on MySQL, instead of JDBC date literal
#16499 - Add support for lambda accepting array functions
#16501 - GeneratorStrategy::getJavaMemberOverride should be called with Mode.DAO for all member-specific fetchByXYZ methods generated in a DAO
#16509 - Avoid more internal COALESCE calls when unnecessary via AbstractField::isNullable
#16515 - Add named parameters to QOM.ArrayReplace, QOM.ArrayRemove, QOM.ArrayPrepend, QOM.ArrayAppend
#16518 - Support CockroachDB 22.1 ON CONFLICT .. ON CONSTRAINT
#16520 - Add AlterTableStep.add(TableElement) overload
#16521 - DefaultRecordUnmapper should be able to unmap a JDBC Struct
#16522 - Add alternative setNonKeyToExcluded(), setNonPrimaryKeyToExcluded(), and setNonConflictingKeyToExcluded() methods to UPSERT syntax
#16524 - Add support for MySQL's BIN_TO_UUID and UUID_TO_BIN functions
#16531 - Document missing Parser::parseSelect and Parser::parseStatement methods in manual
#16563 - Support delimiter expressions in LISTAGG() and GROUP_CONCAT()
#16592 - Add OrderedAggregateFunction::orderBy as a synonym for withinGroupOrderBy
#16594 - Add BigQuery support for ARRAY_AGG
#16600 - Add a flag
#16601 - Add more support to jooq-meta.xsd
#16607 - Add DataType.hasFixedLength()
#16608 - Add a documentation example in the manual page about matcher rule showing how to remove prefixes / suffixes
#16615 - Support BigQuery's ALTER COLUMN SET OPTIONS as a COMMENT ON COLUMN implementation
#16620 - Add parser support for the T-SQL DDL ALTER TABLE .. WITH CHECK clause
#16628 - Rename SQLDialect.ORACLE23C to ORACLE23AI
#16629 - Support CTE column aliasing for plain SQL templates where this isn't supported
#16633 - Add broader DELETE .. USING and UPDATE .. FROM support, using the same emulation as that for DML ORDER BY .. LIMIT
#16638 - Let DataAccessException::sqlStateClass be based on HANA error codes for SQLStateClass 22 or 23
#16639 - Add HANA support for LATERAL, CROSS APPLY, OUTER APPLY
#16640 - Add HANA support for COLLATE
#16643 - Add parser support for SQLite's TOTAL() aggregate function
#16644 - Add parser support for Teradata's MAXIMUM() and MINIMUM() synonyms for MAX() and MIN()
#16666 - Add SQLite support for GROUP_CONCAT(DISTINCT ..)
#16670 - Add jakarta.annotation.Generated as possible GeneratedAnnotationType
#16690 - Support Kotlin 2.0
#16695 - Create subsections for the ORDER BY clause
#16696 - Add a new Settings to override the reflection cache sizes
#16732 - Support references to UPDATE .. FROM tables from SET clause in dialects that support UPDATE .. JOIN
#16751 - Emulate JSON_OBJECTAGG() with FILTER in Oracle
#16752 - Add a SQLDialect.MARIADB_11_2 dialect
#16754 - Add JSON function support in BigQuery
#16759 - Add support for BigQuery PERCENTILE_CONT, PERCENTILE_DISC window functions
#16760 - Support DEFAULT expression in BigQuery INSERT and UPDATE
#16767 - Add DataType.autoIncrement() and DataType.generatedByDefaultAsIdentity() as a synonyms for DataType.identity(true)
#16768 - Parse and ignore SQL Server CREATE TABLE column constraint index options
#16784 - Add manual page for readonly related Settings flags
#16805 - Clarify EmbeddableRecord Javadoc
#16825 - The code generation initScript property should be able to read from the file system
#16827 - Add Source.resolve(String) to allow for varied, string based input sources
#16830 - Add DuckDB spatial support
#16836 - Add support for DuckDB 1.0.0
#16839 - ArrayDataType.getRow() and ArrayDataType.getRecordType() should delegate to underlying elementType
#16841 - Add native support for Oracle23ai BOOLEAN typed field expressions from conditions
Breaking changes
----------------
#7668 - DAO fetch methods should use GeneratorStrategy::getJavaMemberName with Mode.DAO instead of getJavaClassName
#10297 - HANA's TINYINT correspond to UByte, not Byte
#10880 - Add support for the Db2, H2, Firebird 4 DECFLOAT data type (HANA: SMALLDECIMAL)
#12851 - Add support for CREATE SEQUENCE .. AS
#15941 - Remove pre 3.9 deprecated API and pre 3.9 documentation
#15966 - Remove mandatory dependency from compileJava to jOOQ-codegen-gradle tasks
#16084 - Wrong order of MiniJAXB.append() calls in jOOQ-codegen-gradle
#16092 - JavaGenerator::generateRecordSetter0 uses wrong Mode.POJO for GeneratorStrategy::getJavaMemberName call
#16344 - QOM.Count.$field() should return null instead of internal asterisk representation
#16444 - Remove experimental sealed type declarations from API again
#16494 - Remove SQLite specific rendering of quoted identifiers, to behave like other dialects
#16500 - Move jakarta.persistence related logic of DefaultRecordMapper into a new jooq-jpa-extensions module
#16539 - DDL statements should produce DATETIME data type for SQLDataType.TIMESTAMP in MySQL
#16598 - Generate backticks for quoted identifiers in SQLite, instead of double quotes
#16801 - Change PERCENT_RANK hypothetical set function to return BigDecimal instead of Integer
#16821 - Don't delay jOOQ-codegen-gradle's configuration until execution by default
Deprecations
----------------
#7585 - Move java.desktop related logic of DefaultRecordMapper into a new jooq-beans-extensions module
#16810 - Deprecate DataType.convert()
#16815 - Deprecate internal, protected AbstractRecord.from(Record) method
Bug Fixes
---------
#579 - Add Settings.renderAutoAliasedDerivedTableExpressions to auto alias unnamed field expressions in derived tables
#2902 - SQLite's binding of BigDecimal through PreparedStatement.setString() doesn't work for predicates
#3791 - Invalid SQL generated when UNION subselects contain ORDER BY
#7263 - Parser should accept qualified field references in MERGE .. INSERT statement
#7467 - Wrong SQL generated in SQL Server when using UNION .. LIMIT without OFFSET
#8209 - Invalid code when generating both POJOs and interfaces with UDTs
#8517 - Row[N].eq(Row[N]) should apply data type bindings if necessary
#9814 - MappedSchema.withInput("").withOutput("abc") prepends schema qualification to derived table references
#10585 - ParserImpl.KEYWORDS_IN_SELECT and other such lists should be tries for improved performance
#11126 - Avoid calling AbstractQueryPart::equals
#11519 - NullPointerException in SchemaMapping due to race condition in SchemaMapping cache
#11716 - Using embedded domains with POJO generation results in duplicate getters
#12243 - name(null, "") should equal to name("")
#12485 - Use PreparedStatement.setObject(int, Object, Types.OTHER) instead of setString(int, String) to bind array bind values in PostgreSQL
#12637 - Compilation error in generated code when UDT attribute name conflicts with getter procedure
#13225 - Add Javadoc to all XJC-generated "withers" and setters of boolean types
#13425 - Correctly emulate UPDATE .. FROM .. ORDER BY
#13533 - SQL Server MULTISET subquery ORDER BY clause doesn't work with UNION
#13665 - Cannot project unnamed MULTISET or ROW from derived table
#14005 - Code generator produces wrong ordering of DataType properties for nullable and defaulted array types
#14307 - Emulate LIMIT 0 where not supported
#14866 - Incorrect conversion of LocalDateTime to LocalDate during daylight saving time
#14965 - Wrong emulation of DISTINCT ON with UNION
#15085 - Confusing error message when reading a non-existing Field from a Record containing accidentally nested row types
#15159 - SQLExceptionLoggerListener logs wrong message on table with IDENTITY column and UNIQUE key
#15189 - Wrong WITH TIES emulation when combined with QUALIFY if QUALIFY is supported natively
#15322 - Meta.ddl() ignores data type for sequences
#15325 - Meta.ddl() includes synonyms or aliases as tables for some dialects
#15636 - Wrong SQL generated when specifying explicit path joins in UPDATE .. FROM and DELETE .. USING
#15762 - Exception in MetaImpl when encountering string literal default expressions in MariaDB 10.1
#15892 - Fix known limitations of embeddable types
#15933 - Maximum consumed results reached when Hikari close a SQL Server connection, leading to excessive logging
#15934 - Code generator and MetaImpl return CREATE DEFAULT statement instead of just the default expression
#15936 - Implicit path correlation produces correlation predicate in ON clause rather than WHERE clause in some cases
#15942 - KeepNamesGeneratorStrategy generates ambiguous path names if implicitJoinPathTableSubtypes is activated
#15943 - SQLite requires parenthesised DEFAULT expressions in DDL
#15944 - jOOQ-codegen-gradle should resolve relative directories with respect to the gradle project, not the running process
#15946 - Compilation error in KotlinGenerator generated code with KeepNamesGeneratorStrategy and generated implicit join paths
#15958 - YugabyteDB doesn't support ALTER TABLE .. DROP CONSTRAINT IF EXISTS
#15965 - Regression in LiquibaseDatabase when omitting the database.liquibaseSchemaName value
#15967 - Implicit path correlation shouldn't generate correlation predicate if correlation isn't in scope
#15974 - Cannot look up tasks.named("jooqCodegen") from gradle scripts
#15975 - Wrong statement generated for MySQL when leading unqualified asterisk is used with plain SQL template table
#15978 - Cannot verify www.jooq.org's certificate on ubuntu-latest (Github Actions)
#15980 - Regression in PostgreSQL query using 'x' = ANY (ARRAY [(SELECT ARRAY ['x'])]) style quantified comparison predicate on multi dimensional arrays
#15982 - Comparison predicates and quantified comparison predicates should hint array type to org.jooq.impl.Array for empty expression array casts
#15991 - Cannot project TableAsField if table contains embeddables in PostgreSQL
#15992 - Version release statement not updated on /download
#15993 - RenderTable.WHEN_MULTIPLE_TABLES only works with table lists, not with joins
#15996 - RenderTable.WHEN_MULTIPLE_TABLES doesn't work correctly in correlated subqueries
#15998 - RenderTable.WHEN_AMBIGUOUS_COLUMNS doesn't cover all ambiguous column name cases
#16000 - Wrong code generation configuration example
#16003 - Misleading XSD warnings logged when working with MiniJAXB
#16006 - Compilation error in KotlinGenerator generated code when GeneratorStrategy produces identifiers conflicting with property access syntax of AbstractRoutine getters
#16008 - Code generator fails when generating triggers because TriggerExecution value is null
#16013 - ClassCastException during invocation of double-wrapped ConvertedDataType
#16029 - Regression: NullPointerException in KotlinGenerator generated code when InlineDerivedTable constructor calls TableImpl.where(null)
#16036 - Join paths don't work when embeddable keys or domains on keys are present
#16037 - ScalaGenerator produces duplicate paths for cyclic foreign key relationships
#16039 - Compilation error in JavaGenerator generated code when is active and a table references a UDT
#16043 - DATE column in Oracle is null when fetched through multiset
#16054 - Regression: Table metadata calculation for Oracle does not work after 3.19.0
#16059 - MetaSQL lookups are done with SQLDialect.family(), not SQLDialect
#16072 - Compilation error in ScalaGenerator generated code of UpdatableRecord subclasses when using scalac 3
#16074 - Compilation error in ScalaGenerator generated code of generated DAOs when using scalac 3
#16075 - Remove unnecessary runtimeClasspath dependency of the jOOQ-codegen-gradle plugin
#16080 - Syntax error in generated SQL of ALTER INDEX or ALTER SCHEMA statement, when identifiers aren't quoted
#16083 - jOOQ-gradle-plugin multi execution configuration shouldn't require an explicit default configuration
#16090 - Unnecessary static type registry warning when inlining custom converted enum value
#16094 - Compilation error in ScalaGenerator generated Keys.scala class when using GeneratorStrategy
#16105 - Wrong Javadoc in RTRIM() and LTRIM()
#16111 - Generated implicit join alias collision when child table foreign keys share the same name
#16113 - jOOQ-codegen-gradle fails with UnknownDomainObjectException when java plugin isn't applied first
#16114 - Settings.returnDefaultOnUpdatableRecord and Settings.returnComputedOnUpdatableRecord don't work for replacing embeddables
#16133 - jOOQ-codegen-gradle doesn't consider basedir property for its OutputDirectory
#16179 - QuantifiedSelect wrapping array doesn't correctly convert array component types
#16180 - %ROWTYPE UDT types generate invalid system columns when underlying table references object types
#16188 - jOOQ-codegen-gradle should lazily evaluate its configuration
#16195 - Overall performance improvement in AbstractNamed.hashCode() specialisations by avoiding Name::append
#16203 - Remove internal AbstractContext::toggle utilities
#16209 - AbstractScope::dsl, ::settings, ::dialect, and ::family should avoid unnecessary null-checks on Configuration
#16213 - Manual gradle codegen examples use wrong property name for boolean properties when using jOOQ-codegen-gradle with kotlin
#16215 - BatchCRUD implementation should extract bind values with SQL string in one go
#16232 - Wrong Support annotation on CREATE TRIGGER for INFORMIX
#16237 - IndexOutOfBoundsException in DerbyDatabase when excludes a column from an index
#16241 - Meta::ddl generates incorrect queries for SQL Server (max) lengths
#16246 - Avoid allocating DataMap in short lived Scope implementations
#16254 - JavaGenerator doesn't generate serialVersionUID in Path classes
#16258 - Avoid allocating Collections.nCopies in ScopeStack
#16262 - Avoid allocating JoinNode in scope registration of tables if unnecessary
#16266 - Avoid constructing DSL.name() for constant internal names
#16270 - Refactor QualifiedName to improve performance
#16275 - Remove unnecessary up-to-date prevention in jOOQ-codegen-gradle plugin
#16279 - Result::formatXML should omit type attribute on columns whose type is unknown
#16290 - Wrong SQL generated for CREATE TABLE in non-default schemas for DuckDB
#16297 - MULTISET equality is ORDER dependent in dialects without support for correlated derived tables
#16302 - Can't parse MySQL ALTER TABLE .. DROP .., DROP .. syntax
#16310 - Wrong SQL generated when nesting predicates on subqueries projecting embeddables within MULTISET
#16315 - Memory leak in DefaultCacheProvider when large amounts of arbitrary projections are mapped with DefaultRecordMapper
#16316 - Regression: Gradle plugin thinks it's up to date when it's not
#16319 - SelectIsNull renders invalid SQL when SELECT projection is embeddable
#16326 - DSLContext.fetchCount(Select) produces wrong SQL when query projects embeddables
#16330 - NumberFormatException in parser when encountering double value with implicit 0 exponent
#16332 - jOOQ parser parses indexed parameters as named
#16334 - UUID bind values should be auto-cast to avoid issues with lack of auto-conversion support in PostgreSQL, HSQLDB
#16336 - Parser shouldn't fail with NumberFormatException
#16340 - DefaultRenderContext::peekIndex doesn't contain correct bind index
#16345 - DSL.count() doesn't return QOM.Count type
#16346 - DSL.count(SelectFieldOrAsterisk) shouldn't wrap ordinary Field in SQLField
#16347 - Parser fails with StringIndexOutOfBoundsException when encountering invalid PostgreSQL unicode literal
#16367 - Cast NULL literal in subquery SELECT projection in PostgreSQL
#16368 - Parser always parses NULL literal of type BOOLEAN
#16378 - Add arity check to synthetic foreign key configuration to avoid wrong generated code when FK / UK columns mismatch
#16379 - Compilation error in generated Indexes.java when index references embeddables that replace their underlying fields
#16385 - Add some WARN logs when synthetic key objects aren't matched
#16392 - Regression in fetchCount execution when argument query uses plain SQL tables
#16393 - Empty derived column lists generate wrong SQL syntax
#16405 - Parser doesn't support GROUPING SETS with specification
#16409 - Improve Javadoc and log DEBUG message on RETURNING clauses, stressing that they can't return any rows for tables without identity in some dialects
#16420 - Code generation tool - Generate : liquibase.exception.MigrationFailedException on column type VARCHAR2(255 CHAR) (Oracle)
#16425 - Static type registry deprecation warning shouldn't appear when using the INSERT valuesOfRows() clause with converted data types
#16427 - DefaultDataType.getDataType logger should add more details about how to fix the problem
#16450 - SEEK doesn't work correctly when there are multiple noField() arguments and ORDER BY is uniform and Settings.renderRowConditionForSeekClause is true
#16452 - Fix other cases where org.jooq.impl.Val uses "inferred data type," but cannot actually lazily infer the type
#16456 - ParsingConnection should not rely on org.jooq.impl.Val identity to match user bind value indexes with rendered indexes
#16459 - Wrong AbstractField::parenthesised overrides in CURRENT_SCHEMA, CURRENT_USER
#16469 - Work around CockroachDB's lack of support for the POWER() function accepting integer arguments
#16470 - Meta::ddl produces incorrect DDL for SQLite, when there are FOREIGN KEY constraints
#16479 - SQL Server's CREATE cannot fully qualify a sequence name
#16493 - Intercept SQLFeatureNotSupportedException caused by DatabaseMetaData::getImportedKeys and other calls
#16503 - Improve compilation speeds of generated QOM types
#16510 - Avoid PostgreSQL empty array cast when explicit cast is given
#16523 - Dead link in manual section "jooq-and-java-8"
#16535 - Parser fails to parse TIME[STAMP] WITH TIME ZONE literals
#16547 - Wrong SEMI JOIN example in manual section "dont-do-this-sql-select-distinct"
#16551 - Get MemSQL dialect up to date
#16552 - Work around lack of support for INSERT .. SELECT .. UNION [ ALL ] SELECT in SingleStore
#16560 - Cannot configure matchers using jOOQ-codegen-gradle plugin
#16567 - Restore caching of resolvedType in AbstractTypedElementDefinition
#16569 - DELETE .. ORDER BY .. LIMIT on partitioned tables without unique constraint uses non-unique ctid for self joins
#16576 - SAXParseException warnings when using jOOQ-codegen-gradle or any other MiniJAXB.unmarshal() usage
#16581 - Time zone information lost when fetching TIMETZ[] value in PostgreSQL
#16585 - Work around HSQLDB bug where wrong LocalTime value is fetched when using bind values of type LocalTime[]
#16602 - Wrong cast type name when casting value to NCLOB in Firebird
#16616 - Fix order of NOT NULL and DEFAULT clauses in BigQuery CREATE TABLE statements
#16627 - Update using multi-column set clause with DSL.row and custom type logs warn on deprecated static type registry
#16631 - Error when running DELETE .. USING .. LIMIT in MySQL
#16632 - Wrong emulation of DELETE .. USING .. LIMIT where DELETE .. LIMIT is not natively supported
#16634 - HANA UPDATE statement always repeats target table, even if unnecessary
#16646 - BlobBinding and ClobBinding should fall back to byte[] and String binding also in HANA
#16651 - TableRecords should refresh() themselves for HANA dialect, when any non-identity value should be fetched after an insert
#16655 - MULTISET nested projection's ContextConverters don't receive correct ConverterContext
#16662 - Wrong source code generated when newline escape sequence of long view source is split into two
#16675 - SQLite "Cannot parse or interpret sql for table" error with both unique columns and foreign key constraints
#16679 - Wrong title in manual section "alter-table-drop-foreign-key"
#16685 - Add missing section to the manual about DISTINCT predicate of degree > 1
#16686 - Error in CockroachDBDatabase when running SHOW INDEXES for table valued function
#16691 - Work around KT-68407 compiler error in generated AbstractSpringDAOImpl class in kotlin 2.0
#16702 - Settings.transformPatternsUnnecessaryScalarSubquery produces wrong SQL when subquery column is aliased
#16705 - Pattern replacement activates RETURNING clause of DELETE / UPDATE statements
#16708 - Settings.transformPatternsUnnecessaryScalarSubquery produces wrong SQL when subquery column is an embeddable
#16725 - Avoid operator associativity rendering logic if operator isn't nested
#16734 - Redundant policy related logic in UpdateQueryImpl
#16739 - Internal SelectQueryImpl::copy behaviour may produce inconsistent copy of WINDOW clause
#16745 - Wrong SQL rendered for MS Access CONCAT function with more than 2 arguments
#16755 - Work around BigQuery's SELECT without FROM clause cannot use aggregation limitation
#16762 - Parser meta lookup fails for DUAL table
#16769 - Work around BigQuery ORDER BY clause limitation where identifiers cannot be resolved if the table and the column share the same name
#16773 - Work around BigQuery limitation of using: HAVING clause on a non-aggregate query
#16777 - Support BigQuery's QUALIFY .. WINDOW keyword order
#16782 - NullPointerException in MetaImpl when looking up a dropped table from a disabled foreign key in MySQL
#16786 - Fix null treatment syntax of window functions in BigQuery
#16792 - Inconsistent formatting of HSQLDB DUAL table emulation
#16796 - Incorrect emulation of inverse distribution functions with FILTER clause
#16797 - Parser error when trying to parse hypothetical set function with FILTER clause
#16834 - Wrong DataAccessException to IntegrityConstraintViolationException translation for DuckDB
#16837 - Wrong DuckDB binary literals generated when inlining bind values
#16842 - jOOQ-codegen-gradle 3.19.10 assumes presence of a "main" source set, which isn't always the case
#16844 - Correctly implement numerous Oracle specific ST_Geometry spatial functions
#16853 - MySQL error "BLOB, TEXT, GEOMETRY or JSON column can't have a default value" when running DDL from generated code
#16854 - SQLite's MetaImpl can't distinguish between multiple unnamed UNIQUE constraints
#16861 - Avoid static members in jOOQ-meta Definition classes to avoid stale build caching
#16865 - TIMESTAMP(0) doesn't work in DDL statements as the datetime precision is simply omitted
#16866 - Add a configuration example to the manual section "converter-provider"
Version 3.19.0 - December 15, 2023
================================================================================
New dialects
------------
It's been a few releases since we've added support for new dialects, but finally
some very interesting RDBMS of increasing popularity have joined the jOOQ family
including:
- DuckDB (experimental support)
- Trino
These dialects are available in all jOOQ editions.
New dialect versions
--------------------
In addition to these entirely new dialects, big new CockroachDB and Oracle
versions have shipped:
- CockroachDB 23
- Oracle 23c
We've added support for many new Oracle features, including:
- Domains
- UPDATE .. FROM
- IF [ NOT ] EXISTS
- Table value constructor
- SELECT without FROM
As well as CockroachDB features, including:
- Triggers
- Stored functions
- UDTs
- Materialized views
- LATERAL
- New native DML clauses
- NULLS FIRST and NULLS LAST
Join path improvements
----------------------
Implicit to-one path joins have been with jOOQ since version 3.11. Now, we've
greatly improved this very useful feature by adding support for:
- Explicit path joins, allowing for more fine grained control of the path join
type:
https://www.jooq.org/doc/3.19/manual/sql-building/sql-statements/select-statement/explicit-path-join/
- To-many path joins, including many-to-many paths for implicit and explicit
joins going from parent to children:
https://www.jooq.org/doc/3.19/manual/sql-building/sql-statements/select-statement/implicit-to-many-join/
- Implicit path correlation, allowing to greatly simplify correlated subqueries,
including the powerful MULTISET correlated subqueries:
https://www.jooq.org/doc/3.19/manual/sql-building/sql-statements/select-statement/implicit-path-correlation/
- Join elimination, allowing to skip unnecessary path segments of a join path
This is best shown by example:
This feature is available in all jOOQ editions.
Gradle plugin
-------------
One of the longest awaited features is an official jooq-codegen-gradle plugin,
that offers a tight integration with gradle's task system while being released
in the same release cadence as jOOQ itself.
Our new gradle plugin supports all of the code generation features in both an
idiomatic groovy or kotlin DSL
More information here:
https://www.jooq.org/doc/3.19/manual/code-generation/codegen-gradle/
This feature is available in all jOOQ editions.
Commercial maven repository
---------------------------
A feature that many of our paying customers have wanted for a long time has
finally been implemented: our commercial maven repository at
https://repo.jooq.org, where all historic and new commercial only jOOQ
artifacts as well as snapshot versions will be hosted, in addition to our
ZIP file download website:
https://www.jooq.org/download/versions
This feature is available only in commercial jOOQ editions.
Policies
--------
Similar to PostgreSQL's powerful POLICY feature, or Oracle's Virtual Private
Database, jOOQ 3.19 allows for declaring policies that act as automatic
filters on some of your tables, to allow for a simple and thorough row level
security implementation.
For example, with a policy on the multi tenancy capable CUSTOMER table, a
query like this:
Might in fact run a SQL statement like this, instead:
SELECT CUSTOMER.ID, CUSTOMER.NAME
FROM CUSTOMER
WHERE CUSTOMER.TENANT_ID = 42
Not just queries, but all DML statements are rewritten to disallow any
inaccessible data from being written / read.
More information here:
https://www.jooq.org/doc/3.19/manual/sql-building/queryparts/policies/
This feature is available only in commercial jOOQ editions.
UDT paths
---------
In addition to adding User Defined Type (UDT) support to CockroachDB and
Informix, we've improved our code generator support for UDTs in a way for
attribute paths to be made accessible to client code in a type safe way.
So, with types like these:
CREATE TYPE country AS (
iso_code TEXT
);
CREATE TYPE name AS (
first_name TEXT,
last_name TEXT
);
CREATE TYPE address AS (
street TEXT,
...,
country COUNTRY
);
CREATE TABLE customer (
id INT PRIMARY KEY,
name NAME,
address ADDRESS
);
You can now destructure the UDTs directly in your SQL query like this:
More information here:
https://www.jooq.org/doc/3.19/manual/sql-building/column-expressions/user-defined-type-attribute-paths/
This feature is available in all jOOQ editions.
Trigger meta data
-----------------
The code generator can now reverse engineer trigger meta data from most RDBMS
that support triggers. This meta data can be helpful at runtime, e.g. to render
improved RETURNING support in the absence of triggers, in dialects where
triggers require special emulations (e.g. SQLite or SQL Server).
This feature is available only in commercial jOOQ editions.
Hierarchies
-----------
A new Collector has been added to recursively collect a flat representation of
hierarchical data into an object hierarchy. This plays very well with our
MULTISET nested collection support.
For more details, see this blog post:
https://blog.jooq.org/how-to-turn-a-list-of-flat-elements-into-a-hierarchy-in-java-sql-or-jooq/
This feature is available in all jOOQ editions.
Java 8 support removed from jOOQ Express and Professional Editions
------------------------------------------------------------------
Like other leading platforms, we're moving on to help with the adoption of
newer JDK versions. Our Java 8 support will be discontinued for the jOOQ
Express Edition and jOOQ Professional Edition. If you require Java 8 support,
you can upgrade to the jOOQ Enterprise Edition, which will continue supporting
Java 8 for another few minor releases, or stay on jOOQ 3.18, which will also
receive bug fixes for another while.
This change affects only commercial jOOQ editions.
For a complete list other, minor improvements, see the below change notes.
Features and Improvements
-------------------------
#228 - Enhance API to provide access to UDT members
#2356 - Support PostgreSQL multi table TRUNCATE statement
#2536 - DAO should copy the inserted identity value back to the POJO on DAO.insert(P)
#2682 - Add org.jooq.Policy, to support shared-schema multi-tenancy and row level security
#3751 - Support UDT object names in MatcherStrategy
#3862 - Improve Javadoc on DSLContext.executeInsert(), executeUpdate(), and executeDelete() about optimistic locking not applying
#4092 - Add a section to the manual showing how to bind LOBs via org.jooq.Binding
#5210 - Add code generation option to generate string constants for all object names
#6028 - Add JSONFormat.NullFormat to offer different NULL encoding options
#6182 - Support renaming Keys and Indexes with matcher strategy
#6542 - Add some gifs to the README.md on Github, also for examples
#6587 - Add InsertQuery.setRecordForUpdate(Record)
#8012 - Override Table.where(Condition) methods in generated tables
#8474 - Add support for CREATE TYPE AS
#8617 - Add org.jooq.Generated annotation with RUNTIME retention for generated code
#9483 - Add support for { CREATE | ALTER | DROP } MATERIALIZED VIEW
#9635 - Add DSL.noTable() for optional, dynamic joins
#9906 - Offer a public Maven repository for commercial distributions
#10096 - LiquibaseDatabase should create database.liquibaseSchemaName, if configured
#10504 - Update manual to show also Gradle/Kotlin configuration examples
#11248 - Add Trigger runtime meta model
#11251 - Add emulation support for IF [ NOT ] EXISTS to MySQL for DDL on INDEX and VIEW objects
#11263 - Add KeyColumnUsage.positionInUniqueConstraint to the InformationSchema for use with XMLDatabase
#11485 - Support for Trino DB
#11584 - Add parser support for SQL Server CREATE TYPE and DROP TYPE
#11944 - Add Firebird 4.0 native support for DELETE .. ORDER BY and UPDATE .. ORDER BY
#12052 - Add experimental DuckDB support
#12083 - Work around missing support for REMARKS on DatabaseMetaData.getColumns()
#12270 - Add Javadoc hints about Record.changed() values to InsertValuesStep[N].valuesOfRecords(...)
#12341 - Add a Records::intoHierarchy Collector to turn Result into tree representations
#12493 - Support INSERTING, UPDATING, DELETING in PostgreSQL via TG_OP
#12747 - Add support for Informix UDTs
#12985 - Create an official jooq-codegen-gradle plugin
#13065 - Document the InlineDerivedTable feature
#13295 - Allow for specifying both and / in
#13301 - Allow kotlin pojos to not have defaulted constructor parameters
#13639 - Add support for to-many path expressions
#13786 - Parser should support TIMESTAMP 'YYYY-MM-DD' and TIME 'HH:MM' literals
#13912 - Simplify SQL Server's RETURNING emulation in the absence of triggers
#13947 - Support CockroachDB 23 user defined functions
#14011 - Add SQLDialect.ORACLE23C
#14429 - Builds should log their build date with the logo
#14551 - Add more startup tips to be logged with the jOOQ logo
#14614 - Implicit JOIN improvements
#14756 - Continue work on public query object model API
#14777 - Add >ResultQuery.fetchValue(): E? extension method to kotlin
#14790 - Add DataType.isUUID()
#14799 - Add support for TRY_CAST()
#14800 - Error when PostgreSQL anonymous block contains dollar quoted string token
#14803 - BlobBinding and ClobBinding should fall back to byte[] and String binding if unavailable
#14808 - Add more documentation after 3.18 release
#14814 - Split Aliased tables section of the manual into subsections
#14818 - Add a remark on the Converter Javadoc that implementations must be able to handle NULL
#14840 - Apply Settings.batchSize also to other batch API
#14876 - Add warnings to manual and Javadoc about ON KEY ambiguity caveats
#14895 - Add Javadoc to DAO::insert and DAO::update regarding Settings.returnRecordToPojo
#14914 - Add DSL.domain(Name, DataType) and overloads
#14932 - Add a jooq.codegen.propertyOverride system property to GenerationTool
#14933 - Add the missing DSLContext.fetchValue(TableField, Condition) and other overloads
#14934 - Upgrade liquibase-core to 4.21.0
#14953 - Add Javadoc hints about implementation of JSONB::toString, JSONB::hashCode, and JSONB::equals
#14967 - Reactive batch implementations should throw UnsupportedOperationException with a message
#14975 - Upgrade Jackson to 2.15.0
#14985 - Allow for specifying explicit path joins
#14988 - Emulate LATERAL (TableImpl | JoinTable) where not supported
#14992 - Join elimination for implicit join paths
#14993 - Add a new subelement
#14998 - Add code generation flag to offer an option to stop generating unused implicit join path constructors
#15002 - Add native support for NULLS FIRST and NULLS LAST in CockroachDB 23
#15003 - Add SQLDialect.COCKROACHDB_23
#15006 - Support Oracle 23c's new 64k IN list limit
#15023 - Add a section to the manual about SQL translation
#15024 - Improve Javadoc of lookupLiteral() for generated enums
#15025 - Generate annotations on generated EnumType::getLiteral method, if so configured
#15050 - Add support for generic org.jooq.log.=threshold system properties
#15051 - Add JooqLogger.isErrorEnabled()
#15060 - Add DataType.isOther()
#15065 - Upgrade maven plugins
#15070 - MiniJAXB should support reading simple elements as attributes
#15072 - Add error message to maven-install.sh which doesn't work with Maven 3.9.0 due to MNG-7679
#15075 - maven-install and maven-deploy shell scripts should use -e flag to report more error info
#15093 - Add API support for ( UNION | INTERSECT | EXCEPT ) DISTINCT
#15103 - Add DSLContext.transactionCoroutine overload accepting CoroutineContext
#15117 - Recognise :yugabytedb: JDBC URLs in JDBCUtils
#15126 - Add SQLDialect.SQLITE_3_40
#15142 - Support parsing T-SQL's named DEFAULT constraints in CREATE TABLE
#15143 - Add native support for CockroachDB 23 DELETE .. USING clause
#15144 - Add native support for DELETE .. LIMIT and DELETE .. ORDER BY in CockroachDB
#15145 - Add runtime support for CockroachDB 23 UDTs
#15148 - Add CockroachDB support for LATERAL
#15156 - Add Context.inScope(QueryPart): boolean
#15160 - Add parser support for Teradata specific analytic functions
#15171 - Upgrade various dependencies
#15181 - Remove manual section about interning
#15186 - Add a section about operator precedence to the manual
#15188 - SelectQueryImpl::toSQLReferenceLimitWithWindowFunctions should use QUALIFY to emulate WITH TIES where possible
#15207 - Add a configuration flag to avoid generating DefaultCatalog and DefaultSchema
#15209 - Support ad-hoc compilation of programmatic GeneratorStrategy objects in the code generator
#15210 - Add code generation flags to avoid overrides of as() methods or rename() methods
#15212 - Add and to allow for passing T and U types to custom Converter and Binding instances
#15213 - Support ad-hoc compilation of programmatic Generator or Database objects in the code generator
#15230 - Add support for MySQL DECIMAL/FLOAT/DOUBLE/REAL UNSIGNED types in Meta and code generation
#15239 - Add Settings.parseMetaViewSource to allow for opting out of parsing view source in MetaImpl
#15248 - Add documentation about the nullability of kotlin generated properties in the presence of DEFAULT or IDENTITY expressions
#15249 - Add ExecuteContext.skipUpdateCounts to allow for setting the AbstractContext.skipUpdateCounts flag in an ExecuteListener
#15258 - Manual section about the QUALIFY clause should reference the QUALIFY transformation section
#15261 - Add Javadoc to plain SQL DSL.field() constructors recommending to use code generation or at least pass a DataType
#15275 - Update jakarta.xml.bind:jakarta.xml.bind-api from 3.0.0 to 4.0.0
#15276 - Add code generation support for synthetic enums
#15277 - Add Replacers.transformPatterns(Configuration) public API to give access to the internal Replacer
#15279 - EnumConverter should support org.jooq.EnumType as U type
#15281 - Generated code should import user defined types in data type definitions
#15293 - Various Meta DDL related issues
#15307 - Emulate CREATE SCHEMA with CREATE USER .. NO AUTHENTICATION in Oracle 18c
#15315 - Upgrade pgjdbc to 42.6.0
#15316 - Add support for SQLite 3.35 RETURNING
#15323 - Add native support for Db2 XML type in DDL, code generator, etc.
#15347 - Support single-statement trigger bodies on RDBMS that only support SQL triggers
#15350 - Add SQLDialect.H2_2_2_220
#15351 - Add PostgreSQL support for CREATE TRIGGER and DROP TRIGGER
#15354 - Emulate REFERENCING clause in CREATE TRIGGER in dialects that don't support it natively
#15356 - Add Replacers.mappingTable(Function super Table>, ? extends Table>)
#15357 - Add manual sections for built-in Replacers
#15372 - Make EACH an optional keyword in FOR EACH ROW / FOR EACH STATEMENT in the parser
#15400 - Add a jOOQ-meta-kotlin module for kotlin extensions to the jOOQ-meta module
#15401 - Add extension functions for Settings, InformationSchema, MigrationsType
#15413 - "Ambiguous match found" warning log should reference qualified field name, if available
#15419 - Add support for CockroachDB 21 MATERIALIZED VIEWS
#15442 - Upgrade dependencies
#15452 - Add parser support for Redshift's DATE_PART_YEAR() function
#15453 - Manual section about data type conversion should contain an example showing how to attach a converter to a DataType or Field
#15455 - Add InsertSetStep.set(Collection extends Record>) and set(Record...)
#15464 - Add matcher strategy to name path Table subclasses
#15465 - Create manual subsections for matcher strategy
#15468 - INSERT .. ON CONFLICT .. DO NOTHING emulation should use MERGE in Firebird 3, HANA
#15488 - DefaultRecordMapper should be able to reflectively map multisets into Sets of POJOs
#15499 - Upgrade jOOR dependency to 0.9.15
#15509 - Add a log message whenever an exception occurs with the SQLDialect.DEFAULT
#15510 - Upgrade scala.version to 2.13.11
#15514 - Upgrade Liquibase to 4.23.1
#15531 - Meta.ddl() exports broken DDL for materialized views
#15546 - Add Database.getComments(): Map
#15551 - Add runtime UDT mapping
#15554 - JavaWriter should have a Mode reference
#15588 - Add support for ALTER TYPE IF EXISTS
#15591 - Remove unnecessary line breaks in formatted DDL
#15592 - Add missing Asterisk and QualifiedAsterisk.except(Collection extends Field>>) overloads
#15593 - Add support for and emulate CREATE OR REPLACE MATERIALIZED VIEW and other objects
#15594 - Add CockroachDB support for CREATE VIEW IF NOT EXISTS
#15607 - Add support for COMMENT ON MATERIALIZED VIEW
#15608 - Upgrade H2 to 2.2.224
#15611 - Add a disclaimer tip to the DAO section
#15620 - Upgrade third party libraries for JDK 21 build
#15627 - Add parser support for functions without parameter names
#15632 - Support InlineDerivedTables in DML
#15635 - Add a Context::scopePart property
#15644 - Add Policy::inherited to specify whether child tables should inherit a parent table's policies
#15657 - Add link to explanation blog article about inline values from manual
#15682 - Emulate INSERT .. DEFAULT VALUES for dialects where no DEFAULT expression exists for DML
#15684 - Add support for POSITION() in Informix via INSTR
#15685 - Emulate DEFAULT expression in multi row INSERT .. VALUES, where that is emulated with INSERT .. SELECT
#15712 - Add documentation about some client side features not working with plain SQL templating
#15719 - Remove experimental status of transform patterns and computed columns
#15731 - Add a section to the manual highlighting the commercial only or experimental features
#15745 - TableDefinition.getTable() should return better meta data
#15754 - Add RenderImplicitJoinType.SCALAR_SUBQUERY to allow for configuring the DML implicit join path behaviour also for SELECT
#15755 - Add Settings.renderImplicitJoinToManyType: RenderImplicitJoinType to govern the implicit to-many join style
#15783 - Add Javadoc to the Query::bind methods indicating that they bind values in the rendered order, not the input order
#15807 - Add support for JOIN algorithm hints
#15808 - Support H2's USE INDEX hint
#15815 - Add more emulation support for ALTER TABLE .. DROP CONSTRAINT IF EXISTS
#15822 - Support parsing dynamic intervals in MySQL DATE_ADD() and DATE_SUB() expressions
#15824 - Add parser support for STRING_AGG()
#15825 - Support parsing a few Oracle DBMS_LOB functions
#15835 - Remove workaround for ojdbc bug where JSON_ARRAY() couldn't combine bind parameter marker with FORMAT JSON
#15843 - Deprecation log warning about should link to relevant manual section
#15844 - Add support for MD5 in SNOWFLAKE dialect
#15845 - Upgrade Jackson dependency to 2.16
#15847 - Upgrade com.oracle.database.r2dbc:oracle-r2dbc to version 1.2.0
#15860 - Get SNOWFLAKE dialect up to date
#15862 - Remove unnecessary managed JDBC drivers from parent pom.xml
#15864 - Add support for PostgreSQL DROP TRIGGER .. ON
#15897 - Offer Java 8 support only in the jOOQ Enterprise Edition
#15939 - Add a Don't do This: SELECT DISTINCT section to the manual
Breaking changes
----------------
#13694 - Remove pre 3.8 deprecated API and pre 3.8 documentation
#14306 - Avoid second ExecuteContext for native implementations of RETURNING
#15005 - Add org.jooq.Path, a type to model join paths
#15046 - Let SchemaImpl and TableImpl avoid traversal and replacement recursion
#15201 - Experimental migrations API changes
#15303 - Meta.ddl() generates broken DDL for columns of unknown types
#15394 - Exception thrown inside blocking TransactionPublishable gets wrapped by DataAccessException unlike when thrown from non-blocking TransactionPublishable
#15476 - Internal DefaultDataType.getDataType(SQLDialect, String) should parse precision and scale and return it
#15487 - Turn off by default
#15634 - Distinguish between Context::qualify and Context::qualifySchema
#15872 - QOM.CreateTrigger and related API should work with new org.jooq.Trigger type
Deprecations
----------------
#15196 - Deprecate inconsistent DSL.jsonObject(Field...) and DSL.jsonbObject(Field...) overloads
#15286 - Add Javadoc to discourage using any m(Class) method if there's an m(DataType) overload
#15583 - UDTImpl should use Name instead of String in constructor
Bug Fixes
---------
#7941 - Allow for using EnumType not referencing any Schema to be used in PostgreSQL
#8283 - BatchCRUD does not update optimistic locking version and timestamp values in UpdatableRecord
#8439 - PostgreSQL: array() causes exception
#8930 - Fix known issues of PL/SQL BOOLEAN type in SQL emulation
#10107 - DDLDatabase throws parse error 'DEFAULT custom_function_name()'
#10234 - Unable to rename table with qualified target table name
#11205 - ORA-38104: Columns referenced in the ON Clause cannot be updated
#11311 - HSQLDB MetaImpl based DataTypes are missing length of array element type
#11975 - Fix known limitations of embeddable types
#12098 - Fix known limitations of the QUALIFY SQL transformation
#12456 - Ambiguous match found when using aliases with implicit join and joining the same table twice
#12547 - Internal patchIso8601Timestamp() isn't safe for 5 digit years
#13171 - Confusing (outdated) gradle examples in manual
#13541 - Various runtime errors when using features in dialects that do not support them
#13680 - Remove workaround for H2 process hanging when using FINAL TABLE (MERGE ...)
#14256 - Syntax error when from current_timestamp when precision bind value is specified for Postgres
#14764 - Avoid dialect version lookup in AbstractDatabase, if unnecessary
#14769 - race conditions in jOOQ internals
#14771 - NullPointerException when using plain SQL identity and additional column in INSERT .. RETURNING
#14776 - Javadoc contains warning boxes
#14780 - Correctly annotate SIMILAR TO operator
#14785 - Compilation error in KotlinGenerator generated code when and are both active
#14791 - SQLDialect version check throws NumberFormatException in Percona DB
#14801 - JavaGenerator creates broken code for arrays when kotlinNotNullPojoAttributes is true
#14802 - [#14801] Fix Java String generation for non-nullable arrays
#14817 - Nullable kotlin records break columns with default values
#14830 - Compilation error in generated code when table valued function returns table with client side computed columns and is active
#14833 - Version support check shouldn't log error message for MockConnection
#14839 - PL/SQL procedure returns wrong result when combining boolean and record type as input
#14841 - ERROR: type "blob" does not exist when casting NULL as a domain converted as user defined type using class literal
#14843 - Switch links from /doc/dev to /doc/latest for recently added diagnostics
#14845 - Upgrade Spring to mitigate CVE-2023-20861
#14849 - ROLLUP, CUBE should generate Keyword, not Name
#14853 - Kotlin Code generator generates invalid code for embeddables in POJOs when immutable interfaces is activated
#14855 - Compilation error in generated code for embeddable properties when reducing visibility to internal, and generating interfaces
#14872 - Regression when using INSERT .. RETURNING pre MariaDB 10.5
#14875 - Inconsistent implementation of TableImpl::equals and TableImpl::hashCode when comparing generated tables with plain SQL ones
#14882 - Generate nullable annotations also on record constructor, when is set
#14883 - Regression: KotlinGenerator produces superfluous public keyword for overriding methods
#14890 - QUALIFY transformation should unalias columns again
#14902 - Work around Oracle 23c regression when nesting aggregate JSON functions in MULTISET
#14906 - Internal API leaks into client code via generated table's join(TableLike>, JoinType) method
#14908 - Missing parentheses when second subquery in set operation contains deep nesting
#14916 - Compilation error with embedded domains and postgres types
#14923 - Explicitly set locale to English in maven-javadoc-plugin
#14924 - Explicitly set locale to English in maven-javadoc-plugin
#14930 - jOOQ-meta should avoid redundancies between getTables0() and sources() methods to fetch view sources
#14937 - Support NULL bind values of type Interval in R2DBC integration
#14938 - Unstable ordering of Derby generated foreign keys
#14942 - Manual section about code generation configuration contains wrong comment about LiquibaseDatabase
#14944 - Wrong warning logged regarding CockroachDB version support
#14949 - Upgrade spring-core dependency to mitigate CVE-2023-20863
#14960 - No-arg DefaultConfiguration() constructor clones default settings twice
#14991 - KotlinGenerator produces wrong code with kotlinNotNullPojoAttributes when multiple references to an embeddable have different nullability
#14995 - OffsetDateTimeRange javadoc should reference tstzrange not tsrange
#14996 - #14995 fix OffsetDateTimeRange javadoc
#14997 - Use awaitSingle instead of awaitFirstOrNull in transactionCoroutine to correctly sequence transaction script
#15007 - Change DSL.multisetAgg() overload accepting Field>...|Collection extends Field>> to work with SelectField> instead
#15008 - Cannot pass Table reference to row() constructor in array or list
#15013 - GROUPING() support was only added in MySQL 8
#15015 - A few MySQL 5.6 related fixes
#15022 - SchemaImpl and CatalogImpl $replace() and $traverse() methods shouldn't recurse into Name or Comment parts
#15028 - R2DBC bind value related exceptions produce misleading error message
#15035 - Support NULL bind values of type Year in R2DBC integration
#15039 - The exported DDL of the table for POSTGRES_15 dialect is missing a default value
#15042 - Support NULL bind values of type UUID in R2DBC integration
#15048 - DDLDatabase defaultNameCase=lower doesn't work with ENUM types
#15052 - JooqLogger log methods don't check if log level is enabled
#15056 - Parser meta lookup fails when using qualified asterisk on a table alias
#15088 - Misleading error message when ON KEY finds ambiguous keys
#15095 - Generate property access syntax in KotlinGenerator generated tables
#15096 - Ambiguous type name warning for non-ambiguous type name in OracleDatabase
#15097 - Compilation error in Oracle generated code for package type in PL/SQL RECORD constructor
#15104 - InlineDerivedTable should wrap query lazily
#15114 - Upgrade sqlite dependency to 3.42.0.0 to mitigate CVE-2023-32697
#15115 - Improve error message when unversioned, row based optimistic locking doesn't work with DAOs and POJOs
#15121 - Derived column list doesn't work on InlineDerivedTable
#15125 - Handle SQLite's incompatible change of implementation for LOG(x)
#15127 - DefaultConfiguration::toString logs wrong flags in R2DBC context
#15149 - PostgresDatabase and subtypes may produce wrong table comments in presence of stored functions
#15154 - Fix various Javadoc links
#15168 - NullPointerException in code generator when omitting directory
#15182 - Add tests to prevent leaking of invisible, internal API through generated code
#15183 - Compilation error in generated DAO code when visibility of a field is changed to private
#15190 - DISTINCT .. LIMIT emulation renders redundant DENSE_RANK() OVER (ORDER BY ...) clauses
#15195 - H2 dialect should cast binary data of unknown length as VARBINARY, not as BINARY
#15202 - Add missing Experimental annotation to migrations API types
#15218 - NullPointerException in AbstractMeta::lookupTable and other methods, when there is no DefaultCatalog
#15238 - MetaImpl::ddl() should produce plain SQL CREATE VIEW statements if it can't parse the view contents
#15250 - LoggerListener logs some batch queries twice, when using BatchMultiple
#15253 - ScalaGenerator produces wrong code when generator strategy adds multiple interfaces to legacy enum type
#15270 - Wrong implementation of SelectQueryImpl::wrapQueryExpressionBodyInDerivedTable in jOOQ Open Source Edition
#15278 - CheckDefinition.getSource() should return CheckDefinition.getCheckClause() contents
#15282 - Wrong encoding of lists in generated programmatic code generation configuration examples
#15291 - Meta.ddl() export generates wrong DDL for constraints with USING INDEX clause in Oracle
#15302 - Meta.ddl() generates broken DDL for smallserial columns
#15318 - MetaImpl is missing view source code or unique constraints for objects in other catalogs
#15319 - Error when generating code from a MariaDB database containing packages
#15326 - Meta.ddl() should export tables first, then views
#15331 - Batch::executeAsync throws NullPointerException when executed with R2DBC driver
#15336 - Parser error when using SET new.x = y syntax in triggers
#15341 - Bad syntax in Firebird when creating triggers for unquoted table names
#15359 - Block::$replace doesn't replace anything
#15364 - Wrong deprecation notices in PostgresDSL
#15366 - Avoid generating sort specification in indexes in dialects that don't support it
#15375 - Table with 255 columns generates record and POJO objects whose constructors have too many parameters
#15383 - Compilation error in generated code when global object references conflict with schema names
#15388 - Settings.metaIncludeSystemIndexes doesn't work for system indexes of unnamed constraints in HSQLDB
#15395 - Exception when MockResult contains UDTRecord
#15402 - Bad formatting of hints at the end of maven-install.sh scripts
#15412 - Missing CAST in generated MERGE statement when using inline values in PostgreSQL 15's ON DUPLICATE KEY UPDATE emulation
#15414 - Can't generate code using CockroachDB materialized view
#15423 - Table list to ANSI JOIN transformation doesn't work if table declarations are fully qualified, but references are not
#15433 - AutoConverter loses nanosecond precision when converting from Instant to LocalDateTime or OffsetDateTime
#15472 - Code generation fails on BigQuery when querying INFORMATION_SCHEMA without a DefaultDataset being specified
#15473 - Failure in MetaImpl.MetaSchema::source in BigQueryDatabase
#15478 - AutoConverter should be lenient about TIME type fractional seconds
#15482 - Can't invoke default methods on proxied types returned by DefaultRecordMapper in JDK 9 or more
#15497 - Work around SQL Server's 1000 row value limitation for INSERT statements
#15504 - Query::isExecutable should be checked in the R2DBC implementation, allowing no-ops for non-executable queries
#15507 - Fix various UDT related issues in KotlinGenerator
#15511 - Manual should stop recommending use of deprecated DefaultExecuteListener or DefaultRecordListener
#15524 - Missing Stringly annotation on String... varargs parameters
#15553 - AbstractTypedElementDefinition should cache resolvedType property only once per file
#15555 - Datetime precision isn't maintained by code generator for domain types
#15559 - KotlinGenerator - isKotlinNotNullPojoAttributes setting prevents generated DAO to set serial ID to pojo
#15563 - DefaultRecordMapper should skip most mappers when an instance is provided
#15564 - MutablePOJOMapper should be able to map to instance, even if there isn't a default constructor
#15569 - Record.into(recordInstance) should modify argument record
#15574 - DefaultOtherBinding shouldn't create string literals for inline values for numeric data types
#15582 - MariaDB UPDATE .. RETURNING emulation should work on tables with unique constraints only
#15584 - Install shell/batch scripts should be clearer about Java 17+ support
#15595 - DefaultStringBinding should bind java.sql.Clob for CLOB types in Oracle MERGE statements
#15598 - Fix DefaultRecordMapper Javadoc to reflect actual behaviour
#15602 - Plain SQL Javadoc disclaimer is absent on api generator generated step methods
#15610 - Bump org.eclipse.jgit:org.eclipse.jgit from 5.9.0.202009080501-r to 6.6.1.202309021850-r in /jOOQ-migrations
#15614 - Wrong Support annotation on COMMENT ON COLUMN for MariaDB
#15619 - On JDK 21, generated code should apply "this-escape" warning suppression
#15621 - Synthetic comment flag should produce @Deprecated annotation in addition to Javadoc
#15623 - Stop using deprecated DSL API in jOOQ-meta
#15625 - QOM.Delete mutators produce a copy that always has a RETURNING clause
#15629 - InlineDerivedTable can't be outer joined
#15639 - RenderMapping doesn't apply to QualifiedRowid
#15650 - DefaultConfiguration doesn't serialize AuditProvider or TransformProvider
#15656 - InlineDerivedTable doesn't maintain contained table's meta data in some cases
#15658 - Copy paste errors in likeIgnoreCase and containsIgnoreCase Javadoc
#15668 - INSERT .. ON DUPLICATE KEY UPDATE emulation mustn't silently insert the last row only in Derby multi row inserts
#15673 - Domains aren't generated if they don't have a CHECK constraint associated with them, in HSQLDB
#15677 - Code generator doesn't generate multiple check constraints for DOMAIN types
#15683 - Incorrect DEFAULT values generated for Informix
#15686 - Generated DEFAULT expressions should always be syntactically valid for all data types in HANA
#15687 - HANA sort indirection doesn't work with bind values
#15693 - Fix a typo in a Tip
#15697 - Upgrade jgit from the jOOQ-migrations prototype to 6.6.1.202309021850-r
#15702 - Reactive transaction hangs when exception thrown in lambda constructing reactive flow
#15714 - Possible compilation errors in generated code when column names contain double quotes
#15724 - BindingSetStatementContext should reference actual ExecuteContext, if available
#15735 - Ill-formed Javadoc causes JDK 21 javadoc tool to crash
#15752 - JSONB inline values should be rendered using JSONB.data() not JSONB.toString()
#15756 - Implicit JOIN implementation for DML is incorrect if paths navigate self joins
#15760 - Compile errors of generated classes using scala 3
#15767 - MiniJAXB::marshal(XMLAppendable, OutputStream) does not flush decorating writer
#15799 - LazyVal::generatesCast should return true
#15803 - MetaImpl reports system indexes for Derby 10.16
#15816 - Misleading example in manual's section about the CREATE TRIGGER statement
#15820 - Incorrect query generated when combining SEEK with GROUP BY
#15823 - Wrong grammar for intervalLiteral in manual
#15826 - Parser cannot parse undocumented reverse syntactic order of FOR UPDATE and LIMIT clauses from PostgreSQL
#15828 - Support overlapping embeddables when enabling
#15832 - Oracle UDTs are sometimes inlined as [UDT] instead of IDENTIFIER(CONTENT)
#15848 - Compilation error in KotlinGenerator generated code for tables containing a FROM column, when is activated
#15850 - Accidental override when enabling for tables with columns X and IS_X in Kotlin
#15873 - IllegalArgumentException when calling UpdatableRecord methods on tables with embedded domains that replace their underlying fields
#15876 - Internal RecordDataType.getDataType() should be non-nullable for records consisting of all non-null fields
#15883 - Compilation error in generated code when using and the domain is part of a composite key
#15899 - Upgrade logback dependency in jOOQ-jooby-example to mitigate CVE-2023-6378
#15901 - Incorrect ExecuteListener Javadoc regarding ExecuteListener lifecycle
#15917 - Swapped examples in manual section "group-by-tables"
#15918 - AbstractDatabase::markUsed doesn't work in some edge cases
#15927 - SnowflakeDataType is missing references to Snowflake's JDBC-internal spellings of TIMESTAMPNTZ, TIMESTAMPLTZ, TIMESTAMPTZ
Version 3.18.0 - March 8, 2023
================================================================================
DiagnosticsListener improvements
--------------------------------
A lot of additional diagnostics have been added, including the automated
detection of pattern replacements, helping you lint your SQL queries
irrespective of whether you're using jOOQ to write your SQL, or if you're using
it as a JDBC / R2DBC proxy for an existing application.
A lot of these diagnostics are available as ordinary pattern transformations,
which we've started adding in jOOQ 3.17. Some new patterns include:
- CASE WHEN a = b THEN 1 END to CASE a WHEN b THEN 1 END
- CASE WHEN x IS NULL THEN y ELSE x END to NVL(x, y)
- CASE WHEN x = y THEN NULL ELSE x END to NULLIF(x, y)
- (SELECT COUNT(*) FROM t) > 0 to EXISTS(SELECT 1 FROM t)
- And much more
See these sections for more details:
- https://www.jooq.org/doc/3.18/manual/sql-execution/diagnostics/
- https://www.jooq.org/doc/3.18/manual/sql-building/dsl-context/custom-settings/settings-diagnostics-connection/
- https://www.jooq.org/doc/3.18/manual/sql-building/dsl-context/custom-settings/settings-diagnostics-logging/
- https://www.jooq.org/doc/3.18/manual/sql-building/queryparts/sql-transformation/transform-patterns/
More SQL/JSON support
---------------------
SQL/JSON is one of the most promising recent additions to the SQL language, and
we're always keen on improving jOOQ's support for these features. In this
release, we've added support for a variety of useful, vendor specific SQL/JSON
extensions, including:
- JSON_KEYS (from MySQL)
- JSON_SET (from MySQL)
- JSON_INSERT (from MySQL)
- JSON_REPLACE (from MySQL)
- JSON_REMOVE (from MySQL)
- Accessors -> and ->> (from PostgreSQL)
More information on new JSON function support can be found here:
- https://www.jooq.org/doc/3.18/manual/sql-building/column-expressions/json-functions/
More QOM implementation
-----------------------
The Query Object Model (QOM) API, which was introduced in jOOQ 3.16, has been
enhanced with more statement, function, expression support, allowing for more
complete SQL transformation and traversal. This is specifically interesting for
pattern replacements, diagnostics, and custom SQL transformations.
The QOM API is still in an experimental state. While we don't expect any
fundamental changes anymore, there can still be source incompatibilities between
minor releases.
For details about the model API, please refer to:
- https://www.jooq.org/doc/3.18/manual/sql-building/model-api/
Oracle associative array support
--------------------------------
When using stored procedures in Oracle, users are likely going to make heavy use
of Oracle PL/SQL package types. We've supported PL/SQL RECORD types and PL/SQL
TABLE types for a while, both of which had limited ojdbc support in the past.
Associative array support can still be a challenge with ojdbc, but with jOOQ and
its code generator, most associative arrays can be bound and fetched very
easily.
PostgreSQL Multi dimensional array types
----------------------------------------
An often requested feature from our PostgreSQL integration is multi dimensional
array support. This version of jOOQ will support those types in code generation
(where possible) and at runtime via multi dimensional Java arrays.
Kotlin specific improvements
----------------------------
jOOQ is also the best way to write SQL in kotlin. We're always looking out for
new convenience via the jOOQ-kotlin extension module, for example:
- ResultQuery Collectors
- JSON access
- More nullability support in generated code
For more details, see:
- https://www.jooq.org/doc/3.18/manual/sql-building/kotlin-sql-building/
R2DBC 1.0 support
-----------------
This jOOQ version upgrades its R2DBC dependency to 1.0.0.RELEASE.
For a complete list other, minor improvements, see the below change notes.
Features and Improvements
-------------------------
#252 - Add support for multi-dimensional ARRAY types
#3173 - Add SQL transformation to inline CTE
#5254 - Add some additional description to each jOOQ-example
#5620 - Add support for PL/SQL TABLE and associative array types in Oracle 18c
#5679 - Document MySQL and T-SQL style hints in the manual
#5799 - Add support for the SQL Standard WITH ORDINALITY clause
#6237 - Merge all manual versions into one
#6311 - Add flag to code generator to use DBA_XYZ views instead of ALL_XYZ views
#7106 - Add support for START TRANSACTION, COMMIT, ROLLBACK, SAVEPOINT statements
#7398 - Add Settings for each individual diagnostic
#7503 - Add support for PostgreSQL functions returning anonymous RECORD types
#7512 - Emulate LATERAL on SQL Server for table lists
#7527 - Add more diagnostics to DiagnosticsListener SPI
#8630 - Support MySQL GROUPING() function
#8893 - Add Settings.renderTable
#8952 - Support parsing JSON_VALID(x) and ISJSON(x) as x IS JSON
#9720 - Support logical XOR operator
#9743 - Support qualified asterisk on unaliased JoinTables
#9760 - Translator's "identifier case" option is confusing
#9818 - Get view source code from org.jooq.Meta views
#9844 - Generator strategies should support , , , ,
#9880 - Translate SQL Server WITH (ROWLOCK) clauses to corresponding FOR UPDATE
#10018 - Add support for PostgreSQL's JSON/JSONB -> and ->> operators
#10026 - Emulate LATERAL on SQL Server for simple JOIN with trivial ON
#10212 - Add options to generate non-null attributes on Records, Pojos, and interfaces in KotlinGenerator
#10340 - Add SQLDialect.category()
#10619 - Create manual subsections for each function
#10730 - Add support for JSON_ARRAYAGG(DISTINCT)
#11355 - Log warning when unsupported dialect version is being used
#11681 - Get SQLDialect.VERTICA up to date
#11830 - Add Settings.renderRowConditionForSeekClause to allow for avoiding row predicate usage
#11966 - Various parser bugs / missing features
#11981 - Add support for more array functions
#11986 - Get HANA dialect support up to date
#12022 - Add code generator support for MySQL's invisible columns
#12033 - Add MULTISET_AGG(DISTINCT ...) aggregate and window function support
#12037 - Implicit JOIN improvements
#12045 - Support correlating MULTISET operators in dialects that can't correlated subqueries from derived tables
#12531 - Auto-inline bind values in ON CONFLICT .. WHERE clause
#12621 - Split manual section about the SELECT clause into its subsections
#12907 - Add a QOM.UConvertibleOperator utility with methods like $converse()
#13182 - Improve formatting XMLATTRIBUTES
#13249 - Emulate JSON_OBJECT's ABSENT ON NULL clause in MySQL
#13262 - Manual should distinguish more clearly between Maven XML and standalone XML content
#13358 - Add SQLDialect.POSTGRES_15
#13375 - Add support for unnesting collections of expressions with DSL::unnest
#13408 - Get TERADATA dialect up to date
#13418 - Add a Settings.emulateComputedColumns
#13423 - Add more "Don't Do This" content to the manual
#13592 - Add more startup tips to be logged with the jOOQ logo
#13593 - Replace more common patterns in query object model
#13596 - Add QOM.Aliasable, a query object model type implemented by all aliasable objects
#13640 - Continue work on public query object model API
#13656 - Add a SQLDialect.SQLSERVER2022
#13698 - Support parsing H2's CREATE MEMORY TABLE and CREATE CACHED TABLE
#13701 - Add a section to the manual about runtime vs code generation version compatibility
#13706 - OnError.FAIL should log a message about the user's option how to handle the problem
#13718 - Log warning should show jOOQ-meta type to help disambiguate objects that share the same name
#13728 - Add SQLDialect.SQLITE_3_39
#13737 - Getting started section should clarify that jooq is the main dependency, and jooq-meta, jooq-codegen are typically unneeded
#13747 - Add a "main types overview" to the manual
#13748 - Support parsing the PostgreSQL DATE_PART function
#13763 - Support DB2 selectivity-Keyword in Query-Parser
#13764 - Refactor internal schema mapping logic to use the new QualifiedImpl type
#13769 - Emulate GROUP BY using substitution in dialects where this isn't natively supported
#13781 - Add SQLDialect.COCKROACHDB_22
#13791 - Apply an auto-converter to in the absence of an explicit converter, if possible
#13850 - Get MEMSQL dialect up to date
#13881 - Parse and ignore SQLite DDL conflict-clause
#13882 - Parse length on unknown data types
#13891 - H2 dialect should always generate standard OFFSET .. FETCH
#13893 - Add SQLDialect.H2_2_1_214
#13894 - Add SQLDialect.precedesStrictly(SQLDialect)
#13902 - Support H2's strict mode
#13925 - Show deprecation warning for javax.persistence annotations also for method and field annotations
#13928 - Emulate UPDATE .. RETURNING in MariaDB 10.5+ using INSERT .. SELECT .. ON DUPLICATE KEY UPDATE .. RETURNING
#13935 - Support H2's qualified domains
#13936 - Code generator should properly qualify H2 domain enums
#13944 - Add Traversers.consuming(Consumer super QueryPart>): Traverser, Void>
#13951 - Add support for MySQL's JSON modification functions
#13957 - Add support for Oracle associative array of object types as IN parameter
#13964 - Add a SQL building in kotlin section
#13970 - PostgreSQL code generation fails when user defined type starts with _
#13971 - Add DataType.array() as a DSL style shortcut for getArrayDataType()
#13973 - Add DataType.getArrayBaseDataType() and getArrayBaseType()
#13986 - Add support for Db2 11.1 LISTAGG(DISTINCT)
#13995 - Improve documentation on Fields lookup methods
#14002 - KotlinGenerator shouldn't generate public default constructor if non-nullable attributes are generated on records
#14004 - Add documentation for KotlinGenerator and ScalaGenerator
#14006 - Add ResultQuery>.fetchMap() and fetchGroups() extension methods to jOOQ-kotlin
#14009 - Add DataType.isBoolean()
#14014 - Slow query against SYS.ALL_INDEXES in OracleDatabase
#14046 - Add support for MySQL's JSON_KEYS()
#14064 - Add SQL Server 2016 support for JSON_VALUE
#14065 - Add internal utilities to help avoid repeating expressions
#14066 - Split SimpleQueryPart into two, allowing for marking types that are always simple
#14071 - Add parser support for undocumented AS keyword in SQL Server procedure parameter list
#14074 - Add support for passing a list of bind values to DSL.unnest(Collection)
#14077 - Add support for SQL Server's ALTER VIEW .. AS syntax
#14081 - Translator should use 100% screen width
#14082 - Add parser support for MySQL's CREATE INDEX .. VISIBLE keyword
#14084 - Parser should parse Oracle WITH FUNCTION syntax (and throw an unsupported exception)
#14089 - Add parser support for CREATE SCHEMA .. DEFAULT CHARSET
#14098 - Document the fact that some DDL emulations may require the commercial editions
#14099 - Upgrade pgjdbc to 42.5.0
#14103 - Add parser support for MySQL USE / FORCE / IGNORE INDEX hints
#14110 - License header should use HTTPS rather than HTTP
#14118 - Support defaulted PL/SQL RECORD and TABLE parameters to stored procedures
#14131 - Improve Val.getName() for array values
#14136 - Let DiagnosticsContext extends Scope
#14146 - Add a LoggingDiagnosticsListener, a default DiagnosticsListener implementation that logs events
#14155 - Add ExecuteListener::transformStart and ::transformEnd events
#14157 - Upgrade to kotlin 1.7.20
#14158 - Add ExecuteContext::batchMode to indicate what type of batch is being executed
#14159 - Add parser support for
#14160 - Parse and ignore the T-SQL SPARSE column definition flag
#14166 - Render correct SQL when COALESCE or CASE have empty contents
#14179 - Add a QOM.UReturnsNullOnNullInput marker interface
#14180 - MANIFEST.MF contains unnecessary javax.persistence dependency
#14181 - All QOM function types should implement UOperator[N]
#14186 - All UOperator[N] types should extend UOperator, offering an $args():List>
#14201 - Improve formatting of non ordinary grouping sets
#14202 - QOM API mutator methods should be annotated with @CheckReturnValue
#14214 - Add Traverser.recurseChildren(): Predicate
#14230 - Add native support for Snowflake * EXCLUDE (columns) syntax
#14242 - Add support for DB2 ROWNUMBER and DENSERANK window function in parser
#14248 - Add parser support for CockroachDB STRING type
#14249 - Add support for RIGHT JOIN and FULL JOIN in REDSHIFT
#14251 - Add an internal Tools.allMatch() utility
#14262 - Field::contains should implement PostgreSQL @> also for JSONB types
#14268 - Add support for SQL Server 2022 GENERATE_SERIES
#14269 - Add support for SQL Server 2022 GREATEST and LEAST
#14270 - Add support for SQL Server 2022 WINDOW
#14271 - Emulate SPLIT_PART using STRING_SPLIT in SQL Server 2022
#14272 - Add support for SQL Server 2022 IGNORE NULLS and RESPECT NULLS
#14301 - Add SQLDialect.MYSQL_8_0_31
#14302 - Add support for INTERSECT ALL and EXCEPT ALL in MySQL
#14303 - Add support for INTERSECT ALL and EXCEPT ALL in MariaDB 10.5
#14308 - Support qualified asterisk on aliased JoinTables
#14309 - Add Field::nullsFirst and Field::nullsLast convenience methods
#14310 - Add support for aliased JoinTables
#14311 - Improve formatting of nested JoinTable
#14320 - Add native Informix DECODE support
#14331 - Add Settings.renderRedundantConditionForSeekClause to improve SEEK predicate performance in some RDBMS
#14336 - Parse and ignore Teradata (TITLE '...') syntax
#14337 - Parse the Teradata (NAMED ...) syntax
#14342 - Generate referenced sections list in manual
#14360 - Add parser support for prefixed PARTITION BY .. OUTER JOIN syntax
#14361 - Add API support for fullJoin(..).partitionBy(..)
#14363 - Support BITNOT in HANA dialect
#14365 - Emulate expressions in LIMIT .. OFFSET where not natively supported in more dialects
#14366 - Add HANA support for UPDATE .. FROM
#14379 - Add DSL.raw(String) and Settings.renderPlainSQLTemplatesAsRaw to allow plain SQL without templating
#14388 - Add support for ARRAY concatenation
#14406 - The AutoAlias feature isn't applied from within the JOIN tree, only from the TableList
#14416 - Support UNNEST(ARRAY[...]) in dialects that do not otherwise support arrays
#14426 - OUTER APPLY emulation should use TrueCondition, not hard coded 1 = 1
#14440 - Add Teradata support for STRTOK via SplitPart
#14441 - Support parsing && and ! logical operators in MySQL
#14442 - Add ParserContext::parseCategory
#14447 - Get BigQuery dialect up to date
#14450 - Add native support for WINDOW in BigQuery
#14457 - Add support for MySQL style ELT() function (equivalent to CHOOSE())
#14458 - Add native DECODE() support in MemSQL and DECODE_ORACLE() support in MariaDB
#14464 - Improve confusing parser error message "SELECT or SEL" expected
#14465 - Add parser support for SQL Server OPENJSON with WITH clause
#14473 - Refactor Db2 v9 and Teradata LISTAGG emulation to use native support for XMLSERIALIZE instead of plain SQL templates
#14481 - Add parser support for bitemporal table queries with system_time and business_time
#14488 - Parser should disambiguate SQL Server + operand based on operand lookup
#14496 - Implement BatchMultiple::toString and BatchSingle::toString
#14499 - Add an R2DBC LoggingConnection
#14506 - Add a manual section for LoggingConnection
#14510 - Add Field.comment(Comment): Field
#14511 - GROUP_CONCAT manual page is missing a reference to `Settings.renderGroupConcatMaxLenSessionVariable`
#14512 - CREATE TABLE statements should generate COMMENT clauses for Field comments
#14513 - ALTER TABLE statements should generate COMMENT clauses for Field comments
#14534 - Add option to the code generator
#14537 - Add org.jooq.True, org.jooq.False, and org.jooq.Null to QOM API
#14538 - Add DataType.isFloat()
#14539 - Add ALTER TABLE .. ADD .. [ FIRST | AFTER .. ] support for MariaDB
#14548 - UOperator[N] QOM types should generate both named accessors and mutators
#14555 - Improved emulation of row value expression predicates of degree 3+
#14560 - Refactor QuantifiedSelectImpl into separate subtypes
#14572 - Document kotlin coroutine usage in manual
#14573 - Add Settings.returnDefaultOnUpdatableRecord and Settings.returnComputedOnUpdatableRecord
#14578 - Add native support for DISTINCT predicate in SQLDialect.SQLSERVER2022
#14579 - Add native support for LEFT_SHIFT(), RIGHT_SHIFT() in SQLDialect.SQLSERVER2022
#14580 - Add native support for BIT_COUNT() in SQLDialect.SQLSERVER2022
#14581 - Add support for BIT_SET or BIT_GET functions
#14584 - Add bitwise operation support for EXASOL
#14586 - Update third party dependencies
#14592 - Add parser support for T-SQL table hints without WITH keyword
#14594 - Support parsing whitespace between : and named parameter identifier
#14595 - Support parsing WITH READ ONLY and WITH CHECK OPTION clauses
#14611 - Support WITH CHECK OPTION and WITH READ ONLY in other dialects
#14631 - Add parser support for SQLite's STRICT tables
#14641 - Settings.emulateMultiset should use NestedCollectionEmulation.JSONB as default again, in PostgreSQL
#14642 - Add a SQLExceptionLoggerListener that logs additional information to help debug constraint violations
#14648 - Get SNOWFLAKE dialect up to date
#14653 - Add SQL/JSON support for the SNOWFLAKE dialect
#14655 - Add Snowflake support for the TABLE() constructor to call table valued functions
#14658 - Get MariaDB dialect up to date
#14660 - Work around Snowflake's INSERT .. VALUES limitation of not being able to reference expressions
#14665 - Non-boolean field emulation should be NOT NULL aware
#14690 - Add parser support for SQLite's WITHOUT ROWID tables
#14701 - Let DataAccessException::sqlStateClass be based on SQL Server error codes for SQLStateClass 22 or 23
#14708 - Add Queries.batch(): Batch
#14711 - Add missing set(String, Param) and setLocal(String, Param) overloads
#14713 - Add support for interval types in DefaultConverterProvider
#14717 - Transform MySQL IN (SELECT .. LIMIT) to derived table also for MemSQL
#14718 - Add dialect versions for MEMSQL
#14722 - Add bitwise aggregate function support for Vertica
#14726 - Document Converter behaviour for UNION and other set operation subqueries
#14738 - Add parser support for Snowflake's EQUAL_NULL function
#14742 - Remove MariaDB's self-reference-in-DML-subquery restriction workaround
#14755 - Link to execute with jOOQ blog post from jOOQ / JPA manual sections
#14763 - Update maven-plugin-api and maven-core depedency
Breaking changes
----------------
#2500 - Add support for the MySQL YEAR data type, mapping to java.time.Year
#5405 - Generated SETOF table_type functions should reuse the TableRecord type of the referenced table
#7841 - DSL.asterisk() does not work well with plain SQL
#13047 - Make JAXB API dependency optional
#13565 - Update R2DBC dependency to 1.0.0.RELEASE
#13961 - Add ContextConverter, a Converter subtype that receives a ConverterContext in from() and to() methods
#14007 - Exclude SQLITE_SEQUENCE, SQLITE_MASTER, SQLITE_STAT% when is false
#14058 - WindowSpecification::$partitionBy should return UnmodifiableList extends GroupField>
#14095 - DSL.createView() returns raw type CreateViewAsStep
#14138 - DiagnosticsConnection should store duplicate SQL strings in Configuration, not static variable
#14153 - Make NullStatement a UTransient QueryPart
#14263 - Add jsonbObject() convenience overloads for single element objects
#14267 - Upgrade liquibase-core dependency to 4.17 in jooq-meta-extensions-liquibase
#14409 - Refactor Values to implement AutoAlias
#14445 - Delay ExecuteContext::connection in BatchMultiple and BatchSingle
#14476 - Move experimental migrations API to DSLContext::migrations to avoid conflicts with transaction statements
#14546 - QOM mutators on generic types such as UOperator should return covariant type
#14561 - Rename various QOM accessors / mutators from $select() to $query()
#14675 - Add a DataException for SQLState 22 and a IntegrityConstraintViolationException for SQLState 23
#14727 - Generated TRecord.from(IT) method behaves differently from Record.from() with respect to NOT NULL DEFAULT columns
Deprecations
----------------
#14634 - Deprecate transformInConditionSubqueryWithLimitToDerivedTable configuration and offer transformation in the jOOQ Open Source Edition
Bug Fixes
---------
#6359 - PostgreSQL inlined numeric arrays shouldn't generate string literals
#6516 - ORA-01704 when generating large CLOB inline values in Oracle
#7076 - ForcedType enum with no matching value being converted to last enum value
#7552 - INSERT .. ON DUPLICATE KEY { IGNORE | UPDATE } emulation should consider all UNIQUE keys on PostgreSQL
#8277 - Manual example for running the code generator with ant is missing the JDBC driver dependency
#8609 - MemSQL does not support "nested scalar subselects in project list"
#9623 - Update manual example about binding JSON types
#10014 - Infinite loop in code generation templating language if a parameter is forgotten
#10712 - Firebird invalid ORDER BY clause when using ORDER BY column with set operation
#10819 - NULL clause on H2's columns should not be produced
#11015 - VALUES() must cast NULL literals in the first row, if the type is known and the RDBMS cannot infer it
#11620 - In MySQL, withReturnAllOnUpdatableRecord(true) causes two SELECT statements
#11682 - Avoid generating field names using toString()
#11856 - StackOverflowError in parser with Settings.parseWithMetaLookups == IGNORE_ON_FAILURE
#12214 - JoinTable.onKey(ForeignKey) does not work when tables are aliased
#12942 - maven-deploy and maven-install bash and batch scripts should terminate on mvn command error
#13343 - R2DBC implementation may hang when there's an exception in the rendering logic
#13575 - Support EXCLUDED table emulation also in expressions
#13669 - Connection::close call is skipped when R2DBC query fails
#13689 - Cannot parse computed columns in the presence of identity column
#13690 - Data type rewrites to BOOLEAN don't work in Oracle JSON_OBJECT
#13703 - Ill formatted Javadoc in DSLContext
#13717 - Wrong query in example of manual section about dynamic SQL
#13722 - Regression: Client code no longer compiles when calling DSLContext.fetchSingle(Table, Condition...)
#13723 - Regression: Zero-length delimited identifier is generated for enum columns when using
#13730 - Generated sources emits "reference not accessible" warning for `org.jooq.impl.AbstractTable#convertFrom`
#13732 - Wrong Javadoc in generated AbstractSpringDAOImpl
#13738 - Reactive transactions don't call Connection::close
#13751 - GROUP BY
does not use table alias
#13752 - Returning null from transactionCoroutine throws NoSuchElementException
#13762 - DefaultRecordBinding.pgRenderRecordCast and others don't apply schema mapping
#13766 - Upgrade log4j to 2.18.0 to mitigate CVE-2022-33915
#13771 - Parser doesn't support parsing parenthesised GROUP BY expression
#13780 - ERROR: unknown function: nameconcatoid() in CockroachDBDatabase on CockroachDB 22
#13796 - Virtual client side computed columns must be excluded from generated DDL statements
#13798 - GenerationOption.DEFAULT should act as STORED in client side computed columns
#13800 - Improve formatting of H2 computed columns
#13802 - TransactionPublisher does not commit transaction when wrapped in reactor's Mono
#13803 - AbstractSpringDAOImpl imported from wrong package when generating multiple schemas
#13804 - Wrong kotlin code generated for SQL Server stored procedures
#13808 - ArrayGet should not produce parentheses when used as a store assignment target, e.g. in UPDATE
#13816 - Wrong example in manual section about ST_Equals
#13818 - MySQL DEFAULT CURRENT_TIMESTAMP column is generated as computed column
#13827 - NullPointerException when calling DBMS_AQ.dequeue
#13843 - Cannot use Table as SelectField from derived table where nesting records is supported natively
#13844 - Fix typo in code generation log message
#13851 - Wrong DDL generated for computed columns in MEMSQL
#13854 - Syntax error in MemSQL code generation
#13857 - Upgrade pgjdbc to mitigate CVE-2022-31197
#13866 - KotlinGenerator produces directory names with backticks when catalog names contain special characters
#13867 - MemSQL doesn't support the SET @@var = @other_var syntax
#13872 - PostgreSQL arrays don't deserialise correctly when using XML MULTISET emulation
#13880 - Parser should parse and ignore PRIMARY KEY UNIQUE
#13890 - Broken Javadoc link for JDK Generated annotation in manual
#13897 - The maven codegen plugin does not load syntheticObjects from external configurationFile
#13904 - Code generation fails with H2 2.1.214 when using CASE_INSENSITIVE_IDENTIFIERS
#13906 - Logger name repeated twice
#13913 - Convert truncates microseconds from OffsetDateTime when converting to Instant
#13919 - PostgreSQL generated code doesn't maintain precision / scale on NUMERIC or TIME, TIMETZ, TIMESTAMP, TIMESTAMPTZ types
#13926 - NullPointerException thrown instead of DetachedException, when executing detached query
#13934 - DDLDatabase cannot handle qualified enum types in CREATE TABLE
#13952 - IsNotDistinctFrom predicate doesn't declare non-nullability
#13965 - Work around HSQLDB bug where NULL literal cannot be fetched as array
#13974 - ParsingConnection doesn't correctly relay Statement::getResultSet, Statement::getUpdateCount, or Statement::getMoreResults on static Statement
#13976 - Wrong Java version support listed on website for jOOQ 3.17 Open Source Edition
#13993 - Wrong value returned from NullCondition::isNullable
#14003 - Compilation error in generated code when combining , and
#14010 - Postgres array of single-field UDT reads UDT's field as null instead of actual value
#14017 - Moderately slow query on ALL_TAB_COLS due to cartesian product in OracleTableDefinition
#14021 - Moderately slow query on ALL_ARGUMENTS due to EXTENDED DATA LINK FULL in OracleTableDefinition
#14026 - Fix "Use case" -> "Possible solution" field name in feature request template
#14027 - ClobBinding and BlobBinding shouldn't delegate sql() generation to internal DefaultStringBinding or DefaultBytesBinding
#14033 - Fix incorrect grammar in XSD documentation
#14034 - Upgrade to Scala 2.13.9 to mitigate CVE-2022-36944
#14052 - Upgrade to HSQLDB 2.7.1 to mitigate CVE-2022-41853
#14053 - Upgrade jackson-databind dependency to 2.13.4 to mitigate CVE-2022-42004
#14055 - Upgrade protobuf-java to 3.16.3 to mitigate CVE-2021-22569
#14060 - Work around Derby's Error [30000] [54002]: A string constant starting with '...' is too long
#14067 - ClobBinding and BlobBinding shouldn't bind a null value on PreparedStatement::setClob and ::setBlob in Firebird, HSQLDB
#14086 - Support parsing SELECT .. INTO FROM ..
#14094 - Manual shouldn't suggest calling JSON::toString or JSONB::toString
#14097 - Cannot pass null values as arguments for associative arrays
#14100 - Table as SelectField native support relies on actual column order, not generated order
#14105 - ClassCastException when nesting array(select row) projections in PostgreSQL
#14108 - Upgrade jackson-databind dependency to 2.13.4.2 to mitigate CVE-2022-42003
#14111 - Wrong key data type stored in associative record
#14112 - Cannot pass null values as arguments for PL/SQL RECORD types
#14125 - Document a few missing SQL transformations in the manual
#14126 - Wrong descriptions in manual section "codegen-extension-postgres"
#14130 - Wrong claims about SQL standard optional FROM clause in manual
#14132 - Code generator shouldn't generate JPA Column precision on non-decimal types
#14141 - Generated text blocks for view sources should escape \
#14163 - Wrong transformation for transformPatternsTrivialPredicates when DISTINCT predicate operand is NULL
#14169 - HAVING TRUE is not a trivial predicate for the transformPatternsTrivialPredicates transformation
#14176 - ParserCLI in interactive mode should use Settings defaults for its SQL transformation flags
#14182 - Typo in window function section of the manual
#14185 - [#14182] Fix typo in percentRank javadoc comment
#14187 - StackOverflowError in transformPatternsArithmeticExpressions when commutative operator has 2 inline arguments
#14191 - DefaultDiagnosticsContext should cache resultSetFetchedRows
#14194 - Bad syntax generated when using the Field.collate() clause in CREATE TABLE statements
#14195 - Cannot query geometry value in a multiset
#14204 - AbstractToJacksonConverter does not work when userType is array
#14205 - ResultSet diagnostics don't work for PreparedStatement
#14206 - Improve formatting of H2 procedural ELSE statement
#14210 - Regression in MS Access CONCAT implementation
#14213 - Typo in mapping exception message
#14215 - Plain SQL INSERT .. RETURNING doesn't work with unqualified field templates in SQL Server
#14220 - Update blog links from Javadoc and comments
#14225 - Missing changelog for version 3.17.5
#14226 - Outdated Javadoc on DSL.array() for how jOOQ renders H2 array constructors
#14231 - Cannot query geometry value in a nested ROW
#14232 - ORA-00904: "v0"."GET_WKT": invalid identifier
#14236 - DefaultDiagnosticsContext shouldn't call ResultSet::getMetaData on already closed ResultSet
#14239 - Work around SQLite's error: HAVING clause on a non-aggregate query
#14245 - Replace internal DSL.NULL(x) by DSL.inline(null, x)
#14246 - Improve DERBY emulation of ROUND
#14252 - Document CHOOSE
#14255 - Improve generated unknown data type javadoc when forcedTypes match return type, but there are still unknown parameter types
#14258 - ClassCastException in WithImpl::$replace
#14276 - Median emulation ignores FILTER and OVER clauses
#14282 - Bump postgresql from 42.5.0 to 42.5.1
#14283 - Kotlin Value Classes in Constructor lead to name based mapping failure
#14286 - Upgrade pgjdbc to 42.5.1 to mitigate CVE-2022-41946
#14289 - ScalaGenerator generated code should avoid "procedure syntax"
#14294 - ON CONFLICT DO NOTHING emulation should continue to be applied for PostgreSQL 9.3 and 9.4
#14300 - Expand unqualified asterisk in MySQL when it's not leading
#14313 - Informix DDL statements generate invalid SQL for timestamp columns
#14316 - Informix CURRENT_TIMESTAMP emulation doesn't work as DDL DEFAULT expression
#14319 - Informix BOOLEAN expressions can't be compared in some cases
#14321 - Wrong NULL behaviour of BitAndAgg, BitOrAgg, and related aggregate function emulations
#14325 - Informix BOOLEAN literals 't' and 'f' need to be cast to BOOLEAN explicitly
#14328 - Excess query executed against SQLite when emulating INSERT .. RETURNING
#14333 - ArrayIndexOutOfBoundsException when parsing ill formed SQL ending with a comment and a semicolon
#14339 - Exception in Teradata code generation: Unknown column TVName
#14346 - Error: Invalid Top N Value: N is too big for Teradata OFFSET emulation
#14349 - Teradata TOP expression or DISTINCT TOP don't work
#14352 - PostgresDSL arrayOverlap does not properly cast arguments
#14353 - Parser meta lookups don't work correctly when using DELETE .. FROM with aliased tables
#14356 - java.lang.StackOverflowError at org.jooq.impl.Expression.acceptAssociative
#14357 - Use ? as parameter marker on MySQL, MariaDB when using R2DBC
#14368 - Meta::getTables should list also PARTITIONED TABLE in PostgreSQL
#14371 - Slow TableAlias::equals implementation, when argument type is TableImpl
#14372 - Parser reports wrong Ambiguous field identifier error when derived tables share column names
#14373 - Parser produces wrong projection data type when parsing doubly nested derived table
#14382 - Wrong example code in manual section "connection-access"
#14383 - Broken link in a logging statement and Javadoc
#14387 - Table::useIndex and similar table wrapping methods break joins using onKey()
#14395 - DSL::noField doesn't work in SEEK clause
#14403 - "You can't specify target table '...' for update in FROM clause" when target table has index hint in MySQL
#14421 - Update error reporting URL in log messages
#14425 - Code generation for sequences fails for SQL Server 2014
#14431 - Generated TableImpl::getSchema override should be annotated Nullable
#14432 - Correctly hint nullability of getSchema() method
#14437 - UnsupportedOperationException when selecting row with YearToSecond
#14448 - BigQuery * EXCEPT can't have qualified identifiers
#14451 - WindowSpecificationPartitionByStep::partitionBy doesn't match dialects from WindowPartitionByStep::partitionBy
#14452 - BigQuery without FROM clause cannot use SELECT DISTINCT
#14453 - Emulate BETWEEN SYMMETRIC in BigQuery
#14454 - Wrong cast to CHAR type when generated code references SQLDataType.CHAR in BigQuery
#14459 - Work around Db2 error "The string constant beginning with ... is too long"
#14463 - Work around SQL Server's 4000 character JSON_VALUE length limitation
#14466 - Wrong result column type for requested conversion when reading JSONB_ARRAYAGG and JSONB_OBJECTAGG in DB2
#14469 - MULTISET comparison doesn't work in Db2 with XML or JSONB emulation
#14470 - Support parsing ALL keyword in aggregate functions
#14477 - Wrong SQL generated in SQL Server when virtual client side computed columns are referenced in RETURNING clause
#14479 - SQL Server RETURNING clause emulation for fetching trigger generated values generates incorrect SQL if no columns are fetched
#14489 - Syntax errors lead to unclosed R2DBC connection in SQL Server
#14507 - Remove redundant manual section "connection access"
#14514 - Feedback about translation tool
#14519 - Building jOOQ on Java 19 fails in xtend
#14524 - Compilation error due to missing import in generated code when using on a routine
#14528 - Update ParserCLI manual page with --help output
#14530 - NullPointerException in DB2Database when constraint schema is unavailable
#14535 - Fix org.jooq.Null Javadoc
#14541 - Add support for top level nested records in R2DBC queries
#14553 - Some QOM mutators of optional function parameters are annotated @Nullable, when they are not
#14564 - KotlinGenerator generates invalid code in equals() and hashCode() methods for inline value class fields
#14565 - Add missing documentation about
#14571 - Regression: UpdateQuery.execute() with RETURNING clause returns 1 even when no records were updated
#14574 - Regression: Meta::getTables returns tables of type TableType.TABLE when they're actually system views
#14597 - CockroachDBDatabase doesn't report enum types on columns correctly anymore
#14598 - Exception while executing meta query on MySQL 5.6: Unknown column 'information_schema.COLUMNS.GENERATION_EXPRESSION'
#14599 - setAllToExcluded also sets fields not specified in insert to excluded when using INSERT .. SET syntax
#14607 - Manual dialects comparison should turn off the generation of optional AS keywords
#14615 - Wrong window function example in manual
#14617 - SQL Server nullability information isn't generated correctly for domains
#14618 - Missing nullability information on nullable DOMAIN types that are made non-null by CREATE TABLE
#14621 - Work around a YugabyteDB regression querying the INFORMATION_SCHEMA.ATTRIBUTES table
#14628 - Missing default information on DOMAIN types that get an overridden DEFAULT by CREATE TABLE
#14635 - Single message JooqLogger doesn't work
#14644 - LoggerListener::fetchEnd should check if DEBUG logging is enabled
#14650 - Wrong emulation of GENERATE_SERIES with STEP parameter for Snowflake
#14657 - Nesting MULTISET/ROW/MULTISET/ROW with ad-hoc converters and JSON emulation results in ClassCastException
#14668 - Wrong ON KEY JOIN generated when aliased table appears twice in the JOIN tree
#14671 - Wrong column resolved by JoinTable.field(Field), when JoinTable contains aliased tables and lookup uses unaliased tables
#14684 - Translator duplicates comment only content when retaining comments
#14694 - INSERT statement does not apply types to bind values in VALUES clause when using valuesOfRows()
#14696 - Wrapping SQLException must copy SQLState and other info from wrapped SQLException
#14699 - PostgreSQL interval parser handle fractional seconds with interval style iso_8601
#14703 - SQL Server RETURNING clause emulation for fetching server side computed columns generates incorrect SQL if only computed columns are fetched
#14721 - performace regression after upgrade from 3.14.16 to 3.17.8
#14723 - Work around Vertica's ERROR: Subqueries not allowed in target of insert limitation
#14730 - Push down ScopeMappable marker interface from AbstractField to AbstractWindowFunction and TableFieldImpl
#14731 - Use LazyName in AbstractParam
#14736 - PostgreSQL Numeric array type with precision/scale too large in generated code
#14747 - Speed up AbstractRow.equals() and hashCode() when comparing with other AbstractRow
Version 3.17.0 - June 22, 2022
================================================================================
Client side computed columns
----------------------------
A ground breaking new core feature available in all commercial distributions is
the new client side computed columns feature, building on top of jOOQ 3.16's
commercial support for readonly columns and server side computed columns.
Not all RDBMS support computed columns (e.g. using the standard SQL syntax
GENERATED ALWAYS AS), and if they do, they might not support them
in both STORED (computed on write) and VIRTUAL
(computed on read) variants. jOOQ can now emulate both features at the client
side, by transforming your SQL queries:
- STORED affects INSERT, UPDATE,
DELETE, and MERGE
- VIRTUAL affects SELECT and the
RETURNING clause of DML statements. To make use of these,
combine them with the new synthetic column generation feature.
Unlike their server side counterparts, these client side features can produce
arbitrary expressions, including:
- Implicit joins
- Scalar subqueries
- MULTISET subqueries
- Much more
Think of this as "views" written in jOOQ, on a per-column basis. An expecially
useful feature combination is to combine these computed columns with the new
visibility modifier that allows for keeping computed columns (or the underlying
base columns) private and thus invisible to user code.
More about this feature here:
- https://www.jooq.org/doc/3.17/manual/code-generation/codegen-advanced/codegen-config-database/codegen-database-forced-types/codegen-database-forced-types-computed/
Audit columns
-------------
A special case of STORED client side computed columns are audit
columns, whose most basic implementation comes in the form of:
- CREATED_AT
- CREATED_BY
- MODIFIED_AT
- MODIFIED_BY
Other approaches to auditing exist, including soft deletion, additional meta
data, (bi)temporal versioning, but these columns are among the most popular
approaches, making this commercial only convenience feature very useful to a lot
of customers.
More about this feature here:
- https://www.jooq.org/doc/3.17/manual/code-generation/codegen-advanced/codegen-config-database/codegen-database-forced-types/codegen-database-forced-types-audit/
Java 17 baseline for the jOOQ Open Source Edition
-------------------------------------------------
Java 17 has been the latest LTS, and it includes a lot of really cool features,
including:
- sealed types (essential for pattern matching)
- records
- instanceof pattern matching
- text blocks
- switch expressions
jOOQ 3.16's experimental new Query Object Model (QOM) API experiments with
sealed types, which will be adopted more generally once the QOM API is
finalized.
To get broader user feedback on these improvements, as well as to embrace Java's
new LTS update cadence, we've decided to make Java 17 the baseline for the jOOQ
3.17 Open Source Edition, continuing our Java 8 and 11 support in the commercial
jOOQ distributions.
The following older jOOQ releases will continue to receive upgrades for a while:
- jOOQ 3.14: The last release with Java 8 support in the jOOQ Open Source
Edition and Java 6 support in the jOOQ Enterprise Edition
- jOOQ 3.15 and 3.16: The last releases with Java 11 support in the jOOQ Open
Source Edition.
PostgreSQL data type support
----------------------------
The jooq-postgres-extensions module, which contained support for the
HSTORE type, now has a lot more support for PostgreSQL specific
data types, including array types of each of:
- CIDR
- CITEXT
- LTREE
- HSTORE
- INET
- RANGE (including all the specialisations for INT4,
INT8, etc.)
In order to profit from these data types, just add the
org.jooq:jooq-postgres-extensions module to your code generation
and runtime dependencies, and the types are generated automatically.
Implicit JOIN improvements
--------------------------
In this release, we experimented with a few new implicit JOIN features,
including support for implicit JOIN in DML statements. The current
implementation produces correlated subqueries where JOIN isn't supported in DML
statements.
We've also experimented with creating a "convenience syntax" for other commonly
used correlated subqueries, such as EXISTS(...) subqueries or
MULTISET(...) subqueries. The experiment has been very interesting.
The prototype, however, was rejected. See the discussions here:
- https://github.com/jOOQ/jOOQ/issues/13063
- https://github.com/jOOQ/jOOQ/issues/13069
Future jOOQ versions will implement the desired convenience in the form of more
implicit JOIN functionality, offering the feature also as an implicit to-many
JOIN.
A leftover from the prototype is the fact that you can now more easily project
expressions other than classic Field in your SELECT
clause, namely:
- Table now extends SelectField
- Condition now extends Field
This means you can write a query like this:
Result> result =
ctx.select(
// Project a CustomerRecord directly
CUSTOMER,
// Project an AddressRecord from an implicit JOIN
CUSTOMER.address(),
// Project a boolean expression, instead of wrapping it with DSL.field()
exists(
selectOne()
.from(PAYMENT)
.where(PAYMENT.CUSTOMER_ID.eq(CUSTOMER.CUSTOMER_ID))
)
.from(CUSTOMER)
.fetch();
Pattern matching SQL Transformations
------------------------------------
SQL transformations have been a strategic feature set to recent jOOQ releases,
offering additional compatibility between SQL dialects to commercial customers,
such as, for example:
- Transforming Oracle's ROWNUM into equivalent window functions or
LIMIT clauses.
- Turning table lists including Oracle's (+) operator into ANSI
JOIN syntax.
This release ships with a new commercial only feature that directly transforms
the new Query Object Model (QOM)'s expression tree prior to rendering. It does
so by applying pattern matching to the expression tree. Some assorted examples
include:
- LTRIM(RTRIM(x)) into TRIM(x)
- x != a AND x != b into x NOT IN (a, b)
- x IN (a, b, c) AND x IN (b, c, d) into x IN (b, c)
- NOT (NOT (x = 1)) into x = 1
- NOT (x = 1) into x != 1
And much more. The primary use-cases for this functionality are:
- SQL linting, e.g. as part of an ExecuteListener
- SQL auto cleanup, including in a ParsingConnection
- Dialect migration, when upgrading database versions, or moving between dialects
- Patching specific SQL features
For more information about the feature, see:
- https://www.jooq.org/doc/3.17/manual/sql-building/queryparts/sql-transformation/transform-patterns/
Note that this feature is also available for free online:
- https://www.jooq.org/translate
Reactive and kotlin coroutine support
-------------------------------------
A lot of minor improvements have been implemented. A few more significant ones
include:
- R2DBC 0.9.1.RELEASE is now supported
- A new reactive transaction API has been added, which offers the same nested
transaction semantics as the existing blocking transaction API, see also:
https://blog.jooq.org/nested-transactions-in-jooq/
- jOOQ's reactive streams bindings via the Publisher SPI are now
bridged automatically to kotlin coroutines in the new
org.jooq:jooq-kotlin-coroutines module using the usual utilites
org.jetbrains.kotlinx:kotlinx-coroutines-core and
org.jetbrains.kotlinx:kotlinx-coroutines-reactor
- The org.jooq:jooq-kotlin extensions module now has additional
extension functions for more MULTISET and other nesting related
convenience.
- The entire blocking execution API is now annotated with
org.jetbrains.annotations.Blocking to help reactive jOOQ users
avoid accidentally blocking on a query, when using IntelliJ. In addition, we
now annotate experimental and internal API with the ApiStatus
annotation from the same package.
For a complete list other, minor improvements, see the below change notes.
Features and Improvements
-------------------------
#1592 - Add formal support for "audit" fields, such as CREATED_AT, CREATED_BY, MODIFIED_AT, MODIFIED_BY
#2092 - Add support for the Postgres INET data type (java.net.InetAddress)
#2333 - Add DSL.noField() for "conditional" LIMIT, OFFSET, GROUP BY, ORDER BY support when creating dynamic SQL
#2968 - Add support for PostgreSQL RANGE types
#3497 - Add methods to Context to distinguish between derived tables and other types of subqueries
#4727 - Let Table extend SelectField
#5214 - Add support for PostgreSQL's EXCLUDED table
#5641 - Support overriding code generation configuration via system properties
#5695 - Allow for expressions to be put in LIMIT / OFFSET
#5934 - Add support for the Postgres CITEXT type
#5970 - Add Setting to auto-inline all bind variables that participate in predicates on certain fields
#6454 - Support converting from java.sql.Array to Object[] types
#6489 - Code generator should support SQL-generated "dynamic regular expressions"
#7284 - Replace common patterns in query object model
#7508 - Add support for path expressions ("implicit joins") in DML
#7803 - Let ArrayRecord extend Formattable
#7912 - Add InsertOnDuplicateSetStep::setAllToExcluded to auto-set all insert column list columns to their EXCLUDED value
#8653 - Add support for parsing VALUES , ...
#8997 - Remove jOOQ-spring-example and documentation
#9335 - Add a jooq-kotlin-coroutines module to support transactional coroutines based on reactive streams Publishers
#9347 - DataType#getCastTypeName() does not respect rendering settings
#9425 - Add Meta.migrateTo(Meta):Queries to generate a migration script between two Meta versions
#9768 - Support MySQL inline INDEX specifications in DDLDatabase
#9817 - Add support for text blocks in generated code
#9879 - Add support for VIRTUAL and STORED client side computed columns
#10120 - Add some more aliasing examples to the manual
#10132 - Cast NULL literal to known type in Derby
#10407 - Add support for FIREBIRD 4 RETURNING * syntax
#10521 - Push down derived column list aliases to derived table's SELECT clause instead of using UNION ALL emulation, if possible
#10523 - Emulate UPDATE .. SET row = (SELECT ...) for dialects with no native support
#10537 - Split manual section about forcedTypes into different subsections
#10677 - Add to code generation configuration to specify behaviour when encountering unused objects
#10756 - Generate @Transactional on DAOImpl and generated DAOs query-methods
#10763 - Official jOOQ-postgres-extensions bindings should register themselves as low priority bindings if found on the code generation classpath
#10832 - Review our Nullable and NotNull annotation usage
#11232 - Parser should parse all Names.* values at least once
#11331 - Support SQLDataType.XML in DDL
#11467 - LoggerListener should log batch sizes for BatchSingle and BatchMultiple
#11575 - Replace internal dialect switches by Set
#11717 - Known limitations of the R2DBC integration
#11731 - Emulate Oracle INSERT .. SELECT.. RETURNING
#11770 - UpdatableRecord::merge should use new EXCLUDED semantics to avoid repeating bind values
#11823 - Investigate whether read-only converters really require the Class reference
#11969 - Let Condition extend Field
#12481 - ParsingConnection's PreparedStatement.getMetaData should be able to produce ResultSetMetaData prior to execution
#12515 - Support for RowN.mapping(Function super Object[], ? extends U>)
#12533 - Use org.jetbrains.annotations.ApiStatus
#12608 - Support referencing the same embeddable type multiple times per table
#12688 - Add support for H2's BIT_NAND_AGG, BIT_NOR_AGG, BIT_XNOR_AGG aggregate functions
#12721 - Add more startup tips to be logged with the jOOQ logo
#12734 - Address known limitations of MULTISET support
#12779 - Add support for MySQL COMMENT syntax in DDLDatabase's CREATE TABLE statements
#12782 - Add DiagnosticsContext.message(): String to give access to a text message
#12785 - Add DiagnosticsListener::exception to handle exceptions encountered while running diagnostics
#12807 - Parse and ignore Teradata's COMPRESS DDL clauses
#12829 - Support parsing H2's undocumented DROP TABLE .. CASCADE CONSTRAINTS syntax
#12830 - Support DROP TABLE .. CASCADE in Oracle
#12832 - Improve parser error message when encountering unterminated quoted identifier
#12834 - Support parsing empty column lists in INSERT statements
#12836 - Parser should support VALUES constructor in FROM clause without parentheses
#12838 - Support parsing DATABASE() as synonym for CURRENT_CATALOG() or CURRENT_DATABASE()
#12840 - Parser improvements thanks to the sqlancer team related test cases
#12843 - Support parsing LOG(n) without explicit base, based on input dialect
#12846 - Support parsing alternative H2 and HSQLDB DROP CONSTRAINT c IF EXISTS clause
#12848 - Support parsing HSQLDB's inline FOREIGN KEY syntax
#12862 - Upgrade all relevant R2DBC dependencies to 0.9.0.RELEASE
#12874 - Upgrade org.jetbrains:annotations dependency to 23.0.0
#12875 - Annotate all blocking execution methods with org.jetbrains.annotations.Blocking
#12877 - Improve blocking call error message when trying to run Query.execute(), etc. with R2DBC
#12883 - Add DSL.nullCondition(), a condition that correctly represents the NULL / UNKNOWN predicate value
#12893 - Add an Replacers.listening(Replacer, BiConsumer) to allow for listening to QueryPart.$replace() events
#12894 - Add accessors for Select::$limit, ::$limitPercent, $limitWithTies, ::$offset
#12896 - Add Settings.renderOptionalAssociativityParentheses
#12905 - Emulate expressions in LIMIT .. OFFSET where not natively supported
#12906 - Add a QOM.UCommutativeOperator utility with methods like $swap()
#12911 - QOM type accessors should accept Collection when they return UnmodifiableList
#12912 - Add missing Select.$groupBy(), $orderBy(), setter accessors
#12914 - Document QOM API outside of the QOM type, and annotate it as @Experimental
#12920 - Add Traversers.recursing()
#12921 - Replace internal org.jooq.impl.Finder utility by Traverser API usage
#12945 - Add Field>.mapping(Function[N]): Field> kotlin extension functions
#12959 - Gradle examples should list the usual commercial groupIds
#12973 - Add Traversers.containing(Predicate super QueryPart>)
#12989 - Update R2DBC dependency to 0.9.1.RELEASE
#13000 - Add Replacers.decomposing(): Replacer to decompose a compound statement into equivalent individual statements
#13001 - Refine Replacer Javadoc
#13004 - Add a TableElement type, a super type of Field> | Constraint | Index
#13014 - Add support for providing a --schema to the ParserCLI
#13031 - Add a rootPath property to the LiquibaseDatabase configuration for the FileSystemResourceAccessor
#13037 - Add documentation for the new FormattingProvider
#13070 - Change Function[N] to be non-experimental
#13072 - Remove experimental status on Row[N].mapping(Function[N])
#13077 - Bump postgresql from 42.3.2 to 42.3.3
#13078 - Add internal Tools.CONFIG as a convenience for Tools.CTX.configuration()
#13093 - Remove a few redundant null checks in jOOQ's internals
#13097 - Add Converters.forArrayComponents(Converter): Converter
#13104 - Reimplement SQL Server RETURNING emulation using QueryPart.$replace instead of SchemaMapping
#13109 - Add Settings.parseIgnoreCommercialOnlyFeatures
#13118 - Pull up Field::convert, ::convertFrom, ::convertTo methods to SelectField
#13129 - Add Context::predicandSubquery
#13131 - Add sections to the manual about using Table references as GroupField, SelectField
#13132 - DSLContext.fetchValue(SelectField) should work with Table
#13135 - Generate mapping() deconstruction convenience methods on generated Tables if is set
#13137 - Change default for code generation option to true
#13142 - Add JSONFormat.mutable(), XMLFormat.mutable()
#13143 - Add code generation flags to turn off the recognition of jOOQ-specific types
#13157 - Remove Oracle work around for JSON_ARRAYAGG causing ORA-40590: invalid format in Oracle 21c
#13161 - Add support for array bindings for the PostgreSQL HSTORE, INET, and CIDR types
#13162 - SchemaVersionProvider etc should be looked up using context classloader, too
#13183 - Add Javadoc warnings to UpdatableRecord::fetchChildren, and TableRecord::fetchParent about the N+1 problem
#13188 - Add support for the LTREE data type in the jooq-postgres-extensions module
#13192 - Add SQLDialect.MARIADB_10_7
#13194 - Various third party dependency updates
#13195 - Add a SQLDialect.SQLITE_3_38 dialect
#13201 - Add SQL Server JSON_ARRAY support via JSON_MODIFY
#13223 - Emulate inline indexes in CockroachDB
#13224 - Document declaration vs reference rendering mode of Field, Table, WindowDefinition, Parameter, CommonTableExpression
#13244 - Upgrade kotlin dependency to 1.6
#13246 - Add more examples to manual section "codegen-database-version-providers"
#13248 - Amend manual sections about data types (XML, Spatial, JSON)
#13255 - Support casting VARCHAR to XML / XMLTYPE in Oracle
#13260 - Add DAO.deleteById(T) overload
#13264 - Manual anchors should be generated from text, not from XSL generated ID
#13267 - Make QOM::unmodifiable public, internal
#13271 - Add support for SQLite 3.33 UPDATE .. FROM
#13272 - Add support for SQLite 3.35 ALTER TABLE DROP COLUMN
#13275 - Add SQLite 3.35 support for CTE MATERIALIZED hint
#13277 - Add support for SQLite 3.35's built-in math functions
#13278 - Add support for inverse hyperbolic functions ASINH, ACOSH, ATANH, ACOTH
#13281 - Add more explicit links to Record::from and RecordUnmapper wherever this applies
#13284 - Add support for T-SQL FOR XML EXPLICIT clause
#13286 - Emulate SQL/XML XMLELEMENT and XMLATTRIBUTES in SQL Server using FOR XML EXPLICIT
#13287 - Emulate SQL/XML XMLCOMMENT in T-SQL
#13288 - Emluate SQL/XML XMLCONCAT in T-SQL
#13289 - Support XMLQUERY() and XMLEXISTS() also in SQL Server
#13306 - Separate QOM.Ln (natural logarithm) from QOM.Log (logarithm with base)
#13324 - Code generation output shouldn't print table mapping output, if it's the same as the input
#13325 - Refactor internal FieldMapForUpdate to support the row assignments, too
#13326 - Emulate UPDATE .. FROM with MERGE, where available
#13329 - Add a FieldOrRowOrSelect nominal union type
#13334 - Add native support for MySQL's derived column lists starting from SQLDialect.MYSQL8_0_19
#13335 - Add Table::as and TableLike::asTable overloads accepting Collection extends X> for derived column lists
#13336 - Generate covariant overrides for Table.rename(Table) and Table.as(Table) methods
#13342 - Refactor Multiset::jsonxArrayaggEmulation
#13391 - Add support for the FOR XML BINARY BASE64 clause
#13393 - Replace internal usage of DatatypeConverter::parseBase64Binary by java.util.Base64
#13399 - jOOQ-checker should system property defaults that apply to the entire checked code
#13400 - Add native Informix MULTISET and nested ROW support
#13410 - Add a "Don't Do This" page to the manual
#13417 - Add native EXASOL ROWNUM support
#13432 - Add code generation option to
#13434 - Add to to generate synthetic columns
#13437 - Add Definition.isSynthetic() to indicate that a jOOQ-meta object has been created synthetically
#13446 - Add H2_2_0_202 support for UPDATE .. RETURNING and DELETE .. RETURNING
#13457 - New configuration to generate implicit join definitions ALWAYS from foreign key name
#13458 - PI() emulation should be ACOS(-1) rather than ASIN(1) * 2
#13461 - ResultQueryTrait::getFields should accept Supplier instead of ResultSetMetaData
#13467 - KotlinGenerator should generate open properties in generated records
#13471 - Add Scope.creationTime() and make it available through GeneratorContext.renderTime()
#13482 - Upgrade H2 dependency to 2.1.212
#13485 - Add a QOM.UOpaque marker interface for non-traversable QueryPart types
#13486 - Replace internal ConstantSortField by noField()
#13496 - Specify the various Scope subtype's lifecycle in their Javadoc
#13497 - Add BindingScope, a common super type of the various BindingXYZContext types
#13502 - Add a reactive transaction API
#13508 - Add MySQL support for INSERT .. ON DUPLICATE KEY UPDATE .. WHERE
#13516 - KotlinGenerator should generate implicit joins path accessors as properties
#13523 - Add support for parsing ! (bang) as equivalent to . (dot) in MS Access identifiers
#13525 - Improve Documentation for DSLContext.fetchStream() and related methods
#13528 - Document flag
#13534 - Avoid rendering PostgreSQL native cast operator :: which cannot be used in Hibernate native queries
#13538 - Add a Field>.collecting(Collector) kotlin extension function, and similar
#13540 - Remove "inline" and "reified" keywords from jOOQ-kotlin extensions where unnecessary
#13544 - Remove EXPERIMENTAL remark from ad-hoc converter and MULTISET construction API
#13546 - Stop aligning generated POJO members and constructor arguments in columns
#13552 - Change DSL.multiset(Select) into DSL.multiset(TableLike)
#13553 - Add TableLike.asMultiset(): Field>
#13556 - Consistently use org.jooq Maven groupId across the manual
#13558 - Add a PrefixSuffixGeneratorStrategy to jOOQ-codegen
#13571 - Emulate the PostgreSQL ON CONFLICT .. EXCLUDED pseudo table in MERGE emulation
#13572 - Add SQLDialect.MYSQL_8_0_20
#13573 - Add parser support for the PostgreSQL EXCLUDED pseudo table and MySQL VALUES() syntax
#13578 - Add native support for BITXNOR in H2
#13579 - Add documentation to the manual for bitwise aggregate functions
#13582 - DefaultRecordMapper should check whether user is attempting to map into an inner class
#13591 - Add a new ColumnElement type
#13594 - Change the Java 17 distribution to --release 17
#13599 - Let Context extends ExecuteScope
#13605 - Add JSONtoJacksonConverter, JSONBtoJacksonConverter, XMLtoJAXBConverter implementations
#13607 - Add JSONtoJacksonConverter, JSONBtoJacksonConverter, XMLtoJAXBConverter forcedType configuration convenience
#13616 - Scala extensions should have some multiset convenience
#13618 - Document EnumType::lookupLiteral's nullable result
#13631 - Add Context.topLevel() and Context.topLevelForLanguageContext() to give access to the top level QueryPart type that is being rendered
#13632 - DDLDatabase should have a sql property, as an alternative to scripts
#13634 - Add Field.mapping(Function[N]): Field kotlin extension functions, and the Scala equivalent
#13642 - Add a section about security to the manual's reference section
#13650 - Settings.emulateMultiset should have NestedCollectionEmulation.JSON as default in PostgreSQL
#13657 - Ability to download OSS edition snapshot
#13666 - Support Oracle JSON data type in DDL
#13670 - Add support for Oracle SYS.XMLTYPE in plain SQL templates
#13679 - Upgrade HSQLDB to 2.6.1
#13693 - JPA code examples should produce a jakarta.persistence.* import
Breaking changes
----------------
#12430 - Make Java 17 the baseline for the jOOQ Open Source Edition
#12772 - Continue work on public query object model API
#12781 - Remove pre 3.7 deprecated API and pre 3.7 documentation
#12895 - Rename QOM.UOperator[N]::constructor to ::$constructor
#12904 - Remove redundant limit(int) and offset(int) overloads
#12910 - Add DSL.emptyGroupingSet(): GroupField for explicit empty grouping sets
#13028 - Generated DAOs should use an embeddable's referencingName, not name for the fetchByXYZ() and fetchRangeOfXYZ() methods
#13053 - java.lang.NoClassDefFoundError: org/postgresql/util/PGInterval when rendering SQL without the pgjdbc dependency
#13068 - Change selectFrom(Table) methods to selectFrom(TableLike)
#13080 - Standard SQL MULTISET emulation using XML produces a null Result
#13082 - SQL Server MULTISET as JSON emulation of empty subquery produces NULL instead of empty Result
#13094 - Throw an exception when calling ConvertedDataType.getArrayDataType() when the type has a custom Binding
#13114 - SelectField.as() should return SelectField, not Field
#13115 - Change Table::getType to Table::getTableType
#13116 - Rename QOM.RowField to QOM.RowAsField
#13149 - Let Query.keepStatement() return CloseableQuery and ResultQuery.keepStatement() return CloseableResultQuery
#13181 - MULTISET emulation using SQL/XML doesn't correctly distinguish between NULL and ''
#13208 - SQL Server JSON_OBJECT should implement NULL ON NULL semantics by default
#13307 - Change $number() arguments in experimental QOM function types to $value()
#13426 - DSLContext::fetchFromJSON and ::fetchFromXML wrongly assume dialect specific data types in header
Deprecations
----------------
#13005 - Deprecate FieldOrConstraint
#13071 - Deprecate the org.jooq.Internal annotation
#13542 - Replace SPI default implementation class (e.g. DefaultExecuteListener) by default methods in interface
Bug Fixes
---------
#1049 - Better GREATEST() and LEAST() emulations for SQL Server using MAX() or MIN() with VALUES() correlated derived table
#5612 - Inline enum values should be cast to their enum type just like inline bind variables
#6133 - Cannot combine CREATE TEMPORARY TABLE .. AS .. with ON COMMIT ..
#7362 - Excess parentheses generated in NOT operator
#7783 - Nested row value expressions produce String column types when concrete type information should be available
#8614 - Passing arrays of generated tableRecords to a stored procedure generates SQL that won't parse due to cast ::any[]
#8681 - Wrong SQL generated for connectByRoot(minus(one()))
#9981 - Some BooleanDataKey values should be reset when entering a new scope
#10277 - CAST to PostgreSQL enum type lacks type qualification
#10304 - Unnecessary parentheses generated in ConditionAsField
#11114 - CAST should generate qualified type when casting to Table::getDataType or UDT::getDataType
#11424 - Improve the alignment of GenerationTool INFO log
#11441 - Inlining PostgreSQL CHAR(len)[] types produces VARCHAR[] instead
#11509 - batchStore(), batchInsert(), etc. with StatementType.STATIC_STATEMENT throws java.sql.BatchUpdateException
#11552 - UpdatableRecord::merge doesn't work in the presence of a unique constraint and in the absence of a primary key value
#11637 - FilePattern cannot load classpath resource from within jar file
#11722 - Code generator cannot handle tables from other schemas than PUBLIC referencing H2 enum domain types
#12036 - Timestamp Arithmetic fails with ConvertedDataType
#12134 - Support deserialising binary data in MULTISET emulations
#12269 - Records detached when converting nested multiset
#12287 - Replace calls to System.currentTimeMillis() by Clock usage
#12428 - DDL export no longer exports INDEX WHERE clause
#12525 - Nesting of converters causes unexpected Exception
#12783 - Feature Comparison on website is different from docs
#12788 - Support SQLite columns having no data type declaration
#12794 - Parser and code generator does not recognise H2 2.0's BINARY VARYING and other standard SQL data type synonyms
#12795 - Upgrade H2 dependency to 2.0.206
#12801 - GroupConcat renders string_agg separator argument within wrong parentheses
#12804 - Add parser support for Teradata's { UPDATE | DELETE } .. ALL syntax
#12811 - DAOImpl.findOptionalById shouldn't be final
#12818 - GROUP_CONCAT doesn't work as window function
#12820 - Parser doesn't support Derby's FOR BIT DATA data type modifier
#12824 - Parser cannot handle 1. decimal syntax in SELECT
#12825 - Parser shouldn't parse Teradata cast syntax based on Settings.parseAppendMissingTableReferences, but only based on the parseDialect()
#12852 - Parser can't handle TRIM (FROM ) syntax
#12854 - jOOQ Open Source Edition code generation doesn't work PostgreSQL 11 or less because of ERROR: column pg_attribute.attgenerated does not exist
#12855 - Bump spring-core from 5.3.13 to 5.3.14
#12858 - Computed column related support annotations claim SQLDialect.POSTGRES instead of SQLDialect.POSTGRES_12
#12864 - OSS Edition H2 INSERT .. RETURNING no longer works if columns are qualified with a schema
#12868 - The DATA_RENDERING_DATA_CHANGE_DELTA_TABLE qualification omission doesn't work correctly in the presence of scalar subqueries
#12884 - Upgrade jOOQ-checker's error_prone_core's transitive protobuf dependency to mitigate CVE-2021-22569
#12888 - Parser should treat AS optional in CREATE TABLE AS SELECT
#12890 - Parser fails to parse SET SCHEMA 'string-literal'
#12908 - Select::$replace loses GROUP BY clause
#12916 - Select.$where(), $having, $qualify(), $connectBy(), $connectByStartWith() don't actually return null in the absence of a predicate
#12917 - Wrong SQL generated when InlineDerivedTable is transformed using $replace()
#12922 - Bump h2 from 2.0.206 to 2.1.210
#12923 - Upgrade H2 to 2.1.210
#12925 - Work around H2 issue 3398 which hangs the process when using FINAL TABLE (MERGE ...)
#12929 - NullPointerException when mapping NULL nested ROW from scalar subquery
#12930 - Nested ROW projection emulation doesn't work in scalar subqueries
#12931 - DAOImpl#deleteById(Collection) ignores Converter
#12938 - Outdated implementation examples in manual's MULTISET section
#12939 - maven-deploy.sh should have same description in --repository flag as maven-deploy.bat
#12944 - Consider improving invalid JDBC URL error messages in class generation
#12951 - GenerationTool should handle JDBC driver returning null Connection on Driver::connect
#12954 - Typo in manual section "codegen-ddl"
#12955 - Wrong code generated for identity columns in H2 1.4
#12956 - Can no longer store/retrieve blob data exceeding 1M in H2 2.0
#12966 - NullPointerException in MetaDataFieldProvider when reading plain SQL column without a name in MySQL
#12970 - jOOQ Open Source Edition does not generate routine with long name
#12976 - Bump postgresql from 42.3.0 to 42.3.2
#12977 - Jooq holds onto connections when using r2dbc
#12979 - Upgrade the pgjdbc dependency to 42.3.2 due to CVE-2022-21724
#12982 - Bump postgresql from 42.2.8 to 42.2.25 in /jOOQ-examples/jOOQ-spark-chart-example
#12983 - Outdated JAXB dependency in manual tutorial
#12991 - Typo in manual section "codegen-tables"
#12992 - Code generation flag should turn on as a dependency
#12993 - [jOOQ/jOOQ#12992] Automatically enable table generation if indexes are enabled
#12994 - Typo in manual section "fetching"
#13008 - Compilation error in KotlinGenerator output when implicit join path cache conflicts with keyword
#13010 - [#13008] Unquote keyword when mapping one to many relation
#13013 - Interpreter does not correctly interpret CREATE INDEX .. WHERE
#13023 - Record.formatJSON(Writer) and Record.formatXML(Writer) should flush the writer
#13029 - SQLDataType.XYZ.getArrayDataType().getTypeName() and getCastTypeName() should produce standard SQL XYZ ARRAY type
#13033 - DSL.function not replacing schema for function call in generated SQL
#13034 - SchemaMapping should apply Settings.defaultCatalog even if Settings.defaultSchema doesn't apply
#13035 - SchemaMapping should cache result of Settings.defaultCatalog or Settings.defaultSchema application
#13040 - AbstractRecord.from(String[], TableField[]) no longer works as expected
#13043 - Avoid generating H2 NUMBER type alias for NUMERIC types
#13048 - Settings.parseRetainCommentsBetweenQueries doesn't work for the last comment
#13054 - java.lang.IllegalArgumentException: Cannot create a VALUES() constructor with an empty set of rows when using JSON_ARRAY(ABSENT ON NULL) in PostgreSQL
#13058 - NullPointerException when using CAST(x AS user-defined-type) with SQLDialect.JAVA
#13060 - Typo in Records.intoArray(Class) Javadoc
#13073 - Order of calling DataType.asConvertedDataType(Converter) and DataType.getArrayDataType() should not matter
#13076 - Bump postgresql from 42.2.25 to 42.3.3 in /jOOQ-examples/jOOQ-spark-chart-example
#13081 - Cannot use H2 enum values in JSON documents
#13085 - Field.sortAsc() should not hard wire NULLS FIRST behaviour
#13089 - MySQL's BIT(1) type doesn't map correctly in MULTISET subqueries
#13107 - Register array types of built-in types in internal static type registry
#13113 - Manual dialects translations for nested records emulations is wrong
#13117 - Bad deserialisation of UDT TIMESTAMP value in the presence of a Converter in PostgreSQL
#13119 - Nested record projection should generate ROW constructor keyword for rows of degree 1 in PostgreSQL's RETURNING clauses
#13120 - Cannot use RETURNING with 2-level nested ROW expressions in SQL Server
#13124 - Sequence.nextvals() doesn't work with DSLContext.selectFrom()
#13138 - Bad JSONFormat rendering of nested records
#13144 - ClobBinding shouldn't call Clob.length() in Firebird
#13147 - Context::scopeMapping should return @NotNull QueryPart
#13148 - Prevent Context::scopeMapping to apply when wrapperFor(X) is equal to X
#13156 - Work around Oracle / ojdbc bug where JSON_ARRAY() can't combine bind parameter marker with FORMAT JSON
#13163 - Compilation error when PostgreSQL stored function has an ANY[] data type reference
#13169 - Incorrect parsing of (NULL) row literal in PostgreSQL for nested records, UDTs, etc.
#13170 - NPE in INSERT .. ON DUPLICATE KEY emulation when defaulted PRIMARY KEY value isn't supplied in Oracle
#13174 - ERROR: could not determine data type of parameter when projecting PostgreSQL UDT bind value
#13184 - UNNEST table expression does not maintain derived column list
#13189 - Feedback about manual section "codegen-ddl"
#13196 - Db2 RowAsField emulation using JSON_OBJECT is lacking RETURNING BLOB when using the JSONB emulation
#13200 - MULTISET nested record as JSON_OBJECT() emulation (Db2, SQL Server) doesn't work for records with more than 10 fields
#13202 - SQL Server CREATE TABLE statement should generate VARBINARY(MAX) for BLOB
#13204 - Boolean values aren't serialised correctly in SQL Server JSON documents
#13211 - KotlinGenerator cannot read existing catalog/schema version
#13212 - [#13211] Use square brackets for KotlinGenerator
#13216 - Change Sakila database such that all ID types are INTEGER
#13217 - Work around xerial SQLite driver's Clob behaviour when data is null
#13220 - SQLite's JSON operators don't retain boolean three-valued logic
#13226 - Wrong escaping of string literals in doubly nested EXECUTE IMMEDIATE blocks for DDL emulations
#13230 - UNNEST with array argument doesn't work in Oracle when used with derived column list
#13237 - ORA-03001: unimplemented feature when nested row emulation produces double quotes in Oracle identifiers
#13240 - Code generation fails with H2 2.1.210 when using MySQL execution mode
#13245 - Bump liquibase-core from 4.4.3 to 4.8.0
#13251 - Error when nesting ROW() expressions with values instead of with fields, with degree > 22
#13252 - Cannot insert data into PostgreSQL XML column due to missing cast
#13273 - INSERT .. ON DUPLICATE KEY { IGNORE | UPDATE } emulation should consider all UNIQUE keys on SQLite
#13276 - Wrong code generated for SQLite table with unnamed primary key and unique constraints
#13290 - NullPointerException in Result.formatJSON(), formatXML(), formatCSV(), formatHTML() when a Record is null
#13302 - H2TableDefinition with H2 2.0+ produces wrong code generation output when the run mode is Oracle
#13311 - QOM API mutators on Select type don't copy OFFSET .. LIMIT and a few other clauses
#13315 - Compilation error in generated UDTRecord's POJO constructor if the UDT contains arrays of table records
#13319 - Generated records shouldn't have a @ConstructorProperties annotation on their POJO constructor
#13340 - Wrong precision documented in forceIntegerTypesOnZeroScaleDecimals manual section
#13341 - jOOQ internals shouldn't create unnamed derived tables
#13348 - Internal deprecation note on FieldsTrait::field leaks into generated code
#13349 - Select.asTable() should delay slow call to Tools::autoAlias
#13355 - Invalid code generated when pojosEqualsAndHashCode option is enabled and column name is 'other'
#13364 - Result::formatXML does not escape type names
#13379 - Generated SQL Server code uses `sp_executeSQL`, which fails for binary (case sensitive) collations
#13383 - Invalid SQL generated in Oracle 11g when query has LIMIT clause and scalar subqueries without explicit aliases
#13392 - Generated column name for binary bind values shouldn't use Java's byte[].toString()
#13395 - Bump spring-core from 5.3.16 to 5.3.18
#13396 - Update spring-core dependency to 5.3.18 to mitigate CVE-2022-22965
#13403 - MULTISET and ROW generated nested records should not have their changed flags set to true
#13415 - GroupConcat renders string_agg separator argument within wrong parentheses in EXASOL
#13422 - Dead links in manual for nested class Javadocs
#13424 - Duplicate headers in manual where there exist redirects
#13429 - DSL.noCondition() isn't applied correctly to aggregate FILTER WHERE clause
#13439 - No warning is logged when readonly columns or rowids are not used
#13447 - Upgrade to org.postgresql:postgresql:42.3.3 to mitigate CVE-2022-26520
#13454 - ARRAY_AGG cannot aggregate array columns in H2
#13465 - Expressions based on computed columns must not retain computation reference
#13468 - Work around SQLite INSERT .. SELECT .. ON CONFLICT bug
#13473 - SQLException when calling oracle.jdbc.driver.ArrayDataResultSet.getMetaData()
#13479 - Bump spring-core from 5.3.18 to 5.3.19
#13488 - org.jooq.SQL and manual should document plain SQL templating's capability of recognising :named parameters
#13489 - ArrayIndexOutOfBoundsException when rendering PostgreSQL plain SQL template containing ?@
#13499 - Improve implementation of QualifiedName.hashCode()
#13503 - Parser meta lookups don't work for INSERT .. SELECT .. RETURNING
#13509 - MariaDB, MySQL, Oracle, SQL Server may ignore MULTISET subquery ORDER BY clause
#13513 - LoaderLoadStep.execute() shouldn't have @CheckReturnValue annotation
#13536 - Wrong documentation for
#13543 - NullPointerException when rendering CTE without a top level context
#13545 - DSL.quotedName(String[]) should produce QualifiedName only if argument array length != 1
#13555 - Field::likeIgnoreCase should cast lhs operand just like Field::like and Field::similarTo
#13557 - MySQL / MariaDB generated columns with enum type are not generated as readonly
#13560 - Invalid SQL generated for Oracle when selecting multiple unaliased rows
#13563 - INSERT .. RETURNING emulations shouldn't acquire multiple connections from ConnectionProvider when using ThreadLocalTransactionProvider
#13574 - UpdatableRecord::merge might produce wrong update count if generated keys can't be fetched
#13581 - Excess parentheses generated in unary ~ (QOM.BitNot) or - (QOM.Neg) operators
#13600 - Bump spring-core from 5.3.19 to 5.3.20
#13601 - Derby boolean expressions have to be wrapped in parentheses when passed to COALESCE
#13608 - Distribute jOOQ-postgres-extensions also with the commercial distributions
#13611 - UnsupportedOperationException when selecting single nested row with JSON column
#13624 - Manual documents wrong artifactId for
#13625 - Wrong code generated for Oracle package procedure SYS.DBMS_STATS.GATHER_DATABASE_STATS
#13635 - Test container does not close in example
#13636 - Close testcontainer in example
#13643 - Wrong result column type for requested conversion when reading JSONB_ARRAY and JSONB_OBJECT nested in ROW in DB2
#13647 - DefaultRecordUnmapper should cache AbstractRow and record type
#13660 - PostgreSQL ON CONFLICT .. WHERE .. DO NOTHING generates not valid SQL
#13663 - Remove the "modern IDEs" section from the manual
#13664 - Avoid ambiguous reference when using Table as SelectField for table conflicting with column
#13667 - Link.$schema() is Nullable
#13671 - Oracle doesn't support ORDER BY in UPDATE .. SET correlated subquery
#13673 - Settings.returnAllOnUpdatableRecord doesn't work for UPDATE queries in HSQLDB
#13676 - Improve warning message in code generator
#13681 - Cannot use scalar subquery originating from MULTISET in JSON_OBJECT() VALUE clause in Db2
#13691 - Manual should link JDBC types to Javadoc
Version 3.16.0 - January 5, 2022
================================================================================
This release tackles two long standing and complex feature requests that users
have asked us to offer for a long time: a public API for manipulating jOOQ's
query object model (QOM), and spatial support.
New Query Object Model (QOM)
----------------------------
Every jOOQ query is modeled as an expression tree constructed via our intuitive
DSL. For some use-cases there exist historic model API versions (e.g.
SelectQuery), but those models aren't readable or transformable. We're now
starting to offer most of our expression tree model as a public API for users to
consume and manipulate. Every expression tree element has a corresponding type
in org.jooq.impl.QOM. Every type provides access to its components using "$"
prefixed method names, e.g.:
// Create an expression using the DSL API:
Field field = substring(BOOK.TITLE, 2, 4);
// Access the expression's internals using the model API
if (field instanceof QOM.Substring substring) {
Field string = substring.$string();
Field extends Number> startingPosition = substring.$startingPosition();
Field extends Number> length = substring.$length();
}
The new API is experimental and might change in the next minor release.
Licensed power users will get auxiliary APIs to traverse and transform the
expression tree, e.g. traversal:
// Contains 7 query parts
long count2 = BOOK.ID.eq(1).or(BOOK.ID.eq(2))
.$traverse(Traversers.collecting(Collectors.counting());
The above prints the following, having removed the redundant NOT operators:
"BOOK"."ID" = 1
This new API is very powerful for even more sophisticated dynamic SQL use-cases,
such as:
- Optimising SQL expressions as the above NOT NOT example
- Row level security
- Soft deletion
- Shared schema multi tenancy
- Audit column support
- And much more (stay tuned for future blogs and out-of-the-box transformations)
For more info, see:
- https://www.jooq.org/doc/dev/manual/sql-building/model-api/model-api-design/
- https://www.jooq.org/doc/dev/manual/sql-building/model-api/model-api-traversal/
- https://www.jooq.org/doc/dev/manual/sql-building/model-api/model-api-replacement/
Spatial support
---------------
A long awaited feature that starts shipping to our commercially licensed
customers is spatial support. Many dialects support the ISO/IEC 13249-3:2016 SQL
standard extension, and finally, so do we.
jOOQ introduces new auxiliary data types for GEOMETRY and GEOGRAPHY data to use
as standardised bind variables, containing WKB or WKT data, as well as a
variety of out of the box functions and predicates.
Future versions will add more support for other functions and dialects.
New dialect and versions
------------------------
Another new officially supported SQL dialect has been added to all jOOQ editions
including the jOOQ Open Source Edition: YugabyteDB. This was a sponsored
integration, thank you very much Yugabyte!
Other dialects have upgraded versions, meaning:
- We support this version in all editions now
- The jOOQ Open Source Edition now requires this version if applicable
The versions are:
- Firebird 4.0
- H2 2.0.202
- MariaDB 10.6
- PostgreSQL 14
- Oracle 21c
Computed and readonly columns including ROWID
---------------------------------------------
A lot of dialects support computed columns ("generated" columns), and we now
support those as well in jOOQ. For most use-cases, this does not affect jOOQ
usage, but especially when writing CRUD code, the new readonly column feature
can be very helpful to avoid having to exclude computed columns manually from
the CRUD operation.
This also includes a new, improved ROWID support, where users can choose to work
with a synthetic ROWID column instead of the primary key, when performing CRUD
operations.
All of these features are available in the commercial jOOQ editions.
Jakarta EE
----------
We've moved on from Java EE to Jakarta EE dependencies. This change is
currently backwards incompatible because:
- It greatly facilitates maintaining the related code
- It prevents tons of user problems resulting from having both dependencies
- We're not actually integrating tightly with Java EE / Jakarta EE
The following Jakarta EE modules are affected:
- JAXB, which we're using to load our configuration objects.
- Validation, whose annotations can be generated by the code generator.
- JPA, which is used by the DefaultRecordMapper and the JPADatabase
If this breaking change causes issues, please get in touch at
https://github.com/jOOQ/jOOQ/issues/9641
Various improvements
--------------------
As with every minor release, a lot of smaller improvements have been
implemented. Some highlights include:
- PostgreSQL procedures are now supported in code generation and at runtime.
- SQLite JSON support has been added, which includes the MULTISET emulation!
- A lot of MULTISET / ROW improvements have been implemented
- R2DBC 0.9 has been released, and we've upgraded our dependency
- The Java 17 distribution now requires Java 17 instead of Java 16
- Pre jOOQ 3.6 deprecations have been removed
API Diff:
---------
See what's changed in terms of an API diff here:
https://www.jooq.org/api-diff/3.15-3.16
Features and Improvements
-------------------------
#982 - Add support for spatial extensions
#4764 - Reduce log level of most DefaultRelations messages from INFO to DEBUG
#4845 - Add support for additional Firebird 3.0 features
#5306 - Add support for the standard SQL
#6492 - Add support for computed columns
#7425 - Integration test jOOQ also on the module path
#7965 - Review manual for places to explain that in jOOQ, views = tables
#8388 - Add code generation option to generate a synthetic, readonly ROWID column
#8431 - Add support for PostgreSQL 11 procedures
#8543 - Support FILTER for GROUP_CONCAT
#9310 - Add support for MariaDB 10.3 PERCENTILE_DISC, PERCENTILE_CONT, MEDIAN functions
#9367 - Create a SQL dialect version support manual page
#9542 - Remove deprecated reference to org.sonatype.oss:oss-parent
#9609 - Add SQLDialect.H2_2_0_202
#9864 - Add support for readonly columns
#9931 - Add a new DSL.systemName type
#10022 - Remove Alias.SUPPORT_DERIVED_COLUMN_NAMES_SPECIAL3 on SQLDialect.H2_2_0_202
#10039 - Add support for the Oracle 21c WINDOW clause
#10051 - UpdatableRecord.merge() should support fetching generated keys, where possible
#10149 - Modularise jOOQ-meta, jOOQ-codegen and others
#10710 - Make org.jooq.impl.CombinedCondition a binary expression
#10881 - Enum literals should be defined by generator strategies
#10935 - Add documentation for formatChart()
#11109 - Add SQLDialect.ORACLE21C
#11120 - Add DSLContext.fetchMap(ResultQuery extends Record2>) and fetchGroups(ResultQuery extends Record2>)
#11415 - Support parsing the JDBC escape syntax { call ... }
#11465 - Add JSON support for SQLite via the JSON1 extension
#11627 - Add ParseListener.parseStart() and parseEnd() events
#11670 - Add support for GROUP BY DISTINCT
#11834 - Let Table> extend GroupField
#11864 - Add more startup tips to be logged with the jOOQ logo
#12005 - Emulate DML in WITH using data change delta tables
#12021 - Address known limitations of MULTISET support
#12102 - Add support for MariaDB 10.6
#12116 - Support nesting ROW in MULTISET
#12120 - Spring Boot example should use `@SpringBootApplication(exclude = { R2dbcAutoConfiguration.class })`
#12128 - Document lack of correlated MULTISET support in Db2, H2, MariaDB, MySQL 5.7
#12146 - Split MCVE template into 3 modules for Java, Scala, and Kotlin
#12151 - Add a cache for Tools.fieldName() and fieldNameString()
#12163 - Add support for TO_CHAR in Db2
#12177 - Remove "These are currently generated" from single page manual and PDF manual
#12193 - Upgrade R2DBC dependency to 0.9.0.RELEASE
#12195 - Improve formatting of XMLELEMENT()
#12206 - Add an R2DBC example project to our examples
#12222 - Avoid reflection with ParserImpl.IGNORE
#12231 - Add support for enums in PostgreSQL R2DBC
#12235 - Avoid maven per-execution configuration in manual, if unnecessary
#12236 - Add missing DSL.dateSub() overloads
#12249 - Support parsing Oracle 21c's JSON construction convenience syntax
#12255 - Let RowIdImpl implement toString(), equals(), hashCode()
#12304 - Add Configuration::formattingProvider to offer various formatting related SPIs
#12305 - Add missing @NotNull annotations to TXTFormat, CSVFormat, JSONFormat, XMLFormat, ChartFormat
#12322 - Add support for SQLDialect.POSTGRES_14
#12344 - Add DMLQuery as a common super type for Insert, Update, Delete, Merge
#12348 - Add parser support for DML in CTEs
#12367 - Add another jOOQ testcontainers example that includes using Flyway
#12371 - Add ParseContext.characters() to access and replace the SQL char[]
#12385 - Upgrade ojdbc dependency to 21.3.0.0 and require its module name com.oracle.database.jdbc
#12394 - Parser should accept 1 and 0 as boolean literals in MySQL
#12405 - CLI programs should set java.util.loggin.SimpleFormatter.format if not already set
#12407 - Add a SQLDialect.YUGABYTEDB dialect
#12408 - Make the OSGi imports for jackson and gson modules optional
#12415 - Add native support for BIT_AND_AGG() and BIT_OR_AGG() in PostgreSQL
#12423 - Offer alternative EnumConverter constructor accepting Function as a Converter::to implementation
#12425 - Add public query object model API draft
#12427 - Extract bitwise operations into their own classes
#12431 - Extract arithmetic operations into their own classes
#12432 - Extract CompareCondition and CombinedCondition into their own classes
#12457 - Generate some Javadoc on implicit join path navigation methods
#12470 - Add better Javadoc documentation about what Class literals can be passed to DSL.val(Object, Class), etc.
#12476 - Change source, target, and release level to 17 for Java 17 distribution
#12484 - Manual should point to JDK 17 Javadoc
#12488 - Log warning in code generator when wrong runtime version is used
#12501 - Offer more Settings flag in ParserCLI and TranslationService
#12506 - SQLDialect.supportedBy() and supportedUntil() should specify that they're inclusive in their Javadoc
#12507 - Improve some internal Nullable / NotNull annotation usage
#12509 - DefaultConverterProvider should be able to convert from JSON(B) to the usual JSON types and back
#12513 - Add new Functions.nullOnAllNull(FunctionN) and nullOnAnyNull(FunctionN)
#12528 - Add ExecuteScope, a Scope that knows about an ExecuteContext
#12529 - Add nullability annotations to BindingXYZContext types
#12530 - Let Function1 <: Function and Function2 <: BiFunction
#12538 - Add Settings.parseRetainCommentsBetweenQueries
#12539 - Better seek clause examples
#12566 - JDBCUtils::safeClose methods should debug log stack traces
#12574 - Add ExecuteContext::resultLevel and ::recordLevel to indicate the Result and Record nesting level
#12582 - ControlFlowSignal should use Throwable(String, Throwable, boolean, boolean) super constructor
#12583 - Add DAO.findOptionalById()
#12585 - Use INFO level instead of WARNING level for routines with more than 254 parameters
#12592 - JPADatabase should log a WARNING message if it cannot find any entities on the classpath
#12601 - Produce compilation error if code generator version doesn't match runtime version
#12604 - Add SQLDialect.FIREBIRD_4_0
#12620 - Document that the asterisk may lead to column order mismatches
#12625 - Manual examples shouldn't re-create Gson or ObjectMapper instances all the time
#12630 - The JavaGenerator.printDeprecationIfUnknownType should hint at a UDT being in a different schema
#12644 - Upgrade Spring Boot example to Spring Boot 2.6
#12658 - Add HANA support for ON DUPLICATE KEY UPDATE et al
#12662 - Add H2 support for ON CONFLICT ON CONSTRAINT
#12663 - Add EnumType.lookupLiteral(Class, String) and generate E.lookupLiteral(String) methods
#12664 - Support distinguishing between STORED and VIRTUAL computed columns
#12667 - Add Source.of(InputStream, int) and Source.of(Reader, int) to create length limited sources
#12681 - Add JooqLogger.getLogger(Class>, int) to create a logger whose number of messages are limited to some number
#12691 - Support parsing single element IN predicate without parentheses
#12692 - Development version of the manual should include a disclaimer in the header
#12720 - Split manual section about CREATE TABLE into multiple subsections
#12725 - Manual section "daos" should link to "codegen-daos"
#12728 - Add support for Informix stored procedures
#12737 - Add DataType.isSpatial()
#12758 - Bump log4j-core from 2.16.0 to 2.17.0
#12759 - Additional SQL statements after JDBC connection
#12766 - Mention fetchSingle() in the manual section about fetching
Breaking changes
----------------
#9641 - Migrate Java EE dependencies to Jakarta EE
#9676 - Add support for H2's data change delta tables
#12109 - Remove pre 3.6 deprecated API and pre 3.6 documentation
#12127 - R2DBC execution should wrap R2dbcException in DataAccessException
#12212 - Unnecessary generic type parameter in localDateAdd and other date time arithmetic functions
#12586 - Remove DB2DataType.ROWID
#12633 - Move XSDs from jOOQ and jOOQ-meta to subpackages to avoid split xsd packages
#12757 - Experiment with sealed classes
Deprecations
----------------
#12238 - Deprecate Internal.fieldsRow(TableField)
#12420 - Deprecate PostgresDSL.oid() and replace its usage by actual OID columns
#12465 - Deprecate IGNITE dialect again
Bug Fixes
---------
#3035 - INSERT .. RETURNING does not return any value in H2, when no AUTO_INCREMENT column is involved
#3398 - Avoid generating new SQL statements for every bind variable length in Firebird 3
#4311 - Usage of jOOQ API inside of ConnectionProvider.acquire() causes issues with Oracle cross-schema OBJECT type bindings
#8205 - Use JDK 9 Matcher.replaceAll(Function) instead of Matcher.replaceAll(String) where possible
#9129 - Support parsing ALTER TABLE ... ADD ... AUTO_INCREMENT
#9136 - Wrong SQL generated in DB2's NTH_VALUE() IGNORE NULLS window function
#9162 - Parser missing type information for Enum fields
#9917 - Codegeneration fails with case sensitive data types in postgres 9.0 or less
#10423 - Bad translation of identity to CockroachDB
#10866 - Generator produces an invalid enum with an underscore "_" as the name
#11386 - Avoid streaming SQL Server FOR JSON or FOR XML in chunked results
#11401 - Improve JSON_VALUE formatting
#11659 - Upgrade Liquibase dependency of jooq-meta-extensions-liquibase to 4.x
#11703 - Parser can't parse functions receiving operator based string expressions
#12025 - Parsed DATE_ADD and DATE_SUB don't translate correctly when lacking column meta data
#12104 - R2DBC nested subscription loops forever when nesting or sequencing INSERT .. RETURNING run on r2dbc-pool
#12108 - Operator called default onErrorDropped: PostgresConnectionClosedException when chaining queries
#12117 - ORA-06550 when calling a PL/SQL procedure with a %ROWTYPE parameter that has DATE fields when dateAsTimestamp=true and javaTimeTypes=true
#12118 - Regression in SQLite code generation for unnamed composite pkeys on JDK 9+ with the jOOQ Open Source Edition
#12123 - Regression in ResultQuery.fetchMap(Field, Field) with null values
#12125 - Wrong Support annotation: HSQLDB doesn't support MULTISET or MULTISET_AGG
#12130 - Wrong deserialisation of temporal data types in MULTISET XML emulation
#12131 - DefaultConverterProvider should be able to convert both ISO timestamp formats to Timestamp and LocalDateTime
#12135 - MULTISET emulation doesn't correctly deserialise single column record containing only a NULL value in SQL Server
#12136 - IndexOutOfBoundsException when deserialising MULTISET as XML emulation with NULLs
#12139 - MULTISET as JSON emulation using JSON_ARRAY must use NULL ON NULL clause
#12141 - Data conversion error converting "TIMESTAMP to JSON" in H2
#12144 - Regression when binding JSONB value containing a JSONB string in PostgreSQL
#12148 - Setter return type must be Unit & '@set:' annotations could be applied only to mutable properties
#12149 - DSL.using(String, String, String) based R2DBC Connection does not use provided username and password
#12150 - [jOOQ/jOOQ#12149] Use username and password properties for r2dbc connection
#12155 - Nested multiset record mapping fails at the 3rd level of nesting
#12158 - MULTISET/JSON emulation can't read TIME type in Db2
#12160 - Error when embedding a timestamp in Db2 XMLELEMENT
#12168 - Deeply nested MULTISET produce quoted JSON in MariaDB
#12174 - Unnecessary finalizer registration in DefaultConnectionProvider
#12181 - SQL Server doesn't correctly serialize TIME bind values in FOR XML and FOR JSON usage
#12183 - An R2dbcException wrapping DataAccessException should properly produce sqlState() and other properties
#12187 - The XML MULTISET_AGG emulation doesn't work with unnamed bind values in Db2
#12189 - Db2 cannot handle scalar subqueries in JSON_OBJECT in the presence of a MULTISET ad-hoc converter
#12192 - INSERT .. RETURNING doesn't work in H2 when a composite key does not have the identity as its first column
#12194 - MySQL DELETE .. USING with JOIN produces duplicate table declarations in USING clause
#12197 - The DataKey.DATA_PREPEND_SQL and DATA_APPEND_SQL feature must work on Query only, not other QueryParts
#12200 - SelectOnStep::onKey returns wrong type, preventing combinations of join predicates
#12201 - Error when embedding a timestamp in Db2 XMLATTRIBUTES
#12208 - Deeply nested MULTISET mappings with ad-hoc conversion doesn't work when using reflection
#12210 - Aliasing implicit join paths produces invalid queries
#12216 - Remove references to javax.annotation.Generated from jooq-codegen Javadoc
#12225 - DefaultConverterProvider truncates timestamps to milliseconds precision when converting from Timestamp to LocalDateTime
#12237 - Embeddables cannot be placed in MULTISET
#12240 - NullPointerException in MetaImpl.MetaTable.getReferences() when there are catalog conflicts in SQL Server
#12244 - Inconsistent formatting of table list when using generated or non-generated aliased tables
#12247 - Replace remaining reflective call to OracleConnection.createARRAY from DefaultBinding
#12253 - Long lists are no longer wrapped when rendering formatted SQL
#12260 - NullPointerException when reading empty results for MULTISET_AGG / JSON emulation
#12262 - Delay initialisation of Jackson, Gson, JAXB classes in Convert
#12265 - Custom data type binding example in manual works only on JDBC, not R2DBC
#12267 - jOOQ 3.15.0 XSD is not published?
#12277 - Wrong method name used in manual section schema-diff
#12278 - Empty subsection in manual section codegen-config-generator
#12281 - IllegalArgumentException: Minimum abbreviation width is 4 when TXTFormat::minColWidth is less than 4
#12286 - java.lang.NoClassDefFoundError: javax/xml/bind/annotation/XmlSchema when running examples from manual tutorial
#12289 - In manual section jooq-in-7-steps-step3, fix multi line shell syntax
#12291 - Reference to database and/or server name in 'master.sys.schemas' is not supported in this version of SQL Server.
#12306 - Wrong table list to ANSI join transformation when tables are qualified and aliased
#12307 - Wrong result for Table or Field.getQualifiedName() on aliased table(Name) or field(Name)
#12308 - MockDataProvider cannot handle MULTISET fields
#12315 - Wrong procedure declaration generated in MySQL when using IN parameters with VARCHAR(length) types
#12316 - ParseListener example doesn't compile, should use onParseCondition(), not onParseField()
#12324 - Wrong (+) to LEFT JOIN transformation in join tree A⟕B, A⟕C, A⋈D
#12327 - ImmutablePOJOMapper cannot map more than one nested POJO on the same level
#12328 - Empty select() should not project asterisk if unknown table is used with leftSemiJoin() or leftAntiJoin()
#12332 - Result.formatChart() produces bad default formatting for Display.HUNDRED_PERCENT_STACKED
#12333 - IndexOutOfBoundsException when calling Result.formatChart() on an empty result
#12340 - Improve to display correct number of dialects for operators
#12345 - Inline floating point formatting shouldn't depend on default Locale
#12357 - Wrong SQL example in manual section multiset-value-constructor
#12363 - Nested Block generates top-level anonymous block behaviour when top level Statement is not a Block
#12364 - Spelling mistake in manual section "jooq-with-flyway"
#12373 - ClassCastException when using returning() with R2DBC
#12375 - NullPointerException in OracleDatabase.getArrays0()
#12379 - Wrong type documented in INSERT .. RETURNING section of the manual
#12381 - DSLContext.explain(Query) doesn't work with bind values in Oracle
#12386 - Positional window functions without ORDER BY should generate ORDER BY 1 in Oracle
#12399 - FOR JSON emulation must use RETURNING CLOB in Oracle
#12413 - DataTypeException in multiset with a mapped nested row
#12417 - BIT_AND_AGG(), BIT_OR_AGG() emulations shouldn't use bind values
#12434 - CVE-2021-26291 via maven-core-3.6.3 dependency
#12437 - Avoid generating overloaded table valued functions with compilation errors, until they are supported
#12440 - Compilation error in KotlinGenerator generated code when @set:JvmName is applied to overriding property
#12441 - Fix generating multi-key DAOs with Java records
#12442 - Compilation errors in generated code when using with
#12446 - Unnecessary cast in Db2 when comparing value with concatenation
#12459 - KotlinGenerator setter return type must be Unit also for records
#12463 - H2 enum values which contain brackets are not generated as Java literals
#12468 - MockFileDatabase example doesn't compile
#12469 - InlineDerivedTable shouldn't inline when used in outer joins
#12480 - DSL.arrayGet() does not generate required parentheses
#12491 - api-diff generates wrong nested class Javadoc links
#12492 - Clarify whether .offset(..) starts from 0 or 1
#12495 - Ignored COMMENT ON CONSTRAINT syntax should support qualified object identifiers
#12498 - Meta does not produce correct DataType::nullable information when data type isn't supported
#12499 - Wrong documentation in section "codegen-database-regex-flags"
#12500 - Unable to fetch Instant field within a multiset
#12502 - NPE in Query.equals() when Query isn't attached
#12508 - Cannot map JSON(B) in MULTISET when mapping with Jackson from DefaultConverterProvider
#12516 - Field with Converter inside multiset causes JSON parsing error on Oracle
#12520 - Parser should support PERCENTILE_CONT / PERCENTILE_DISC with expressions as percentiles
#12527 - DefaultExecuteContext.LOCAL_SCOPE is reset to null when nesting lazy executions
#12537 - ParserCLI interactive mode ignores setting booleans to false
#12543 - ParserCLI interactive mode can't handle leading /* comment block
#12544 - Field.div(int) regression for Instant fields that have a converter
#12545 - Lenient support for H2's time zone format when using the Instant type
#12549 - Wrong JSON_MERGE_PRESERVE function generated when embedding JSON in MULTISET in MariaDB and MySQL
#12557 - Add support for unwrapping Optional types in DefaultConverterProvider
#12561 - ROWNUM transformation doesn't work when projecting an expression containing ROWNUM
#12564 - Exception in LoggerListener when projecting top level row(...).mapping()
#12568 - Connection leak when ExecuteListener::fetchEnd throws an exception
#12589 - CockroachDB IDENTITY column recognition is broken
#12596 - ParamType.INLINED produces wrong behaviour for Settings.cacheParsingConnection
#12599 - Incorrect MERGE statement syntax generated in FIREBIRD when aliasing USING derived table
#12602 - Parser cannot parse INSERT .. SELECT without column list
#12611 - SQLDataType.null generated when using XMLDatabase with lower case array type
#12612 - Generated column in table valued function of type TIMESTAMP without precision is generated using precision zero
#12638 - OracleDatabase::sequences produces query that doesn't work on older ojdbc driver versions
#12639 - typo in jOOQ-academy setup script
#12640 - OracleDatabase doesn't produce correct CYCLE sequence flag information in code generation
#12645 - Parser should support PostgreSQL date part syntaxes with explicit type casts
#12649 - Parser parses and ignores NOT keyword after column expression
#12655 - Fix Firebird Support annotations on INSERT .. ON DUPLICATE KEY UPDATE as well as UpdatableRecord.merge
#12659 - Wrong SQL generated for PostgreSQL functions returning single UDT OUT parameters
#12666 - Restore streaming bind value method behaviour on ParsingStatement
#12669 - Blob.length() and Clob.length() calls shouldn't be silently downcast to int
#12674 - HanaTableDefinition reports all computed columns as identities
#12675 - MariaDBDatabase no longer generates check constraints
#12678 - Potential resource leak in SettingsTools static initialiser
#12683 - Regression in code generation catalog mapping
#12697 - Mapped JSON in multiset causes multiple ad-hoc conversions
#12700 - Single element IN predicate without parentheses uses wrong operator precedence
#12704 - DefaultRecordUnmapper.IterableUnmapper uses name based field access instead of index based ones, leading to ambiguities
#12706 - Cannot nest MULTISET in top level ROW in PostgreSQL
#12712 - Parser mis-interprets KEY columns as MySQL KEY (INDEX) specification if unquoted and of type VARCHAR(n)
#12713 - Debug log output causes exceptions when data type converter is re-applied incompatibly
#12718 - Some manual "previous" and "next" links use wrong URL
#12731 - DB2Database should order routine overloads by signature, not specificname
#12733 - Update log4j to 2.15.0 because of CVE-2021-44228
#12741 - Loader.onDuplicateKeyIgnore doesn't work on tables that don't have a PRIMARY KEY
#12742 - ListAgg not working with filter clause.
#12751 - Bump h2 from 1.4.199 to 2.0.202 in /jOOQ-examples/jOOQ-javafx-example
#12752 - DDLDatabase defaultNameCase property shouldn't affect built in functions in view definitions
#12753 - SQLDialect.JAVA produces wrong output for quotedName()
#12755 - DSL.unquotedName() has wrong Javadoc
#12776 - Compilation errors in generated code when enabling and
#12780 - Support generating the PostGIS GEOMETRY type as SQLDataType.GEOMETRY
Version 3.15.0 - July 6, 2021
================================================================================
R2DBC
-----
What a lot of users have been waiting for: jOOQ 3.15 is reactive, thanks to the
new native R2DBC integration. Recent versions already implemented the reactive
streams Publisher SPI, but now we're not cheating anymore. We're not longer
blocking. Just wrap your R2DBC ConnectionFactory configured jOOQ query in a Flux
(or any reactive streams API of your choice), and see what happens.
Flux.from(ctx.select(BOOK.TITLE).from(BOOK));
Both blocking (via JDBC) and non-blocking (via R2DBC) can work side-by-side,
allowing users to quickly a query between the two execution models without any
changes to the query building logic.
Projecting ROW types, ARRAY of ROW Types, and MULTISETS
-------------------------------------------------------
After having implemented standard SQL/XML and SQL/JSON support in jOOQ 3.14,
another major milestone in taking SQL to the next level is now available as an
experimental feature: Nesting collections using the standard SQL MULTISET
operator.
The operator is currently emulated using SQL/XML or SQL/JSON. The resulting
documents are parsed again when fetching them from JDBC. Future versions will
also provide native support (Informix, Oracle), and emulations using ARRAY
(various dialects, including PostgreSQL).
Imagine this query against the Sakila database (https://www.jooq.org/sakila):
Two collections were nested in a single query without producing any unwanted
cartesian products and duplication of data. And stay tuned, we've added more
goodies! See this article on how to map the above structural type to your
nominal types (e.g. Java 16 records) in a type safe way, without reflection!
More info here:
- https://www.jooq.org/doc/3.15/manual/sql-building/column-expressions/multiset-value-constructor/
- https://www.jooq.org/doc/3.15/manual/sql-building/column-expressions/aggregate-functions/multiset-agg-function/
New Dialects
------------
We've added support for 5 (!) new SQLDialect's. That's unprecedented for any
previous minor release. The new dialects are:
- BIGQUERY
- EXASOL
- IGNITE
- JAVA
- SNOWFLAKE
Yes, there's an experimental "JAVA" dialect. It's mostly useful if you want to
translate your native SQL queries to jOOQ using https://www.jooq.org/translate,
and it cannot be executed. In the near future, we might add SCALA and KOTLIN as
well, depending on demand.
BigQuery and Snowflake were long overdue by popular vote. The expedited EXASOL
support has been sponsored by a customer, which is a great reminder that this is
always an option. You need something more quickly? We can make it happen, even
if the feature isn't very popular on the roadmap.
Many other dialects have been brought up to date, including REDSHIFT, HANA,
VERTICA, and two have been deprecated: INGRES and ORACLE10G, as these grow less
and less popular.
Drop Java 6/7 support for Enterprise Edition, require Java 11 in OSS Edition
----------------------------------------------------------------------------
We're cleaning up our support for old dependencies and features. Starting with
jOOQ 3.12, we offered Java 6 and 7 support only to jOOQ Enterprise Edition
customers. With jOOQ 3.15, this support has now been removed, and Java 8 is the
new baseline for commercial editions, Java 11 for the jOOQ Open Source Edition,
meaning the OSS Edition is now finally modular, and we get access to little
things like the Flow API (see R2DBC) and @Deprecate(forRemoval, since).
Upgrading to Java 8 allows for exciting new improvements to our internals, as we
can finally use default methods, lambdas, generalised target type inference,
effectively final, diamond operators, try-with-resources, string switches, and
what not. Improving our code base leads to dogfooding, and that again leads to
new features for you. For example, we've put a lot of emphasis on
ResultQuery.collect(), refactoring internals:
https://blog.jooq.org/use-resultquery-collect-to-implement-powerful-mappings/
There are new auxiliary types, like org.jooq.Rows and org.jooq.Records for more
functional transformation convenience. More functions mean less loops, and also
less ArrayList allocations.
At the same time, we've started building a Java 17 ready distribution for
the commercial editions, which unlocks better record type support.
Refactoring of ResultQuery to work with DML
-------------------------------------------
With all the above goodies related to Java 8, and a more functional usage of
jOOQ, we've also finally refactored our DML statement type hierarchy (INSERT,
UPDATE, DELETE), to let their respective RETURNING clauses return an actual
ResultQuery. That means you can now stream(), collect(), fetchMap() and
subscribe() (via R2DBC) to your DML statements, and even put them in the WITH
clause (in PostgreSQL).
Massive improvements to the parser / translator use case
--------------------------------------------------------
jOOQ's secondary value proposition is to use its parser and translator, instead
of the DSL API, which is also available for free on our website:
https://www.jooq.org/translate
With increasing demand for this product, we've greatly improved the experience:
- The ParsingConnection no longer experimental
- Batch is now possible
- We've added a cache for input/output SQL string pairs to heavily speed up the integration
- We're now delaying bind variable type inference to use actual PreparedStatement information. This produces more accurate results, especially when data types are not known to the parser.
- A new ParseListener SPI allows for hooking into the parser and extend it with custom syntax support for column, table, and predicate expressions.
CREATE PROCEDURE, FUNCTION, TRIGGER and more procedural instructions
--------------------------------------------------------------------
Over the recent releases, we've started working on procedural language
extensions for the commercial distributions. In addition to creating anonymous
blocks, we now also support all lifecycle management DDL for procedures,
functions, and triggers, which can contain procedural language logic.
This is great news if you're supporting multiple RDBMS and want to move some
more data processing logic to the server side in a vendor agnostic way.
Explicit JDBC driver dependencies to avoid reflection
-----------------------------------------------------
To get AOP ready, we're slowly removing internal reflection usage, meaning we're
experimenting with an explicit JDBC driver build-time dependency. This currently
affects:
- Oracle
- PostgreSQL
- SQL Server
Only drivers available from Maven Central have been added as dependency so far.
API Diff:
---------
See what's changed in terms of an API diff here:
https://www.jooq.org/api-diff/3.14-3.15
Features and Improvements
-------------------------
#1729 - Add DSL.aggregate() and DSL.aggregateDistinct() as plain SQL AggregateFunctions
#1985 - Add support for the EXASOL database
#2620 - Add support for Google BigQuery
#3884 - Add support for the MULTISET operator
#4474 - Allow to form CTE from plain SQL or from ResultQuery
#4876 - Add Firebird 3.0 support for IDENTITY columns
#5179 - Add support for returning unique constraints from Meta Table.getKeys()
#5310 - DataType.toString() should generate DDL type declaration fragment
#5507 - Add a new jooq-postgres-extensions module for PostgreSQL specific extension
#5757 - Support batch in DSLContext.parsingConnection()
#5810 - Emulate Teradata's QUALIFY clause for window function filtering
#6080 - Add support for multiple ROW nesting
#6277 - Add SQLDialect.JAVA to generate Java code from a SQL statement
#6347 - Add TableLike.get(X) kotlin operators as aliases for Table.field(X)
#6562 - Add a recursive CTE example to the manual
#6604 - Add multi Row[N] or Record[N] VALUES support
#6956 - Add support for { CREATE | DROP } TRIGGER commands
#7100 - Add Field.convert(Binding), convert(Converter), convert(Class, Function, Function)
#7290 - Add DSL.chr(int)
#7421 - Stop rendering "FROM dual" in MySQL 8+ and MariaDB 10.4+
#7520 - Add code generator support for foreign keys in Teradata
#7536 - Implicit JOIN improvements
#7789 - Support Java 8 only in Professional and Enterprise Edition
#7900 - Add support for SQL Server style DATEDIFF(datepart, date, date)
#8166 - Add support for SELECT .. INTO for use inside statement blocks
#8230 - Add support for RAISE or SIGNAL in the procedural API
#8263 - Add syntax highlighting to /translate
#8284 - Emulate label-less iterate and leave in DB2, HSQLDB, MariaDB, MySQL
#8334 - ParsingConnection should cache frequent input / output SQL string pairs
#8469 - org.jooq.Meta should try parsing default expressions
#8495 - Avoid copying around lists and arrays in jOOQ's internals
#8500 - Review callers of Tools#field(T) in AbstractField
#8521 - Transform MySQL IN (SELECT .. LIMIT) to derived table
#8714 - Support SQL Server function SQUARE()
#8715 - Add support for the LOG10 function
#8775 - Record.get(n) etc, Javadoc could state if n starts from 0 or 1
#8821 - Add Settings.parseNamedParamPrefix to support dialect specific named parameter placeholders
#8888 - Improve HSQLDB Dual table implementation
#8973 - Create a troubleshooting page in the manual
#9038 - Add support for the PostgreSQL SPLIT_PART function
#9087 - Document CallbackExecuteListener
#9190 - Add support for CREATE FUNCTION and CREATE PROCEDURE
#9191 - Add support for DROP FUNCTION and DROP PROCEDURE
#9376 - Document in the manual
#9472 - Add support for UUID generator functions, such as NEWID() or GEN_RANDOM_UUID()
#9627 - Add Settings.metaIncludeSystemIndexes
#9650 - Add support for the Snowflake database
#9728 - Add configuration to allow for generating custom Javadoc on generated code
#9753 - Change DEFAULT rendering of CURRENT_DATE, CURRENT_TIME, and CURRENT_TIMESTAMP
#9767 - Built in SQL transformations
#9804 - Make TableOptions available through code generation to remaining dialects
#9854 - Add support for DB2 DIGITS() function
#9945 - Implement generated TIMESTAMP precision in code generation
#9953 - Add support for nested declarations in Firebird procedural logic
#10030 - Add a type annotation to all jOOQ API that accepts explicit string types
#10036 - Add support for BIT_AND_AGG(), BIT_OR_AGG(), BIT_XOR_AGG()
#10048 - Add logging to BatchCRUD when the number of generated SQL queries is too high
#10080 - Add a manual section about LATERAL and APPLY
#10118 - Add support for CockroachDB CREATE OR REPLACE VIEW
#10150 - Support JDK 14, 15, 16
#10175 - Add support for H2 and PostgreSQL array functions
#10181 - Improve parser performance
#10229 - Convert should be able to convert types into any type with a single argument constructor
#10243 - Add ParseListener SPI to parse custom syntax
#10287 - Add to allow for generating Java POJOs as JDK records instead
#10349 - Add more Settings to enable / disable DefaultRecordMapper mapping algorithms
#10437 - Get HANA dialect support up to date
#10505 - Split up manual's JOIN section into different subsections
#10514 - Improve Settings.parseWithMetaLookups
#10522 - Emulate UPDATE .. SET row = (SELECT ...) using UPDATE .. FROM for uncorrelated subqueries
#10528 - Improve procedural language abstraction API
#10546 - Add { Schema, Meta } . { getUniqueKeys(), getForeignKeys(), getIndexes() }
#10551 - Add support for Apache Ignite
#10572 - Various parser bugs / missing features
#10626 - Add support for CockroachDB CREATE SCHEMA et. al
#10645 - Add SQLDialect.POSTGRES_13
#10690 - Use some newer JDK API when creating a distribution for JDK 17
#10724 - Get Redshift dialect support up to date
#10745 - SQLDialect Javadoc should explain the distinction between commercial and OSS dialects
#10775 - Add Rows.toRowList() and Rows.toRowArray() methods to create Row[N] arrays and lists
#10801 - Add JavaGenerator.printDaoConstructorAnnotations() to allow for custom annotations in generated DAO constructors
#10807 - Meta.migrateTo(Meta) should not produce any diff when timestamp default precision is specified
#10827 - Add a DSL.currentCatalog() function
#10829 - Exclude synthetic fields and keys from diff
#10844 - Implement MetaImpl.getSequences()
#10851 - Add to allow for generating explicit / implicit public visibility, as well as internal in KotlinGenerator
#10873 - Add alternative DSL.key(...).value(...) syntax to produce JSONEntry
#10883 - Add Table.getUniqueKeys()
#10893 - Add Javadoc link from SQLDialect to the new version support matrix page
#10898 - Add Settings.metaIncludeSystemSequences
#10899 - Add to code generator configuration
#10909 - Enhance MCVE template to also include KotlinGenerator and ScalaGenerator out-of-the-box
#10913 - Add Database.getPrimaryKeys() and overloads to jOOQ-meta
#10927 - Add code generator support for SQLite CHECK constraints
#10932 - Support MySQL 8.0.16 CHECK constraints
#10936 - Add DataType.null_() and notNull() as synonyms for nullable(boolean)
#10952 - Add a DDL textarea to /translate
#10953 - Add additional JSONFormat options to optimise formatting of JSON in the presence of SQL/JSON result set content
#10962 - Remove Disqus from manual
#10963 - Parse DEFAULT nextval('_seq'::regclass) as Serial data type
#10990 - Add support for MERGE in Informix
#10998 - Add to let ScalaGenerator generate Java enums
#11002 - Remove the outdated manual section about dependencies
#11009 - Add support for the MySQL FIELD() function
#11023 - Throw more explicit DataTypeException when Convert fails to convert between JSON/JSONB/XML and a user-defined type
#11031 - Extract common API from Cursor | Record | RecordType | Result | Row | TableLike | UDT to new Fields type
#11061 - Parser should look up data types for bind variables from context
#11063 - Add TableOptions.function(String)
#11070 - Propagate type nullability through API
#11074 - Parser should be able to replace expressions for bind variables
#11076 - Add support for SQLDialect.MYSQL_5_6
#11082 - DSL.currentTimestamp(int) is missing
#11089 - Add parser support for COERCE(x AS )
#11091 - Avoid calling DSL.nullSafe() and similar all over the DSL API, move the calls to QueryPart constructors
#11093 - Use instance methods in parser implementation
#11097 - Add single argument DSL.function() overload
#11107 - Parser should parse 3-argument Oracle INSTR function
#11123 - Add Settings.mapConstructorProperties to allow for opting out of reading the ConstructorProperties annotation in DefaultRecordMapper
#11125 - Let AbstractQueryPart::configuration return Tools.CTX::configuration
#11131 - Make functional interfaces F0, F1, F2 public, internal, deprecated
#11136 - Add Name.qualifierQualified() to check if a Name's qualifier (if any) is qualified as well
#11154 - Add Javadoc to Map producing API (fetchMap(), fetchGroups()) about map iteration order guarantees
#11155 - Add documentation for using LiquibaseDatabase with Liquibase's YAML or JSON formats
#11157 - Add support for COVAR_SAMP and COVAR_POP aggregate and window functions
#11161 - Add formal support for SQL Server PIVOT clause
#11172 - Add support for SQLite's fts3 and fts4 virtual tables
#11176 - Add to exclude SQLite virtual table implementation tables from code generation
#11177 - Add further vendor-specific implementations
#11180 - Clarify unused logger warning message about what is obsolete
#11182 - Generate DAO.fetchByXYZ() methods for embeddable types
#11183 - Generate a record constructor taking a generated POJO
#11187 - Add DAO.fetch(Field, Collection extends Z>) overload
#11189 - Improve generated Javadoc formatting
#11190 - UPDATE .. RETURNING cannot be used Reactively
#11192 - Add Javadoc remark to code generation flags available to commercial editions only
#11194 - Add code generation configuration for Javadoc line wrapping
#11202 - Add documentation for the QUALIFY clause
#11231 - Support parsing Access ASC() or Firebird ASCII_VAL() functions
#11237 - Add SafeVarargs annotation to DSL.greatest() and DSL.least()
#11243 - Emulate FOR UPDATE .. WAIT n using SET LOCAL LOCK_TIMEOUT in PostgreSQL dialects
#11246 - Add support for TRIGGER pseudo columns DELETING, INSERTING, UPDATING
#11250 - Add a language context to the ParserContext and RenderContext
#11252 - Add support for SET LOCAL statements
#11253 - Add some convenience API for locally overriding Context.paramType(), Context.qualify(), and other flags
#11254 - Add lambda constructor in CustomField, CustomCondition, CustomQueryPart
#11269 - Add CreateTableConstraintStep.primaryKey(), unique(), check() convenience methods
#11279 - Support ALTER TABLE .. RENAME INDEX .. TO .. in SQL Server
#11318 - Add native support for the standard JSON function RETURNING clause
#11323 - Add HSQLDB procedural language support
#11333 - Add parser support for hash style comments (#) in MariaDB, MySQL
#11336 - Emulate CREATE OR REPLACE in MySQL using compound statements
#11338 - Add convenience for common bracing / formatting / indenting SQL rendering
#11344 - Add Context.declareParameters()
#11356 - Add support for CALL in procedural languages
#11358 - Add some CSS syntax highlighting to all content in the manual
#11359 - Add support for INFORMIX procedural language
#11360 - Add CustomStatement
#11367 - Refactor internal ScopeMarkers functionality
#11369 - Emulate using expressions in Db2 DECLARE .. DEFAULT statements
#11373 - Add ParamOrVariable, a common super type of Param and Variable
#11374 - Wrong algorithm to aggregate local variable declarations at the beginning of a block
#11379 - Update RecordListener documentation to explain this is about UpdatableRecords only, not bulk DML
#11382 - Add parser support for
#11383 - Add Configuration.commercial()
#11389 - Add parser support for PL/SQL style variable declarations in function / procedure headers
#11390 - Support parsing RETURN statement
#11393 - Add CockroachDB ENUM type support
#11394 - Support parsing Teradata's zeroifnull()
#11402 - Support parsing Teradata's UPDATE .. FROM .. SET syntax
#11403 - Support parsing Teradata's undocumented SELECT .. GROUP BY .. WHERE clause ordering
#11405 - Emulate procedural SELECT .. INTO variables in T-SQL
#11406 - Field.as(unquotedName("@i")) should produce T-SQL aliasing syntax
#11408 - Procedural DECLARE should support declaring multiple variables, for convenience
#11410 - Support HSQLDB's procedural destructuring assignment
#11420 - Support Parsing the MySQL version of the VALUES constructor
#11421 - Parser should throw exception if not all rows have the same degree in a VALUES constructor
#11422 - Add parser support for JSON_ARRAYAGG() and JSON_OBJECTAGG() as window functions
#11429 - Add missing parser support for EXECUTE IMMEDIATE
#11430 - Add parser support for ALTER TABLE .. DROP .. DROP syntax
#11432 - Support parsing Db2 style LISTAGG() without WITHIN GROUP clause
#11433 - Add parser support for ALTER TABLE .. ADD .. ADD syntax
#11436 - Support parsing UPDATE .. SET (row) = (row | subquery)
#11449 - Support parsing SQLite MIN() and MAX() functions
#11450 - Support parsing SQLite's IS [ NOT ] predicate
#11452 - Add parser support for MySQL's DATE_ADD and DATE_SUB functions
#11458 - Add support for the ANY_VALUE() aggregate function
#11461 - MetaTable does not contain table COMMENT (REMARKS)
#11470 - Add support for the CORR aggregate functions
#11472 - Document immutability of CSVFormat and related types
#11481 - Stop using the deprecated JSON_MERGE function in MariaDB 10.4+ and MySQL 8.0.19+
#11491 - Add a Settings.forceIntegerTypesOnZeroScaleDecimals
#11492 - Add jbang example to the manual
#11494 - Add parser support for OCTET_LENGTH alternative names
#11499 - [jOOQ/jOOQ#11492] Add jbang catalog
#11502 - Unknown table identifier when trying to look up CustomTable or TableImpl whose Schema doesn't reference its tables
#11504 - Default[UnsignedType]Bindings should delegate to integer bindings, rather than implement their own
#11507 - Add Log.isWarnEnabled()
#11508 - Emulate procedural RETURN (SELECT ..) statement where not supported
#11512 - ParsingConnection should infer bind variable type from PreparedStatement calls
#11520 - Add CallbackXYZListener implementations, and static convenience API on XYZListener
#11525 - Upgrade scala version to 2.13.5
#11530 - Add Configuration.setAppending() and Configuration.deriveAppending() methods to create derived configurations by appending listeners
#11531 - Add jsonEntry(X, Select>) overloads
#11536 - Document pom.xml plugin inheritance mechanism
#11543 - Emulate FOR UPDATE .. WAIT n using SET SESSION innodb_lock_wait_timeout in MySQL dialects
#11547 - Emulate statistical aggregate functions
#11549 - Add startup tips to be logged with the jOOQ logo
#11559 - Add parser support for ADD_YEARS, ADD_MONTHS, ADD_DAYS, ADD_HOURS, ADD_MINUTES, ADD_SECONDS
#11567 - Add Database.getSources(): Map as an alternative way to produce source code for generated objects
#11572 - Add versioned dialects for COCKROACHDB 20, 21
#11578 - Add DSL.inlined(Field): Field
#11585 - Remove unnecessary restriction from sequences and domains "Must provide a qualified name of length 1 or 2"
#11587 - Fix ordering of TOP_LEVEL_CTE
#11601 - Add a manual section for trueCondition(), falseCondition(), and noCondition()
#11602 - Support parsing WITH in derived tables or scalar subqueries
#11603 - Add parser support for WITH nested inside WITH
#11606 - DefaultRenderContext(RenderContext) constructor should only copy flags
#11616 - Missing DB2 and Derby @Support on DROP SCHEMA .. RESTRICT
#11623 - Refactor a few internal checked exception throwing functional interfaces
#11626 - Add DefaultDataType.getDataType(SQLDialect, int) to lookup JDBC types
#11633 - ParsingConnection should batch translated statements without having to re-translate the statement several times
#11640 - Use ojdbc8 API internally
#11641 - Emulate SPLIT_PART
#11642 - Emulate OVERLAY in H2 using INSERT
#11645 - Add procedure support in the VerticaDatabase
#11647 - Add MySQL SUBSTRING_INDEX() support
#11648 - Add Db2, Derby, H2 support for POSITION(in, search, startIndex) via LOCATE
#11649 - Add parser support for Db2's LOCATE_IN_STRING function
#11650 - Get SQLDialect.VERTICA up to date
#11654 - Add code generation support for CHECK constraints in Vertica
#11655 - Emulate statistical window functions in Vertica
#11656 - Add support for a TO_HEX(number) function
#11660 - Emulate CONNECT BY LEVEL < x and CONNECT BY ROWNUM < x
#11666 - Expand unqualified asterisk when combined with other projection expressions and when not supported
#11672 - Function and QueryPartCollectionView formatting improvements
#11674 - Add native support for NVL2 where supported
#11684 - Add a CacheProvider SPI to allow for overriding the default ConcurrentHashMap
#11688 - Remove experimental remarks from all parser related API
#11694 - Support parsing TO_DATE(string) and TO_TIMESTAMP(string)
#11699 - Support parsing Oracle comparison operators with whitespace in between
#11700 - Add R2DBC support
#11707 - SQUARE() should be emulated using POWER() if the argument is not a SimpleQueryPart
#11711 - Use floating point literals for inline DOUBLE, FLOAT, and REAL literals
#11712 - Support parsing the ** exponentiation operator
#11718 - Annotate DSL API with @CheckReturnValue to help detect when calling execute() etc is forgotten
#11719 - Add support for TO_DATE() in SQL Server
#11729 - Create a Java 17 distribution
#11737 - Add dialect version support for H2
#11738 - Add optional, provided dependency on mssql-jdbc, ojdbc, pgjdbc to avoid reflection
#11743 - Support parsing Teradata cast syntax
#11744 - Support the Teradata DATE function
#11755 - Extract AttachableQueryPart from Query
#11757 - Add Settings.renderCoalesceToEmptyStringInConcat
#11763 - Upgrade shaded jOOR dependency to 0.9.14
#11772 - Convert should support conversions between ByteBuffer and byte[]
#11774 - Add a to
#11778 - DefaultRecordMapper should reflect on Class.getRecordComponents()
#11779 - Upgrade XJC to com.sun.xml.bind:jaxb-xjc:2.3.4
#11780 - Include identity-generated system sequences in PostgreSQL generated code
#11784 - Add code generation support for Firebird 3.0 stored functions
#11787 - Add an flag to turn on/off the generation of system UDTs
#11788 - Add QualifiedRecord and RecordQualifier to unify the Table|UDT and TableRecord|UDTRecord type hierarchy
#11794 - Improve MappingException message when no RecordMapper implementation could be found
#11799 - Refactor some internals to re-use a new functional mapping method
#11800 - Fields.field() methods should add better documentation about what it means when null is returned
#11801 - Move some Tools content such as Tools.Cache to the top level
#11803 - Support = ANY and != ALL quantified comparison predicates of degree > 1 for MySQL
#11804 - Add Records class with common record mapping utilities
#11808 - Make sure the SQL in MetaSQL is dialect version specific
#11809 - Add SQLDialect.isVersioned()
#11810 - RecordMapper should extend Function
#11812 - Let Row[N] extend SelectField>
#11813 - Add Row[N].mapping(Class, Function[N]) to create a SelectField reference
#11815 - Change DSLContext.fetchValue(Field) to DSLContext.fetchValue(SelectField)
#11816 - Add missing ConstraintTypeStep.primaryKey(Collection extends Field>>) and related overloads
#11817 - Add Converter.from(Class, Class, Function) and Converter.to(Class, Class, Function) to create one-way converters
#11821 - Support parsing Teradata INSERT without VALUES
#11822 - Translator should offer specifying a default schema / search path
#11826 - Remove serialVersionUID from jOOQ's internals
#11829 - Add DataType.row() to track nested ROW types and allow access to their Field>[]
#11831 - Support parsing array(select)
#11838 - Add Settings.namePathSeparator
#11843 - Add parser / render support for COUNTIF()
#11844 - Support parsing Teradata eq, ne, gt, ge, lt, le operators
#11845 - Transform Teradata style implicit join syntax in the parser
#11850 - Get SQLDialect.TERADATA up to date
#11851 - Add Settings.renderImplicitWindowRange handling different default window RANGE clause defaults
#11854 - Generate identity column information in Teradata
#11855 - Support parsing CT as Teradata alias for CREATE TABLE
#11860 - Generate FOREIGN KEY meta data in Teradata
#11861 - Emulate LISTAGG in Teradata using XMLAGG
#11863 - Add SingleStore native support for multi row inserts
#11871 - Document missing ExecuteListener::resultEnd event when ResultQuery::collect and other methods are used
#11879 - Define rawtype API compatibility strategy
#11880 - Implement improved INSERT .. ON DUPLICATE KEY UPDATE emulation via MERGE
#11884 - Refer to DSL.val() in Javadoc to raise awareness
#11897 - ClassCastException when calling Convert.convert(Object, Class) with a collection
#11905 - Update Hibernate dependency in jooq-meta-extensions-hibernate
#11908 - Use the @Deprecate(forRemoval = true, since = "...") flags in the API
#11925 - Emulate DELETE .. USING where some equivalent native syntax is available
#11926 - Add parser support for DELETE .. JOIN and UPDATE .. JOIN
#11927 - Add a Javadoc remark about performance to all the fetch() methods that map results
#11931 - Support translating DATEADD from Snowflake to BigQuery
#11932 - CLI APIs should log more helpful error messages on NoClassDefFoundError
#11938 - Support parsing Snowflake style DATEADD() function with date part as string literal
#11943 - Add native OFFSET support to Db2 11.1
#11960 - Add support for Redshift YEAR TO MONTH interval literals
#11961 - Get Redshift dialect up to date
#11964 - Add new DefaultBinding(Binding) constructor
#11979 - Add Configuration.deriveSettings(Function)
#11985 - Add HANA support for REGEXP_REPLACE
#11992 - Pull up Fields super type declaration from Select to ResultQuery
#12002 - Support parsing HSQLDB CALL statement
#12011 - BindingGetResultSetContext should offer field(): Field methods
#12028 - Add MULTISET_AGG aggregate and window function support
#12030 - Support creating MULTISET predicates
#12035 - Upgrade kotlin dependency to 1.5
#12042 - Improve error message in MockFileDatabase from "Invalid SQL" to something more descriptive
#12043 - Add DataType.isMultiset()
#12046 - Add support for XMLSERIALIZE
#12053 - Add disclaimers about mocking also to Javadoc
#12055 - Highlight new manual menu items in each version
#12061 - Improve XML path notation in section jooq-in-7-steps-step3
#12065 - Add manual section about scalar subqueries
#12071 - Add an internal means of ad-hoc table mapping
#12079 - Avoid auxiliary in-memory table when emulating DML RETURNING in SQL Server, if not strictly necessary
#12092 - MySQL queries running GROUP_CONCAT() or JSON_ARRAYAGG() should auto-increase the default group_concat_max_len
#12093 - Add to let code generator and match package procedures and functions
#12110 - Move Sakila database to own repository
Breaking changes
----------------
#3185 - Let InsertResultStep, UpdateResultStep, DeleteResultStep extend ResultQuery
#7863 - Link Oracle %ROWTYPE references to their corresponding table types
#9280 - Unsupport Scala 2.10
#9288 - Offer Result.intoMap(), intoGroups(), intoSet() functionality as Collector
#9715 - Render DSL.currentDate() as TRUNC(CURRENT_DATE) in Oracle
#10803 - Remove jOOQ-refaster from distributions
#10809 - Dialect specific data type is reported from Meta, instead of SQLDataType
#10884 - Change jOOQ-meta Relations.getUniqueKeys() to return unique keys only
#10918 - XMLasDOMBinding and AbstractXMLasObjectBinding should implement Binding, not Binding
#10937 - Add Settings.renderDefaultNullability
#11053 - Pull up PostgresDSL.array() to DSL.array()
#11115 - Table.getSchema() should not return the generated schema for aliased generated tables
#11164 - Remove ResultQuery::fetchLater and ResultQuery.fetchLazy(int)
#11196 - Drop support for Java 6 and 7 in jOOQ Enterprise Edition
#11207 - AbstractBinding empty base implementations should throw exception
#11218 - KotlinGenerator generates Record[N] for PK types in DAOs, instead of Record[N]
#11242 - Remove deprecated on(Boolean), where(Boolean), having(Boolean), etc
#11286 - Use org.jooq.Meta to discover SQLite primary key, unique key, and foreign key names in code generator
#11495 - Remove pre 3.5 deprecated API
#11498 - DSLContext.connection() and connectionResult() shouldn't produce null Connection when detached
#11511 - Stop casting SQLDataType.OTHER to VARCHAR
#11625 - GeneratorStrategy references package-private AbstractGenerator.Language class
#11720 - XResultStep should not extend X for X = Insert | Update | Delete
#11802 - Add new Transformation enum for Settings with values ALWAYS, WHEN_NEEDED, NEVER
#11892 - Add Settings.fetchIntermediateResult
#11901 - Implement more optimal ResultQuery.forEach() method
#11980 - MockConfiguration set() and derive() calls return delegate instead of MockConfiguration
#12023 - JSONB equals, hashCode, toString() should be formatting agnostic
Deprecations
----------------
#8611 - Some MySQL encryption functions were removed in MySQL 8.0.x
#10796 - Deprecate the empty dialect specific DSL classes
#11092 - Deprecate DSL.nullSafe() and related protected methods, and move them to Tools
#11129 - Log a warning when users call deprecated Param.setValue(), setConverted(), setInline()
#11329 - Deprecate XYZFinalStep types
#11505 - Deprecate DateToLocalDateConverter, TimeToLocalTimeConverter, TimestampToLocalDateTimeConverter
#11506 - Log deprecation warning when Serialization of jOOQ API is triggered
#11515 - Deprecate INGRES dialect
#11618 - Deprecate JDBC41Connection, JDBC41Statement, JDBC41ResultSet
#11797 - Deprecate Oracle 10g support
#11898 - Deprecate org.jooq.tools.Convert, the public API
#11902 - Deprecate RecordHandler
Bug Fixes
---------
#2815 - Bad SQL rendered in MySQL, when selecting from DUAL with ORDER BY
#3619 - Result.intoGroups() and intoMap() do not run through RecordListener
#5851 - VALUES constructor generates wrong SQL if one row contains a null bind variable
#5865 - Avoid allocation of new internal ConvertAll instances
#6252 - Infinity values not correctly escaped with PostgreSQL
#7201 - Incorrect emulation of SELECT DISTINCT .. FETCH NEXT .. ROWS WITH TIES
#7648 - Issue with insertion with DEFAULT value with H2 and onDuplicateKeyIgnore
#7721 - OFFSET .. FETCH should not be emulated in Oracle 18c anymore even when projection has duplicate column names
#8509 - Equals on fields not symmetric
#8554 - Improve documentation regarding nullable forced types
#8762 - Improve performance of implicit join algorithm
#8875 - Field.getDataType().defaultValue() value is 'null' instead of actual value.
#8917 - INSERT .. RETURNING emulation doesn't work on SQL Server when returning expressions or aliases
#9067 - StackOverflowError generating code from Postgresql XML schema with ARRAY columns
#9206 - Wrong implementation of DayToSecond#equals() and YearToMonth#equals()
#9475 - Support parsing number literals with exponent
#9553 - Parser cannot parse WITH in EXISTS() and other subqueries
#10019 - Fetched result is not logged when using collect(), only with fetch()
#10245 - Blocking subscriber.onComplete called after subscriber.onError
#10527 - Fix known limitations of embeddable types
#10529 - Ignore false for UDTRecords
#10668 - Parser should ignore TRUNC() call when parsing TRUNC(CURRENT_DATE) or TRUNC(SYSDATE)
#10697 - Address known issues of Settings.transformTableListsToAnsiJoin
#10699 - Parser cannot parse set operations combining SELECT * with SELECT
#10716 - Fix known issues of Settings.transformRownum
#10760 - Wrong emulation of INSERT .. RETURNING for embeddables on SQL Server
#10761 - KotlinGenerator produces invalid syntax for PostgreSQL enum types
#10762 - Wrong XSD schema in org.jooq.Constants#XSD_CODEGEN in version 3.14.0
#10767 - Kotlin code generator generates Record with invalid kotlin syntax when a column is named "value" and is true
#10768 - Compilation errors in KotlinGenerator generated classes when tables have array types
#10769 - Cannot convert from UUID to JSON in H2's JSON_OBJECT() and related functions
#10771 - KotlinGenerator creates incorrect @Generated annotation
#10774 - Remove @Nullable annotation from ResultQuery.fetchSingleInto(Class) and Record.into(Class)
#10778 - Fix compilation errors for Oracle Packages, UDTs, ArrayRecords, Queues, Links in KotlinGenerator
#10779 - Compilation error in KotlinGenerator generated DAOs for data type TINYINT
#10782 - Wrong code generated for Table annotations with KotlinGenerator
#10783 - KotlinGenerator does not annotate properties with
#10787 - KotlinGenerator and ScalaGenerator don't produce correct POJO.toString(), equals(), hashCode() methods for array types
#10788 - DSL.jsonbArray() generates json_build_array() call in PostgreSQL, instead of jsonb_build_array()
#10793 - Most package-info Javadocs refer to Sybase ASE
#10797 - Applying a forcedType prevents identity(true) from being generated
#10804 - NullPointerException when calling MetaImpl.snapshot() on a PostgreSQL schema with function based indexes
#10805 - Kotlin POJOs with array properties must implement equals() and hashCode()
#10808 - Converter using primitive types fails when used in UDT array in PostgreSQL
#10812 - Compilation error in KotlinGenerator generated code when flag is turned on
#10813 - Meta.migrateTo(Meta) produces constraint rename operations for MySQL PRIMARY KEY constraints
#10817 - MetaImpl should not produce explicit DEFAULT NULL value
#10821 - Code generation fails in PostgreSQL when grants for enum types are missing
#10822 - Meta.migrateTo(Meta) should not produce DROP SCHEMA "" calls
#10824 - Stop using information_schema.table_constraints in PostgresDatabase
#10825 - Missing INFORMIX dialect in CTE support annotations
#10828 - Record.get(Field) doesn't work for embeddable table fields when non field-replacing embeddables are projected explicitly
#10830 - There should be no diff between implicit and explicit ASC ordering in index definitions
#10834 - Wrong columns requested from Connection.prepareStatement(String, String[]) when running INSERT .. RETURNING with embeddables in HSQLDB and Oracle
#10835 - KotlinGenerator should produce open classes
#10837 - KotlinGenerator produces invalid syntax for enums with special characters
#10839 - DefaultConverterProvider should be Serializable
#10849 - Deadlock on lazy initialisation of Tables in Scala
#10852 - Parser fails to parse schema qualified type in CREATE TYPE .. AS ENUM commands
#10856 - Avoid querying information_schema.columns.datetime_precision in older versions of MySQL 5.7
#10858 - doesn't work correctly on MySQL 8.0.22
#10864 - Don't create a diff between DECIMAL and NUMERIC types, where they are just aliases
#10867 - KotlinGenerator should quote identifiers containing $
#10869 - KotlinGenerator should escape $ in string literals
#10871 - Add `yield` to kotlin keywords for use in KotlinGenerator
#10877 - Compilation error in ScalaGenerator generated code when table has column "CLASS"
#10882 - Code examples contain excess or missing semi colons
#10887 - ALTER TABLE code examples shows wrong multi column addition syntax
#10889 - Meta.filterPrimaryKeys() is not implemented correctly
#10895 - Attaching configuration to unbound ResultQuery does not work when executed async
#10900 - Compilation error in KotlinGenerator generated code, when OTHER data type columns have a default value
#10904 - KotlinGenerator produces compilation error in generated interfaces when is set
#10910 - java.lang.ClassCastException: class java.lang.Class cannot be cast to class java.lang.reflect.ParameterizedType when custom data type extends List
#10915 - Wrong code generated by KotlinGenerator for
#10920 - PostgreSQL supports XMLTABLE only after version 10
#10923 - KotlinGenerator produces compilation errors in UDT Records when is true
#10931 - LIMIT without OFFSET is emulated using window functions when value is not a bind variable
#10934 - Unnecessary ORDER BY (SELECT 0) clause generated in SQL Server when using TOP
#10939 - Wrong SQL generated for IIF() emulation in MySQL
#10940 - fails with missing FROM-clause entry for table "alias_18649163" on PostgreSQL
#10944 - Code generator warning message should refer to deprecated only if customType configuration is present
#10949 - Missing data type display in ParserCLI help listing
#10951 - JPAConverter may cause DataTypeException if it does not detect the proper types using reflection
#10954 - Unqualified field lookup in ON DUPLICATE KEY UPDATE clause doesn't work
#10956 - Add missing documentation about throwing of DataDefinitionException in relevant API
#10964 - Parser should support plural form of DatePart where applicable
#10968 - Ambiguous field identifier when parsing unions with unqualified columns and parseWithMetaLookups
#10970 - Unknown field identifier when parsing ORDER BY clauses referencing field aliases with parseWithMetaLookups
#10972 - jOOQ-checker does not work with error prone 2.4.0
#10974 - Support ARRAY_AGG in H2
#10979 - XMLDatabase does not produce parameters for overloaded routines
#10983 - Wrong Oracle style to ANSI JOIN transformation result, depending on predicate order
#10989 - Wrong SQL generated for INSERT .. SELECT .. ON DUPLICATE KEY IGNORE emulation using NOT EXISTS
#10992 - Wrong SQL generated when outer and correlated subquery share implicit join path
#10997 - Compilation error in KotlinGenerator generated code when enum literals conflict with modifier keywords
#11000 - Parser cannot look up column from tables by same name from different schemas
#11011 - Subquery IS [ NOT ] NULL predicate should avoid RVE emulation for degree = 1
#11014 - JSON_TABLE emulation in PostgreSQL broken
#11016 - Kotlin POJO generator produces wrong equals/hashCode for binary types
#11017 - KotlinGenerator should generate equals(other: Any?), not equals(obj: Any?) on pojos
#11021 - Avoid synthetic ORDER BY clause in window functions if not strictly necessary
#11022 - The NAME keyword in XMLELEMENT(NAME ) should be optional for the parser
#11025 - Wrong variable binding for boolean values in Oracle and Db2 JSON_OBJECT(), JSON_ARRAY() and others
#11032 - Compilation errors for when referenced table is called RECORD_TYPE
#11041 - Bug in documentation for JSON_TABLE
#11042 - Add support for parsing INSERT .. WITH .. SELECT
#11043 - NullPointerException when parsing WITH .. INSERT .. SELECT without explicit INSERT column list
#11045 - Support parsing table aliases in DELETE statements
#11047 - Code generator does not produce indexes for quoted identifiers in PostgreSQL
#11050 - Parser doesn't support derived column lists in MERGE
#11051 - DSL.array(Select) produces bad formatting
#11055 - RenderQuotedNames.ALWAYS does not work correctly for stored functions
#11056 - Wrong nullability annotations on Parser.parseSelect() and others, when parsing blank strings
#11057 - KotlinGenerator should generate kotlin.Deprecated annotation instead of java.lang.Deprecated
#11062 - Remove deprecated Param.setValue(), setConverted(), setInline() calls from manual
#11066 - Tests failed for jooq-spring-boot-example
#11078 - Override CatalogImpl.equals()
#11086 - Wrong SQL generated when DomainDataType is loaded before base SQLDataType for SQLDialect.DEFAULT
#11095 - KotlinGenerator should take ParameterDefinition nullability into consideration
#11101 - Misleading error message when something goes wrong in the code generator
#11103 - NullPointerException when custom JavaGenerator subclasses don't call JavaWriter.printPackageSpecification()
#11105 - NullPointerException when GenerationTool is not properly initialised
#11116 - Cache implicit join path references
#11118 - Nested records produced by DefaultRecordMapper do not pass through RecordListener lifecycle
#11132 - ParseWithMetaLookups produces wrong projection on self join
#11134 - ParseWithMetaLookups looks up columns in Meta that cannot possibly appear in query
#11139 - ParseWithMetaLookups propagates wrong type from derived table
#11143 - ParserWithMetaLookups reports ambiguous column in correlated subquery, when there is none
#11148 - Regression calling Record1.into(OtherTableRecord)
#11150 - Omitting parts of the foreign key in onKey(TableField…) doesn't produce the expected result
#11165 - Converter should use Jackson kotlin module if available when mapping JSON to kotlin data classes
#11166 - Wrong SQL generated for Informix STDDEV_SAMP and VAR_SAMP
#11168 - DataType.convert(Object...) and convert(Collection>) don't work for converted data types
#11179 - Compilation errors in generated DAOs when embeddables use
#11185 - Compilation errors in generated embeddable pojos if the embeddable is located in a "synthetic" schema
#11191 - Generated code of a routine with TIMESTAMP parameter has too little precision
#11200 - Multithread deadlock: org.jooq.impl.AbstractField references subclass org.jooq.impl.Val in static initializer
#11201 - MetaTable::getReferences and MetaUniqueKey::getReferences do not take into account inverseSchemaCatalog
#11213 - Error mapping a jsonObject field: Cannot convert from LinkedHashMap
#11216 - JDBCUtils.dialect() should recognise MariaDB versioned SQLDialect
#11220 - Manual produces wrong Javadoc link for java.beans package
#11223 - Prevent parsing the same flag twice in CREATE SEQUENCE and ALTER SEQUENCE
#11224 - DROP TEMPORARY TABLE doesn't generate TEMPORARY keyword in MariaDB
#11226 - Broken JDK Javadoc links in the PDF version of the manual
#11228 - Settings.isMapConstructorParameterNamesInKotlin doesn't work for kotlin inline classes
#11233 - Parser throws IllegalArgumentException instead of ParserException when date_trunc() is parsed with invalid DatePart
#11235 - Parser fails when union subquery contains correlated subquery
#11238 - FILTER or OVER clause does not work on JSON_ARRAYAGG() or JSON_OBJECTAGG() functions in H2, MySQL, and PostgreSQL style dialects
#11239 - Generated order of check constraints does not respect Database::getOrderProvider
#11244 - SelectQuery.setForUpdate and similar methods do not clear flag when value is false
#11247 - VariableImpl should render qualified name
#11255 - Meta.getTables() does not include PostgreSQL foreign data wrapper tables
#11258 - NullPointerException in MetaImpl.snapshot() when foreign key column order doesn't match unique key column order
#11259 - NullPointerException when using table valued function without explicit parameters
#11261 - Interpreter cannot find unique key if foreign key references columns in different order
#11265 - Internal DataKey.DATA_PREPEND_SQL functionality should be cumulative
#11270 - Wrong support annotation for FIREBIRD ALTER TABLE .. RENAME
#11273 - Behavior of MockResultSet.close() differs from ResultSet.close() javadoc
#11275 - NullPointerException when using InsertSetStep.set(Map) on plain SQL table with plain SQL field names
#11277 - Wrong Support annotation for Derby DROP { INDEX | TABLE } IF EXISTS
#11280 - Add native support for CREATE INDEX .. INCLUDE in Db2
#11281 - Wrong SQLSTATE handled in Db2's CREATE INDEX IF NOT EXISTS
#11284 - Wrong emulation of CREATE UNIQUE INDEX .. INCLUDE
#11287 - NullPointerException in AbstractMeta.copyFK for SQLite when a foreign key references a unique key
#11290 - Parser parses PRIMARYKEY as PRIMARY KEY
#11292 - AbstractMeta.getForeignKeys() and other key / index producing methods don't handle namespacing correctly for named keys
#11295 - POSITION(in, search, startIndex) emulation returns wrong result when search was not found
#11299 - SQLite's DSL.extract() emulation should render an explicit CAST(STRFTIME(...) AS INT)
#11302 - Wrong Support annotation on ALTER TABLE .. RENAME CONSTRAINT
#11304 - ExecuteContext.exception() should accept null exceptions and translate them to an unspecified DataAccessException
#11307 - PostgreSQL MetaImpl based DataTypes are missing length of array element type
#11309 - ArrayDataType.toString() should indicate that it's an array type
#11317 - Wrong documentation of RenderQuotedNames.EXPLICIT_DEFAULT_UNQUOTED
#11319 - JDBCDatabase produces empty string as default value everywhere
#11325 - PostgreSQL routines with long names are excluded by code generator
#11334 - Field.getDataType(Configuration) resets nullability
#11341 - intoXML() throws NPE exception
#11343 - Simplify JSONConverterProvider example in the manual
#11345 - Memory leak regression in DefaultDataType cache
#11347 - Wrong syntax generated when WITH clause is empty in DSL
#11348 - BooleanDataKey.DATA_FORCE_STATIC_STATEMENT only forces inlining of bind values, not static statement execution
#11350 - Missing H2 support on WithStep::selectOne and similar methods
#11361 - Wrong emulation of the procedural FOR loop with index
#11366 - Collect nested DECLARE statements in Firebird and pull them up to the top level block
#11370 - Occasionally repeated BEGIN BEGIN blocks from emulations around DECLARE
#11376 - Implicit joins don't work inside of procedural logic
#11377 - DML statements should enter a ScopeStack scope
#11387 - NullPointerException when using Enums
#11388 - java.lang.IllegalStateException: Cannot create a DerivedColumnList from a qualified name
#11398 - Wrong emulation of JSON_OBJECTAGG in Db2 and other dialects for String values
#11417 - Parser::parseStatements parses DECLARE BEGIN END; into bad structure
#11427 - Parser doesn't accept INSERT .. SELECT .. ON CONFLICT
#11435 - Support parsing quoted identifiers containing escaped quotes
#11437 - Passing an empty array or collection to returningResult() does not match the behaviour of returning()
#11442 - Plain SQL templates improperly recognise "?<>" as a PostgreSQL operator
#11443 - BatchedPreparedStatement doesn't work if statement is re-used
#11446 - Bad formatting for UPDATE .. ROW = ROW statements
#11447 - Missing CockroachDB support on WITH RECURSIVE method Support annotations
#11462 - LoaderOptionsStep.commitAfter() is not implemented correctly
#11466 - DataType::identity Support annotation should list dialects that support identity types
#11468 - CustomTable.getUniqueKeys() should return super.getUniqueKeys() not super.getKeys()
#11474 - Cannot parse JSON[B]_AGG() FILTER or OVER clause
#11475 - Translator should avoid bind variable casts in the absence of schema information
#11477 - Missing ABSENT ON NULL declarations in JSON_OBJECT emulated by FOR JSON
#11484 - FILTER clause does not work on JSON_ARRAYAGG() or JSON_OBJECTAGG() functions in Db2 and Oracle dialects
#11486 - Bad extra derived table generated when INSERT .. SELECT references target table from correlated subquery in MariaDB, MySQL
#11517 - Support annotation wrong for Derby on DROP VIEW IF EXISTS
#11521 - ClassCastException when ResultQuery.fetchArray() returns no rows
#11522 - Wrong precision generated for SQL Server SMALLDATETIME data type
#11535 - Parser parses incorrect FOR UPDATE OF syntax, depending on dialect
#11560 - java.lang.ClassCastException: class org.jooq.impl.ResultImpl cannot be cast to class java.sql.ResultSet when mocking Oracle SYS_REFCURSOR procedure
#11564 - Add a way for emulated table expressions to auto-alias themselves
#11566 - JDBCDatabase doesn't yet distinguish between TableType.TABLE and VIEW and others
#11576 - DefaultMetaTableDefinition doesn't consider DataType.identity() flag
#11579 - Add internal Cascade enum type
#11580 - fetchParent() doesn't work properly with foreign key referencing just a part from a composed primary key
#11582 - Avoid auxiliary derived table in SQLite GENERATE_SERIES emulation
#11586 - Put TOP_LEVEL_CTE marker at DML statement beginning, not SELECT, in SQL Server
#11591 - Misleading Javadoc about Settings.isInsertUnchangedRecords
#11596 - ArrayTable doesn't pass derived column list to ArrayTableEmulation
#11605 - DropTableStep.cascade() and restrict() have wrong dialects in Support annotation
#11614 - Fix @Support on ALTER TABLE .. RENAME INDEX
#11621 - Parser wrongly recognises VERSIONS table alias as keyword
#11629 - Cannot parse MariaDB FOR LOOP syntax
#11630 - Cannot parse empty blocks
#11631 - Boolean field expected when parsing NOT(?)
#11632 - Parser fails when parsing nested not unary operator without parentheses
#11634 - XMLFormat.quoteNested() is not being considered in Result.intoXML()
#11638 - Missing DERBY @Support on DSL.date(), DSL.time(), DSL.timestamp() methods
#11639 - Support parsing DROP SEQUENCE .. RESTRICT
#11644 - Invert defaults for internal Tools.visitSubquery() parentheses flag
#11651 - Add parser support for VERTICA IDENTITY column type
#11652 - Vertica has native support for DECODE
#11658 - PostgresDatabase doesn't produce CHAR type length for CHAR(n)[] array types
#11661 - ROWNUM transformation doesn't work in the presence of DISTINCT
#11663 - Wrong order of WINDOW / QUALIFY clauses
#11667 - Oracle MetaTable fields do not have identity information
#11673 - Emulate NVL using COALESCE instead of CASE, where possible
#11683 - REPLACE should inline empty string parameter, not use val
#11689 - Code generator regression for SQL Server defaulted parameters
#11695 - Support parsing "! =" and "< >" and other operators containing white space in Oracle
#11701 - Bad inlining of Infinity or NaN in PostgreSQL
#11704 - Support floating point NaN and (-)Infinity values in other dialects
#11705 - Add parser support for Firebird's BLOB SUB_TYPE syntax
#11709 - Oracle typed REF CURSOR produce wrong code
#11721 - Wrong precision for H2 timestamp when using domains
#11732 - PostgreSQL ON CONFLICT .. WHERE generates not valid SQL
#11733 - Column "INFORMATION_SCHEMA.COLUMNS.INTERVAL_TYPE" not found in H2 1.4.197
#11740 - Stop using deprecated ojdbc API
#11747 - TO_CHAR(x) without format is not natively supported in PostgreSQL
#11749 - Oracle UPDATE .. RETURNING emulation doesn't work for boolean data type rewrites
#11760 - NullPointerException instead of DetachedException when executing a detached Routine
#11762 - Regression when using plain SQL H2 array types
#11767 - ROWNUM transformation should avoid creating derived tables if possible
#11769 - NPE when ParsingConnection is not attached to an actual connection
#11783 - Named parameter mapping doesn't work with missing or excess source column values
#11790 - Oracle DUAL table incorrectly quoted by RenderQuotedNames.ALWAYS
#11791 - no longer works in Scala
#11818 - Avoid new Integer(...) calls in JSON Parser
#11819 - Coerce should delegate all QueryPartInternal calls to the wrapped field
#11832 - Typo in AggregateFunction.keepDenseRankLastOrderBy() Javadoc
#11841 - Work around Simba for BigQuery's lack of NULL bind variable support
#11847 - Regression in Teradata where DUAL is no longer quoted
#11852 - DUAL emulation in Teradata MERGE .. USING DUAL doesn't work
#11857 - Emulate CASE WHEN EXISTS in Teradata
#11866 - MemSQL computed columns of type int aren't generated correctly
#11870 - MiniJAXB cannot read code generation's regexFlags content (an xs:list type)
#11873 - Code generation error when generating code for Redshift
#11876 - Regression in OracleDatabase for sequences with large MAXVALUE
#11883 - jOOQ 3.13 manual refers to not-yet existing jsonEntry(String, Field)
#11893 - DefaultConverterProvider isn't able to look up value to single-arg constructor conversions
#11895 - ResultQuery.fetchStream() fetches entire resultset at once
#11904 - ORDER BY should resolve nested record emulation
#11912 - KotlinGenerator generates invalid code when column names X and isX clash
#11918 - Add Settings.renderOptionalXYZ support to ParserCLI
#11921 - Wrong position reported for parser meta lookup failures
#11924 - Incorrect SQL generated for multi table DELETE with JOIN in MySQL
#11930 - Wrong result displayed for SQRT(4) function call in the manual
#11934 - Constants.MINOR_VERSION was not updated in 3.14
#11936 - Manual section using-jooq-with-jdbctemplate shouldn't use deprecated JdbcTemplate method
#11953 - Parser grammar does not reflect both possible positions of FROM FIRST / LAST and IGNORE / RESPECT NULLS
#11954 - Date Add and Date Sub conversion not working for Redshift dialect
#11958 - BOOL_AND() and BOOL_OR() emulation does not correctly implement FILTER clause
#11973 - JDBCUtils.dialect(Connection) recognises MYSQL_8_0, not MYSQL_8_0_19
#11977 - PostgresDatabase should ignore unknown functions when parsing index column expressions
#11987 - Parser doesn't support date time arithmetic in DATE_TRUNC arguments
#12007 - Column "INFORMATION_SCHEMA.COLUMNS.DOMAIN_SCHEMA" and "INFORMATION_SCHEMA.COLUMNS.DOMAIN_NAME" not found in H2 1.4.197
#12013 - Support parsing HSQLDB post-fix IF EXISTS in DROP statements
#12019 - ORA-06550 when calling a PL/SQL procedure with a %ROWTYPE parameter that has DATE fields when dateAsTimestamp=true
#12020 - Result.formatXML() and formatJSON() do not correctly format nested records
#12026 - Result.formatXML() re-declares xmlns on each level for nested results
#12044 - Correctly emulate XMLAGG(...) FILTER (WHERE ...) in Db2, Oracle, Teradata
#12050 - CAST must not generate length, precision, scale in Oracle PL/SQL context
#12054 - Wrong comment in manual meta section about the manual
#12064 - Informix can't handle bind values as arguments to NVL() or COALESCE()
#12070 - JSON_OBJECT and JSON_ARRAY functions should generate a Name, not a Keyword
#12072 - Work around Oracle bug where a CASE expression without ELSE clause in JSON_ARRAYAGG causes ORA-40590: invalid format
#12078 - SQL Server UpdatableRecord.refresh() is unnecessary when calling UpdatableRecord.store()
#12080 - Generate a FORMAT JSON clause in Oracle's JSON_OBJECT if contents are of type JSON
#12085 - Work around Oracle's JSON_ARRAYAGG() bugs when aggregate inputs should be DISTINCT
#12086 - Nested JSON_OBJECT() emulation is wrong in SQL Server
#12088 - UDT.getQualifiedName() does not produce package qualification for a package UDT
#12091 - Manual section data-types-oracle-date uses deprecated API
#12094 - Meta.ddl() produces TIMESTAMP instead of DATE for columns with dateAsTimestamp=true active
#12105 - Work around Db2 Reply.fill() - insufficient data (-1). Message: Insufficient data. when fetching JSON_ARRAY
#12106 - Manual section about limit-clause contains broken link about Oracle ROWNUM filtering performance
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:
- https://blog.jooq.org/using-sql-server-for-xml-and-for-json-syntax-on-other-rdbms-with-jooq/
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:
- https://blog.jooq.org/nesting-collections-with-jooq-3-14s-sql-xml-or-sql-json-support/
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:
- https://blog.jooq.org/stop-mapping-stuff-in-your-middleware-use-sqls-xml-or-json-operators-instead/
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:
- https://www.jooq.org/doc/3.14/manual/code-generation/codegen-embeddable-types/
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:
- https://www.jooq.org/doc/3.14/manual/code-generation/codegen-domains/
- https://www.jooq.org/doc/3.14/manual/code-generation/codegen-embeddable-types/codegen-embedded-domains/
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:
- https://www.jooq.org/doc/3.14/manual/sql-building/sql-statements/select-statement/implicit-join/
- https://www.jooq.org/doc/3.14/manual/code-generation/codegen-advanced/codegen-config-database/codegen-database-synthetic-objects/
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
---------------
With the parser and our translator tool https://www.jooq.org/translate, we'll
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:
https://www.jooq.org/doc/3.14/manual/sql-building/sql-parser/sql-parser-cli/
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:
- https://www.jooq.org/doc/3.14/manual/sql-building/queryparts/sql-transformation/
- https://github.com/jOOQ/jOOQ/issues/10054 (future work)
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
terms of list of Javadoc links: https://www.jooq.org/api-diff
API Diff:
---------
See what's changed in terms of an API diff here:
https://www.jooq.org/api-diff/3.13-3.14
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 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 and types
#4528 - Add manual section about DSLContext.connection()
#4941 - Add LoaderListenerStep.onRowStart() for preprocessing input data
#5216 - Add UpdatableRecord.children(ForeignKey): Table
#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
#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 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 to code generator 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) 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
#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 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 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 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 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, not Class
#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) 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.(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 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
#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 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 configuration in 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 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
#10654 - Make the generation of the serialVersionUID configurable
#10658 - Add Sequence.nextvals(int):Select> and DSLContext.nextvals(Sequence, int):List 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 into a Converter
#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, 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 true
#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 in
#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 - and 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 element is not paired with
#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 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 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 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 - and are not implemented in XMLGenerator
#10394 - and related flags implemented incorrectly in JavaGenerator
#10398 - 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 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
#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 implementations into Converter 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
Version 3.13.0 - February 13, 2020
================================================================================
Starting with this release, we will further embrace our support for parsing,
translating, executing, and now also interpreting DDL statements. The driving
force is better code generation support, but in the future, also better
integration with database change management systems like Flyway or Liquibase.
We've added support for a very promising new dialect: CockroachDB.
We're starting to support one of SQL:2011's most interesting features: temporal
tables for system and application time versioning, and we've generally improved
the way we build and distribute jOOQ to our paying customers.
SQL Dialects
------------
We've worked together with a team of great engineers at CockroachDB to speed up
our newly added, formal CockroachDB support in the jOOQ Professional and
Enterprise Editions. While many users have successfully used the POSTGRES
dialect with CockroachDB for simple integrations, this new dialect is now fully
integration tested and supported for future jOOQ and CockroachDB versions. The
integration fixed a variety of issues and minor differences that we have
encountered in the code generator and the runtime library.
We've added support for a variety of features now available in Firebird 3.0+,
MariaDB 10.3+, MySQL 8+, and PostgreSQL 10+.
DDL interpretation
------------------
Our biggest investment has been made in the area of DDL interpretation. Since
jOOQ 3.9, we can parse more and more SQL syntax. A logical next step is to allow
for interpreting parsed (or ordinary, DSL constructed) DDL statements in order
to maintain an incremental, in-memory meta model of a database. This has a
variety of benefits, which we will take advantage of in this release and in the
future.
The main out of the box benefits in this version include:
- Being able to create a diff between two versions of a schema, programmatically
through Meta.migrateTo(Meta), on the command line through DiffCLI
(https://www.jooq.org/doc/latest/manual/sql-building/schema-diff-cli),
or online, through our website: https://www.jooq.org/diff
- Such a diff or the meta model itself can be used for ad-hoc introspections, or
formally, for automated migrations by tools built on top of jOOQ. Future
versions will offer such migrations out of the box.
- Unfortunately, we have not yet replaced our H2 backed DDLDatabase by our new
DDL interpretation capabilities. This is a high priority for jOOQ 3.14, though
In the context of these investments, we have improved a variety of
infrastructure that were needed for these features and that users can benefit as
well. These improvements include:
- A new LiquibaseDatabase, which uses Liquibase behind the scenes to simulate a
schema migration in memory (similar to the DDLDatabase for Flyway), to reverse
engineer that for the code generator. If you're using Liquibase, chances are
that you no longer need to connect to an actual database to use jOOQ's code
generator. More info here:
https://blog.jooq.org/how-to-simulate-a-liquibase-migration-using-h2/
- We now support the inclusion of SQL text in generated code and other parts of
the runtime meta model, including for CHECK constraints and views
- A lot of improvements to the JDBC DatabaseMetaData backed org.jooq.Meta API
have been implemented.
- A lot of additional DDL statement and syntax support has been added throughout
the API, parser, and other tooling.
- The runtime meta model has been enhanced with new information, such as
sequence flags, check constraints, table type information, and more.
Temporal table support
----------------------
Perhaps the SQL:2011 standard's most exciting "new" feature are temporal tables,
an enhancement on top of Oracle's historic flashback query feature, and much
more.
In many systems, single, or bi temporal versioning of data is essential. The two
dimensions of versioning that are now supported in jOOQ are:
- System versioning, useful for backups and auditing, where every mutating
operation results in a backup copy of the data in a managed backup table.
- Application versioning, useful for data that has a timely limited validity,
such as a price for a product, which could have a temporary discount.
jOOQ 3.13 supports org.jooq.Period and related API in Select, Update, and Delete
to manipulate and query temporal tables in dialects that ship with native
support for these features. To different degrees, these dialects include:
- DB2
- MariaDB
- Oracle
- SQL Server
Emulations of incompletely supported syntax in the above dialects, as well as in
all other dialects will be added in future jOOQ versions, making temporal
validity a problem of the past.
More details here:
https://www.jooq.org/doc/3.13/manual/sql-building/table-expressions/temporal-tables/
This is a commercially licensed only feature.
Build improvements
------------------
We've invested a lot of time in improving our build automation using newer
Jenkins features that allow us to publish builds more frequently, especially
snapshot builds of upcoming minor releases for early adopters, as well as patch
releases for customers needing urgent fixes:
https://www.jooq.org/download/versions
These new releases also include trial versions for Java 6, 8, 11, without the
need to register for extended trials.
In addition to the above, we've improved and continue to improve our
documentation of features per edition, in the future.
Procedural API improvement
--------------------------
In jOOQ 3.12, we've introduced support for procedural languages, which we are
improving in every new release. jOOQ 3.13 adds support for additional
procedural statements, including:
- EXECUTE for dynamic SQL execution embedded in procedural blocks
- RETURN to return from functions
- Plain SQL statement support
In the future, we're planning to support also the generation of functions,
procedures, and triggers through standard jOOQ API.
More details here:
https://www.jooq.org/doc/3.13/manual/sql-building/procedural-statements/
This is a commercially licensed only feature.
jOOQ-Refaster
-------------
Some of our users have had a lot of success using our checker-framework or
ErrorProne integrations, which allow for some static API usage analysis in
client code (e.g. plain SQL / SQLi risk, dialect compatiblity, etc.)
Starting from jOOQ 3.13, we're also adding support for ErrorProne's sub project
"refaster", which allows for automatically rewriting bad API usage to something
better, such as for example:
- Migrate deprecated API usage like field.trim(), to its replacement trim(field)
- Migrate inefficient SQL usage like ctx.fetchCount(select) != 0 to
ctx.fetchExists(select)
More details here:
https://www.jooq.org/doc/3.13/manual/tools/refaster/
API Diff:
---------
See what's changed in terms of an API diff here:
https://www.jooq.org/api-diff/3.12-3.13
Features and Improvements
-------------------------
#2286 - Add LiquibaseDatabase to support interpreting the liquibase XML format in the code generator
#2370 - Add org.jooq.TableOptions to describe the various storage and other options of a table in the meta model
#3521 - Implement JDBCDatabase.loadForeignKeys()
#3676 - Treat identical UNION [ ALL ] and INTERSECT set operations as associative avoiding unnecessary parentheses
#4245 - Add support for PostgreSQL's DELETE .. USING syntax
#4454 - Implement Table.getIdentity() for tables obtained via org.jooq.Meta
#4793 - Add support for Catalog in runtime schema mapping
#5181 - Add additional runtime meta information for indexes
#5317 - Add support for ALTER TABLE .. ADD [ COLUMN ] .. [ { PRIMARY KEY | UNIQUE } ] [ REFERENCES | CHECK .. ]
#6314 - Add Meta.getIndexes()
#6412 - DSLContext.ddl() should distinguish between table types (table, temporary table, view, etc.)
#6659 - Add support for PostgreSQL 10 IDENTITY columns
#7004 - Add support for MariaDB sequences
#7006 - Add support for MariaDB 10.3 Features
#7241 - Add support for ALTER TABLE .. ADD .. [ FIRST | BEFORE | AFTER ]
#7293 - Generate OFFSET .. FETCH for Firebird 3.0
#7421 - Stop rendering "FROM dual" in MySQL 8+ and MariaDB 10.4+
#7511 - Add support [ NOT ] ENFORCED in constraints
#7629 - Add support for exporting CHECK constraints through DSLContext.ddl()
#7639 - Add code generation support for CHECK constraints
#7752 - Add support for Sequence flags in meta model
#7775 - Add support for ALTER TYPE to modify enum types in PostgreSQL
#8104 - Add support for ALTER DATABASE with DDLDatabase
#8105 - Interpreter should have an option to disable foreign key checks
#8194 - Add a Configuration.systemConnectionProvider() SPI
#8201 - Add support for EXECUTE for use in procedural blocks
#8252 - Add build integration test verifying if all pro API is annotated with the org.jooq.Pro annotation
#8323 - Publish existing jOOQ-xtend project as a Maven module
#8345 - Add an org.jooq.Typed marker interface
#8507 - Add a parent pom.xml for all examples
#8524 - Add support for CREATE TEMPORARY TABLE IF NOT EXISTS
#8528 - Add org.jooq.Meta implementation that is based on DDL interpretation
#8541 - Use MySQL's native derived column lists support
#8545 - Add support for CockroachDB
#8621 - Add support for exception syntax in MockFileDatabase
#8642 - Separate section for jOOQ's SQL extensions
#8755 - Make Loader(CSV|JSON|Rows)Step.fields() calls optional
#8787 - Support DSL#alterIndexIfExists() for SQL Server
#8800 - Add Settings.transformAnsiJoinToTableLists to support pre-ANSI join syntax
#8807 - Add setting to specify whether INNER and OUTER keywords should be generated in joins
#8870 - Support Scala 2.13
#8901 - Cannot use INSERT .. RETURNING in Oracle to fetch back a UDT
#8923 - Consider using jaxb2-annotate-plugin in XJC compiler
#8953 - Use Internal API for generated code of Queues and Sequences
#8995 - Add Javadoc to XJC generated with-methods
#9019 - Render DROP TEMPORARY TABLE in MySQL
#9043 - Add org.jooq.Source API
#9053 - Offer a SNAPSHOT repository
#9086 - Add tags to the manual documenting what editions support a given feature
#9096 - Document the procedural language API
#9101 - Improve method Javadoc of JAXB generated classes
#9109 - Emulate multi column COUNT (DISTINCT col1, col2) in H2 using row value expressions
#9127 - Update jOOQ-mcve dependency versions
#9130 - Support MySQL FOREIGN KEY [ index_name ] syntax
#9132 - Support parsing MySQL's USING [ BTREE | HASH ] index type syntax everywhere where it is supported
#9138 - Parser errors from DDLDatabase should hint at jOOQ's parser ignore comment syntax
#9141 - DDLDatabase should output query results to log output
#9155 - Various third party dependency updates
#9161 - Add support for parsing MySQL FULLTEXT KEY inline declaration in CREATE TABLE
#9166 - Deprecate loading settings from /jooq-settings.xml or from -Dorg.jooq.settings
#9168 - Add a DSL.execute(Query) convenience method
#9171 - Add Javadoc to DSL::execute
#9183 - Add support for DISTINCT ON in H2
#9186 - Correct various @Support annotations for MariaDB
#9192 - Add DSL.statement(String), a plain SQL procedural Statement API
#9194 - Add support for RETURN in the procedural API
#9200 - Avoid unnecessary warning when there are multiple nextval default values (not caused by serial types) in PostgreSQL
#9209 - Add support for exceptions in MockResult
#9213 - Introduce versioned MARIADB dialects
#9217 - Support parsing MySQL's USING HASH index_type in CREATE INDEX
#9221 - Postgres supports DateParts MILLISECOND and MICROSECOND
#9222 - Align @Support annotation of DatePart enum constants with DSL methods
#9233 - Use new Source API throughout the jOOQ API
#9238 - Add a new Settings.parseNameCase
#9240 - Constraint with empty name rendered as CONSTRAINT ""
#9244 - Add support for DROP TEMPORARY TABLE IF EXISTS
#9252 - H2: Omit OFFSET clause if offset is 0
#9255 - Upgrade Maven version to 3.6.2 in Travis
#9263 - Better support for fields with boolean converter
#9265 - Add JSON.data() and JSONB.data()
#9272 - Slightly improved code generation pattern
#9273 - Update Gradle example to use newer version of H2
#9276 - Java generator always uses LF line terminator for import statements
#9285 - Add a link from the dialect family to the latest dialect version in each SQLDialect
#9289 - Add Javadoc to Configuration.dsl() explaining that it is just convenience
#9294 - Add support for MariaDB FOR UPDATE .. [ WAIT n | NOWAIT ]
#9295 - Use Settings.getQueryTimeout() consistently
#9305 - Support parsing Vertica's TEMP table syntax
#9307 - Add Mock.of(SQLException)
#9312 - Add SQLDialect.supportedBy(SQLDialect...) to produce a set of supported dialects from an input
#9313 - Add SQLDialect.predecessors() to produce a set of all preceding versions of a given dialect
#9316 - Also support STRAIGHT_JOIN for MariaDB and MemSQL
#9317 - Synchronize @Support annotations on JoinType and Table methods
#9318 - H2: Support WITH clause for MERGE statement
#9320 - Add a new DataDefinitionException to be thrown by DDLInterpreter
#9325 - Add Name.empty() to check if a name consists only of the empty string ""
#9327 - Add DDLFlag.SEQUENCE to allow for exporting CREATE SEQUENCE statements from DSLContext.ddl()
#9329 - Add reactive streams in published ZIP file as a dependency, for convenience
#9344 - Fix Support annotations for CREATE SEQUENCE flags
#9352 - Only render CREATE SEQUENCE ... NO CYCLE clause where supported
#9353 - Support parsing ALTER TABLE .. ALTER .. SET DEFAULT
#9354 - Add support for ALTER TABLE .. ALTER .. DROP DEFAULT
#9358 - Add support for parsing the H2 SCHEMA() function
#9359 - Refactor common meta extensions code to new InterpretingDatabase
#9361 - Upgrade H2 dependency to 1.4.200
#9362 - Add Settings.interpreterDialect
#9364 - Add DDLFlag.INDEX to allow for exporting CREATE INDEX statements
#9371 - H2: DSL#currentTime() should render as CURRENT_TIME
#9372 - Improve SEMI / ANTI JOIN documentation
#9374 - Support various H2 ALTER .. IF EXISTS statements
#9375 - Add code generation and runtime flags to include/exclude automatic indexes on PK/UK/FK
#9380 - Add support for ALTER TABLE .. DROP CONSTRAINT .. [ CASCADE | RESTRICT ]
#9382 - Add support for Oracle's ALTER TABLE .. DROP UNIQUE () syntax
#9384 - DataType.getDataType(Configuration) turns this on dialect specific data types
#9394 - Move DSLContext.ddl() API to Meta
#9395 - Let Meta extend Scope
#9399 - Move DSLContext.informationSchema() to Meta
#9403 - Deprecate CUBRID dialect
#9407 - Deprecate remaining Field.xyz() convenience API
#9410 - Various Firebird DDL improvements
#9413 - Add support for RDB$DESCRIPTION in Firebird code generation
#9421 - Add Firebird code generation support for indexes
#9426 - DSLContext.meta(Source...) should be able to read InformationSchema from sources
#9427 - Let Name extend Comparable
#9428 - Meta.toString() should call Meta.ddl()
#9429 - Add DSLContext.meta(Query...) as a shortcut for meta(Source...)
#9431 - Add a /diff tool to the website
#9432 - Add Queries.concat(Queries)
#9433 - Implement Meta.equals() and hashCode() based on Meta.ddl()
#9434 - Add DDLExportConfiguration.respectOrder flags
#9435 - Let Key extend Named
#9436 - Add Meta.apply(Queries)
#9437 - Add support for ALTER SEQUENCE [ sequence flags ]
#9438 - ALTER SEQUENCE .. RESTART emulation should use Sequence.startWith() flag, if available
#9441 - Add DSLContext.meta(String...) for convenience
#9442 - Add code generation support for sequence flags
#9445 - Various Sybase ASE DDL improvements
#9460 - Support additional Settings.interpreterDialects and add an InterpreterConnectionProvider SPI
#9476 - Add parser support for MySQL [ INNER ] JOIN without ON clause
#9478 - Support parsing ALTER TABLE .. ALTER COLUMN .. SET NULL syntax
#9482 - Add new internal org.jooq.impl.Names class for commonly used DSL.name() references
#9490 - Create an FAQ on the website, and link to it from the issue template
#9491 - Add 301 redirects for non-modular Javadoc
#9502 - Add Settings.renderOptionalAsKeywordForTableAliases and ...ForFieldAliases
#9504 - Add DDLExportConfiguration.createViewIfNotExists and DDLExportConfiguration.createOrReplaceView
#9505 - Add org.jooq.Version to describe a database version
#9508 - Add Settings.interpreterDelayForeignKeyDeclarations
#9511 - Avoid quoted identifiers in jOOQ-meta queries
#9514 - LiquibaseDatabase should allow for passing parameters to the Liquibase
#9520 - Log info message when a forcedType never matches
#9533 - Add support for DROP INDEX .. [ CASCADE | RESTRICT ]
#9534 - Add support ALTER TABLE .. DROP UNIQUE
#9536 - Add DataType.isInteger()
#9558 - Clarify in Javadoc of selectFrom() and related methods that all Table.fields() will be fetched, not DSL.asterisk()
#9562 - Add Table.getChecks() to return a list of check constraints
#9565 - Add CheckConstraint XSD type to jooq-meta.xsd
#9570 - Generate single ADD or DROP ALTER TABLE statements when a list of length 1 is passed
#9578 - Upgrade Hibernate dependency to 5.4.9.Final
#9580 - Add DDLExportConfiguration.defaultSequenceFlags
#9584 - Add Source.readString()
#9588 - Use H2's native BITNOT()
#9589 - Use H2's native LSHIFT() and RSHIFT()
#9591 - Let DefaultRecordContext and DefaultExecuteContext extend AbstractScope
#9595 - Regenerate HSQLDB information schema against 2.5.0
#9600 - Add code generation flag
#9603 - Add sequence flag support on jooq-meta.xsd
#9604 - Implement a default OrderProvider in the code generator
#9610 - Add code generation support for Derby indexes
#9611 - Add code generation support for Informix indexes
#9612 - Document JSON and JSONB NULL semantics
#9613 - Update Configuration Javadoc
#9614 - Clarify that SQL Data Warehouse = Azure Synapse Analytics
#9616 - Support parsing ALTER TABLE .. ADD, .. ADD
#9624 - Add a DiffCLI command line tool
#9629 - Add new flag to allow for turning off sequence flag generation
#9630 - Add more ErrorProne and Refaster checks / refactorings
#9633 - Add a new Settings.interpreterNameLookupCaseSensitivity
#9636 - Add Settings.locale() as a default for renderLocale() and other locales
#9646 - Document
#9651 - Support parsing // as a single line comment token
#9657 - Publish 3.12 snapshots on website
#9660 - Update dependency to Derby 10.15
#9661 - Support parsing MySQL's unnamed constraint syntax
#9667 - Ignore changes to sun-jaxb.episode files
#9668 - Offer Java 11 and 6 trial downloads from website
#9669 - Move xjb files out of artifacts
#9670 - Make slf4j-api version backwards compatible to OSGi consumers
#9672 - Add new ConstraintDefinition type
#9675 - Postgres: Support MD5() function
#9677 - Add Settings.interpreterSearchPath
#9681 - Synchronize @Support annotations on MergeUsingStep#columns() methods
#9682 - Add SQLDialect.SQLITE_3_30
#9692 - Add InsertQuery.setSelect(Collection, Select) overload
#9696 - Add a new flag
#9698 - How to alter a table to add a column of Enum/Set type in MySQL.
#9700 - Sakila/PostgreSQL: Don't fail if language plpgsql already exists
#9703 - Document the requirement of matching versions between code generator and runtime library
#9719 - Support MySQL ISNULL() function in the parser
#9727 - Add configuration/basedir to resolve relative paths in code generator
#9733 - Add and
#9734 - Add and
#9741 - Add org.jooq.Period for temporal validity
#9747 - JSON and JSONB should implement Serializable
#9762 - Add support for DB2 SET SCHEMA command
#9772 - Add SQLDialect.MYSQL_8_0_19
#9776 - Add support for MySQL 8.0.19 VALUES clause
#9777 - Add SQLDialect.supportedUntil()
#9778 - Support NULLS [ FIRST | LAST ] in SQLite 3.30
#9779 - Add native support for aggregate and window function FILTER clause in SQLite 3.30
#9780 - Add Settings.parseSetCommands
#9781 - Add DSLContext.set(Name, Param>) for arbitrary set commands
#9790 - Add internal functional interfaces F0, F1, F2
#9796 - Generated annotation should produce HTTPS link to jOOQ website
#9799 - Make TableOptions available through code generation
#9800 - Make TableOptions available through org.jooq.Meta
#9801 - Make TableOptions available through InformationSchema
#9805 - Generate view source code with generated views
#9806 - Add Batch.executeAsync() methods
#9807 - Apply Configuration.onError flag also to SQL errors from AbstractDatabase
#9808 - Add JooqLogger.log(Level) overloads
#9811 - Document that CustomRecord subclasses need a no-arg constructor
#9816 - Add Definition.getSource()
#9819 - Add support for INFORMATION_SCHEMA.VIEWS in jooq-meta.xsd
#9822 - Firebird support for ALTER TABLE ... ALTER ... [ DROP | SET ] NOT NULL
#9827 - Remove SQL 2 jOOQ section from the manual
Breaking changes
----------------
#4934 - Delay query execution until a Stream terminal op is called
#5714 - Change default value to "true"
#9031 - Remove unnecessary AlterSequenceRestartStep
#9235 - Remove checked exceptions from LoaderSourceStep methods
#9237 - Remove checked exceptions from MockFileDatabaseConfiguration::source methods
#9241 - Change to default to false
#9283 - DefaultBinding should return null on null JSON values, instead of JSON[B].valueOf(null)
#9365 - Support H2's standard LOG() function
#9470 - FilePatter.Loader should accept Source, instead of InputStream
#9479 - Remove internal, deprecated DefaultConfiguration constructors
#9596 - Regenerate MySQL information schema against 8.0.18
#9601 - Add code generation flag
#9725 - Move org.jooq.meta.tools.FilePattern API to core library
#9732 - Change default value of to "false"
#9737 - Wrong generics on DSLContext.selectFrom(Name) and similar methods
#9758 - Generated constraint names should not be table prefixed in meta data in DB2 and PostgreSQL
Bug Fixes
---------
#2967 - Impossible to inline "decimals" parameter of ROUND() function
#4856 - UNION generates bad SQL for MySQL, when UNION subqueries contain duplicate column names from JOIN operations
#6497 - Add LocalDateAsLocalDateTimeBinding to make and work together
#7377 - When using org.jooq.Meta, UniqueKey.getReferences throws NPE in Firebird
#7962 - ORA-04043 on INSERT when using qualified, quoted table name and fetching generated keys
#8335 - DDLDatabase loads too many files when using relative path
#8508 - Fix Javadoc warnings
#8555 - Parser cannot handle enum literals that are invalid java identifiers
#8580 - LikeEscapeStep#escape() also supported by Teradata
#8677 - Log warning when file based databases have invalid configurations
#8721 - Enum type with '-' character does not compile
#8824 - DDLDatabase can not handle multiple constraints with the same name
#8966 - Invalid SQL rendered for recursive query
#8967 - Generator outputs duplicate method (not compilable)
#8968 - An exception in ExecuteListener#start is not routed to ExecuteListener#exception
#8991 - DSL.field(Name) fields should support schema mapping
#9099 - Cannot build Javadoc in jOOQ-checker under Java 11
#9100 - Fix Javadoc links starting from jOOQ 3.12, which is built with JDK 11
#9104 - JooQ 3.12.0 codegen fails with an incorrect query where 3.11 worked correctly (PostgreSQL)
#9110 - Wrong SQL generated by DSL.countDistinct() without arguments
#9111 - Allow parsing of COUNT(DISTINCT )
#9121 - Generator does not report file in which invalid SQL was found
#9122 - java 8+ distribution of 3.12.0 broken
#9133 - 404s on /latest Javadoc
#9134 - Wrong rendering of [ FROM { FIRST | LAST } ] clause for NTH_VALUE()
#9140 - Translation of USE command should result in SET SCHEMA command in dialects that do not support catalogs
#9144 - ParserCLI "-f" flag does not work as shortcut for "--from-dialect"
#9145 - Manual page about ParserCLI misses reactive-streams in classpath
#9146 - ParserCLI --from-dialect is not case insensitive
#9147 - ParserCLI -h parameter throws a RuntimeException
#9150 - Compilation error in generated code when Oracle OBJECT type contains index_of(varchar2) member procedure
#9157 - Prevent "Illegal reflective access operation" warning in jOOQ Open Source Edition
#9158 - Review and fix a few formatting issues in the manual
#9165 - Quantified LIKE predicate (LIKE ANY) is not documented correctly
#9177 - H2: SelectLimitPercentStep#percent() not working properly
#9187 - Bad parenthesis in UNION under HSQLDB
#9193 - Consecutive RenderContext.formatSeparator() calls ignored when formatIndentStart() is called in between
#9196 - Only first value added to date time appears in rendered SQL
#9201 - Negative intervals not rendered properly for PostgreSQL
#9205 - Fix DefaultYearToMonthBinding and DefaultYearToSecondBinding for Aurora Postgres
#9214 - SQLDialect.MEMSQL lacks Pro annotation
#9219 - Regression in Extract(QUARTER) on Postgres in 3.12.1
#9223 - MySQL: Support date parts MICROSECOND and WEEK
#9224 - Regression for "= ANY(?::int[])" no longer produces array bind variable
#9225 - Postgres: FILTER clause no longer rendered
#9231 - Wrong Javadoc on org.jooq.Source
#9242 - AbstractKey#equals() assumes name is unique
#9248 - Regression: DSLContext#nextval() broken for H2
#9250 - LEFT [ ANTI | SEMI ] JOIN ... USING not implemented
#9251 - H2's WITH TIES support broken in OSS edition
#9266 - Consistently document all commercial SQLDialects
#9274 - AttributeConverterExtractor should receive custom Hibernate configuration properties
#9277 - Improve error message when AttributeConverters cannot be loaded due to NoClassDefFoundError
#9291 - Sequences are generated as tables in MariaDB
#9296 - withRenderSchema(false) does render schema in order by clause
#9311 - Incomplete @Support annotations on UpdateQuery.addValues(Row[N], Select)
#9315 - Remove unnecessary generic type variable on CreateSchemaImpl
#9324 - Name.append(Name) should not produce a QualifiedName when one of the parts is empty
#9331 - Postgres 12 exception in code generation output: "column c.consrc does not exist"
#9338 - Parse ignore comments not parsed correctly if stop comment is last token of file, prior to a newline
#9343 - Wrong SQL generation for PostgreSQL function calls having arguments with custom data types.
#9355 - LoggingConnection does not log static statements
#9368 - Outdated comment in manual about H2 supporting window functions
#9386 - RenderMapping is not applied to DSL.schema(Name)
#9389 - CREATE INDEX commands created from DSLContext.ddl() based on Meta contain illegal WHERE clause
#9411 - Firebird generated code contains "DEFAULT" keyword in default expressions
#9414 - Unable to create index with qualified index name on Oracle dialect
#9415 - Emulate RETURNING * in Firebird
#9418 - Regression in Firebird's SUBSTRING() implementation
#9420 - Incorrect emulation of unnamed indexes
#9424 - Add line breaks to a few parser grammar diagrams
#9443 - Regression in Sybase ASE source code generation: Cannot generate tables
#9457 - UDT.getQualifiedName() doesn't return schema qualification for generated tables
#9461 - Missing @PlainSQL annotation on some DSLContext#batch() methods
#9462 - Missing @Support annotations on BatchBindStep methods
#9463 - Add missing @Support annotations to methods of LoaderSourceStep
#9468 - SQLDialect.ASE cannot be used with a MockConnection
#9471 - JDBCDatabase does not order objects alphabetically
#9473 - Creating tables using DSLContext.ddl() converts VARBINARY columns to TEXT in MySQL
#9480 - CREATE SEQUENCE implementation should reuse Sequence.getDataType() in various flags
#9493 - JoinStep#crossApply() throws IllegalArgumentException
#9497 - NullPointerException when calling methods on DAO that is not attached to a Configuration
#9498 - DDLDatabase: Flyway's repatable migrations are executed to early
#9513 - Oracle: PIVOT ... FOR always rendered as quoted
#9516 - Cannot use MERGE .. DELETE WHERE without UPDATE WHERE
#9528 - Some ConstraintForeignKeyReferencesStep.references() methods are missing Support annotations
#9531 - Open Source version references dual license
#9545 - Parser cannot parse views with WITH
#9547 - Query ALL_MVIEWS instead of ALL_MVIEW_COMMENTS in Oracle
#9551 - Bad code generated when using SQL Server user defined types
#9567 - Cosmetic exceptions caused by JPADatabase when using attribute converters
#9571 - Multi column ALTER TABLE .. ADD statement shouldn't qualify column names
#9582 - Generator's does not prevent the generation of Indexes.java
#9597 - DefaultRelations#getCheckConstraints() returns all checks on first call
#9598 - Static class initialisation deadlock race between DefaultDSLContext.java:388 and DefaultDSLContext.java:505
#9620 - No DiagnosticsListener.missingWasNullCall() when nullability is unknown
#9621 - NullPointerException in DefaultRecordMapperProvider when setting a new instance to a Configuration
#9648 - ArrayIndexOutOfBoundsException if query has a single or double quote char in vendor specific comment
#9653 - Meta.ddl() loses Schema and Constraint Name.quoted() information
#9658 - Parser settings repeat available flag documentation
#9659 - Missing documentation for Settings.inListPadBase
#9664 - Parser should reject duplicate identities
#9671 - Fixes #9670 to make jooq OSGi backwards compatible for slf4j and also…
#9674 - Bad SQL generated from implicit join from within subqueries
#9685 - Generate.globalTableReferences should not impact what is returned by Schema#getTables()
#9690 - All links in FAQ are broken
#9697 - Full identifier qualification in generated code when is turned off
#9708 - Mapping schema with RegEx generates invalid output name after upgrade to 3.12
#9718 - Wrong type returned by LoaderCSVStep#fields(LoaderFieldMapper)
#9726 - FilePattern matches too many files when wildcards are being used
#9751 - MySQL 5.7: Invalid SQL for set operations in subqueries
#9756 - Regression in IGNORE NULLS clause for DB2
#9782 - Add missing @Support annotation to PivotForStep#for_(Field)
#9791 - Meta.getTables() returns the same table for each catalog in SQL Server
#9792 - Meta doesn't produce correct data type in SQL Server for identity columns
#9793 - BLOB SUBTYPE not supported in dialect FIREBIRD when using plain SQL
#9797 - XMLDatabase cannot read INT type
#9823 - WITH TIES emulation not used for FIREBIRD dialect
#9824 - Informix check constraint and view generated SQL code is not trimmed
Version 3.12.0 - August 29, 2019
================================================================================
In this release, we've focused on a lot of minor infrastructure tasks, greatly
improving the overall quality of jOOQ. We've reworked some of our automated
integration tests, which has helped us fix a big number of not yet discovered
issues, including a much better coverage of our 26 supported RDBMS dialects.
We're excited about these internal changes, as they will help us implement a lot
of features that have been requested by many for a long time, including an
immutable query object model, with all the secondary benefits like caching of
generated SQL, and much more powerful dynamic SQL construction and
transformation in the future.
Major new features include the new procedural language API shipped with our
commercial distributions, new data types including native JSON support, MemSQL
support, formal Java 11+ support, a much better parser, and reactive stream API
support.
Procedural languages
--------------------
Following up on jOOQ 3.11's support for anonymous blocks, the jOOQ 3.12
Professional and Enterprise Editions now include support for a variety of
procedural language features, including
- Variable declarations
- Variable assignments
- Loops (WHILE, REPEAT, FOR, LOOP)
- If Then Else
- Labels
- Exit, Continue, Goto
- Execute
This feature set is part of our ongoing efforts to continue supporting more
advanced vendor specific functionality, including our planned definition and
translation of stored procedures, triggers, and other, ad-hoc procedural logic
that helps move data processing logic into the database server.
New Databases Supported
-----------------------
The jOOQ Professional Edition now supports the MemSQL dialect. MemSQL is derived
from MySQL, although our integration tests have shown that there are numerous
differences, such that supporting MemSQL formally will add a lot of value to our
customers by providing much increased syntactic correctness.
Reactive streams
----------------
The reactive programming model is gaining traction in some environments as new,
useful streaming APIs emerge, such as e.g. Reactor. These APIs have agreed to
work with a common SPI: reactive streams, and since JDK 9 the new
java.util.concurrent.Flow SPI. jOOQ 3.12 now implements these paradigms on an
API level, such that an integration with APIs like Reactor becomes much more
easy. The implementation still binds to JDBC, and is thus blocking. Future
versions of jOOQ will abstract over JDBC to allow for running queries against
ADBA (by Oracle) or R2DBC (by Spring)
New data types
--------------
We've introduced native support for a few new data types, which are often very
useful in specific situations. These include:
- JSON / JSONB: A native string wrapper for textual and binary JSON data. While
users will still want to bind more specific JSON to maps and lists using
custom data type Bindings, in a lot of cases, being able to just serialise and
deserialise JSON content as strings is sufficient. jOOQ now provides out of
the box support for this approach for various SQL dialects.
- INSTANT: RDBMS do not agree on the meaning of the SQL standard TIMESTAMP WITH
TIME ZONE. PostgreSQL, for example, interprets it as a unix timestamp, just
like java.time.Instant. For an optimal PostgreSQL experience, this new INSTANT
type will be much more useful than the standard JDBC java.time.OffsetDateTime
binding.
- ROWID: Most RDBMS have a native ROWID / OID / CTID / physloc identity
value that physically identifies a row on the underlying storage system,
irrespective of any logical primary key. These ROWIDs can be leveraged to run
more performant, vendor specific queries. Supporting this type allows for
easily using this feature in arbitrary queries.
Parser
------
Our parser is seeing a lot of continued improvements over the releases as we
gather feedback from our users. Our main drivers for feedback are:
- The DDLDatabase which allows for generating code from DDL scripts rather than
live JDBC connections to your database
- The https://www.jooq.org/translate website, which translates any kind of SQL
between database dialects.
SQL dialect translation will evolve into an independent product in the future.
DDL parsing is already very powerful, and a lot of customers rely on it for
their production systems.
In the next versions, we will be able to simulate DDL on our own, without H2,
which will open up a variety of possible use cases, including better schema
management.
Specific jOOQ 3.12 parser improvements include:
- Being able to access schema meta information (column types, constraints) to
better emulate SQL features / translate SQL syntax between dialects
- A parse search path, similar to PostgreSQL's search_path, or other dialects'
current_schema, allowing support for unqualified object references.
- The DDL simulation from the DDLDatabase is now moved into the core library,
supporting it also out of the box as a DDL script based meta data source
- A new special comment syntax that helps ignoring SQL fragments in the jOOQ
parser only, while executing it in your ordinary SQL execution.
- A new interactive mode in the ParserCLI
- Support for nested block comments
- And much more
Formal Java 11 Support
----------------------
While we have been supporting Java 11 for a while through our integration tests,
jOOQ 3.12 now fully supports Java 11 to help improve the experience around the
transitive JAXB dependency, which we now removed entirely out of jOOQ.
The commercial editions ship with a Java 11+ supporting distribution, which
includes more optimal API usage, depending on new Java 9-11 APIs. All editions,
including the jOOQ Open Source Edition, have a Java 8+ distribution that
supports any Java version starting from Java 8.
Commercial Editions
-------------------
Dual licensing is at the core of our business, helping us to provide continued
value to our customers.
In the past, the main distinction between the different jOOQ editions was the
number of database products each edition supported. In the future, we want to
provide even more value to our customers with commercial subscriptions. This is
why, starting from jOOQ 3.12, we are now offering some new, advanced features
only in our commercial distributions. Such features include:
- The procedural language API, which is available with the jOOQ Professional
and Enterprise Editions
- While the jOOQ 3.12 Open Source Edition supports Java 8+, the jOOQ 3.12
Professional Edition also ships with a Java 11+ distribution, leveraging some
newer JDK APIs, and the jOOQ 3.12 Enterprise Edition continues supporting
Java 6 and 7.
- Since Java 8 still sees very substantial market adoption, compared to Java 11,
we still support Java 8 in the jOOQ 3.12 Open Source Edition.
- Starting from jOOQ 3.12, formal support for older RDBMS dialect versions in
the runtime libraries is reserved to the jOOQ Professional and Enterprise
Editions. The jOOQ Open Source Edition will ship with support for the latest
version of an RDBMS dialect, only. The code generator is not affected by this
change.
By offering more value to our paying customers, we believe that we can continue
our successful business model, which in turn allows us to continue the free
jOOQ Open Source Edition for free. Our strategy is:
- To implement new, advanced, commercial only features.
- To offer legacy support (legacy Java versions, legacy database versions) to
paying customers only.
- To continue supporting a rich set of features to Open Source Edition users.
H2 and SQLite integration
-------------------------
Over the past year, both H2 and SQLite have seen a lot of improvements, which we
have now supported in jOOQ as well. Specifically, H2 is moving at a very fast
pace, and our traditional close cooperation got even better as we're helping
the H2 team with our insights into the SQL standards, while the H2 team is
helping us with our own implementations.
Other improvements
------------------
The complete list of changes can be found on our website:
https://www.jooq.org/notes
A few improvements are worth summarising here explicitly
- We've added support for a few new SQL predicates, such as the standard
UNIQUE and SIMILAR TO predicates, as well as the synthetic, but very useful
LIKE ANY predicate.
- The JAXB implementation dependency has been removed and replaced by our own
simplified implementation for a better Java 9+ experience.
- The historic log4j (1.x) dependency has been removed. We're now logging only
via the optional slf4j dependency (which supports log4j bridges), or
java.util.logging, if slf4j cannot be found on the classpath.
- The shaded jOOR dependency has been upgraded to 0.9.12.
- We've greatly improved our @Support annotation usage for better use with
jOOQ-checker.
- jOOQ-checker can now run with ErrorProne as well as with the checker framework
as the latter still does not support Java 9+.
- We've added support for a lot of new DDL statements and clauses.
- There is now a synthetic PRODUCT() aggregate and window function.
- We added support for the very useful window functions GROUPS mode.
- Formatting CSV, JSON, XML now supports nested formatting.
- UPDATE / DELETE statements now support (and emulate) ORDER BY and LIMIT.
- When constructing advanced code generation configuration, users had to resort
to using programmatic configuration. It is now possible to use SQL statements
to dynamically construct regular expression matching tables, columns, etc.
- Configuration has a new UnwrapperProvider SPI.
- MockFileDatabase can now handle regular expressions and update statements.
- Settings can cleanly separate the configuration of name case and quotation.
- MySQL DDL character sets are now supported, just like collations.
- A new Table.where() API simplifies the construction of simple derived tables.
This feature will be very useful in the future, for improved row level
security support.
- A nice BigQuery and H2 feature is the "* EXCEPT (...)" syntax, which allows
for removing columns from an asterisked expression. We now have
Asterisk.except() and QualifiedAsterisk.except().
- A lot of improvements in date time arithmetic were added, including support
for vendor specific DateParts, like WEEK.
API Diff:
---------
See what's changed in terms of an API diff here:
https://www.jooq.org/api-diff/3.11-3.12
Features and Improvements
-------------------------
#714 - Add support for non-standard ORDER BY .. LIMIT clauses in UPDATE, DELETE statements
#1699 - Add support for the SQL standard UNIQUE predicate
#1725 - Add support for SQL standard SIMILAR TO predicate
#2026 - Add a new @Internal annotation to annotate API parts that are not supposed to be used
#2059 - Add support for the MemSQL database for the jOOQ Professional Edition
#2132 - Add support for non-standard date-time fields in the EXTRACT() function
#2208 - Implement a MockFileDatabase
#2233 - Add Result> DSLContext.fetchFromXML() to allow for loading results that were exported using Result.formatXML()
#2731 - Add some sections to the manual helping users migrate from other popular ORMs
#3606 - Emulate INSERT/UPDATE/DELETE (SELECT ...) by WITH v AS (SELECT ...) INSERT/UPDATE/DELETE v on SQL Server
#3607 - Allow for emitting common table expression declarations to RenderContext
#4371 - Let ResultQuery extend Publisher
#4473 - Add ResultQuery.coerce(Field>[]), coerce(Table), that coerce a new Record type on a ResultQuery
#4498 - Emulate INSERT .. RETURNING via SQL Server OUTPUT clause
#5110 - Add support for Derby's MERGE statement
#5576 - Add support for SQLite 3.15's row value expression support
#5601 - IN list padding setting should also apply to row IN predicates
#5640 - MockFileDatabase should support all jOOQ import formats, including JSON, XML
#5700 - Add support for Oracle's STATS_MODE() aggregate function
#5781 - Add support for ALTER TABLE .. RENAME COLUMN in MySQL 8
#5895 - Add support for TIME[STAMP] WITH TIME ZONE in HSQLDB
#5899 - jOOQ-checker should provide both checker-framework and ErrorProne checks
#5909 - Deprecate RenderNameStyle.QUOTED and replace feature by renderQuotedNames
#5939 - Add PRODUCT() aggregate and window function
#5966 - Add support for NATURAL FULL [ OUTER ] JOIN
#5969 - Add to code generator configuration to allow for hiding Oracle's and H2's INVISIBLE columns
#6234 - Add newline configuration to code generator
#6260 - Support loading multiple files in XMLDatabase
#6450 - Javadoc should reference JDK 11 Javadoc
#6475 - Add procedural language abstraction API
#6486 - Add a JDK 11 build
#6548 - Support multiple external configuration files through
#6583 - Work around MySQL's self-reference-in-DML-subquery restriction
#6709 - Support custom Hibernate properties in JPADatabase
#6778 - Support parsing PostgreSQL's dollar quoted string constants
#6944 - Add a way to specify what object type a should match
#6971 - Allow Maven plugin to succeed in absence of valid DB connection if schema is up to date
#7005 - Add support for MariaDB INTERSECT and EXCEPT
#7048 - Document the FILTER clause
#7143 - Support merging external into Maven configuration
#7153 - Allow for configuring a locale to be used for upper/lower casing inside of jOOQ
#7163 - Add Settings.parseWithMetaLookups
#7216 - Add RecordN fetchSingle(Field, ..., Field)
#7235 - DDLDatabase fails with ParserException on JSON field
#7268 - Add support for MySQL's UNIQUE [ index_name ] syntax
#7297 - Support deriving a WindowDefinition from another WindowDefinition
#7305 - Add support for DECLARE statements inside of statement blocks
#7306 - Add support for the SET command to assign values to variables
#7331 - Add reference to configuration in DataType, Converter, Binding
#7336 - Add new flags to Settings to govern parser behaviour
#7337 - Add Settings.parseDialect
#7361 - Improve formatting of nested joins
#7397 - Add a section to the manual about SELECT *
#7426 - Add support for Teradata QUALIFY
#7445 - Support parsing PostgreSQL-specific interval literals
#7470 - Add indexOf() methods to all TableLike types
#7485 - Document jOOQ's auto-conversion utility
#7490 - Upgrade jOOQ-meta-extensions dependency to Hibernate 5.4
#7545 - ForcedType configurations should have include / exclude expressions
#7570 - Add support for CREATE TYPE .. AS ENUM
#7587 - Use --release flag in JDK 9+ based builds
#7591 - Add new ResourceManagingScope which allows for Binding implementations to register resources which are freed after execution
#7595 - Add support for Java 11
#7598 - Add search box to Javadocs
#7599 - Print row count in LoggerListener for ResultQuery
#7602 - Upgrade jOOR dependency's Java 9 functionality
#7609 - Add Setting to turn off ORDER BY clause in emulated OFFSET .. FETCH pagination
#7612 - Add configuration to DDLDatabase to indicate whether unquoted names are reported in lower case, upper case or as-is
#7619 - Don't ship old XSDs in binaries
#7628 - Add support for PostgreSQL 11
#7633 - ALTER TABLE .. ADD FOREIGN KEY .. REFERENCES references unqualified table name
#7646 - Support for window functions GROUPS mode
#7647 - Support window function EXCLUDE clause
#7678 - Mention more ways to inline parameters in manual
#7705 - Add support for PostgreSQL FOR NO KEY UPDATE and FOR KEY SHARE
#7712 - Add support for Catalogs in JDBCDatabase
#7719 - Add code generation flag to treat MySQL TINYINT(1) as BOOLEAN
#7727 - Support parsing DEGREES() as a synonym for DEGREE() and DEG(), and RADIANS() for RADIAN(), RAD()
#7734 - Make the JAXB implementation dependency optional with a custom fallback implementation
#7748 - Add support for CREATE SEQUENCE flags
#7749 - Support parsing CREATE INDEX .. ON .. USING btree (..)
#7751 - Add support for ALTER TABLE ONLY
#7755 - Add an integration test to discover all DSL API that is not covered by the parser
#7756 - Improve SQLite repeat() emulation
#7757 - Improve SQLite LPAD() and RPAD() emulation
#7759 - Add DDLDatabase property unqualifiedSchema to specify what the unqualifiedSchema is
#7760 - Upgrade SybDriver version in JDBCUtils.driver(String)
#7774 - Add support for DROP TYPE
#7776 - Add support for parsing custom data types
#7782 - Record.formatJSON() should format nested records recursively
#7788 - Support Java 6 and 7 only in Enterprise Edition
#7792 - Support DatePart.DAY_OF_WEEK and DatePart.ISO_DAY_OF_WEEK
#7793 - Support DatePart.DAY_OF_YEAR
#7794 - Support DatePart.EPOCH
#7796 - Support DatePart.QUARTER
#7799 - jOOQ manual about Gradle code generation should not make explicit use of JAXB
#7800 - Let Record extend Formattable
#7801 - Record.formatXML() should format nested records recursively
#7802 - Record.formatCSV() should format nested records recursively
#7809 - Generate overridden Table.fieldsRow() method in generated tables
#7810 - Add DSL.rowField(RowN)
#7839 - Emulate { UPDATE | DELETE } ORDER BY and LIMIT
#7856 - Upgrade maven-scala-plugin to scala-maven-plugin
#7862 - Add SQLDialect.ORACLE18C
#7865 - Add support for SQLite window functions
#7866 - Add support for SQLite ALTER TABLE .. RENAME COLUMN
#7870 - Add support for Java 11
#7872 - Add support for HSQLDB EXPLAIN PLAN FOR
#7873 - Add HSQLDB support for Sequence.currval()
#7882 - Add Field.startsWithIgnoreCase() and Field.endsWithIgnoreCase()
#7885 - Add Table.rowid()
#7902 - Add parser support for negative numeric scales
#7904 - Apply optimistic locking logic also for non-updatable TableRecords on insert()
#7905 - Add a new org.jooq.RowId type that corresponds to java.sql.RowId
#7906 - Add support for H2 window functions
#7907 - Support parsing vendor-specific RESPECT NULLS / IGNORE NULLS syntax
#7909 - ExecuteContext.sqlException(SQLException) should accept null
#7913 - Add support for H2 standard MERGE statement
#7914 - Overload fetchXYZ(T, Collection extends Condition>) and fetchXYZ(T, Condition...)
#7915 - Add Query.poolable(boolean) to govern the JDBC Statement.setPoolable() behaviour
#7921 - Add support for Asterisk.except(Field...) and QualifiedAsterisk.except(Field...)
#7922 - Upgrade org.checkerframework:checker dependency in jOOQ-checker
#7924 - Add a CompileOptions argument object to pass annotation processors and other things to Reflect.compile()
#7947 - Let code generation patterns match also partially qualified object names
#7948 - Use the new H2 1.4.198 INFORMATION_SCHEMA.COLUMNS.IS_VISIBLE column
#7952 - Add SQLDataType.INSTANT
#7954 - Document in Javadoc that JDBCUtils.dialect() and similar methods return DEFAULT, not null
#7956 - Deprecate DSL.groupConcat(Field>, String)
#7966 - Add Setting to turn off fetching generated keys from UpdatableRecord
#7971 - Add delegation support to JDBC 4.3 methods in DefaultConnection and similar types
#7974 - Add Reflect.initValue(Class)
#7999 - Overload AbstractTable.createField(Name, ...) methods
#8000 - Deprecate AbstractTable.createField(String, ...) methods
#8001 - Overload all date time arithmetic API with Instant arguments
#8004 - Handle edgecase with Kotlin boolean types
#8005 - Improve the manual's section about serializability to disclaim any backwards compatible format
#8010 - Add Table.where(Condition) and overloads
#8022 - Support passing java.util.Date as a Field