-
Notifications
You must be signed in to change notification settings - Fork 1
fix: PLSQL batch LOB handling #110
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
fix: PLSQL batch LOB handling #110
Conversation
| func isJSONField(f *schema.Field) bool { | ||
| // Support detecting JSON fields through the struct's "type" tag. | ||
| // Also support jsonb for compatibility with other databases. | ||
| if f.DataType == "json" || f.DataType == "jsonb" { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would you mind explaining a bit more about the use case for supporting "jsonb" here? I’d like to better understand the context.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We're not really "supporting it" with this condition per se, it's more that we're allowing fields which have the "type" gorm struct tag set to "jsonb" to be interpreted as a field containing JSON.
This is useful if you've got a gorm struct which has been using jsonb for a field in, say, Postgres and wants to use the same struct for Oracle. Both JSON and JSONB Postgres datatypes map to JSON in Oracle, so this behavior reflects that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Got it. Thanks for clarifying!
|
Thank you for taking the time to work on this fix; it’s a complex issue, and I agree that the frontloading approach is the better way to address it. Overall, it looks good to me. I’ll wait for @aarrasseayoub01’s feedback before merging. |
Thanks for reviewing! Happy to chat about any of the proposed additions. Some of the behavior was not obvious (to me, at least), but I've tried to document it. |
aarrasseayoub01
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks great! It does seem that the best way to handle LOB bulk inserts is through PLSQL. And thank you for taking the time to add what was missing in the PLSQL merge code path
Description
Inserting strings or byte arrays which exceed the builtin character limit for PLSQL VARCHAR2 variables causes failures. #102 fixes this issue for single inserts/merges. However, in batch inserts where some VARCHAR2 variables have been converted to LOBs and some have not, the subsequent UNION or RETURNING operations will fail due to inconsistent types.
This change was complicated to fix. Ultimately, it feels like the best thing to do in these scenarios is handle all LOB bulk inserts through PLSQL, where we have the ability to cast input/output as LOB types consistently across an entire column. In order to do that, we have to frontload the real type determination before choosing the code branch. I have attempted to do that in a way that only traverses and casts the createValues object once for efficiency. It will be a net efficiency loss for inserts/merges which do not end up needing PLSQL, though.
As part of testing this change, we found many other deficiencies in the PLSQL merge code path. For example, detecting conflict columns containing a primary key, as well as supporting JSON, UUIDs, boolean, and custom Valuer types in PLSQL. This PR fixes those cases and adds tests for those situations as well.
Type of change
How Has This Been Tested?
Numerous unit tests have been added which would fail without the proposed fixes.
Checklist: