New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for SQL:2011 temporal validity #4704
Comments
Incredibly interested in this feature. I'm currently working on an application backed by Postgres in which virtually all the data is either completely immutable or bitemporal. It has actually been fairly painless using JOOQ compared to previous experience using ORMs on top of bitemporal schemas. We are using Joda time's Intervals in Java (Scala) and Postgresl's range types inside the database which seem to work together perfectly. A couple questions on your approach,
Should add, thank you for a fantastic product! |
I'd love to learn more about that. Did you intend to write a blog post somewhere, about your experience? That would be very useful!
In principle, the only valid system version is the latest one (highest timestamp, or sequence number). Deletes would need to be tracked with an additional value, indeed. The reason why I wanted to use this single timestamp / sequence number is because we already have such synthetic columns for optimistic locking. It would be good to reuse existing functionality here.
Yes, this isn't completely specified yet. If the additional value was a boolean (called "versioned" in the feature request text) indicating whether the record is active (and there can be only one active record per primary key), then there's no problem to find the latest version very quickly. An entirely different option for system versioning would be to use a secondary table of the same row type. Ultimately, we don't want to enforce one or the other model. Which is why this will be a rather complex feature to implement.
I've had the same thoughts. SQL:2011 implementations also use the transaction time (see again the linked document)
Thank you :) |
No blog post yet. Hopefully once we get into production and things calm down a little bit (is that ever how it actually works?). One last question about your proposed design.
It seems like this is going to require two additional fields.
If I'm understanding that correctly and you do need the timestamp, I'm not sure the current column adds additional value. |
@mfoody: Sorry for the delay. You may well be right, I cannot tell yet. We do want to implement this for jOOQ 3.8, but we haven't thought this through yet. It might just be a bit too early to discuss all the details fo the proposal. |
Not realistic for jOOQ 3.8 |
The full scope of this feature will be reviewed again in jOOQ 3.14, but parts might already be in scope for 3.13, specifically #9741. |
Basic API support mapping to native implementations has been added for 3.13 through #9741. This includes:
|
SQL:2011 standardised on bitemporal validity, which is an important topic in many areas where data needs to be historised in two ways:
A good paper from IBM illustrates these parts of the SQL:2011 standard:
http://www.sigmod.org/publications/sigmod-record/1209/pdfs/07.industry.kulkarni.pdf
Few databases support these features natively, and if they do (DB2, Oracle, SQL Server), they ship with a vendor-specific syntax.
jOOQ should support all of those syntaxes (Oracle flashback query is already supported) and go beyond by providing emulations for these features:
System versioning (technical)
An additional
INTEGER
orTIMESTAMP
column per table can be used for versioning, similar to the existing optimistic locking versioning scheme in jOOQ. Such columns will be configured in the source code generator and marked specifically in generated code. An additionalBOOLEAN
"versioned" column might be added too, to simplify identifying the current version of each row.Impact on queries:
SELECT
statements must ensure that only the latest version of a row is fetched, unless previous versions are explicitly asked for usingAS OF
on theorg.jooq.Table
INSERT
statements remain unchangedUPDATE
statements will execute as:UPDATE
the existing records, mark them as "versioned"INSERT .. SELECT
the existing records in order to duplicate themUPDATE
on the duplicated rowsDELETE
statements will execute as:UPDATE
the existing records, mark them as "versioned"MERGE
and other forms ofUPSERT
are not supportedSemantic versioning
An additional
DATE
orTIMESTAMP
range column per table can be used for semantic versioning to specify the validity of a row during a range. Such columns will be configured in the source code generator and marked specifically in generated code. It is assumed that ranges must not overlap for the same primary key. Typically, the primary key will include anID
and the range'sFROM
date.Impact on queries:
SELECT
statements usually fetch all the ranges, unless a specific period filtering predicate was appliedINSERT
statements must ensure that no periods overlap. If an insert is made for a period that overlaps with an existing period, the existing period isUPDATE
statements remain unchanged, unless an explicitFOR PORTION OF
clause is issued, in case of which theUPDATE
statement translates to individualINSERT
statements for each overlapping periodDELETE
statements remain unchanged, unless an explicitFOR PORTION OF
clause is issued, in case of which theDELETE
statement translates to anINSERT
statement for that specific portion and then deletes it again.MERGE
and other forms ofUPSERT
are not supportedAlternative implementations are possible too
In all cases, technical versioning may apply in addition to semantic versioning
Impact on
UpdatableRecord
In addition to transforming individual DML statements for explicit use, it will be very useful to have additional generated
store()
,insert()
,update()
,delete()
methods onUpdatableRecord
, which helps executing temporal DML directly on a CRUD level. The semantics of this change yet needs to be defined.Tasks
A number of improvements need to be made in order to accomplish this feature. These will be listed here, and possibly, extracted to new issues:
org.jooq.Period
, allowing both system versioning and application versioning (see Add org.jooq.Period for temporal validity #9741)CREATE TABLE
andALTER TABLE
statementsMeta
supportInformationSchema
supportSELECT .. FROM
clause support for all clauses, includingAS OF
(already existing Oracle flashback query support), andAS OF PERIOD FOR
(see Add org.jooq.Period for temporal validity #9741)FOR PORTION OF
and other clauses(no dialect implements these yet, but emulation is certainly possible), as implemented e.g. in MariaDB (see Add org.jooq.Period for temporal validity #9741)MERGE
statement support (see Add support for temporal validity in MERGE #9789)See also
The text was updated successfully, but these errors were encountered: