Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Parser] Validate and collect all properties from a clause #693

Open
snj07 opened this issue May 3, 2023 · 3 comments
Open

[Parser] Validate and collect all properties from a clause #693

snj07 opened this issue May 3, 2023 · 3 comments

Comments

@snj07
Copy link

snj07 commented May 3, 2023

I want to collect all the properties used for filtering the data and do some validation on them. For example:

String query = "MATCH (start {name: 'v1'}) RETURN count(*) AS COUNT";
var statement = CypherParser.parse(query, options)

In the above query I want to collect vertex property "name". Similarly, I want to collect the properties used in other clauses like WHERE, WITH etc. Is there any possible way to access Clause list of Statement without using reflection so I can collect the properties?
Is it possible to convert org.neo4j.cypherdsl.core.Clause to org.neo4j.cypher.internal.ast.Clause so I can modify the parsed clauses and use Neo4jASTFactory class to create a new Statement?

@ikwattro
Copy link
Contributor

ikwattro commented May 3, 2023

For retrieving the property filters, you can make use of the recent Catalog feature -> https://neo4j-contrib.github.io/cypher-dsl/2023.3.0/#catalog-support

Here is a simple example and the output

    @Test
    void catalog_usage() {
        parseQuery("MATCH (start {name: 'v1'}) RETURN count(*) AS COUNT");

        parseQuery("MATCH (n:Person {name: 'bob'}) WITH n WHERE n.age > 20 RETURN bob");
    }

    private void parseQuery(String query) {
        Statement statement = CypherParser.parse(query);
        var catalog = statement.getCatalog();
        System.out.println("----");
        catalog.getAllPropertyFilters().forEach((key, value) -> {
            var labels = key.owningToken().stream().toList();
            var label = labels.size() > 0 ? labels.get(0) : "NONE";
            var propertyKey = key.name();
            value.forEach(propertyFilter -> {
                var clause = propertyFilter.clause().name();
                var operator = propertyFilter.operator().name();
                var left = propertyFilter.left().toString();
                var right = propertyFilter.right().toString();

                System.out.println("detected property filter on token `%s` for property `%s` during `%s` clause , operator is `%s`, left is `%s` and right is `%s`".formatted(
//                        owningType,
                        label,
                        propertyKey,
                        clause,
                        operator,
                        left,
                        right
                ));
            });
        });
    }
----
detected property filter on token `NONE` for property `name` during `MATCH` clause , operator is `EQUALITY`, left is `InternalPropertyImpl{cypher=start.name}` and right is `StringLiteral{cypher='v1'}`
----
detected property filter on token `Token[type=NODE_LABEL, value=Person]` for property `name` during `MATCH` clause , operator is `EQUALITY`, left is `InternalPropertyImpl{cypher=n.name}` and right is `StringLiteral{cypher='bob'}`
detected property filter on token `Token[type=NODE_LABEL, value=Person]` for property `age` during `WITH` clause , operator is `GREATER_THAN`, left is `InternalPropertyImpl{cypher=n.age}` and right is `NumberLiteral{cypher=20}`

@snj07
Copy link
Author

snj07 commented May 3, 2023

I cannot use 2023.3.0, as I'm using Java 11 and it requires Java 17. Is there any other possible way? Could you also suggest a way to add additional clause/filter in parsed dsl?

@michael-simons
Copy link
Collaborator

We don't have plans to backport the catalog feature to Java 8. And in addition, the recent Neo4j parser itself requires JDK 17, so we are bounded on that side anyway.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants