Repository navigation
Conversation
…eral A comparison may test a key against a set of values through a quantifier: `key op any(v1, v2)` (alias `either`) holds when the comparison holds for at least one member and `key op every(v1, v2)` (alias `all`) when it holds for every member. The quantifier composes with every operator; `between` takes parenthesized pairs. `in` is sugar for `= any(...)` and `not_in` (aliases `nin`, `notin`) for `!= every(...)`. An empty set is a syntax error and the quantifier words are not reserved. The set may be supplied by a `select`, `get`, `find`, `trace` or `navigate` subquery, which parses to a SubquerySymbol holding the command's CommandTree. The subquery's condition is detached from the enclosing condition. `trace <key> from <record>` traces links through one key. The unquoted word `null` is a literal for an absent value, accepted only with `=` and `!=`; the quoted string "null" stays a string. ExpressionSymbol exposes quantifier(); the token stream carries a quantified set as one ValueSetSymbol so criteria round-trip through CCL. Refs cinchapi/concourse#779, cinchapi/concourse#780, cinchapi/concourse#778, cinchapi/concourse#791, #53
A quantified set is written any[v1, v2], every[(1, 5), (10, 20)] and in [v1, v2], so brackets hold a collection everywhere in CCL and parentheses only group, call a function or form a pair. The change also removes the collision between a quantifier and a value function named with the same word. Parentheses around a set are a syntax error. Refs cinchapi/concourse#779, #53
SQL spells the existential quantifier SOME as well as ANY, and some reads correctly with the ordering operators, where any can be misread as every: age > some[20, 30, 40] holds when age exceeds at least one of them. The word is not reserved. Refs cinchapi/concourse#779
A subquery parsed with bound data kept each $name placeholder in its CCL, while its parsed command held the bound value. Its toString() then failed to parse without the bindings, and two subqueries with different bindings compared equal, because SubquerySymbol equality follows that CCL. The CCL of a subquery now holds the CCL of each bound value in place of its placeholder, so it parses to an equal subquery without the bindings. Refs cinchapi/concourse#780
CommandAnalysis answers what a whole command touches, and the commands that take an optional key, such as audit and diff, report that key. Compiler#analyze now reports the key of a keyed trace, such as manager in trace manager from 42. Refs cinchapi/concourse#778
The changelog states that a key named not_in, nin or notin has no CCL form on its own, and how to use one, and that an unquoted null in an existing statement now means an absent value. The Javadoc of ASTExpression#toString and of a subquery test names the bracket form of a value set, and the grammar's helper methods carry their parameter, result and failure tags. Refs cinchapi/concourse#779, cinchapi/concourse#791
The engine resolves a subquery that supplies a quantified value set as its own command, so Compiler#analyze of the enclosing statement does not report the subquery's keys, operators or timestamps. StatementAnalysis and CommandAnalysis now state that boundary and point to the analysis of the subquery's CommandTree. Refs cinchapi/concourse#780
The build regenerates Grammar.java and GrammarTokenManager.java on every compile, so an edit to either file lasts only until the next build. The suppressions they need now come from the generator: the grammar's class annotation also suppresses unchecked warnings, and the generator task removes the imports JavaCC copies into the token manager and marks that class @SuppressWarnings("unused").
The subquery test compares the order and page of a subquery with those of the same command parsed on its own, instead of checking that they exist. The keyed trace test parses a single record, a bracketed collection and a bare collection after each preposition. A new test checks that not_in, nin and notin are reserved words: a syntax error as an unquoted value or a key, a string when quoted, and still a stop in a navigation key.
…-and-null-literal Resolved conflicts in: - CHANGELOG.md: kept this branch's 4.2.0 (TBD) sections and develop's Distribution section in the same block, followed by develop's 4.1.1 (TBD) block. - src/main/java/com/cinchapi/ccl/generated/Grammar.java: regenerated from the merged grammar.
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.
Summary
Concourse is adding quantified comparisons (cinchapi/concourse#779), subqueries that supply a value set (cinchapi/concourse#780), a single-key
trace(cinchapi/concourse#778) and anullcriteria literal (cinchapi/concourse#791). Each one needs the CCL grammar and symbol model to express it before the driver and server can evaluate it. This change gives CCL that surface: the parser recognizes every form, the parsedExpressionSymbolexposes the quantifier and the value set, the token stream that Concourse uses to round-trip criteria carries them, and the local evaluator applies the quantifier.in/not_in(#53) land here as sugar for the equality quantifiers rather than as new operators, so Concourse needs no newOperatormember for them. Keyedtracelands here because it is the CCL form of thetrace(key, record)subquery source.A value set is delimited with square brackets,
any[...], because brackets already hold every collection in CCL ([1, 2, 3],[name, age]) while parentheses group conditions, call functions and, here, form abetweenpair. Brackets also keep a quantifier from colliding with a value function of the same name.Refs cinchapi/concourse#779, cinchapi/concourse#780, cinchapi/concourse#778, cinchapi/concourse#791. Closes #53.
Behavior
Quantified value sets
key op any[v1, v2, ...]means(key op v1) or (key op v2) or ...;eitherandsomeare aliases.key op every[v1, v2, ...]means(key op v1) and (key op v2) and ...;allis an alias. The words are case-insensitive and are not reserved, sostatus = allstill compares against the stringall.betweentakes a set of parenthesized pairs:age bw any[(1, 5), (10, 20)].key in [...]iskey = any[...]andkey not_in [...]iskey != every[...].not_in,ninandnotinare reserved words.any[]is a syntax error, and so is a set in parentheses such asany("a", "b"). A timestamp after the closing bracket applies to the comparison.ExpressionSymbol#quantifier()returnsQuantifierSymbol.ANYorEVERY, ornullfor a plain comparison.values()holds every member in order; forbetween, each consecutive pair is one member.ExpressionSymbol#createtakes a quantifier, and the rawContentexposesquantifier().Compiler#tokenizeandParsing#ungroupExpressionsemit oneValueSetSymbolin the value position for a quantified expression. It renders asany[v1, v2](or as pairs), so a token stream joined with spaces is valid CCL, andParsing#groupExpressionsandCompiler#parse(List<Symbol>, Multimap)rebuild the quantified expression from it, including$nameplaceholders inside the set.Compiler#evaluatetests each member with the usual single-value semantics (any stored value may satisfy it) and combines the results with the quantifier.Subqueries
select,get,find,traceornavigatecommand supplies the set, with its own condition, order, page and timestamp clauses:name = any[select name where group = "vip"],reports_to lnks2 any[trace manager from 42].betweenset.SubquerySymbolwhosevalue()is the subquery'sCommandTreeand whosetoString()is the subquery's CCL. A$nameplaceholder in the subquery renders as its bound value, so that CCL parses to an equal subquery without the bindings. The subquery's condition is not a child of the enclosing condition, andCompiler#analyzeof the enclosing statement does not report the subquery's keys, operators or timestamps; analyzing the subquery'sCommandTreedoes.Compiler#evaluatethrowsUnsupportedOperationExceptionfor a condition that holds a subquery; the engine resolves it.Keyed trace
trace <key> from <record>andtrace <key> from [<records>], withinorwithinin place offromand an optional timestamp, parse to aTraceSymbolwhosekey()is the key, andCompiler#analyzereports the key among the keys the command touches. The record-only forms are unchanged and report anullkey. A key with a bracket timestamp is rejected, as it is for the other single-key commands.Null literal
nullin any letter case parses toNullValueSymbol.INSTANCE, whosevalue()is Javanull. It is accepted with=and!=, alone or as a member of a set; any other operator rejects it with aSyntaxExceptionthat namesnull."null"stays a string, andValueSymbolrenders it with quotes so a round trip through CCL keeps it a string. An unquotednullfollowed by another word is a multi-word string.Compiler#evaluatepasses the literal to the evaluator as anulloperand and a missing key as anullstored value; the evaluator defines what absence means.API
ExpressionSymbolgains the abstract methodquantifier(). An implementation outside this library must add it; returningnullkeeps it a plain comparison.CCL_REFERENCE.mddocuments each form and the formal grammar;CHANGELOG.mdhas a4.2.0 (TBD)block.