Repository navigation
Turn Oracle's JSON table transformation off in a query of two tables or more, so a node keeps its label test - #275
Merged
Conversation
…or more, so a node keeps its label test Port of liberation-data/drivine4j#432. Oracle's JSON table transformation rewrites several JSON reads of one node's props into one JSON_TABLE view, and beside another node's table that view lost the node's label and property tests: MATCH (a:N1), (b:N2) RETURN a.n + b.n, a.n - b.n gave 9 rows on Oracle, one for each two nodes, where Neo4j and Postgres give 1. A compiled query, a UNION, and each query of a write's procedure (SELECT ... INTO, FOR ... IN loops, the rows it returns) go through a new planned() hook. It does nothing on Postgres. On Oracle, a query that names the graph's node or edge table twice or more opens with /*+ NO_JSON_TABLE_TRANSFORM */, joined to a hint comment it already opens with. Spec v0.6.19: Postgres SQL is byte-identical for all 1,030 statements. On Oracle 248 change (177 queries, 70 writes, 1 temporal), each only by the hint, as in drivine4j. Fixes #258
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.
Fixes #258. Port of liberation-data/drivine4j#432.
Cause
Oracle's JSON table transformation (
FORCE_JSON_TABLE_TRANSFORM) rewrites several JSON reads of one node'spropsinto oneJSON_TABLEview. Beside another node's table, the view drops that node's label and property tests. On Oracle 23 (gvenzl/oracle-free:23-faststart), over N1, N2 and N3 seeded,MATCH (a:N1), (b:N2) RETURN a.n + b.n AS sum, a.n - b.n AS diffgave 9 rows here before this change ([4, 0], [4, -1], [4, -2], [5, 1], …), where Neo4j and Postgres give[[3, -1]].Fix
planned(query)hook inSqlCypherCompiler, which does nothing (Postgres).OracleCypherCompiler, a query that names the graph's node or edge table twice or more (\b(?:<graph>_node|<graph>_edge) \w, with the graph's name escaped) opens with/*+ NO_JSON_TABLE_TRANSFORM */. If the query already opens with a hint comment (/*+ NO_MERGE */), the hint joins it.UNION, and to each query of a write's procedure:SELECT … INTO(_select_into),FOR … INloops (_loop, andMERGE's match), and the rows it returns.SQL
Every statement of the Cypher spec (v0.6.19, 1,030 statements) was compiled before and after the change.
queries, 70 inwritesand 1 intemporal. The hint is the only change in each. It's added once in 235 statements, and twice or three times in 13 procedures. These are the same counts as drivine4j.Tests
test_properties_of_a_node_beside_another_nodes_table_give_the_rows_of_the_pattern_and_that_nodes_values(async and sync): drivine4j's 13 statements, plus review pass 1's two (an unlabelled neighbour with filters, and two nodes of one label with a relationship property), on Neo4j, Postgres and Oracle. On Oracle it failed before the fix and passes after.tests/unit/test_oracle_json_table_transform.py: where the hint goes and where it doesn't (a query of two tables, one table, aUNION, a declared function, a write'sSELECT … INTO, aMERGEloop, the graph name escaped, a hint comment joined, Postgres unchanged).Gates:
check_cypher_spec.py, ruff check and format, pyright,unasync.py --check, andORACLE_TESTS=true uv run pytest -q(5167 passed, 298 skipped).