Repository navigation
Make a date or a moment from a week, an ordinal day or a quarter, and filter a grouping WITH by an aggregate in its WHERE, as drivine4j does, at Cypher spec v0.19.0 - #318
Merged
Conversation
… filter a grouping WITH by an aggregate in its WHERE, as drivine4j does, at Cypher spec v0.19.0 Ports drivine4j's #495 (merged as liberation-data/drivine4j#498) and #497 (merged as liberation-data/drivine4j#501), with the spec's liberation-data/drivine-cypher-spec#40 and #41. Calendar fields (#312): - date, localdatetime and datetime take {year, week[, dayOfWeek]}, {year, ordinalDay} and {year, quarter[, dayOfQuarter]}, beside a time and a timezone; localtime and time refuse them ("localtime() takes no field week."). - Written as numbers, the date is worked out when compiling (_calendar_date, proleptic Gregorian at any year) and made as {year, month, day} is, so it fails where Neo4j fails: two calendars, a day without its week or quarter, no year, a number past its range or not whole, a year past +-999,999,999. Week 53 of a 52-week year and a day of the quarter up to 92 run on into the next; ordinal day 366 of a common year fails. - Given by an expression, Temporals.of_calendar works it out in SQL; a field past its range gives the day 0, which the store fails on. A moment's date is read as a date first, as Oracle's JSON_VALUE reads a moment with day 0 as null. - dayOfQuarter is read off a temporal value. HAVING (#313): - check_aggregates takes the WHERE of a WITH that aggregates, or is DISTINCT, as filtering its groups; it refuses there only an aggregate in a comprehension's, a quantifier's, a reduce's or a pattern's own expressions. The message now says "unless its WITH aggregates". - SqlCypherCompiler._having makes each aggregate in that WHERE an item of the WITH (#havingN, named by _hidden as no text of the statement is, or the item that is that aggregate already), and reads a key written as its item is before its name as that item, compared as grouping compares them (a function's name in any case, a property's name as written, count(DISTINCT i) apart from count(i)). The made items are no variables after the WITH. The WHERE is still met after ORDER BY, SKIP and LIMIT; a CALL that imports the row reads it after the WITH too. The spec moves to v0.19.0. HELD in tests/cypher/cypher_spec.py holds the steps later ports own, each checked to fail until its port lands: #314 (null grouping, v0.17.0), #316 (Implicit grouping key's nested-body, order-term and any/none steps, v0.18.0), #317 (temporal from another, v0.19.0). drivine4j's CompilerRefusalTest, CypherQueryContract and CypherTemporalContract cases not in the spec are ported. Fixes #312 Fixes #313
…isleap, and say when an aggregate is refused
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 drivine4j's #495 (liberation-data/drivine4j#498) and #497 (liberation-data/drivine4j#501), with liberation-data/drivine-cypher-spec#40 and #41. The compiler follows Drivine for TypeScript's port of the same two.
Calendar fields (#312)
date,localdatetimeanddatetimetake{year, week[, dayOfWeek]},{year, ordinalDay}and{year, quarter[, dayOfQuarter]}, with a time and atimezonebeside them.localtimeandtimerefuse these fields.{year, month, day}is. That gives Neo4j's refusals at compile time: fields of two calendars, a day without its week or quarter, no year, a number past its range or not whole, and a year past ±999,999,999. Week 53 of a 52-week year and a day of the quarter up to 92 run on into the next. Ordinal day 366 of a common year fails.Temporals.of_calendarworks the date out in SQL. A field past its range gives day 0, and the store fails on it. A moment's date is read as a date first, because Oracle's JSON_VALUE reads a moment whose day is-00as null.dayOfQuartercan now be read off a temporal value.HAVING (#313)
WITHthat aggregates, or isDISTINCT, theWHEREfilters the groups. An aggregate there is now allowed, except inside a comprehension's, a quantifier's, a reduce's or a pattern's own expressions. The refusal's message now reads "… unless its WITH aggregates, …"._havingmakes each aggregate in thatWHEREan item of theWITH:#havingNby_hidden, which also names_anew_variable's variables, so the name is no text of the statement. Where an item already is that aggregate, its name is read instead.count(DISTINCT i)is notcount(i).WITH.WHEREis still met afterORDER BY,SKIPandLIMIT. ACALLthat imports the row reads it after theWITHtoo.Spec at v0.19.0.
HELD(tests/cypher/cypher_spec.py) holds the steps a later port owns. Each held step must still fail; one that passes fails the test, so its hold comes out when its port lands:The golden statements are unchanged. drivine4j's CompilerRefusalTest, CypherQueryContract and CypherTemporalContract cases that the spec doesn't hold are ported, and the sync twins are regenerated.
Fixes #312
Fixes #313