Repository navigation
Bind a property's texts beside a long operand on Oracle, so a text past 32 KB a text function or a sum reads beside one leaves the session open - #255
Merged
Conversation
…st 32 KB a text function or a sum reads beside one leaves the session open Port of liberation-data/drivine4j#370 (drivine4j PR #387, squash commit 8d6e12c4). A text function or `+` over a property and an operand whose SQL is long had its operands bound by shared() in a NO_MERGE subquery: the property as JSON, read as a CLOB from that, so drivine4j#255's direct read never applied. On Oracle a text past 32 KB read so closed the session from the second run on, given two rows or more (ORA-03113). - Oracle's texts() binds a property's VARCHAR2 and CLOB texts beside the long value, each read by the property's own path: CONTAINS, STARTS WITH, ENDS WITH, split and replace. Within a body given CLOBs, the CLOB alone. - A `+`, and a stored value plus or minus a duration, go through a new shared_sum() hook, shared() on Postgres. On Oracle a property side beside a long value is bound as three columns, each read by its own path: its JSON, null past 32,767 characters; its kind; its CLOB. The body's kind and CLOB reads are rewritten to those columns. - shared_bound() counts each binding, so _binds() still sees them. - On Oracle, a list plus a stored text past 32,767 characters gives null, as in drivine4j. Fixes #232
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Port of liberation-data/drivine4j#370 (drivine4j PR liberation-data/drivine4j#387, squash commit 8d6e12c4). Only the PR's final version is ported. Its first version, a
readInPlacehook, closed Oracle's session in the object manager's save, so drivine4j replaced it. Drivine for TypeScript's port is liberation-data/drivine#430.What happened
A text function or
+over a property and an operand whose SQL is long, such astoLower(trim(coalesce($p.q, m.name))), has its operands bound byshared()in aSELECT /*+ NO_MERGE */subquery. The property was bound there as JSON and then read as a CLOB from that JSON, so drivine4j#255's_direct()read never applied. On Oracle, a text past 32 KB read this way closed the session from the second run on, given two rows or more (ORA-03113, DPY-4011 here).Fix
The rule behind the fix: on Oracle, reading the outer row's properties beside a
NO_MERGEview can close the session, but reading them inside the view is safe.texts(), Oracle: binds a property'sVARCHAR2and CLOB texts beside the long value, each read by the property's own path. This covers CONTAINS, STARTS WITH, ENDS WITH,splitandreplace. In_longmode, only the CLOB is bound, as before.shared_sum(), a new hook: the+site calls it, and so does the temporal binary'sread(a stored value plus or minus a duration). On Postgres it is justshared(). On Oracle, a property side next to a long value is bound as three columns, each read by its own path:_BOUND_TEXT);The body's reads of the kind and the CLOB are rewritten to those columns, the way
_direct()rewrites reads.shared_bound(): counts each binding, so_binds()(which decides when an aggregate's argument is worked out first) still sees them.Differences from drivine4j
binds_long(values): this is drivine4j'sbinds(vararg values)._bindsis already taken here.Tests
tests/integration/test_cypher_compiled.py: drivine4j's cross-store test, with its sync copy regenerated. It runs on every store; on Oracle every statement runs three times on one session (one_session), and the session is checked after each (asked_again).tests/unit/test_oracle_item_property.py: drivine4j's SQL pins fromOracleItemPropertyTest:a.id + '->' + b.id;main, the Oracle case fails in both async and sync with DPY-4011 (the database closed the connection), and the 3 SQL pins fail. Neo4j and Postgres pass.ORACLE_TESTS=true uv run pytest -q, the whole suite, gave 5,120 passed, 298 skipped, 0 failed.ruff check,ruff format --check,pyrightandunasync.py --checkpass.Not covered
shared_sum.=,<>,INand>beside a long value;splitlist, read by index.Fixes #232