Type predicate expressions

A type predicate expression can be used to verify the type of a variable, literal, property or other Cypher® expression.

Syntax

<expr> IS :: <TYPE>

Where <expr> is any Cypher expression and <TYPE> is a Cypher type. For all available Cypher types, see the section on types and their synonyms.

Verify the type of a Cypher expression

UNWIND [42, true, 'abc', null] AS val
RETURN val, val IS :: INTEGER AS isInteger
val isInteger

42

true

true

false

'abc'

false

null

true

Rows: 4

Vector values and supertypes

The following examples use VECTOR values (constructed using the vector() function) with 3 dimensions and INTEGER8 coordinate type.

Verify a VECTOR<TYPE>(DIMENSION) value against a VECTOR the same coordinate type and dimension
WITH vector([1, 2, 3], 3, INTEGER8) AS vector
RETURN vector IS :: VECTOR<INTEGER8>(3) AS isVector
Table 1. Result
isVector

true

Rows: 1

Although it is not possible to store VECTOR values without a coordinate type and dimension, it is possible to use the VECTOR supertype (encompassing all combinations of VECTOR<TYPE>(DIMENSION)) in type predicate expressions.

Verify a VECTOR<TYPE>(DIMENSION) value against the VECTOR supertype
WITH vector([1, 2, 3], 3, INTEGER8) AS vector
RETURN vector IS :: VECTOR AS isVector
Table 2. Result
isVector

true

Rows: 1

The same is true for the supertypes VECTOR<TYPE> (which encompasses all VECTOR values with the same coordinate type regardless of the dimension) and VECTOR(DIMENSION) (which encompasses all VECTOR values with the same dimension regardless of the coordinate type).

Verify a VECTOR<TYPE>(DIMENSION) value against the VECTOR<TYPE> supertype
WITH vector([1, 2, 3], 3, INTEGER8) AS vector
RETURN vector IS :: VECTOR<INTEGER8> AS isInteger8Vector
Table 3. Result
isInteger8Vector

true

Rows: 1

Verify a VECTOR<TYPE>(DIMENSION) value against the VECTOR(DIMENSION) supertype
WITH vector([1, 2, 3], 3, INTEGER8) AS vector
RETURN vector IS :: VECTOR(3) AS isDimension3Vector
Table 4. Result
isDimension3Vector

true

Rows: 1

If the coordinate type or dimension in the VECTOR does not match what is specified in the type predicate expression, the result will be false.

Verify a VECTOR<TYPE>(DIMENSION) value against a VECTOR with a different dimension
WITH vector([1, 2, 3], 3, INTEGER8) AS vector
RETURN vector IS :: VECTOR(5) AS isDimension5Vector
Table 5. Result
isDimension5Vector

false

Rows: 1

Verify a VECTOR<TYPE>(DIMENSION) value against a VECTOR with a different coordinate type
WITH vector([1, 2, 3], 3, INTEGER8) AS vector
RETURN vector IS :: VECTOR<INTEGER16> AS isInteger16Vector
Table 6. Result
isInteger16Vector

false

Rows: 1

Type predicate expressions with NOT

It is also possible to verify that a Cypher expression is not of a certain type, using the negated type predicate expression IS NOT ::.

UNWIND [42, true, 'abc', null] AS val
RETURN val, val IS NOT :: STRING AS notString
val notString

42

true

true

true

'abc'

false

null

false

Rows: 4

Type predicate expressions for null

All Cypher types includes the null value. Type predicate expressions can be appended with NOT NULL. This means that IS :: returns true for all expressions evaluating to null, unless NOT NULL is appended.

RETURN
  NULL IS :: BOOLEAN AS isBoolean,
  NULL IS :: BOOLEAN NOT NULL AS isNotNullBoolean
isBoolean isNotNullBoolean

true

false

Rows: 1

Likewise, IS NOT :: returns false for all expressions evaluating to null, unless the type is appended with NOT NULL.

RETURN
  (null + 1) IS NOT :: DATE AS isNotDate,
  (null + 1) IS NOT :: DATE NOT NULL AS isNotNotNullDate
