Predicate Functions

Predicates are Boolean functions that return true or false for a given set of inputs. They are most commonly used in the WHERE clause of queries to filter subgraphs.

exists(property)

exists(property) returns true if the specified property exists on a vertex, edge, or map. This function is distinct from the EXISTS subquery clause.

Syntax: exists(property)

Returns:

An agtype Boolean value.

Parameters:

Name Description
property A property from a vertex or edge.

Query:

SELECT *
FROM cypher('graph_name', $$MATCH (n)
     WHERE exists(n.surname)
     RETURN n.first_name, n.last_name
$$) as (first_name agtype, last_name agtype);

Result:

first_name last_name
'John' 'Smith'
'Patty' 'Patterson'

EXISTS(path)

EXISTS(path) returns true if the specified path pattern matches at least one path in the graph.

Note!
Known limitation of EXISTS subqueries
In YMatrix AGE, an EXISTS subquery that references variables from an outer scope may fail with the error:
ERROR: could not devise a query plan for the given query.

  • Trigger condition:
    This occurs when EXISTS appears in the WHERE clause of an OPTIONAL MATCH, and the EXISTS pattern references a variable defined before that OPTIONAL MATCH.

  • Examples:
    Fails: MATCH (a:A) WITH a OPTIONAL MATCH (a)-[:incs]->(c) WHERE EXISTS((c)<-[:incs]-(a)) RETURN a, c;
    Succeeds: MATCH (a:A) WITH a OPTIONAL MATCH (a)-[:incs]->(c) WHERE EXISTS((c)<-[:incs]-()) RETURN a, c.

  • Cause:
    AGE translates OPTIONAL MATCH into a SQL LATERAL LEFT JOIN, and EXISTS into a SQL EXISTS SubLink. When the EXISTS sublink references an outer-scope variable, it creates a deeply nested structure: a LATERAL subquery containing an EXISTS sublink that references variables two levels up. YMatrix’s distributed query planner cannot generate a valid execution plan for such multi-level outer-variable references — a limitation of the underlying distributed planner.

  • Recommended workarounds:

    1. Merge the EXISTS pattern directly into the OPTIONAL MATCH pattern:
      MATCH (a:A) WITH a OPTIONAL MATCH (a)-[:incs]->(c)<-[:incs]-(a) RETURN a, c;
    2. Split the query into multiple steps to avoid referencing outer variables inside EXISTS within OPTIONAL MATCH:
      MATCH (a:A) WITH a OPTIONAL MATCH (a)-[:incs]->(c) WITH a, c WHERE c IS NULL OR EXISTS((c)<-[:incs]-()) RETURN a, c.

Note!
Scope of impact: This limitation applies only when all of the following conditions hold simultaneously:

  1. An OPTIONAL MATCH is used (which generates a LATERAL LEFT JOIN);
  2. EXISTS is used in its WHERE clause;
  3. The EXISTS pattern references a variable from the outer scope of that OPTIONAL MATCH.

EXISTS in regular MATCH, property existence checks (EXISTS(n.prop)), and EXISTS patterns that do not reference outer variables are unaffected.

Query:

SELECT *
FROM cypher('graph_name', $$
     MATCH (n)
     WHERE exists((n)-[]-({name: 'Willem Defoe'}))
     RETURN n.full_name
$$) as (full_name agtype);

Result:

full_name
'Toby Maguire'
'Tom Holland'