Repository navigation
Pass on a CALL's imports through a leading WITH *, and work out a pattern comprehension that reads only the row per match - #309
Merged
Conversation
…tern comprehension that reads only the row per match, at Cypher spec v0.12.0 Ports drivine4j#472 (#304) and drivine4j#467 (#305), as Drivine for TypeScript's #490 does. - `_called_part` runs a CALL without brackets through `_starred_imports`: its leading `WITH *` names each variable the CALL imports, leaving out the compiler's own per-row UUID names. Bracket CALLs are as they were. - `_read` leaves out a bare `WITH *` where nothing is bound; its WHERE still filters the rows it reads. DISTINCT, ORDER BY, SKIP or LIMIT on it are refused as before. - `variables_read_in`, and `_pattern_comprehension` works out a body that reads none of the pattern's own variables per match in a derived table, so its aggregate is no longer the row query's. - Cypher spec synced from v0.10.0 to v0.12.0. drivine4j's two cross-engine tests ported, async and sync.
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.
Ports two merged drivine4j fixes, as Drivine for TypeScript's liberation-data/drivine#490 does, and syncs the Cypher spec from v0.10.0 to v0.12.0 (liberation-data/drivine-cypher-spec#35 and #37).
Fixes #304
Fixes #305
#304:
WITH *at the start of a CALL (port of liberation-data/drivine4j#472, merged as liberation-data/drivine4j#484)_called_partnow runs a CALL without brackets through_starred_imports. Its leadingWITH *(after the per-row UUIDUNWINDthat_anew_calladds) names each variable the CALL imports in place of the star. The compiler's own_made_anewnames are left out. A CALL that imports nothing keeps its clauses as they are.CALL (i),CALL (*)) keep their clauses as they are. Neo4j's star there gives none of the bracket imports, and the query sees them throughout anyway._read, a bareWITH *whereselect.boundholds only_made_anewnames returns the rows as they are. If it has aWHERE, that still filters them (_filtered_rows, so arandomUUID()in it is made for each row). With DISTINCT, ORDER BY, SKIP or LIMIT it is still refused ("A projection has at least one item").#305: a pattern comprehension whose body reads only the row (port of liberation-data/drivine4j#467, merged as liberation-data/drivine4j#488)
variables_read_in: the same asvariables_in, but it leaves out names that a comprehension, quantifier or reduce binds itself. It still counts a binder's own list, so[m IN [m.x] | m]reads the outerm. A nested pattern comprehension's or EXISTS's pattern counts in full._pattern_comprehension: a body that reads none of the pattern's own variables, and reads some variable or holds a subquery, is worked out per match in a derived table:(SELECT agg(pcN.v) FROM (SELECT <body> AS v FROM … WHERE …) pcN). Postgres refused these before ("must appear in the GROUP BY clause"). Literal, parameter andrandomUUID()bodies compile as before.WITH 1 AS p RETURN [p = ()-->() | length(p)]compiles byte for byte as before. drivine4j takespthere as the row's. The rows are the same either way.Spec version
Synced to v0.12.0, not v0.13.0. At v0.13.0 the only failures are the refusal cases of liberation-data/drivine-cypher-spec#38, "Aggregate in a WHERE" and "Implicit grouping key in a body or an ORDER BY" (4 refusal tests, on Postgres and on Oracle). Those are drivine4j#489/#482's aggregation refusals, which are #306 and #307 here. v0.13.0 differs from v0.12.0 only by spec #38.
Tests
column "n1.props" must appear in the GROUP BY clause), "CALL imports only what it names" and "RETURN *". Oracle failed the last two of those. Both failed with "A projection has at least one item". With the fix, all 516 spec tests pass on Neo4j, Postgres and Oracle.CypherQueryCrossEngineTestcases, as Drivine for TypeScript ported them, are added totests/integration/test_cypher_compiled.py, and to the sync twin throughscripts/unasync.py.SQL comparison
I compiled 4,074 statements on Postgres and on Oracle, before and after (8,148 compilations). The statements were every spec statement at v0.6.19, v0.12.0 and v0.13.0, the golden statements, every Cypher string in this repo's tests, samples and docs, drivine#482's corpus, and every Cypher literal in drivine4j's
CypherQueryCrossEngineTest.kt. SQL, prelude and parameters are compared. 8,020 are byte-identical. Each of the other 128 is a targeted shape:WITH *shapes.CALL () { WITH * RETURN i … }andCALL { WITH * RETURN * } RETURN i.tests/golden/statements.jsonis unchanged, and all 164 golden statements compile byte for byte as before. TCK Create3 #2 and #3 (MATCH () CREATE () WITH * CREATE ()) now compile.Cross-library: drivine4j has both fixes, and Drivine for TypeScript has them in liberation-data/drivine#490.