isNotDate isNotNotNullDate

false

true

Rows: 1

It is also possible to check whether a value is the only null value using the null type.

RETURN NULL IS :: NULL AS isNull
isNull

true

Rows: 1

Closed dynamic union types (INNER_TYPE_1 | INNER_TYPE_2…​) cannot be declared as NOT NULL. Instead, all the inner types should be individually declared as not nullable to achieve this behavior.

Note that all inner types in a closed dynamic union must be either nullable, or not nullable. This is because null values cannot be attributed to a specific type. A syntax error will be raised if the inner types are not of the same nullability.

RETURN 1 IS :: INTEGER NOT NULL | FLOAT
Error message
All types in a Closed Dynamic Union must be nullable, or be appended with `NOT NULL`.

Type predicate expression for properties

Type predicate expressions can also be used to filter out nodes or relationships with properties of a certain type.

A graph containing the following nodes is used for the example below:

The following query finds all Person nodes with an age property that is an INTEGER with a value greater than 18.

MATCH (n:Person)
WHERE n.age IS :: INTEGER AND n.age > 18
RETURN n.name AS name, n.age AS age
name age

'Charlie'

21

Rows: 1

The type PROPERTY VALUE can also be used to check whether a type is storable as a property. Types not storable in properties, such as MAP, will return false when checked with IS :: PROPERTY VALUE.

Type predicate expressions for numbers of different sizes

For numerical values passed in as parameters, Cypher does not take the size of the number into account. Cypher will therefore regard any exact numerical parameter as an INTEGER regardless of its declared size. For example, an INT16 or an INT32 passed through from a language library will both be treated by Cypher as an INTEGER. Note that any exact numerical parameter used must fit within the range of an INT64.

RETURN $int16param IS :: INTEGER AS isInteger
isInteger

true

Rows: 1

More information about parameters can be found here.

The vector-only coordinate types cannot be used as the numeric type to verify against in type predicate expressions.

Syntactical variations of type predicate expressions

Type predicate expressions allow for some alternative syntax:

<expr> IS TYPED <TYPE>
<expr> :: <TYPE>

For verifying that an expression is not of a certain type, the following alternative syntax is supported:

<expr> IS NOT TYPED <TYPE>

Use of ANY and NOTHING types

ANY is a supertype which matches values of all types. NOTHING is a type containing an empty set of values. This means that it returns false for all values.

RETURN 42 IS :: ANY AS isOfTypeAny, 42 IS :: NOTHING AS isOfTypeNothing
isOfTypeAny isOfTypeNothing

true

false

Rows: 1

Closed Dynamic Unions

Closed dynamic union types allow for the testing of multiple types in the same predicate.

UNWIND [42, 42.0, "42"] as val
RETURN val, val IS :: INTEGER | FLOAT AS isNumber
val isNumber

42

true

42.0

true

"42"

false

Rows: 3

List Types

Type predicate expressions can be used for LIST types, where the inner type of the elements in the list must be specified. If the inner type is not relevant, then the ANY type may be used.

For a LIST type check to return true, all values in the list must match the inner type.

UNWIND [[42], [42, null], [42, 42.0]] as val
RETURN val, val IS :: LIST<INTEGER> AS isIntList
val isIntList

[42]

true

[42, null]

true

[42, 42.0]

false

Rows: 3

An empty list will match on all inner types, even the NOTHING type.

RETURN
    [] IS :: LIST<NOTHING> AS isNothingList,
    [] IS :: LIST<INTEGER> AS isIntList,
    [] IS :: LIST<FLOAT NOT NULL> AS isFloatNotNullList
isNothingList isIntList isFloatNotNullList

true

true

true

Rows: 1

Lists can be combined with closed dynamic union types to create tests for heterogeneous lists.

WITH [1, 0, true, false] AS booleanList
RETURN booleanList IS :: LIST<BOOLEAN | INTEGER> as isMixedList
isMixedList

true

Rows: 1