cleishm / libcypher-parser

Cypher Parser Library
Apache License 2.0
149 stars 39 forks source link

Syntax error when combining CALL and WHERE #14

Closed jeffreylovitz closed 5 years ago

jeffreylovitz commented 5 years ago

Procedure calls cannot currently be succeeded by WHERE conditions:

$ echo "CALL db.labels() YIELD label WHERE label = 'fruit' RETURN label" | ./src/cypher-lint -a
<stdin>:1:31: Invalid input 'H': expected WITH
CALL db.labels() YIELD label WHERE label = 'fruit' RETURN label

Interpolating a WITH projection allows us to make this combination:

$ echo "CALL db.labels() YIELD label WITH label WHERE label = 'fruit' RETURN label" | ./src/cypher-lint -a
 @0   0..75  statement              body=@1
 @1   0..75  > query                clauses=[@2, @6, @12]
 @2   0..29  > > CALL               name=@3, YIELD=[@4]
 @3   5..14  > > > proc name        `db.labels`
 @4  23..29  > > > projection       expression=@5
 @5  23..28  > > > > identifier     `label`
 @6  29..62  > > WITH               projections=[@7], WHERE=@9
 @7  34..40  > > > projection       expression=@8
 @8  34..39  > > > > identifier     `label`
 @9  46..62  > > > binary operator  @10 = @11
@10  46..51  > > > > identifier     `label`
@11  54..61  > > > > string         "fruit"
@12  62..75  > > RETURN             projections=[@13]
@13  69..75  > > > projection       expression=@14
@14  69..74  > > > > identifier     `label`

The CALL...WHERE construction is supported in Neo4j.

cleishm commented 5 years ago

Hi @jeffreylovitz!

Thanks for picking up on this. While the opencypher TCK doesn't test for the use of a WHERE predicate on a CALL clause, I do think the grammar should support it.

This shouldn't be too hard to add. Would you be interested in doing so? You'd need to add an optional WHERE predicate to the call-clause in the parser (https://github.com/cleishm/libcypher-parser/blob/v0.6.2/lib/src/parser.leg#L326-L341), similarly to other clauses that accept this predicate (e.g. https://github.com/cleishm/libcypher-parser/blob/v0.6.2/lib/src/parser.leg#L306), and also update the AST builder call_clause to accept the AST nodes for the WHERE.

Cheers, Chris

jeffreylovitz commented 5 years ago

Thanks, @cleishm!

I can give this a shot. If I understand correctly, after making the changes you outline, the CALL interface will have to be extended for the functionality cypher_ast_call_get_predicate. Are there other tasks this change entails?

cleishm commented 5 years ago

Resolved by #17